C++ 遗传算法中的单点交叉
我用一点交叉来交叉两个人。假设我有两个人,比如C++ 遗传算法中的单点交叉,c++,c++11,genetic-algorithm,evolutionary-algorithm,crossover,C++,C++11,Genetic Algorithm,Evolutionary Algorithm,Crossover,我用一点交叉来交叉两个人。假设我有两个人,比如 I1='10010011' I2='11001101' //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(mi
I1='10010011'
I2='11001101'
//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;
}
tmp\u p
是两个单独的I1
和I2
向量存储。我想在C++中实现一个点交叉。是这样吗
//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;
}
这是算法描述
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
//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\u int
出于调试目的(重复性),您不应该总是调用//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; }
。此外,您在每次调用时都会重新创建伪RNGrd()
只调用随机设备一次,然后使用(随机)种子伪RNG执行其他操作。作为奖励,您应该将种子值存储在日志文件中,以便以后可以重播伪随机序列//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 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 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; }
这更简单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); }
//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 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;
}
pos
/aux
,请参阅)因此,类似这样的方法应该有效:
//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;
}
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;
}
unsigned random_int(最小无符号,最大无符号)
{
#如果已定义(NDEBUG)
静态标准::mt19937 gen(标准::随机_设备());
#否则
静态标准:mt19937 gen(1234u);
#恩迪夫
标准:均匀分布图(最小值、最大值);
返回dis(gen);
}
标准::向量交叉(标准::向量tmp_P)
{
const auto N=tmp_P.size();
const auto n=tmp_P[0]。大小();
用于(无符号i=0;i 如果(RND()是,则std::uniform_int_distribution
将生成在闭合间隔[a,b]
上均匀分布的数字。因此,如果要从pos+1
启动for循环,必须使用n-2
。但是,我建议使用random_int(0,n-1)
然后从k=pos
开始,因为它看起来更干净。