我正在构建一个项目,其主要目标是使用6个给定数字和主要运算符(+, - ,*,/)找到给定数字(如果可能,否则最接近可能)。想法是使用给定的数字和运算符,以反向抛光(后缀)表示法随机生成表达式,因为我发现它最容易生成和计算。那些表达是我的遗传算法的人口中的个体。这些表达式在Java中具有字符串ArrayList的形式,其中字符串既是运算符又是操作数(给定的数字)。
这里的主要问题是,交叉这些人的最佳方法是什么(实际上是后缀表达式)?现在我正在考虑交叉表达式,这些表达式是由给出的所有六个操作数(以及5个操作符)组成的。后来我可能也会用较少的操作数(5,4,3,2也只有1)来表达这些表达式,但我想我应该首先解决这个问题,因为最复杂的情况(如果你认为以不同的方式开始可能是一个更好的主意,我可以接受任何建议。所以,问题在于每个表达式都是由给定的所有操作数组成的,并且子表达式也应包含所有操作数。我知道这需要某种有序的交叉(经常用于像TSP这样的问题),我读了很多关于它的内容(例如here,其中描述了多种方法),但我并不是很清楚在我的情况下哪一个最好(我也知道在遗传算法中有很多'试验和错误'过程,但我在这里谈论别的东西)
我说的是打扰我,是运营商。如果我只有一个操作数列表,那么跨越2个这样的列表就不会有问题,例如从1个父节点中取出一个半元素的随机子数组,并用父节点2中剩余的元素填充其余的元素。订单喜欢它。但是在这里,如果我从第一个父表达式中获取表达式的前半部分,我肯定必须用剩余的操作数填充子表达式,但是我应该如何处理运算符?从父2中取出它们就像其余的操作数一样(但是我必须要注意,因为为了在后缀表达式中使用运算符,我需要至少有1个操作数,并且检查所有时间可能都很耗时,或者没有?),或者我可以为子表达式的其余部分生成随机运算符(但那不是纯粹的交叉,那么,是吗?)
谈到交叉时,也有变异,但我想我已经解决了。我可以采用表达式并执行变异,我只需要切换2个操作数,或者使用表达式并随机更改1个或多个运算符。为此,我有一些想法,但交叉是真正困扰我的。
所以,这几乎总结了我的问题。就像我说的,主要的问题是如何交叉,但如果你对程序有任何其他的建议或问题(可能更容易表达表达式 - 其他然后字符串列表 - 这可能更容易/更快交叉,也许我没有&和在这里提到,它并不重要,甚至可能是解决这个问题的全新方法?),我很乐意听到它们。我没有在这里提供任何代码,因为我不认为它需要回答这个问题,但是如果你认为它会有所帮助,我肯定会编辑以解决这个问题。再一次,主要的问题是回答如何交叉,问题的这个特定部分(想法或伪代码预期,虽然代码本身也很棒:D),但如果你认为我需要更改一些东西,或者你知道我的整个问题的其他解决方案,随便说。
提前致谢!
答案 0 :(得分:1)
有两种方法可以想到:
将每个基因组编码为固定长度表达式,其中奇数索引是数字,偶数索引是运算符。对于变异,您可以稍微更改数字和/或更改运算符。
优点:
缺点:
将每个基因组编码为语法树。例如,4 + 3 / 2 - 1
相当于Add(4, Subtract(Divide(3, 2), 1))
,如下所示:
_____+_____
| |
4 ____-____
| |
__/__ 1
| |
3 2
然后当越过时,从每棵树中挑选一个随机节点并交换它们。对于变异,您可以添加,删除和/或修改随机节点。
优点:
缺点:
以下是第二种方法的示例: