题目
问题分析
即: N个点相互直接的距离要尽可能大,且每一个点距离自身最近点的距离的差值需要尽可能小
代码解释:
对于方形域,使用笛卡尔坐标系,对于圆形域,使用极坐标系,对于球域,使用球坐标系,方便GA工具箱进行优化
编码方法:
将x
,y
或r
,theta
或r
,phi
,theta
按顺序排列,每一条遗传链均由多个点的坐标顺序排列而成,并使用相同的方法进行解码,分别计算每个点距离最近点的距离,并相加,得到N个点距离最近点的距离之和,另外,计算该距离的平均值,并求出方差和,以权重系数bias_2
相乘加入返回结果中,根据多次实验,bias_2=0.3 bias_1=0.7
时可以满足题目条件,因此,通过GA工具箱进行不断求解,下面展示部分结果,不同数目的点仅需更改Num
值即可。
部分效果:
注: 三维图在二维中不便观察,但是通过多视角拖动,此六点均在圆三个轴的六个顶点处,符合题目要求。
代码如下:
GA工具箱的使用方法可以参考上一篇文章,只需要更改函数名、变量数量、upper_bound即可
方形:
function result = allocate(a)
Num = 9;
sum = 0;
bias_1 = 0.7;
bias_2 = 1 - bias_1;
x = [];
y = [];
for i = 1:Num
x(i) = a(i*2-1);
y(i) = a(i*2);
end
for i = 1:Num
min = 9999;
for j = 1:Num
if i == j
break
end
dis = sqrt(power((x(i)-x(j)), 2)+power((y(i)-y(j)), 2));
if min > dis
min = dis;
end
end
if min ~= 9999
sum = sum + min;
end
end
mid = sum/Num;
adjust = 0;
for i = 1:Num
min = 9999;
for j = 1:Num
if i == j
break
end
dis = sqrt(power((x(i)-x(j)), 2)+power((y(i)-y(j)), 2));
if min > dis
min = dis;
end
end
if min ~= 9999
adjust = adjust + bias_2*abs(min - mid);
end
end
sum*bias_1;
adjust;
result = -bias_1*sum + adjust;
%x_1 = a(1);
%y = a(2);
end
方形可视化:
function plots(a)
Num = 9;
x = [];
y = [];
for i = 1:Num
x(i) = a(i*2-1);
y(i) = a(i*2);
end
% plot(x(1),y(1), '*');
for i = 1:Num
plot(x(i), y(i), '*');
[x(i),y(i)]
hold on;
end
end
圆形
function result = allocate_circle(a)
Num = 8;
sum = 0;
bias_1 = 0.7;
bias_2 = 1 - bias_1;
% x为r,y为theta
x = [];
y = [];
for i = 1:Num
x(i) = a(i*2-1);
y(i) = a(i*2);
end
for i = 1:Num
min = 9999;
for j = 1:Num
if i == j
break
end
x_1 = x(i)*cos(y(i));
y_1 = x(i)*sin(y(i));
x_2 = x(j)*cos(y(j));
y_2 = x(j)*sin(y(j));
% dis = sqrt(power((x(i)-x(j)), 2)+power((y(i)-y(j)), 2));
dis = sqrt(power(x_1-x_2, 2)+power(y_1-y_2, 2));
if min > dis
min = dis;
end
end
if min ~= 9999
sum = sum + min;
end
end
mid = sum/Num;
adjust = 0;
for i = 1:Num
min = 9999;
for j = 1:Num
if i == j
break
end
x_1 = x(i)*cos(y(i));
y_1 = x(i)*sin(y(i));
x_2 = x(j)*cos(y(j));
y_2 = x(j)*sin(y(j));
% dis = sqrt(power((x(i)-x(j)), 2)+power((y(i)-y(j)), 2));
dis = sqrt(power(x_1-x_2, 2)+power(y_1-y_2, 2));
if min > dis
min = dis;
end
end
if min ~= 9999
adjust = adjust + bias_2*abs(min - mid);
end
end
sum*bias_1;
adjust;
result = -bias_1*sum + adjust;
%x_1 = a(1);
%y = a(2);
end
圆形可视化
function plots_circle(a)
Num = 8;
x = [];
y = [];
for i = 1:Num
x(i) = a(i*2-1);
y(i) = a(i*2);
end
% plot(x(1),y(1), '*');
for i = 1:Num
plot(x(i)*cos(y(i)), x(i)*sin(y(i)), '*');
[x(i),y(i)]
hold on;
end
theta=0:2*pi/3600:2*pi;
r = 1;
Circle1=0+r*cos(theta);
Circle2=0+r*sin(theta);
plot(Circle1,Circle2,'m','Linewidth',1);
end
球
function result = allocate_qiu(a)
Num = 6;
sum = 0;
bias_1 = 0.7;
bias_2 = 1 - bias_1;
% x为r,y为theta,z为phi
x = [];
y = [];
z = [];
for i = 1:Num
x(i) = a(i*3-2);
y(i) = a(i*3-1);
z(i) = a(i*3);
end
for i = 1:Num
min = 9999;
for j = 1:Num
if i == j
break
end
x_1 = x(i)*cos(z(i))*cos(y(i));
y_1 = x(i)*cos(z(i))*sin(y(i));
z_1 = x(i)*sin(z(i));
x_2 = x(j)*cos(z(j))*cos(y(j));
y_2 = x(j)*cos(z(j))*sin(y(j));
z_2 = x(j)*sin(z(j));
% dis = sqrt(power((x(i)-x(j)), 2)+power((y(i)-y(j)), 2));
% dis = sqrt(power(x_1-x_2, 2)+power(y_1-y_2, 2));
dis = power(power(x_1-x_2,2)+power(y_1-y_2,2)+power(z_1-z_2,2),1/3);
if min > dis
min = dis;
end
end
if min ~= 9999
sum = sum + min;
end
end
mid = sum/Num;
adjust = 0;
for i = 1:Num
min = 9999;
for j = 1:Num
if i == j
break
end
x_1 = x(i)*cos(z(i))*cos(y(i));
y_1 = x(i)*cos(z(i))*sin(y(i));
z_1 = x(i)*sin(z(i));
x_2 = x(j)*cos(z(j))*cos(y(j));
y_2 = x(j)*cos(z(j))*sin(y(j));
z_2 = x(j)*sin(z(j));
% dis = sqrt(power((x(i)-x(j)), 2)+power((y(i)-y(j)), 2));
% dis = sqrt(power(x_1-x_2, 2)+power(y_1-y_2, 2));
dis = power(power(x_1-x_2,2)+power(y_1-y_2,2)+power(z_1-z_2,2),1/3);
if min > dis
min = dis;
end
end
if min ~= 9999
adjust = adjust + bias_2*abs(min - mid);
end
end
sum*bias_1;
adjust;
result = -bias_1*sum + adjust;
%x_1 = a(1);
%y = a(2);
end
球可视化
function plots_qiu(a)
Num = 6;
x = [];
y = [];
z = [];
for i = 1:Num
x(i) = a(i*3-2);
y(i) = a(i*3-1);
z(i) = a(i*3);
end
% plot(x(1),y(1), '*');
for i = 1:Num
% plot(x(i)*cos(z(i))*cos(y(i)), x(i)*cos(z(i))*sin(y(i)), '*');
scatter3(x(i)*cos(z(i))*cos(y(i)),x(i)*cos(z(i))*sin(y(i)),x(i)*sin(z(i)),'k');
[x(i)*cos(z(i))*cos(y(i)),x(i)*cos(z(i))*sin(y(i))];
hold on;
end
end