【问题标题】:Comparing Values in a Single Vector比较单个向量中的值
【发布时间】:2016-07-27 16:55:50
【问题描述】:

我正在开发 GA,但似乎在锦标赛选择方面遇到了问题。我认为这是因为我没有比较我想要比较的东西(就适应度值而言)

srand(static_cast <unsigned> (time(0)));
    population Pop;
    vector<population> popvector;
    vector<population> survivors;

    population *ptrP;

    for (int i = 0; i <= 102; i++)
    {
        ptrP = new population;
        ptrP->generatefit;
        ptrP->findfit;
        popvector.push_back(*ptrP);
        //include finding the persons "overall".  WIP

    }
    cout << "The fit values of the population are listed here: " << endl;
    vector<population> ::iterator it; //iterator to print everything in the vector 
    for (it = popvector.begin(); it != popvector.end(); ++it)
    {
        it->printinfo();
    }

    unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); // generate a seed for the shuffle process of the vector.

    cout << "Beggining selection process" << endl;

     shuffle(popvector.begin(), popvector.end(), std::default_random_engine(seed));

    //Shuffling done to randomize the parents I will be taking.     
    // I also want want to pick consecutive parents 
    for (int i = 0; i <= 102; i = i + 3)
    {
        if (popvector[i] >= popvector[i++]);

    }


}

现在我认为我的问题是,当我尝试比较总体值时(尚未找到,正在研究如何正确建模它们以提供准确的总体适应度值)我没有比较我应该是什么.

我在想,一旦我找到“总体”的人,我应该将其存储在 Float 向量中并从那里开始,但我不确定如果我想创建一个新的“这是否是正确的方法”父”池,因为(我认为)“父池”必须是我的人口类别的一部分。

感谢任何反馈。

【问题讨论】:

  • 除了您遇到的问题之外,您还遇到了可怕的内存泄漏。你在堆上new-ing 一个population,然后复制到一个向量中,然后没有deletenew。经验法则:如果你new某事,某处,在某个时候你必须delete它。
  • @SamVarshavchik 这整个代码目前是一个 WIP,还没有真正了解任何细节。我只想确保我的函数在我微调代码之前运行。话虽这么说,你会在哪里删除人口?在一切结束时还是在每个循环结束时?
  • 一开始就不要分配。只需使用population p; p.generatefit(); p.findfit(); popvector.emplace_back( std::move( p ) );。现在,请注意我在您的函数调用中添加了括号。也许那是你的意图?如果你不这样做,它只是一个无操作并且你的函数不会被调用。也许这就是问题的一部分。
  • 我不敢相信我没有将 () 添加到我的函数调用中。我不知道它为什么提到我。我觉得好像我不需要使用指针,但我想拥有一个以防万一我以后需要使用一个指针来做某事。现在我会删除它,如果我在某个时候需要它,我会添加它。 @paddy
  • 这很好,但如果您想使用动态内存,请确保您将指针实际存储在向量中。你现在这样做的方式,你仍然存储一个从你分配的另一个值复制的值,然后指针丢失。因此,要使用指针,您将具有以下类型:std::vector&lt;population*&gt;。甚至更好:std::vector&lt;std::unique_ptr&lt;population&gt;&gt;.

标签: c++ class vector genetic-algorithm


【解决方案1】:

srand(static_cast &lt;unsigned&gt; (time(0)));

这是没用的:你以不是基于std::rand的形式调用std::shuffle

shuffle(popvector.begin(), popvector.end(), std::default_random_engine(seed));

如果您需要在程序的其他地方生成随机数,请通过random pseudo-random number generation library 中的函数/分布/引擎来完成(不要使用std::rand)。

还要考虑到,出于调试目的,您应该有一种方法来使用固定种子初始化随机引擎(调试需要可重复的结果)。


for (int i = 0; i

不要使用magic numbers

为什么是 102?如果是人口规模,请将其存储在一个常量/变量(populationSize?)中,记录变量的使用并“享受”这样一个事实,即当您需要更改值时,您不必记住使用它的位置(只是在这个简单的 sn-p 中有两个不同的使用点)。

还要考虑人口规模是您需要在 GA 中经常更改的参数之一。


ptrP = new population;
ptrP->generatefit;
ptrP->findfit;
popvector.push_back(*ptrP);

绝对考虑Sam Varshavchikpaddy 的言论。


for (int i = 0; i <= 102; i = i + 3)
{
  if (popvector[i] >= popvector[i++]);
  // ...

通常,在for 循环体内更改索引变量不是一个好习惯(在某些语言中,不是 C/C++,循环变量在循环体范围内是不可变的)。

这里还有一个未定义的行为:

popvector[i] >= popvector[i++]

等价于

operator>=(popvector[i], popvector[i++])

函数参数的求值顺序未指定。所以你可能有:

auto a = popvector[i];
auto b = popvector[i++];
operator>=(a, b);  // i.e. popvector[i] >= popvector[i]

auto b = popvector[i++];
auto a = popvector[i];
operator>=(a, b);   // i.e. popvector[i + 1] >= popvector[i]

这两种情况都是错误的。

在第一种情况下,您正在比较相同的元素并且表达式始终为真。

在第二种情况下,比较可能与您的想法相反。

看看:

并始终使用-Wall -Wextra(或它们的等价物)编译源代码。


我不确定是否正确理解类population 的作用。可能是名称具有误导性。


您可能会感兴趣的其他问题/答案:

【讨论】:

    猜你喜欢
    • 2013-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-21
    • 1970-01-01
    • 2012-10-04
    • 2013-02-09
    相关资源
    最近更新 更多