1

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

我的算法:

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

(算法取自《遗传算法 + 数据结构 = 进化程序,第 2 章》一书) 种群规模、数据量、数据收集范围、步数、突变数(步内)、在程序选项中严格设置交叉次数(在一个步骤中)。

问题在于,在种群中经过一定(相对较少)的步骤后,所有染色体都是相同的。问题说明了这个图表:http: //imageshack.us/m/96/7693/wykresb.png

我做错了什么?如何解决?提前致谢。

编辑:

在这里你可以找到我的应用程序的日志:http: //paste.pocoo.org/show/391318/

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

4

3 回答 3

3

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

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

轮盘赌选择利用这些概率的相对差异并放大它们。如果您的人口规模为 100,并且一个人的健康状况是其他人的五倍,那么它将被选择五倍。由于突变率通常较低,您很快就会陷入这样一种情况:您两次选择同一个体进行重组,产生一些新的相同后代,进行非常小的变化(也许),然后将它们放回种群中。因为你还处于运行初期,大多数解决方案仍然很糟糕,所以你确实有一个高于平均水平的解决方案,你选择了五个高于平均水平的解决方案,培育它们得到十个高于平均水平的解决方案,然后开始整个过程再次。如果您不是,这些解决方案可以很快接管整个人口

解决方案是使用更好的选择运算符。二元锦标赛选择更快、更容易编码,并且施加的选择压力更容易承受。还有排名偏向的选择,它通过适应度排名而不是绝对差异按比例选择。

编辑:这并不是说您不能使用比例选择。只是它很容易过早收敛并有效地使用它,您通常必须考虑到这一点来构建一整套运算符。

于 2011-05-18T10:57:20.903 回答
1

在应用遗传算法时,算法可能会陷入局部最优。然而,人们对全局最优(或者更确切地说是对这种最优的近似)感兴趣。

可以通过以下方式避免局部最优:

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

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

希望这有帮助,克里斯蒂安

编辑

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

于 2011-05-18T10:56:51.343 回答
1

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

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

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

换句话说,确保你的列表总是包含不同的染色体并且总是从最好到最差排序!

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

  • 创建 P 个不同的染色体并将它们添加到列表 Pop 中;
    1. while (没有找到最优解 && 迭代次数 < LIM)
    2. 使用交叉、突变或任何其他方法创建新染色体;
    3. 将创建的染色体添加到列表 Pop
    4. 排序列表 Pop(从最适合到最差)
    5. 选择前 P 个不同的染色体并从 Pop 中丢弃所有其他染色体。
    6. 结束时
于 2011-05-19T04:57:34.590 回答