我必须做一个使用遗传算法解决子集和问题的项目。不幸的是,在对算法进行编码时,我发现了一个大问题......
我的算法:
(算法取自“遗传算法+数据结构=进化程序,第2章”一书) 人口规模,数据量,数据收集范围,步数,突变数量(步骤),交叉数量(步骤)等变量在程序选项中严格设置。
问题是在群体中一定数量(相对较小)的步骤之后,所有染色体都是相同的。问题说明了这张图: http://imageshack.us/m/96/7693/wykresb.png
我做错了什么?怎么解决? 提前谢谢。
修改
此处您可以从我的应用中找到日志: http://paste.pocoo.org/show/391318/
我认为轮盘赌不是最好的解决方案(如deong所说)。突变也需要改进。
答案 0 :(得分:3)
这是(可能)问题。免责声明当然是你可能只有一个错误的程序。
轮盘赌选择非常糟糕。问题是在运行的早期,适应值的分布是随机的。你有一些糟糕的解决方案,有些是合理的,相比之下。你不希望它们中的任何一个非常好,但是你会期望它们中的一些 比其他的更好。
轮盘赌选择考虑概率的这些相对差异并放大它们。如果您的人口规模为100,并且一个人的健康状况比其他人高五倍,则会经常选择五次。通常具有较轻微的突变率,在两次重组选择同一个体,产生一些新的相同后代,进行非常小的变化(可能),然后将它们重新放入群体的情况下,您会很快结束。因为你还处于运行的早期阶段,大多数解决方案仍然很糟糕,所以你确实有一个高于平均水平的解决方案,你将它选择为五个高于平均水平的解决方案,培育它们以获得十个高于平均水平的解决方案,然后开始所有流程再次。如果你不是很谨慎地设计你的运算符,这些解决方案可以非常快速地接管整个人口,即使所有算法都知道它们比它看到的真正糟糕的解决方案更好。
解决方案是使用更好的选择运算符。二元锦标赛选择更快,更容易编码,并且应用更加可容忍的选择压力。还存在等级偏差的选择,其按比例选择健身等级而不是绝对差异。
修改:这并不是说无法使用比例选择。只是它很容易过早收敛并有效地使用它,你通常需要构建一整套操作符。
答案 1 :(得分:1)
当应用遗传算法时,可能会发生算法陷入局部最优的情况。然而,人们对全局最优(或者更接近于这种最优)感兴趣。
可以通过以下方式避免本地最优:
此外,杀死克隆可能很有用。这意味着您在每次迭代后“快速”查看您的人口,并且不允许克隆。快速我的意思是你只是寻找近似的克隆,因为检查确切的克隆将需要O(m * n ^ 2),其中n是你的种群大小,m是染色体的大小。 这个方法帮助我解决了克隆人面临的另一个问题。
希望这有帮助, 基督教
修改强>
如果你能发布你的交叉功能也很好。最好不要作为代码,而是用简单的英文文本。交叉函数是遗传算法的关键部分。
答案 2 :(得分:1)
之前我遇到过类似的问题,我希望它和你的问题一样
首先,您需要检查(使用任何测量指标)染色体A是否优于染色体B.这使您可以对您的人口染色体进行严格的排序,并能够对您的人群进行排序。
然后,当你产生一条新的染色体(通过突变或交叉)时,你可能会产生一个已经存在于你的人群中的染色体。请确保不要将其包含在人口列表中。
换句话说,确保您的列表始终包含不同的染色体,并始终从最佳到最差排序!
注意: 我使用的遗传算法通常是这样的(这是最常用的算法,也是最常用的算法):