【问题标题】:Two point crossover in MatlabMatlab中的两点交叉
【发布时间】:2014-12-07 12:18:06
【问题描述】:

在 Matlab 中实现两点交叉的最佳方法是什么?两点交叉描述为here。请注意,在我的应用程序中,我无法在任何地方拆分列表。它们按四个分组,因此允许拆分列表的位置(染色体)是 4、8、12 等等(这是因为我的应用程序是线性遗传编程问题)。

我试过这个,但它不起作用,因为有时我得到的染色体有许多不能被四整除的元素。我需要帮助弄清楚如何让它发挥作用。

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

EDIT. 似乎有些混乱。我想要我的代码描述的交叉版本。在此代码中,每个染色体的片段长度不同。这意味着我在进行交换时会改变染色体的大小,这是有意的。 McMa 的评论中提供了进一步的解释。

【问题讨论】:

  • 随机数的生成成本很低。为什么不通过 round(rand(1)*length(chromosomeLength)/4)*4 生成第一个随机数,然后通过相同的公式生成第二个并检查是否等于过去的?
  • @ASantosRibeiro 为什么会比我现在做的更好?
  • 完全一样(相同的随机生成器和相同的意识形态),只是方式不同,因为我不明白你的问题,因为它已经优化了。
  • 此外,问题似乎与优化无关,但当您创建“newChromosome1”和“newChromosome2”时,您的代码似乎不正确

标签: matlab genetic-algorithm crossover


【解决方案1】:

保持一切原样,因为它已经优化,并更正:

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 ) ];

【讨论】:

    【解决方案2】:

    使用单个 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 点交叉。

    另外,xOver=4*sort(randperm(len-1,2)); 将排除 randperm() 返回最大值 len 的可能性,这将导致较小向量仅发生 1 点交叉

    【讨论】:

    • 没有理由选择最短的长度。然后它永远不会从较长的染色体末端挑选元素。也没有必要使用floor,因为染色体总是可以被 4 整除,因为它们使用该数量的组件编码指令。这也是不正确的,因为您从两条染色体中选择了相同的片段。应该从不同的染色体中挑选出不同的片段,然后交换它们。
    • 不同长度向量中的N点交叉将始终使它们之间的差异保持不变,因为它们没有对应要交叉的对应关系。如果这是一个问题,您将不得不选择不同的重组方法:/
    • 你错了。我面前有一本书支持我的交叉版本。 N点分频有很多版本,但我已经明确了我想要哪一个。
    • 我对n点交叉的理解不允许这样做,但是如果您介意分享本书的部分内容,我的代码应该很容易适应它。
    • 我认为如果您阅读我的代码会有所帮助,因为它或多或少地完成了我正在尝试做的事情。假设我取出第 1 号染色体中的第 5 到第 7 号元素。然后我取出第 2 号染色体中的第 3 到第 9 号元素。然后我将这六个元素放在第 1 号染色体中的第 4 号和第 8 号元素之间。然后我从第 1 号染色体中取出元素,然后将它们放在旧元素 2 和 10 之间的 2 号染色体中。染色体的总长度适应变化的长度,所以 1 号染色体中的 8 号元素现在是 11 号元素。
    【解决方案3】:

    我不确定您是否正确理解了 randperm 函数。 此外,2 点交叉通常不限于长度可被 4 整除的染色体。

    恕我直言,最简单的方法是绘制两个随机数来定义您的交叉点并存在于 [1,chromiumLength] 范围内。不仅仅是简单地交换这些点之间的信息。我认为您不需要 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 ) 会导致异常

    【讨论】:

    • 遗传算法用于许多事情。在这种情况下,这是一个线性遗传编程问题,其中四个基因的序列编码一个“指令”。第一个基因是操作符,第二个是目的寄存器,第三和第四个是操作数。我无法拆分指令,因此我需要交叉点位于 4、8、12 等处。我正在使用 randperm 来获取区间中的两个唯一数字。如果我使用randi,我可能会得到两个相同的。异常是一个大问题;你正在避免所有困难的事情......
    • 好的,我还没有看到这是一个遗传编程问题。在这种情况下,交换完整的指令集而不是单个位是有意义的……对不起,我的错。
    猜你喜欢
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-21
    • 2015-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多