Matlab中的两点交叉

时间:2014-10-13 00:30:53

标签: matlab genetic-algorithm crossover

在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的评论中提供了进一步的解释。

3 个答案:

答案 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点交叉