如果你只需要较少数量的点,那么暴力解法或许可以奏效。所谓的暴力解法指的是对于 2 到 10 的解进行预计算并在
N<=10
时进行数组查找。
对于这样小的 N
,通过数学优化问题,应该可以实现最佳点分布的求解。你需要多次启动才行,但对于小的 N
这不应该是个问题。下面是我在 AMPL 中的尝试:
param N;
var x;
var y;
var z;
var d;
param xbest;
param ybest;
param zbest;
param dbest;
maximize obj: d;
all_points_on_the_sphere:
x[i]^2 + y[i]^2 + z[i]^2 = 1;
all_pairs:
(x[i]-x[j])^2 + (y[i]-y[j])^2 + (z[i]-z[j])^2 >= d;
fix_first_x: x[1] = 1;
fix_first_y: y[1] = 0;
fix_first_z: z[1] = 0;
fix_second_z: z[2] = 0;
#############################################
option show_stats 1;
option presolve 10;
option substout 1;
option var_bounds 2;
#option nl_comments 0;
#option nl_permute 0;
option display_precision 0;
option solver "/home/ali/ampl/ipopt";
for
let _svar[j] := Uniform(-1, 1);
let d := N;
solve;
if (solve_result_num < 200 and d > dbest) then
}
}
print "@@@";
printf "N=%d, min distance %6f\n", N, sqrt(dbest);
for
printf "(%9.6f, %9.6f, %9.6f)\n", xbest[i], ybest[i], zbest[i];
}
在我的机器上运行这个脚本花费了5分钟,解决方案如下:
N=2,最小距离为2.000000
(1.000000,0.000000,0.000000)
(-1.000000,0.000000,0.000000)
N=3,最小距离为1.732051
(1.000000,0.000000,0.000000)
(-0.500000,0.866025,0.000000)
(-0.500000,-0.866025,0.000000)
N=4,最小距离为1.632993
(1.000000,0.000000,0.000000)
(-0.333333,-0.942809,0.000000)
(-0.333333,0.471405,-0.816497)
(-0.333333,0.471405,0.816497)
N=5,最小距离为1.414214
(1.000000,0.000000,0.000000)
(-0.208840,0.977950,0.000000)
(-0.000000,0.000000,1.000000)
(-0.212683,-0.977121,0.000000)
(0.000000,0.000000,-1.000000)
N=6,最小距离为1.414214
(1.000000,0.000000,0.000000)
(-1.000000,0.000000,0.000000)
(0.000000,-0.752754,-0.658302)
(0.000000,0.752754,0.658302)
(0.000000,0.658302,-0.752754)
(0.000000,-0.658302,0.752754)
N=7,最小距离为1.256870
(1.000000,0.000000,0.000000)
(-0.688059,-0.725655,0.000000)
(0.210138,-0.488836,-0.846689)
(0.210138,-0.488836,0.846688)
(-0.688059,0.362827,0.628435)
(-0.688059,0.362827,-0.628435)
(0.210138,0.977672,0.000000)
N=8,最小距离为1.215563
(1.000000,0.000000,0.000000)
(0.261204,-0.965284,0.000000)
(0.261204,0.565450,0.782329)
(-0.783612,-0.482642,-0.391165)
(0.261204,-0.199917,-0.944355)
(0.261204,0.882475,-0.391165)
(-0.783612,0.599750,0.162026)
(-0.477592,-0.399834,0.782329)
N=9,最小距离为1.154701
(1.000000,0.000000,0.000000)
(-0.500000,-0.866025,0.000000)
(0.333333,-0.577350,-0.745356)
(-0.500000,0.866025,0.000000)
(-0.666667,-0.000000,0.745356)
(-0.666667,0.000000,-0.745356)
(0.333333,-0.577350,0.745356)
(0.333333,0.577350,-0.745356)
(0.333333,0.577350,0.745356)
N=10,最小距离为1.091426
(1.000000,0.000000,0.000000)
(-0.605995,0.795469,0.000000)
(0.404394,0.816443,0.412172)
(-0.664045,-0.746251,-0.046407)
(0.404394,-0.363508,-0.839242)
(-0.664045,0.002497,0.747688)
(-0.605995,0.046721,-0.794096)
(0.404394,-
通过观察这些数字,很明显有些解决方案可以通过解析计算得出(例如sqrt(2)和sqrt(3))。我相信对于N=2、4和6,解决方案是直线([-1,0,0],[1,0,0])、四面体和八面体。
上述的点分布可能不是最佳的,没有
强烈的保证。非线性求解器可能会陷入局部极值;随着
N
的增长,局部极值的数量也会增加。
您可以将上述解决方案放在数组中,并在Python、C++或您使用的任何语言中使用它们。