在Matlab中实现两点交叉的最佳方法是什么?两点交叉描述here。请注意,在我的应用程序中,我无法将列表拆分到哪里。它们按四个分组,因此允许分割列表(染色体)的位置是4,8,12等等(这是因为我的应用程序是线性遗传编程问题)。 / p>
我尝试了这个,但它不起作用,因为有时我得到的染色体有许多元素,这些元素不能被4整除。我需要帮助找出如何使其发挥作用。
function newPopulation = Crossover( population, p )
newPopulation = population;
for i=1:2:length(population)
if p < rand
[newPopulation{i}, newPopulation{i+1}] = PerformCrossover( newPopulation{i}, newPopulation{i+1} );
end
end
end
function [newChromosome1, newChromosome2] = PerformCrossover( c1, c2 )
l1 = length(c1)/4;
l2 = length(c2)/4;
i1 = 4*sort( randperm( l1, 2 ) )-[3 4];
i2 = 4*sort( randperm( l2, 2 ) )-[3 4];
newChromosome1 = [ c1( 1:l1<i1(1) ) c2( i2(1):i2(2) ) c1( 1:l1>i1(2) ) ];
newChromosome2 = [ c2( 1:l2<i2(1) ) c1( i1(1):i1(2) ) c2( 1:l2>i2(2) ) ];
end
编辑。似乎有些混乱。我想要我的代码描述的交叉版本。在此代码中,每条染色体的片段长度不同。这意味着当我进行交换时,我会改变染色体的大小,这是有意的。 McMa的评论中提供了进一步的解释。
答案 0 :(得分:2)
将所有内容保留原样,因为它已经过优化,并更正了这一点:
i1 = 4*sort( randperm( l1, 2 ) )-[3 3];
i2 = 4*sort( randperm( l2, 2 ) )-[3 3];
newChromosome1 = [ c1( 1:i1(1) ) c2( i2(1)+1:i2(2)-1 ) c1( i1(2):end ) ];
newChromosome2 = [ c2( 1:i2(1) ) c1( i1(1)+1:i1(2)-1 ) c2( i2(2):end ) ];
答案 1 :(得分:0)
我不确定你是否正确理解了randperm功能。 此外,2点交叉通常不限于可被4整除的长度的染色体。
恕我直言最简单的方法是绘制两个定义交叉点的随机数,并存在于[1,chromosomeLength]范围内。而不仅仅是简单地交换这些点之间的信息。我认为你不需要randperm功能...
% use randi(n) that gives a random integer in the range [0,n]
% create the first crossover point pos1 in the interval [1, chromosomelength-1]
% create the second crossover point pos2 in the interval [pos1+1, chromosomeLength)]
newChromosome1 = [ c1( 1 : pos1-1 ) ) c2( pos1 : pos2-1 ) c1( pos2 : chromosomeLength ) ];
newChromosome2 = [ c2( 1 : pos1-1 ) ) c1( pos1 : pos2-1 ) c2( pos2 : chromosomeLength ) ];
另外你可能会处理pos1得到值1的情况,因为c1(1:1-1)会导致异常
答案 2 :(得分:0)
使用不带混合参数的单randperm()
应该有效:
function [newChromosome1, newChromosome2] = PerformCrossover( c1, c2 )
len=floor(min(length(c1),length(c2))/4);
xOver=4*sort(randperm(len,2));
newChromosome1=[c1(1:xOver(1)),c2(xOver(1)+1:xOver(2)),c1(xOver(2)+1:end)];
newChromosome2=[c2(1:xOver(1)),c1(xOver(1)+1:xOver(2)),c2(xOver(2)+1:end)];
end
这将是可以被4整除的2分段交叉。
Additionaly xOver=4*sort(randperm(len-1,2));
将排除randperm()
返回len
的最大值的可能性,这将导致较小的向量只有1点交叉