适用范围:
1、算法流程图
2、部分使用函数解释说明:
randi([0,1],1,100);表示生成0到1的整数,生成1行长度为100的随机数
repmat(template,30,1);30表示行数,1表示列数,template是个结构体,相当于复制结构体
3、代码:
clc;clear;
nVar=100;
nPop=30;
maxIt=2000;%迭代200次
nPc=0,8;%代表交叉的比例
nC=round(nPc*nPop/2)*2 ;%代表迭代规模的大小,用round去掉整数,因为不能为小数,也不能为奇数,因为交叉是两个个体进行交叉,肯定为偶数,不能为奇数,所以要先除以2,再乘以2进行一个偶数化的处理
nMu=0.01;%定义变异概率
%定义结构体
template.x=[];
template.y=[];
Parent=repmat(template,nPop,1);%30表示行数,1表示列数,template是个结构体,相当于复制结构体
for i=1:nPop
Parent(i).x=randi([0,1],1,nVar);
Parent(i).y=fun(Parent(i).x);
end
%初始化种群结束
for It =1:maxIt
offspring=repmat(template,nC/2,2);%单列不好看出交叉结果,两列好看结果,故而写成2列形式,放在里面不是外面,放在外面的话会不断增长
%进行交叉操作
for j=1:nC/2
%选择两个
p1=selectPop(Parent);
p2=selectPop(Parent);
%进行交叉
[offspring(j,1).x,offspring(j,2).x]=crossPop(p1.x,p2.x);
end
offspring=offspring(:);%两列不好看,把他变成一列好进行for循环
for k=1:nC
offspring(k).x=mutatePop(offspring(k).x,nMu);
offspring(k).y=fun(offspring(k).x);
end
newPop=[Parent;offspring];%将父代种群和子代种群进行拼接
[~,so]=sort([newPop.y],'ascend');%对大的种群进行一个排序,升序;sort返回值和对应下标,因为值不需要,只要下表so
newPop=newPop(so);
Parent=newPop(1:nPop);
disp(['迭代次数:',num2str(It),',最小值为:',num2str(Parent(1).y)]);%每次迭代的第一个为最佳
end
function y=fun(x)
y=sum(x);
end
%选择操作
function p=selectPop(Parent)
%锦标赛选择法,选择两个个体进行比较,结果较为靠近fun(x)的留下,另一个淘汰
n=numel(Parent);%计算出总体样本的个数
index=randperm(n);%给出一个序列,序号值不重复,两个作为一组比较的对象
p1=Parent(index(1));
p2=Parent(index(2));
if p1.y<=p2.y
p=p1
else
p=p2
end
end
%交叉操作
function[y1,y2]=crossPop(x1,x2)
%单点交叉,不可选第一个点或者最后一个点,因为没有意义,相当于全部都交换了,那样还是那两个数组。比如两个1x8的数组,然后假设选定第四个点后的数据进行交换,那么两个数组第四个数值之后的数组都进行交换
n=numel(x1);
s=randi([1,n-1]);%因为最后一个位置没有意义,所以选到n-1
y1=[x1(1:s) x2(s+1:end)];
y2=[x2(1:s) x1(s+1:end)];
end
%变异操作
function p=mutatePop(x,mu)%mu表示变异概率
%单点变异
if rand<=mu %如果随机生成的概率小于变异概率,则进行变异
n=numel(x);
s=randi([1,n]);%变异点,这里不需要到n-1,因为每个点都有可能发生变异
if x(s)==0
x(s)=1;
elseif x(s)==1
x(s)=0;
end
end
p=x;%将结果输出到p
end
附上原作者b站链接: