交叉操作的实现
编程实现部分映射交叉规则的交叉操作,两点交叉
Step1
:对染色体群体前后相邻的两条染色体,根据交叉概率决定这两个染色体是否进行交叉操作;如果进行交叉操作,则执行 step2
,否则继续查找后面两条相邻染色进行判断,直至全部染色体判断完毕;
Step2
:随机生成
1
:
n*m
之间的两个点
p1
和
p2
;
Step3
:将父代染色体
C1
和
C2
在
p1
和
p2
两点间的基因片段交换,形成新的子代
D1
和
D2
Step4
:对子代
D1
和
D2
进行有效性处理
‐
编码不能有缺的,也不能有重复的;
Step4.1
:将两个交换片段对比,将不能抵消的代码保留下来;
Step4.2
:将不能抵消的代码逐次对子串进行替换
%交叉操作
function outChromes=crossChromes(chromes,crossRate)
pop=size(chromes,1); %其实就是种群的行数
cols=size(chromes,2); %确定基因片段的长度
for i=1:2:pop %每隔两个来判断一次
if rand()<crossRate %进行交叉操作
parent1=chromes(i,:);
parent2=chromes(i+1,:);
p=sortrows(randperm(cols,2)')'; %将行转置位列再排序再转置回来
crossP1=parent1(p(1):p(2)); %表示p(1)和p(2)这两个数值之间的数据
crossP2=parent2(p(1):p(2));
son1=parent1;
son1(p(1):p(2))=crossP2;
son2=parent2;
son2(p(1):p(2))=crossP1;
%子片段对比
crossLen=size(crossP1,2);
for j=crossLen:-1:1
midCode=crossP1(j);
for k=1:size(crossP2,2)
if crossP2(k)==midCode
crossP1(j)=[];
crossP2(k)=[];
break;
end
end
end
%染色体编码置换
repeatNum=size(crossP1,2);
if repeatNum>0
%对子代1的有效性置换
for j=1:repeatNum
midCode=crossP2(j);
if p(1)==1
for k=p(2)+1:cols
if son1(k)==midCode
son1(k)=crossP1(j);
break;
end
end
else
if p(2)==cols
for k=1:p(1)-1
if son1(k)==midCode
son1(k)=crossP1(j);
break;
end
end
else
getIt=0;
for k=1:p(1)-1
if son1(k)==midCode
son1(k)=crossP1(j);
getIt=1;
break;
end
end
if getIt==0
for k=p(2)+1:cols
if son1(k)==midCode
son1(k)=crossP1(j);
break;
end
end
end
end
end
end
%对子代2的有效性置换
for j=1:repeatNum
midCode=crossP1(j);
if p(1)==1
for k=p(2)+1:cols
if son2(k)==midCode
son2(k)=crossP2(j);
break;
end
end
else
if p(2)==cols
for k=1:p(1)-1
if son2(k)==midCode
son2(k)=crossP2(j);
break;
end
end
else
getIt=0;
for k=1:p(1)-1
if son2(k)==midCode
son2(k)=crossP2(j);
getIt=1;
break;
end
end
if getIt==0
for k=p(2)+1:cols
if son2(k)==midCode
son2(k)=crossP2(j);
break;
end
end
end
end
end
end
end
chromes(i,:)=son1;
chromes(i+1,:)=son2;
end
end
outChromes=chromes;
end