遗传算法 - 子集和问题

时间:2011-05-18 10:35:10

标签: algorithm genetic-algorithm subset-sum

我必须做一个使用遗传算法解决子集和问题的项目。不幸的是,在对算法进行编码时,我发现了一个大问题......

我的算法:

  • 只要找不到解决方案并且步骤数小于步骤数:
  • 计算每条染色体的概率然后分布函数
  • 执行选择(轮盘赌)
  • 选择要交叉的n条染色体
  • 执行交叉(交叉点随机选择)
  • 选择m染色体进行突变
  • 执行突变
  • 如果找到解决方案,请停止

(算法取自“遗传算法+数据结构=进化程序,第2章”一书) 人口规模,数据量,数据收集范围,步数,突变数量(步骤),交叉数量(步骤)等变量在程序选项中严格设置。

问题是在群体中一定数量(相对较小)的步骤之后,所有染色体都是相同的。问题说明了这张图: http://imageshack.us/m/96/7693/wykresb.png

我做错了什么?怎么解决? 提前谢谢。

修改

此处您可以从我的应用中找到日志: http://paste.pocoo.org/show/391318/

我认为轮盘赌不是最好的解决方案(如deong所说)。突变也需要改进。

3 个答案:

答案 0 :(得分:3)

这是(可能)问题。免责声明当然是你可能只有一个错误的程序。

轮盘赌选择非常糟糕。问题是在运行的早期,适应值的分布是随机的。你有一些糟糕的解决方案,有些是合理的,相比之下。你不希望它们中的任何一个非常好,但是你会期望它们中的一些 比其他的更好。

轮盘赌选择考虑概率的这些相对差异并放大它们。如果您的人口规模为100,并且一个人的健康状况比其他人高五倍,则会经常选择五次。通常具有较轻微的突变率,在两次重组选择同一个体,产生一些新的相同后代,进行非常小的变化(可能),然后将它们重新放入群体的情况下,您会很快结束。因为你还处于运行的早期阶段,大多数解决方案仍然很糟糕,所以你确实有一个高于平均水平的解决方案,你将它选择为五个高于平均水平的解决方案,培育它们以获得十个高于平均水平的解决方案,然后开始所有流程再次。如果你不是很谨慎地设计你的运算符,这些解决方案可以非常快速地接管整个人口,即使所有算法都知道它们比它看到的真正糟糕的解决方案更好。

解决方案是使用更好的选择运算符。二元锦标赛选择更快,更容易编码,并且应用更加可容忍的选择压力。还存在等级偏差的选择,其按比例选择健身等级而不是绝对差异。

修改:这并不是说无法使用比例选择。只是它很容易过早收敛并有效地使用它,你通常需要构建一整套操作符。

答案 1 :(得分:1)

当应用遗传算法时,可能会发生算法陷入局部最优的情况。然而,人们对全局最优(或者更接近于这种最优)感兴趣。

可以通过以下方式避免本地最优:

  • 更高的突变率
  • 不同的交叉功能

此外,杀死克隆可能很有用。这意味着您在每次迭代后“快速”查看您的人口,并且不允许克隆。快速我的意思是你只是寻找近似的克隆,因为检查确切的克隆将需要O(m * n ^ 2),其中n是你的种群大小,m是染色体的大小。 这个方法帮助我解决了克隆人面临的另一个问题。

希望这有帮助, 基督教

修改

如果你能发布你的交叉功能也很好。最好不要作为代码,而是用简单的英文文本。交叉函数是遗传算法的关键部分。

答案 2 :(得分:1)

之前我遇到过类似的问题,我希望它和你的问题一样

首先,您需要检查(使用任何测量指标)染色体A是否优于染色体B.这使您可以对您的人口染色体进行严格的排序,并能够对您的人群进行排序。

然后,当你产生一条新的染色体(通过突变或交叉)时,你可能会产生一个已经存在于你的人群中的染色体。请确保不要将其包含在人口列表中。

换句话说,确保您的列表始终包含不同的染色体,并始终从最佳到最差排序!

注意: 我使用的遗传算法通常是这样的(这是最常用的算法,也是最常用的算法):

  • 创建P不同的染色体和 将它们添加到列表Pop;
    1. while(未找到最佳解决方案&& number of iteration< LIM)
    2. 使用交叉,突变或任何其他方法创建新的染色体 方法;
    3. 将创建的染色体添加到列表Pop
    4. 对Pop列表进行排序(从最合适到最差)
    5. 选择第一个P不同的染色体并丢弃所有其他染色体 来自Pop。
    6. 结束时