遗传算法及其实际应用

419 阅读8分钟

什么是遗传算法?

遗传算法(GA)是解决搜索和优化问题的一个非常强大的工具,它包括尝试几个解决方案,并利用在每次尝试中收集的信息来提高下一个建议的质量。遗传算法的灵感来自达尔文的进化理论,并实现了适者生存、自然选择、变异等概念。它们被认为是仿生的,因为它们是受大自然的启发来解决问题的。我写了一篇关于它的文章,你可以在这里查阅:生物仿生学:为什么出去 "摸摸草 "可能真的是你问题的答案

在这篇文章中,我将解释遗传算法是如何工作的,以及我是如何用它来解决一个实际问题的。

你可以在这里访问项目库:遗传算法-旅行的小偷

遗传算法是如何工作的?

如前所述,GA实现了达尔文的进化理论的功能。为了在谈论该算法之前有一个更好的背景,我们需要了解这个理论是如何工作的。

达尔文的进化论

随着时间的推移,生物经历了随机的遗传变化(突变),这些变化可以在它们生活的环境中引起适应性优势。通过自然选择,最适应的个体有更多机会生存和繁殖,将这些遗传优势转移到下一代。

遗传算法的组成

  • 基因
    将被遗传算法改变的信息。

  • 染色体
    数据结构,包含基因的集合。

  • 个体
    对象,包含染色体并存储适配度值。

  • 群体
    个体的集合。

  • 突变
    将改变个体基因的函数。突变将使基因发生微小的变化。

  • 交叉
    函数将对群体中个体的染色体进行交叉。交叉是一种突变,它结合了两个个体。

  • 健身
    对个体进行评分的函数。健身函数是GA中最重要的部分之一。它定义了每个个体的表现如何,因此它的适应性如何。

  • 选择
    决定哪些个体将成为下一代的初始种群的函数。这个函数负责分析每个个体的适应性,并选择哪些个体应该 "生存"。

遗传算法的步骤

遗传算法的工作方式如下:

  1. 产生一个由个体组成的初始种群。这个群体可以是随机的,也可以不是,取决于你需要的代码的优化程度。
  2. 从初始种群中产生经历过变异的种群和经历过交叉的种群。这些被合并成一个。我将在后面详细介绍突变和交叉。
  3. 整个种群中的所有个体都要经过选择,那些具有最高适配度的个体(最适应的)"幸存 "下来,成为下一代的起始种群。
  4. 这个过程不断重复,直到达到某种停止条件,如最小误差或最大世代。

为了便于可视化,请看GA的代码:
Image description

遗传算法的实践

一切都在良好的解释下更容易理解。从这一点出发,我将解释我是如何使用GA来解决一个问题的!

这个问题

问题的介绍

AIC(国际犯罪署)向Joana提出了一个挑战,即在72小时内在几个城市进行抢劫。Joana必须谨慎地使用付费的公共交通工具,并将偷来的物品装在一个重达20公斤的背包里。每个城市都有贵重物品可供偷盗,但每次偷盗都需要时间来完成。此外,城市之间的旅行有经济成本,也需要时间。如果她成功地偷到了最大数量的物品,她必须回到埃斯康迪多斯的AIC总部领取她的奖品。

问题数据

所提供的数据是:

  • 一张包含物品数据的表格:

Image description

  • 一个包含城市间旅行的成本和时间数据的表格:

Image description

上述表格是不完整的,因为它非常长。它的完整版本可以在项目库中找到。

遗传算法的应用

数据处理

为了处理这些数据,我们创建了一个 "数据工厂 "类。它负责处理表格并创建字典,以便在代码中使用它们。
Image description

类和函数的建模

为了使用GA,有必要对我们的问题进行建模,以适应GA的组成。对于这个问题,它被定义了:

  • 基因:每个城市都在一个列表中
  • 染色体:一个包含城市的列表
  • 个体:"路线 "类的一个对象,它包含染色体并存储健身值。
  • 群体:"Routes "类的一个对象,包含 "Route "对象的一个列表。

个体

个体被定义为Route类的一个对象。该个体可以用随机或预定义的路线进行实例化。这对于在初始种群中或在突变和交叉功能中使用是很有用的。该个体还存储了它的健身值。

路线的生成确保第一个城市总是 "Escondidos",因为它是Joana离开的地方。因为它也是Joana完成抢劫后必须返回的地方,所以 "Escondidos "是唯一一个在路线中出现超过一次的城市。
Image description
由于健身和变异函数是针对每个人的,所以它们也被定义在路线类中。

健身

健身是GA中最重要的函数之一。它负责评估该个体的优秀程度。

这就好像是Fitness定义了哪些个体可以生存,哪些不可以。例如,如果一个人的体重是23公斤,那么健身就会说他不适合,并对他进行负面评价。这就使得我们没有必要去阐述超级复杂的突变和交叉函数,因为如果生成的个体是坏的,那就由适配度来决定。

由于这个问题定义了我们要使利润最大化,所以它就成了一个最佳的健身函数返回,因为越大越好。

然而,在计算利润之前,要检查路线是否有效,路线是否没有超过重量和时间限制。

为了计算这一切,路线被认为是从 "隐藏 "的第一次到第二次出现。第二次出现后的所有内容都不被考虑。这使得我们的路线总是有一个固定的大小,并使交叉和变异更容易。
Image description
Image description

变异

突变使个体的染色体发生微小变化。由于我把染色体定义为一个城市列表,突变使两个城市的位置随机改变(除了第一个)。
Image description
在GA代码中,产生了新的变异个体群体,并将其加入到原始个体中。由于这个原因,突变函数生成了一个新的个体。另一个原因是,每当一个新的个体被生成时,它的适配度会被自动计算。

群体

种群是一个Routes类的对象。

Image description
每当实例化时,该类会生成预定数量的随机个体。

群体类负责实现个体的交叉和选择。

交叉

在这种情况下,种群被分成两半,每个个体与另一半的同类个体结合。

为了交叉选择个体,我创建了一个合并染色体的函数,如下图所示:
Image description
Image description
Image description
结果:
Image description
与突变一样,交叉返回一个新个体的列表。

选择

选择负责确定哪些个体将传给下一代。它通过对整个种群列表进行排序,并将新种群定义为前10名。
Image description
有了这些,GA就可以运行了

结果、问题和限制

问题和限制

尽管很吸引人,但GA并不完美。在实施过程中,我注意到关于GA的两个常见问题

过早收敛

GA的一个大问题是过早收敛。当一个相当好的个体过早出现时,算法倾向于使用它作为生成新个体的模型。这是一个问题,因为它阻碍了更好的个体的产生。为了更好地理解,下面的图片举例说明了全局和局部的最大值和最小值:

Image description

有一些方法可以缓解这个问题,如更好的交叉和变异功能或消除相同的个体,但这仍然是一个没有明确解决方案的问题。

缺乏对优化的保证

GAs是启发式算法,不能保证在所有情况下都能获得最优解。虽然它们可以收敛到高质量的解决方案,但不能保证找到的解决方案是最好的。当算法运行数次而答案不同时,人们注意到了这一点。这一点可以通过增加代数来缓解,但其代价是需要更多的时间和处理。

结果

来自GA的最适合的个体是:

Image description

结论

就个人而言,GA让我着迷。在这个项目上工作并能与大家分享是一件非常愉快的事情。在这个过程中我学到了很多东西,这促使我在这个领域寻找更多的知识。在开发过程中,我与Estefane George Macedo de Lacerda的博士论文《通过遗传算法选择RBF网络的模型》有过接触,这对了解GA的工作原理有很大帮助,我想公开祝贺她的精彩研究。

你可以在这里访问我的资料库