【问题标题】:Genetic algorithm to solve a quadratic equation求解二次方程的遗传算法
【发布时间】:2017-04-24 03:41:16
【问题描述】:

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

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

感谢任何帮助

【问题讨论】:

    标签: algorithm genetic-algorithm quadratic fitness


    【解决方案1】:

    如果你想解一个二次方程

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

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

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

    作为适应度函数,和那时的精度一样,所以需要最小化。

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

    【讨论】:

    • 感谢您的回答,那么我们需要找到 4 位数字的解决方案的要求会发生什么?我怎样才能将它整合到问题中?
    • @Farzad 你可以使用浮点数,如果 f(x)
    【解决方案2】:

    第一步是选择解决方案的表示。最广泛使用的是二进制编码。例如,您的 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 的值由二进制字符串编码)。搜索空间代表基因型,解码的解决方案是表型。遗传学算子使用解码解决方案处理搜索空间个体(在这种情况下为二进制字符串)和适应度函数。

    【讨论】:

    • 感谢您的详细解释。您能否详细说明一下我们案例中的适应度函数,即找到二次方程的解
    • 好的,例如,您尝试在区间 0-256.xxxx 上找到二次函数的最大值。二次方程可能看起来像:2*x^2 - 5x + 3。你解码一个二进制字符串,你得到例如 5。fitness_of_binary_string = 2*5^2-25+3 =28。所以这个字符串的适应度是 43。你解码另一个字符串并得到值 10。所以这个字符串的适应度将是 2*10^2-50+3=153。解码值 10 的字符串具有更大的适应度:)
    • 对不起,第一个字符串的适应度为 28。
    【解决方案3】:

    我有一个可以解方程: a(x1*x1+x2*x2)+b(x1+x2)+2*c = 0 这是添加: ax1x1+bx1+c=0ax2x2+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));
    }
    

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

    【讨论】:

      猜你喜欢
      • 2022-06-23
      • 2013-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-28
      • 2012-06-17
      • 2018-08-05
      • 1970-01-01
      相关资源
      最近更新 更多