Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 遗传算法中的单点交叉_C++_C++11_Genetic Algorithm_Evolutionary Algorithm_Crossover - Fatal编程技术网

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;
    }
    
    出于调试目的(重复性),您不应该总是调用
    rd()
    。此外,您在每次调用时都会重新创建伪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;
    }
    
    只调用随机设备一次,然后使用(随机)种子伪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;
    }
    
    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
开始,因为它看起来更干净。