0

我在理解遗传算法的过程时遇到了问题。我找到了在一个区间内最大化函数的例子,我想我理解它们,但是如何使用遗传算法来求解例如二次方程?

假设我们想找到一个最多 4 位的解决方案,那么对数字进行编码的正确表示是什么?什么可以用作评估每个数字的适应度函数?

任何帮助表示赞赏

4

3 回答 3

1

如果你想解一个二次方程

a * x^2 + b * x + c = 0

那么您只需要一个变量x作为表示。您可以使用

f(x) = abs(a * x^2 + b * x + c)

作为适应度函数,与那时的精度相同,因此需要最小化。

但是只有一个变量很难进行交叉,您可以每个人使用 10 个数字,然后取平均值得到 x,或者在进行交叉时只取两个数字的平均值。同样对于突变而不是完全覆盖 x,您可以将其乘以 0.5 到 2 之间的随机数,例如。

于 2016-12-08T20:02:30.500 回答
1

第一步是选择解决方案的表示。最广泛使用的是二进制编码。例如,您的 x 可能看起来:

1 0 0 1 1 1 1 0 | 0 0 0 0 0 0 0 0 0 0 1 1 1

前 8 位编码数字的整数部分,剩余的 13 位编码点后数字的一部分。在此示例中,二进制字符串编码一个数字 158.0007。

交叉可能看起来

1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 - 158.0007

1 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 - 225.0008

最简单的交叉算子是一个分界点。您从 1 到字符串长度生成一个数字 - 1。到此为止,您从一个字符串中获取一个位,然后从第二个字符串中获取该位。在本例中,我们选择分割点 4 的位置。后代将如下所示:

1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 - 145.0008

突变随着选择的概率而改变一些位。

适应度函数可能是 x 中的二次方程的函数值(如果您尝试找到最大值),并且 x 是作为比特字符串的解码获得的。

最后还有一些理论。你有两套。一组是搜索空间(带有二进制字符串的空间),第二组是带有解决方案的空间。来自搜索空间的个体被解码为解决方案空间中的解决方案(在我们的例子中,x 的值由二进制字符串编码)。搜索空间代表基因型,解码的解决方案是表型。遗传学算子使用解码解决方案处理搜索空间个体(在这种情况下为二进制字符串)和适应度函数。

于 2016-12-12T12:20:04.230 回答
0

我有一个可以解方程: a(x1*x1+x2*x2)+b(x1+x2)+2*c = 0 这是加法: ax1x1+bx1+c=0并且ax2x2+bx2+c=0 由于 x1 和 x2 都是方程的解,所以可以进行加法。代码为 aa=1、bb=-1 和 cc=-30 提供以下输出:

best solutions at generation 0 :: fitness = 1
chromosome 13 : x1 = -5 , x2 = 6
chromosome 269 : x1 = 6 , x2 = 6
chromosome 340 : x1 = 6 , x2 = -5
chromosome 440 : x1 = -5 , x2 = 6
chromosome 452 : x1 = 6 , x2 = -5
chromosome 549 : x1 = -5 , x2 = -5
chromosome 550 : x1 = 6 , x2 = -5
chromosome 603 : x1 = -5 , x2 = -5
chromosome 826 : x1 = 6 , x2 = -5
chromosome 827 : x1 = -5 , x2 = 6
chromosome 842 : x1 = -5 , x2 = -5
chromosome 952 : x1 = 6 , x2 = 6
chromosome 986 : x1 = 6 , x2 = -5

也就是说,我相信一个好的开始,我只是还不知道如何从不太好的解决方案中筛选出好的。

这是部分代码:

void objective(Chromosome* c){
    // the problem here is when one root is found the fitness
    // will be 1 :
    // resulting in the second value is a non-root or the same 
    // value as the first root
    //so probably I need to rewrite the fitness function
    c->result = aa * ((c->gene[0].geneticcode * c->gene[0].geneticcode) + (c->gene[1].geneticcode * c->gene[1].geneticcode)) /
              + bb * (c->gene[0].geneticcode + c->gene[1].geneticcode) /
              + 2 * cc;
}

void fitness(Chromosome* c){
    //rewrite of fitness function for this example
    c->fitness = 1.0 / (1.0 + fabs(c->result));
}

如果有人可以改进,我相信有请分享。

于 2021-09-09T19:55:12.933 回答