如何在二进制字符串中执行遗传算法的开发?

问题描述

我有一个 32 位的二进制向量。这个向量代表我的解空间中的一个整数。现在我想在这个向量中执行利用以在搜索空间中进行搜索。我了解到我必须在二进制字符串中的 LSB 周围翻转更多位才能执行利用。所以,我想到了生成指数分布和变异(翻转)根据它的位。它会是一个可行的解决方案。 ?

另外,如果有人可以帮忙编写代码,那将是一个很大的帮助。我很难编写这个逻辑。我试图做这样的事情:

double exploit_probs[32]={2.1760605535605863e-14,5.915145860370273e-14,1.6079033504929256e-13,4.3707344595633353e-13,1.1880888058450779e-12,3.229560211524282e-12,8.778854836900806e-12,2.3863401577827254e-11,6.486745087422874e-11,1.763280129698758e-10,4.793092335043042e-10,1.3028975796473835e-09,3.5416428150987542e-09,9.627183307175482e-09,2.6169397443139367e-08,7.113579753140834e-08,1.933671457825691e-07,5.256263986017488e-07,1.4288006878775044e-06,3.883882946347204e-06,1.0557488436917582e-05,2.869822897223955e-05,7.800987432419569e-05,0.00021205282381583498,0.0005764193376520116,0.001566870211111862,0.004259194822419162,0.011577691889648859,0.031471429479130154,0.08554821486874982,0.23254415793483257,0.6321205588285657};
int i=0;
for(int k=0;k<32;k++){
    if( (rand()/RAND_MAX) < exploit_probs[i++]){
        if(key[k]==0){  //key is the binary array.
            key[k]=1;
        }
        else{
            key[k]=0;
        }
    }
}

但是,我觉得上面的代码会有偏差,因为 rand()/RAND_MAX 会生成 0-1 之间的值。但是我的概率分布范围从 2.1760605535605863e-14 到 0.6321205588285657。所以我的位的概率非常小将被翻转。最后一位有 63% 的机会被翻转。

解决方法

首先,您是说您有字符串,但您正在为其分配一个整数。应该是这样的

if( (rand()/RAND_MAX) < exploit_probs[i++])
{
    if(key[k]==0){  //key is the binary array.
        key[k]= '1';
    }
    else{
        key[k]= '0';
    }
}

此外,变异在通用算法中很少见。真正的改变来自交叉。所以他们有那么一点变异的机会是可以的。

,

解决方案的变化越小,您应用的漏洞利用就越多。因此,就您而言,在您的解决方案中仅翻转一位是您可以实现的最高级别的利用。相比之下,您可以实现的最高级别的利用是通过随机搜索。

GA 尝试通过应用交叉和变异算子来平衡它。突变本质上是为您的人口增加多样性(以探索搜索空间的新领域)。 Crossover 通过向搜索空间的已知(良好)位置创建(或移动)解决方案来利用搜索空间。

如果您想在算法中进行真正的开发步骤,在使用交叉和变异算子生成新种群(后代)之后,您可以对每个新个体应用局部搜索算子。从这个意义上说,您的算法将是一种混合元启发式算法。

在后代产生后应用局部搜索保证每个新的采样解实际上都在局部最小值上。目前,VRP和FJSP等非常难的组合问题的最佳算法是混合元启发式算法。

局部搜索依赖于邻域函数。因此,在您的情况下,定义邻域函数非常简单。对于由 n 位组成的任何给定解决方案,您生成 n 新解决方案,其中每个新解决方案与原始解决方案相比翻转了一位,例如,解决方案 [0,0],邻居 {{1 }}。

[1,0],[0,1,1]

请注意,可以为同一问题定义多个邻域函数。