使用遗传算法解决旅行商问题的时候,在交叉变异中如何产生正确可用的子代是个很重要的问题。有学者提出了Grefenstette编码。
下面我就写了其MATLAB如何实现的。
编码:s是种群数量,M是城市的个数。randperm(M)是随机产生初始城市序列。编码过程是:首先找到随机序列第一个元素假如为7在顺序序列1,2,…,M中的位置,就是7,记录下来,然后把这个元素7从顺序序列中去除,然后再寻找第二个元素假如是8在顺序序列中去掉第一个元素值7的位置,这时也是7。以此循环,知道随机序列每个元素的位置都找完。
pop=zeros(s,M);
for i=1:s
pop(i,1:M)=randperm(M); %产生1-t的随机数列
end
%% 编码
grePop=zeros(s,M); %原始种群Grefenstette编码的结果
for i=1:s %Grefenstette的编码
temp=[1:1:M];
for j=1:M
loc=find(pop(i,j)==temp);
grePop(i,j)=loc(1);
temp(loc(1))=[];
end
end
解码:grePop是上面产生的编码序列,当然是用就换成交叉变异后产生的自带编码。思路:首先判断子代序列第一个元素在顺序序列中的位置,然后将顺序序列该处的值给Pop第一个元素赋值,然后就把顺序序列该位置的元素去掉,然后再进行第二个元素操作。
for i=1:s %解码
temp=[1:1:M];
for j=1:M
pop(i,j)=temp(grePop(i,j));
temp(mutated(i,j))=[];
end
end