我正在构建一个简单的“Hello,World!”用于学习目的的遗传算法。我的人口是一群随机的弦。通过变异和交叉,字符串演变为“Hello,World!”。由于某种原因,我的人口将保持健康状态,并且似乎永远不会进化。其他时候,我的种群将达到目标基因“Hello,World”。我正在使用随机选择和单点交叉。虽然,当我使用锦标赛和轮盘选择时也会发生这种情况。

问题:
即使我通过突变使人群多样化,为什么我的人群变得过时并且没有达到目标基因?是由于遗传算法的随机性还是我的代码中的错误?

例如
种群中的每个染色体最终都将具有“HellV,Wor`dL”基因。即使经过10,000代的基因,它们也是相同的。其他时候,这些基因到达目标基因“Hello,World!”。 〜33代之后

  • 注意:
    下面的代码在使用Java时按预期工作。使用Java时,种群总能达到目标基因。另外,我今天才开始学习C++,因此很可能我的代码中有一个我看不到的缺陷。

  • 人口规模:333
    精英:真实
    精英比例:25%
    变异概率:20%
    交叉概率:95%
    选择类型:随机
    分频类型:一分

    编辑:
    我已经从这篇文章中删除了代码,而是添加了指向我的github的链接,因为它有数百行代码。

    Genetic Algorithm - C++

    最佳答案

    感谢@molbdnilo的评论,我得以解决我的问题。

    事实证明,这是因为C++如何复制对象,这解释了为什么此代码在Java中而不是C++中起作用。

    如@molbdnilo所述:



    为了解决我的问题,我更改了以下方法声明:

    1. int calculateFitness(GAChromosome chromosome); ---> int calculateFitness(GAChromosome const &chromosome);在此方法声明中,我告诉编译器我要使用&通过引用而不是通过值传递染色体,并使用const将其设为常数。这样做可以防止染色体被复制和更改。

    2. void mutate(GAChromosome chromosome); ---> void mutate(GAChromosome &chromosome);在此方法声明中,我告诉编译器我想使用&通过引用而不是通过值传递染色体。这样做可以防止复制染色体。由于先前的方法声明未指定染色体是通过引用传递的,因此在方法达到作用域末尾时,将进行复制,更改和丢弃的操作。最终,从未进行过更改。

    3. std::pair<GAChromosome, GAChromosome> onePointCrossover(GAChromosome chromosomeA, GAChromosome chromosomeB); ---> std::pair<GAChromosome, GAChromosome> onePointCrossover(GAChromosome const &chromosomeA, GAChromosome const &chromosomeB);在此方法声明中,我告诉编译器我要使用&通过引用而不是通过值传递染色体,并使用const将其设为常数。这样做可以防止染色体被复制和更改。

    总之,问题源于将染色体传递给变异方法的方式。染色体是通过值而不是通过引用传递的,这导致染色体被复制,并且当mutate方法到达作用域的末尾时,更改被抛出。

    07-24 19:13