【问题标题】:Crossover in genetic algorithm遗传算法中的交叉
【发布时间】:2016-08-31 03:24:45
【问题描述】:

我得到错误的部分(更具体地说,我得到一个弹出窗口说 Debug error!Abort () 已被调用)是我尝试进行交叉的部分。

for (int i = 0; i < number_of_variables; i++)
    {
        int gene1 = gene_selection(rng);
        std::cout << gene1 << " ";
        if (gene1 == 0)
        {
            std::cout << "test 0";
            new_individuals[k].chromosomes[0].at(i) = individuals[father].chromosomes[0].at(i);
        }
        else if (gene1 == 1)
        {
            std::cout << "test 1";
            new_individuals[k].chromosomes[0].at(i) = individuals[mother].chromosomes[0].at(i);
        }
    }

它足以显示“测试 0”或“测试 1”,但实际上不会将来自父亲/母亲的基因分配给 new_individual。

我尝试改变将旧基因分配给新个体的线路,但无论我尝试什么,我都无法让它发挥作用。

如果有人能告诉我我在哪里(或如何)搞砸了,我将非常感激 :)

编辑:通过调试器,我得到以下内容

http://prnt.sc/b0iprq LearnCPP.exe 中 .... 处未处理的异常:Microsoft C++ 异常:内存位置的 std::out_of_range .....

另一个编辑:为了清楚起见,正是发生中止的这一行:

new_individuals[k].chromosomes[0].at(i) = individuals[father].chromosomes[0].at(i);

【问题讨论】:

  • 找出问题所在的最佳方法是使用调试器单步调试代码。
  • 我做到了,但这并没有让我更清楚:\ prnt.sc/b0iprq 是我得到的。在文本中:LearnCPP.exe 中 .... 处的未处理异常:Microsoft C++ 异常:内存位置处的 std::out_of_range .....
  • 检查ki 是否包含有效值以在到达该行时访问元素。
  • 我只是这样测试的:new_individuals[1].chromosomes[0].at(0) = individual[father].chromosomes[0].at(0);哪个应该是有效值。父亲和母亲也都有一个有效值,我通常会输出它,但我在将代码发布到此处之前对其进行了修剪。我也只是在尝试将值分配给新向量之前简单地让它输出 i 和 k 来尝试它,它输出 i = 0 和 k = 1 这是正确的。

标签: c++ genetic-algorithm crossover


【解决方案1】:

我很惊讶你得到“test0”或“test1”,没有std::endl

关注new_individuals的故事

你分配和调整它的大小

std::vector<one_individual> new_individuals;
new_individuals.resize(population_size);

接下来这个resize(),你有一个population_size(5)个one_individual元素的向量,其中chromosomes是大小为0的std::vector&lt;std::vector&lt;double&gt;&gt;

接下来你调整chromosomes的大小

for (int i = 0; i < population_size; i++)
{
    new_individuals[i].chromosomes.resize(number_of_variables);
}

此时您的cromosomes 大小为number_of_variables (7),但这是什么意思?

这意味着每个cromosomes 都是大小为零的七个std::vector&lt;double&gt; 中的一个std::vector

所以,当你访问

new_individuals[k].chromosomes[0].at(i)

带有k == 1(为什么是1而不是0?)和i == 0new_individual[1].chromosomes[0]存在但是的大小为0,new_individuals[k].chromosomes[0].at(i)检查chromomoses[0]的大小以查看是否至少1,失败并导致异常(std::out_of_range

您的意图是分配每个new_individuals[i].chromosomes[j]

或者你的意图是写

new_individuals[k].chromosomes[0].push_back(individuals[father].chromosomes[0].at(i));

?

ps:对不起,我的英语不好。

--- 编辑---

如果您打算预订 7x7 chromosomes,一种方法可以是

for (int i = 0; i < population_size; i++)
{
    new_individuals[i].chromosomes.resize(number_of_variables);

    for (int j = 0; j < population_size; j++)
        new_individuals[i].chromosomes[j].resize(number_of_variables);
}

即使使用push_back(),我建议你预留空间

for (int i = 0; i < population_size; i++)
{
    new_individuals[i].chromosomes.resize(number_of_variables);

    for (int j = 0; j < population_size; j++)
        new_individuals[i].chromosomes[j].reserve(number_of_variables);
}

【讨论】:

  • new_individuals[k].chromosomes[0].push_back(individuals[father].chromosomes[0].at(i));正是我真正需要的!太感谢了。至于为什么 k == 1 而不是 0,第一个向量(所以 k = 0)已经充满了上一代最好的基因,作为一种简单的精英主义。还有一个问题,如果我想将染色体作为大小为 7 而不是大小为 0 的向量,我应该如何调整大小?我认为通过执行chromosomes.resize 我将它们调整为7,但你说我没有调整向量的大小?无论如何,非常感谢!
  • 再次感谢您的编辑 :) 非常有帮助,谢谢。
猜你喜欢
  • 2014-08-12
  • 1970-01-01
  • 2015-07-03
  • 2016-09-16
  • 1970-01-01
  • 2011-10-11
  • 2015-07-15
  • 2016-09-05
相关资源
最近更新 更多