gpt4 book ai didi

c++ - 遗传算法中的一点交叉

转载 作者:行者123 更新时间:2023-11-30 05:43:53 30 4
gpt4 key购买 nike

我正在使用一点交叉来交叉两个人。假设我有两个人,例如

I1='10010011' 
I2='11001101'

tmp_P 是 vector 存储两个单独的 I1I2。我想在 C++ 中实现一点交叉。对吗?

这是算法描述

fori=1 to N/2 (N is number of individual=2 in my case)
if random[0,1]<=Pc //cross prob.
pos=random_int[1,n-1]
for k=pos+1 to n //Length of individual=8 in my case
aux=tmp_P_i[k]
tmp_P_i[k]=tmp_P_(i+N/2)[k]
tmp_P_(i+N/2)[k]=aux;
end
end
end

我的问题是我混淆了 pos 的索引。它是从 [0 到 n-2] 随机获得的吗?这样对吗?

 //Random integer in range [min max]
int random_int(int min, int max) //range : [min, max]
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(min, max);
return dis(gen);
}
//One-point Crossover
vector< vector<int> > crossover(vector< vector<int> > tmp_P)
{
int pos=0;
for (int i=0;i<N/2;i++)
{
//If random number smaller than crossover probability then do Crossover
if(RND()<=Pc)
{
pos=random_int(0,n-2);//Index in C++ from 0
int aux=0;
for (int k=pos+1;k<n;k++)
{
//swat
aux=tmp_P[i][k];
tmp_P[i][k]=tmp_P[i+N/2][k];
tmp_P[i+N/2][k]=aux;
}
}
}
return tmp_P;
}

最佳答案

  • random_int

    出于调试目的(可重复性),您不应该总是调用 rd()。此外,您在每次调用时都会重新创建伪 RNG。

    只调用随机设备一次,然后使用(随机)播种的伪 RNG 完成其他所有操作。作为奖励,您应该将种子值存储在日志文件中,以便稍后重播伪随机序列。

    应该是这样的:

    int random_int(int min, int max)
    {
    #if defined(NDEBUG)
    static std::mt19937 gen(std::random_device()); // or thread_local
    #else
    static std::mt19937 gen(1234); // or, better, thread_local
    #endif

    std::uniform_int_distribution<> dis(min, max);
    return dis(gen);
    }
  • 交叉

    • pos 正确(在[0;n-2]范围内);实际交叉位置在 [1;n-1] 范围内(跳过 0 索引是正确的,因为它会交换整个基因组)。

      你可以直接初始化pos:

       unsigned pos = random_int(1, n-1);

      for (unsigned k = pos; k < n; ++k)
      { /* ... */ }

      这样更简单。

    • 你可以使用 std::swap功能

    • 如果变量在第一次出现在代码中时习惯性地被赋予有意义的值,那么它们就不可能被意外地与无意义或未初始化的值一起使用(例如 pos/aux,参见 Why declare a variable in one line, and assign to it in the next? )
    • 如果个人的长度是固定的你也可以考虑std::bitset存储基因组

所以这样的事情应该可行:

unsigned random_int(unsigned min, unsigned max)
{
#if defined(NDEBUG)
static std::mt19937 gen(std::random_device());
#else
static std::mt19937 gen(1234u);
#endif

std::uniform_int_distribution<> dis(min, max);
return dis(gen);
}

std::vector<std::vector<int>> crossover(std::vector<std::vector<int>> tmp_P)
{
const auto N = tmp_P.size();
const auto n = tmp_P[0].size();

for (unsigned i = 0; i < N/2; ++i)
{
assert(tmp_P[i].size() == n);

// If random number smaller than crossover probability then do Crossover
if (RND() <= Pc)
for (unsigned k = random_int(1, n-1); k < n; ++k)
std::swap(tmp_P[i][k], tmp_P[i + N/2][k]);
}

return tmp_P;
}

关于c++ - 遗传算法中的一点交叉,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30058303/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com