带约束permutation problem的进化算法优化:矩阵配对方案咨询
约束排列配对问题的优化方案
一、直接嵌入约束的解表示方式
当然存在,当前全排列编码会生成大量无效解,完全是浪费计算资源,换用以下编码方式能从根源上规避约束违规:
1. 无2-循环的置换循环编码
排列本质是置换,我们直接用不含长度为2的循环的置换分解结果作为解编码:
- 每个解由若干长度≥3的循环组成(比如
i→j→k→i这种循环,避免了i→j、j→i的对称配对,直接满足约束1)。 - 生成循环时,强制要求循环中每个元素的下一个元素(包括循环首尾)属于不同类别,直接满足约束2。
2. 循环链表式编码
把每个解表示为一个或多个循环链表,每个链表长度≥3,且链表中任意相邻元素(含首尾)类别不同。这种编码生成的解天然符合两个约束,不需要事后检查或惩罚。
注:因为n=25是奇数,必然会有一个元素无法纳入长度≥3的循环?可以把它合并到任意一个循环中,调整循环结构后确保长度≥4且所有相邻元素类别不同,或者如果题目允许单个元素不配对,单独处理即可。
二、若保留原编码,如何在操作中直接实现约束
如果不想更换编码方式,就在初始化、交叉、变异的每一步都加入约束检查和修正逻辑,确保生成的解都是可行解:
1. 初始化阶段
别随机生成全排列,直接构造满足约束的排列:
- 先按类别分组,记录每个矩阵的类别标签。
- 用循环构造法:从任意未处理的矩阵i开始,随机选一个不同类别的未处理矩阵j作为i的配对(即数组第i位设为j);再从j出发,随机选一个不同类别的未处理矩阵k作为j的配对;以此类推,直到回到某个已处理节点形成长度≥3的循环。重复这个过程直到所有矩阵都被纳入循环。
- 针对最后剩下的单个元素,要么合并到已有循环(调整后保证循环长度≥4且类别约束满足),要么按题目要求单独标记。
2. 交叉操作(替换原cut-and-crossfill)
原交叉算子会直接破坏约束,换成约束感知的交叉算子:
- 用变种循环交叉(CX):
- 从父代1中提取一个完整循环,检查该循环内所有元素的配对是否符合类别约束。
- 将父代2中对应位置的元素替换到这个循环里,替换后必须保证:新循环长度≥3,且每个元素的配对对象类别不同。
- 如果替换后违规,就重新选择循环或调整替换的元素。
- 或者用变种有序交叉(OX):
- 选一段子序列复制到子代,再从父代2中填充剩余元素。
- 填充时必须实时检查:不能出现
i的配对是j、j的配对是i的情况,且每个元素的配对对象类别不同。
3. 变异操作
原随机交换容易触发违规,换成约束友好的变异方式:
- 禁止直接交换两个元素(大概率会形成对称配对)。
- 采用循环旋转变异:选一个长度≥3的循环,把循环内的元素顺序旋转(比如
i→j→k→i改成i→k→j→i),旋转后检查每个元素的配对是否符合类别约束,符合就保留结果。 - 或者采用循环拆分/合并变异:把一个长度≥4的循环拆成两个长度≥3的循环,或者把两个循环合并成一个,操作过程中必须保证所有元素的配对对象类别不同。
4. 适应度计算优化
即使做了约束感知操作,也可以保留极轻量的惩罚项(应对操作中的小概率失误),但核心适应度还是以两矩阵标量积的元素和为主,绝不能让惩罚项主导适应度计算。
内容的提问来源于stack exchange,提问作者Liisjak
相关产品推荐
相关产品推荐

