Java 遗传算法-对人进行分组:只找到包含X、Y和Z标准的解决方案

Java 遗传算法-对人进行分组:只找到包含X、Y和Z标准的解决方案,java,algorithm,sorting,genetic-algorithm,Java,Algorithm,Sorting,Genetic Algorithm,我正在尝试解决以下问题: 我有30个人的名单 这些人需要分成6人一组 每个人都给出了另外3个人的名字,他们想和他们一起组成一个小组 我想用遗传算法解决这个问题。 健身功能可以评估所有组,并根据每个房间满足所有偏好的人数分配健身分数。(或类似的评分系统) 例如: 生成的解决方案之一是:1,3,19,5,22,2,7,8,11,12,13,14,15,13,17…等 我假设前5个人在第一组中,下5个人在下一组中,并由此计算出适合度值 我认为这个解决方案会起作用——有人看到更好的方法吗 我的主要问

我正在尝试解决以下问题:

  • 我有30个人的名单
  • 这些人需要分成6人一组
  • 每个人都给出了另外3个人的名字,他们想和他们一起组成一个小组
我想用遗传算法解决这个问题。 健身功能可以评估所有组,并根据每个房间满足所有偏好的人数分配健身分数。(或类似的评分系统)

例如: 生成的解决方案之一是:1,3,19,5,22,2,7,8,11,12,13,14,15,13,17…等 我假设前5个人在第一组中,下5个人在下一组中,并由此计算出适合度值

我认为这个解决方案会起作用——有人看到更好的方法吗

我的主要问题是: 如果我想确保人A和人B肯定在同一组中,我可以实现fitness函数来检查这一点,如果不满足此条件,则分配一个糟糕的fitness。这是最好的方法吗?这似乎效率很低。 有没有一种方法可以“锁定”解决方案的某些部分(“某些基因”),然后只解决或解决剩余部分

任何帮助或见解将不胜感激

提前谢谢。
AK

只是澄清一点,你的问题不是遗传编程,而是遗传算法,这是两个不同的东西。遗传编程是关于生成(使用进化算法)可执行个体,这些个体将生成您的解决方案,而遗传算法个体直接表示您的解决方案

话虽如此,你的两个假设是正确的。一般来说,数据表示是进化算法的一个关键要素,不好的表示可能会阻碍有效的解空间探索。在我看来,您当前的数据表示似乎是正确的,给定的组只允许有5个人。你对强制执行某些标准的第二个想法也是正确的。在文献中表达无效解的首选方法是使用一个较大的适应度值(最好是一个即使不好的解决方案也不能表示潜在有效的值),例如无穷大(如果您的库/语言允许的话)。这比简单地删除无效个体有多个优点:在选择阶段,不好的个体不会被选择,因此它们所代表的解空间不会像有趣的解空间那样被探索,这在计算上是好的,因为它肯定不会包含最优解。毕竟,知道一个解决方案是坏的就是好的知识。同时,为了避免停滞,遗传多样性在进化算法中非常重要。为了遗传多样性,至少应该保留一些不好的个体,以便探索当前代表区域之间的解决空间

遗传算法的目标是计算不可能或太难用解析法或蛮力计算的解。尝试用启发式方法动态锁定某些基因需要大量关于问题内部运作以及潜在进化机制的知识,这将违背使用进化算法的目的。进化算法的有效目标是锁定看似正确的基因


事实上,如果你先验地绝对肯定某些特定的基因一定有特定的价值,就不要在你的个体中代表它们。例如,如果您确定其他两个个体必须具有某个给定值,则将您的第一组3个体设置为长。然后,您可以将评估函数编码为第一组中有5个个体,但不会进化/搜索以替换2个固定个体。

您的交叉操作是什么样子的?按照你描述的方式,我不确定你是如何干净地实现它的。例如,如果您有两种解决方案:

1,2,3,4,5,…,30

1,2,30,29,…,10

假设你使用单点交叉功能,你将有可能为同一个人获得多个任务,而其他人则完全没有使用上述基因组获得任务

我会有一个有30个值的基因组,每个值定义一个人的群体分配(1-6)。它看起来像65632411355632…等等。因此,第1个人被分配到第6组,第2个人被分配到第5组,等等。这将使交叉操作更容易实现,因为您不必确保交叉后每个新解决方案都是有效的分配,无论它是否最优


适应度函数将为每个成员数不正确的组分配惩罚(5),并为次优的组成员分配额外惩罚。我会使第一个惩罚明显大于第二个惩罚,然后调整它们以得到您想要的结果。

这可以建模为广义二次分配问题(GQAP)。该问题允许指定需要特定容量的设备(人员)数量、提供容量的位置(组)数量以及指定设备之间距离的权重矩阵和指定位置之间距离的距离矩阵。此外,还有安装成本,但您的问题不需要这些成本。我已经在中实现了这个问题。它不是主干的一部分,但是如果你感兴趣(或者你自己编译),我可以给你发送插件

对于这个问题,使用遗传算法最具挑战性的部分似乎是实现交叉。我会这样做:

首先选择一个常数,C.C将在所有世代中保持不变,我将在稍后解释它的用途

我将使用一个比5组6到5组更小的示例