算法

该博客详细介绍了如何在Matlab中实现遗传算法,用于解决现代优化问题。通过代码展示了从数据预处理、距离矩阵计算到遗传算法的交叉和变异操作的全过程,旨在帮助读者理解遗传算法的工作原理及其在实际问题中的应用。
摘要由CSDN通过智能技术生成

关于 南叔学生的学习笔记-Matlab算法篇-现代优化算法 中遗传算法的代码详解**

其链接:
https://blog.csdn.net/seek97/article/details/108324749

话不多说,上代码!


%% 实现遗传算法## 
tic
clc,clear 
%% 实现遗传算法
tic                     %用来计时的这是开头,下面有toc作为结尾!
clc,clear 
figure(1)
data1=[
53.7121   15.3046     51.1758    0.0322    46.3253   28.2753    30.3313    6.9348 
56.5432   21.4188     10.8198   16.2529   22.7891   23.1045    10.1584    12.4819 
20.1050   15.4562     1.9451    0.2057      26.4951   22.1221    31.4847    8.9640 
26.2418   18.1760     44.0356   13.5401   28.9836   25.9879    38.4722    20.1731 
28.2694   29.0011     32.1910    5.8699    36.4863   29.7284    0.9718      28.1477 
8.9586    24.6635       16.5618   23.6143   10.5597   15.1178    50.2111    10.2944 
8.1519    9.5325        22.1075   18.5569    0.1215   18.8726     48.2077    16.8889 
31.9499   17.6309      0.7732    0.4656     47.4134   23.7783    41.8671    3.5667 
43.5474    3.9061       53.3524   26.7256  30.8165   13.4595    27.7133    5.0706 
23.9222    7.6306       51.9612   22.8511  12.7938   15.7307    4.9568      8.3669 
21.5051   24.0909      15.2548   27.2111   6.2070    5.1442      49.2430    16.7044 
17.1168   20.0354      34.1688   22.7571   9.4402    3.9200      11.5812    14.5677 
52.1181    0.4088        9.5559   11.4219   24.4509    6.5634     26.7213    28.5667 
37.5848   16.8474      35.6619    9.9333   24.4654    3.1644     0.7775      6.9576 
14.4703   13.6368      19.8660   15.1224   3.1616    4.2428      18.5245    14.3598 
58.6849   27.1485      39.5168   16.9371  56.5089   13.7090     52.5211   15.7957 
38.4300    8.4648       51.8181   23.0159   8.9983   23.6440      50.1156   23.7816 
13.7909    1.9510       34.0574   23.3960  23.0624    8.4319      19.9857   5.7902 
40.8801   14.2978      58.8289   14.5229  18.6635    6.7436      52.8423   27.2880 
39.9494   29.5114      47.5099   24.0664  10.1121   27.2662     28.7812   27.6659 
8.0831     27.6705      9.1556    14.1304   53.7989    0.2199     33.6490    0.3980 
1.3496    16.8359      49.9816    6.0828   19.3635    17.6622    36.9545   23.0265 
15.7320   19.5697     11.5118   17.3884  44.0398   16.2635     39.7139   28.4203 
6.9909     23.1804     38.3392   19.9950  24.6543   19.6057     36.9980   24.3992 
4.1591     3.1853       40.1400   20.3030  23.9876    9.4030      41.1084   27.7149
];                                       %加载敌方 100 个目标的数据 
x=data1(:,1:2:8);x=x(:);     % 经度     %1 3 5 7  后面那个步骤是将x第二列和第三列都放在排在第一列上
y=data1(:,2:2:8);y=y(:);     % 纬度     %2 4 6 8
data1=[x y];                       % 这个时候data1表示的就是第一列是经度,第二列全是纬度了
%也就是说这里以上的操作是整理数据,将维度和经度分别排成一列

d1=[70,40];                       %这里分别是基地的经度和纬度
data0=[d1;data1;d1]; 
%距离矩阵 d data0
data1=data0*pi/180;          %这里是将角度制换成弧度制
d=zeros(102);                %这里应该定点           %加载敌方 100 个目标的数据 
for i=1:101 
    for j=i+1:102 
        temp=cos(data1(i,1)-data1(j,1))*cos(data1(i,2))*cos(data1(j,2))+sin(data1(i,2))*sin(data1(j,2)); 
        %这里是公式Rarcos[cos(x1-x2)cos(y1)cos(y2)+sin(y1)+sin(y2)];
        %下面是给乘上了R和arccos
        %这里的数学公式是需要数学建模的
        %一般是二维平面上的话,两点距离公式:d=sqrt((x2-x1).^2+(y2-y1).^2)就行了,注意这里是点方!因为数据是矩阵!
        d(i,j)=6370*acos(temp); 
    end 
end 
d=d+d'; %这个步骤没搞懂   自己试了一下发现可能是将是零的位置补全,但就是会留一条斜0
             %是为了构造一个对称矩阵   如果不记得为什么要的话可以去看看https://blog.csdn.net/AlexiosQ/article/details/115036181?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161993157116780262510237%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=161993157116780262510237&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-5-115036181.pc_search_result_hbase_insert&utm_term=matlab%E4%B8%AD%E6%94%B9%E8%89%AF%E5%9C%88%E7%AE%97%E6%B3%95&spm=1018.2226.3001.4187
L=102;  
w=50;%种群个数
dai=100; 
%通过改良圈算法选取优良父代 A 
%改良圈算法其实就是也是不断地改变位置然后缩小两目标之间的距离
for k=1:w 
    c=randperm(100); 
    c1=[1,c+1,102]; %1(基地的位置固定),102(回到基地的位置) 而1-102之间是敌方飞机的随机位置 
    %c1是从1-102的原始圈
    flag=1;         %应该只是一个用来判断的值
 while flag>0       %若是没有需要修改的圈数(flag=0)则直接跳出,减少计算量    
      flag=0;  
   for m=1:L-3       %L表示的是1-102的要处理的目标   然后 L-3 是一次性处理三条边
      for n=m+2:L-1  %n从m+2开始,是因为要已经用了 m 和 m+1,而最后有个 n+1 就不用到 L 了只需要到 L-1
        if d(c1(m),c1(n))+d(c1(m+1),c1(n+1))<d(c1(m),c1(m+1))+d(c1(n),c1(n+1)) %若是改变后的距离小于原始距离的话就变为改良圈,否则不变
           flag=1; 
           c1(m+1:n)=c1(n:-1:m+1); %换完后的改良圈与原始圈更换,要改良圈
        end 
      end 
   end 
 end 
  J(k,c1)=1:102; %记录下优化完后较好的解  你会发现所有的距离都是先相同的
end 
J=J/102;  
J(:,1)=0;
%产生 0~1间随机数列进行编码 相当于转化成染色体编码
%经过上两部之后你会发现第一列全是0,最后一列全是1  
%成功转换成了[0,1]的实数
J(:,102)=1; 
rng('default');  %rng是一种可以控制rand或者randi函数产生的随机数的函数   而这里的default是用来固定随机数的
%使用方法:
           % s=rng          %先固定,将其引出来
           % x=rand(2,4)   %再随机设定一个数用于储存
           % rng(s)         %储存x产生的随机数组
           % y=rand(2,4)    %此时y产生的与x产生的是相同的

%遗传算法实现过程 
A=J; 
for k=1:dai %迭代次数
    B=A; 
    c=randperm(w); 
%交配产生子代 B 
    for i=1:2:w   
        F=2+floor(w*rand(1)); %这里乘以w种群数或者迭代数die都可以,自己试一下看哪个效果更好,下面一个也一样
        %产生交叉操作的地址
        %其实本来这里需要和下面变异一样先找出能进行交叉的位置的
        %也就是需要一个by1=find(rand(1,w)<pc);w是种群数量
        temp=B(c(i),F:102); 
        B(c(i),F:102)=B(c(i+1),F:102); 
        B(c(i+1),F:102)=temp; 
    end 
%变异产生子代 C 
by=find(rand(1,w)<0.1); %找到所有概率小于pm=0.1的位置,也就是他们的地址
%下面这串的意义暂时不知道在哪里,因为有了上面这句话了已经
% if length(by)==0 
%     by=floor(50*rand(1))+1; %感觉如果用了上面那一个的话应该这一步就不需要了?
% end 
C=A(by,:);              %产生的变异操作的初始染色体
L3=length(by);          %需要变异的个体次数!
for j=1:L3              %变异次数
   bw=2+floor(dai*rand(1,3)); %为什么是rand(1,3)呢? 是因为下面用到了bw(1),2,3来进行“重组变异”,其实rand(1,2)也可以的,那下面就是只能用到bw(2)
   bw=sort(bw); 
   C(j,:)=C(j,[1:bw(1)-1,bw(2)+1:bw(3),bw(1):bw(2),bw(3)+1:102]); %类似于重组?他是[ 1:33,49:49,33:48,50:102]总共遍历的还是从1-102。
   %这里是对上面的解释C(j,:)=C(j,[1:bw(1)-1,bw(1):bw(2)-1,bw(2):bw(3)-1,bw(3):102]);%怎么感觉有点类似于交叉啊。。。
   %C(j,bw)=
end 
   G=[A;B;C];         %父代和子代种群合在一起   B是交叉子代,C是变异子代
   TL=size(G,1);      %行数
   %在父代和子代中选择优良品种作为新的父代 
   [dd,IX]=sort(G,2); %dd记录数值,IX记录数值的位置  也可以说是将染色体翻译成所在的位置->1-102序列
   temp(1:TL)=0;      %初始化长度其实也可以直接用temp=zeros(1,TL);
   for j=1:TL         %计算每条路径的长度
       for i=1:101 
           temp(j)=temp(j)+d(IX(j,i),IX(j,i+1)); 
       end 
   end 
     [DZ,IZ]=sort(temp);   %对路径长度从小到大排列,并选出其位置和数值
     A=G(IZ(1:w),:);       %选出w个较短路径对应的染色体
end 
path=IX(IZ(1),:)           %解的路径
long=DZ(1) ;
toc                        %用来计时的
xx=data0(path,1);yy=data0(path,2); 
plot(xx,yy,'-o') 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值