【问题标题】:What Crossover Method should I use for crossing Postfix expressions in Genetic Algorithm?我应该使用什么交叉方法来交叉遗传算法中的后缀表达式?
【发布时间】:2018-01-23 21:20:35
【问题描述】:

我正在构建一个项目,其主要目标是使用 6 个给定数字和主要运算符(+、-、*、/)找到给定数字(如果可能,否则最接近)。想法是使用给定的数字和运算符以反向抛光(后缀)表示法随机生成表达式,因为我发现它最容易在以后生成和计算。这些表达式是我的遗传算法中的个体。这些表达式在 Java 中具有字符串数组列表的形式,其中字符串既是运算符又是操作数(给定的数字)。

这里的主要问题是,交叉这些个体(实际上是后缀表达式)的最佳方法是什么?现在我正在考虑交叉表达式,这些表达式由给定的所有六个操作数(以及它们的 5 个运算符)组成。稍后我可能还会交叉由较少操作数(5、4、3、2 和只有 1)组成的表达式,但我想我应该首先弄清楚这一点,作为最复杂的情​​况(如果你认为以不同的方式开始可能是一个更好的主意,我愿意接受任何建议)。所以,问题是每个表达式都是由所有给定的操作数组成的,子表达式也应该包含所有的操作数。我知道这需要某种有序的交叉(通常用于诸如 TSP 之类的问题),并且我阅读了很多关于它的内容(例如here,其中描述了多种方法),但我不太清楚哪一个会在我的情况下最好(我也知道在遗传算法中有很多“试错”过程,但我在这里谈论的是其他事情)。

我说的困扰我的是运营商。如果我只有一个操作数列表,那么跨越 2 个这样的列表不会有问题,例如,从 1 个父项中获取半个元素的随机子数组,然后用父项 2 中的剩余元素填充其余部分,保持顺序如下它是。但是在这里,如果我说,从第一个父表达式中获取表达式的前半部分,我肯定必须用剩余的操作数填充子表达式,但是我应该如何处理运算符呢?像其余的操作数一样从父级 2 中获取它们(但是我必须小心,因为为了在后缀表达式中使用运算符,我需要至少有 1 个操作数,并检查所有时间可能很耗时,或不是?),或者我可以为子表达式的其余部分生成随机运算符(但那不会是纯粹的交叉,对吧)?

当谈到交叉时,也有变异,但我想我已经解决了。我可以采用一个表达式并执行一个突变,我只需切换 2 个操作数,或者采用一个表达式并随机更改 1 个或多个运算符。为此,我有一些想法,但真正困扰我的是跨界。

所以,这几乎概括了我的问题。就像我说的,主要问题是如何交叉,但是如果您对程序有任何其他建议或问题(也许更容易表示表达式 - 除了字符串列表 - 交叉可能更容易/更快,也许是我没有'这里不提,没关系,甚至是解决问题的全新方法?),我很想听听他们的意见。我在这里没有给出任何代码,因为我认为不需要回答这个问题,但如果你认为它会有所帮助,我一定会编辑以解决这个问题。再一次,主要问题是回答如何交叉,这个问题的特定部分(想法或伪代码预期,虽然代码本身也很棒:D),但如果你认为我需要做更多的改变,或者您知道我的整个问题的其他解决方案,请随意说。

提前致谢!

【问题讨论】:

    标签: java algorithm genetic-algorithm postfix-notation crossover


    【解决方案1】:

    我想到了两种方法:

    方法#1

    将每个基因组编码为一个固定长度的表达式,其中奇数索引是数字,偶数索引是运算符。对于突变,您可以稍微更改数字和/或更改运算符。

    优点:

    • 编码非常简单

    缺点:

    • 必须创建一个中缀解析器
    • 固定长度表达式

    方法#2

    将每个基因组编码为语法树。例如,4 + 3 / 2 - 1 等价于 Add(4, Subtract(Divide(3, 2), 1)),如下所示:

       _____+_____
       |         |
       4     ____-____
             |       |
           __/__     1
           |   |
           3   2
    

    然后在交叉时,从每棵树中随机选择一个节点并交换它们。对于突变,您可以添加、删除和/或修改随机节点。

    优点:

    • 可能会找到更好的结果
    • 可变长度表达式

    缺点:

    • 增加时间复杂度
    • 增加编程复杂性

    这是第二种方法的示例:

    Source

    【讨论】:

    • 感谢您的简洁回答,我喜欢您为这两种方法写的优缺点。我理解最后在这个例子中做了什么,但问题是操作数需要保持不变,所以在大多数情况下只交换表达式的一部分是不够的。此外,我喜欢这种树形语法,从现在开始我可能会这样想。
    • @Urke 如果我理解正确的话,你会得到6 数字,也可以使用+-*/,类似于this 游戏.因此,如果您决定使用语法树方法,那么所有operands 都将是树的叶子。您是说运算符是固定的(按顺序),您需要找到数字的最佳排列吗?
    • @Ijeabmreosn 再次感谢您的回答,我完全理解。现在我希望听到另一种意见,希望对这个问题有一个新的答案,因为我想在进入它之前一直考虑它。
    猜你喜欢
    • 2014-08-12
    • 2016-08-31
    • 1970-01-01
    • 1970-01-01
    • 2015-07-03
    • 2016-09-16
    • 1970-01-01
    • 2021-02-07
    相关资源
    最近更新 更多