遗传算法求点的分布问题

题目

在这里插入图片描述

问题分析

即: N个点相互直接的距离要尽可能大,且每一个点距离自身最近点的距离的差值需要尽可能小

代码解释:

对于方形域,使用笛卡尔坐标系,对于圆形域,使用极坐标系,对于球域,使用球坐标系,方便GA工具箱进行优化

编码方法:

xyrthetarphitheta 按顺序排列,每一条遗传链均由多个点的坐标顺序排列而成,并使用相同的方法进行解码,分别计算每个点距离最近点的距离,并相加,得到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
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值