遗传算法中的单点交叉
One-point cross over in genetic algorithm
我正在使用一个点交叉交叉两个个体。假设我有两个人,例如
I1='10010011'
I2='11001101'
tmp_P
是矢量存储两个单独的I1
和I2
。我想在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); }
-
crossover
-
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
,请参见为什么一行声明变量,并分配一个。在下一个?) - 如果固定了个人的长度,您也可以考虑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++向量初始化遗传算法的代理向量
- 编程作业:机器人遗传算法
- 在遗传算法中永远不会达到100%
- 多线程galib247遗传算法陷入局部极大值
- 遗传算法中的单点交叉
- 如何利用遗传算法求C中数的平方根来实现选择和交叉
- 遗传算法的选择机制
- 在遗传算法中使用二进制编码是必要的吗
- 遗传算法和神经网络:临时地址[-fallowive]
- 访问基于遗传算法的PNRG中的数组? " no match for operator[] "
- 在遗传算法中,对于非排序群体,应该如何组织轮盘选择
- 在电子邮件地址内移动点(句点)的算法
- 是否使用LDAP+kerberos作为身份验证程序启用SASL(带有GSSAPI)的客户端和服务器?(单点登录SSO系统
- 为什么我的遗传算法不收敛
- 为遗传算法分配和检索逐位内存值
- 神经网络与遗传算法问题
- 单点触摸:添加.a资源,gcc错误
- 种群变得陈旧——遗传算法
- 如何为遗传算法生成随机数?
- 用C(++)语言将double转换为遗传算法的位数组