为何添加软约束后OptaPlanner无法找到可行解?
问题:添加软约束后OptaPlanner无法找到可行解
问题背景
项目原本包含以下两个硬约束:
fun cpMustUseN(constraintFactory: ConstraintFactory): Constraint { return constraintFactory.forEach(MealMenu::class.java) .join(CpMustUse::class.java, equal({ mm -> mm.slottedCp!!.id }, CpMustUse::cpId)) .groupBy({ _, cpMustUse -> cpMustUse.numRequired }, countBi()) .filter { numRequired, count -> count < numRequired } .penalize(HardSoftScore.ONE_HARD) .asConstraint("cpMustUseN") } fun cpMustUseAtLeastOne(constraintFactory: ConstraintFactory): Constraint { return constraintFactory.forEach(CpMustUse::class.java) .ifNotExists(MealMenu::class.java, equal({ cpMustUse -> cpMustUse.cpId }, { mealMenu -> mealMenu.slottedCp!!.id })) .penalize(HardSoftScore.ONE_HARD) .asConstraint("cpMustUseAny") }
运行相关测试用例时,OptaPlanner能够找到得分为0hard/0soft的可行解。
但添加以下第三个软约束后,系统无法再找到可行解,测试用例的最优结果仅为-1hard/-3soft:
fun cpVariety(constraintFactory: ConstraintFactory): Constraint { return constraintFactory.forEachUniquePair( MealMenu::class.java, equal(MealMenu::slottedCp) ) .penalize(HardSoftScore.ONE_SOFT) .asConstraint("cpVariety") }
根据OptaPlanner文档,只要存在可行解(无硬约束违反),无论软约束违反情况如何,都应优先选择可行解。确认当前场景存在可行解,但系统未找到,请问可能的原因是什么?
编辑补充:最终可用约束
为方便后续读者,以下是基于Lukas的回答调整后的最终可用约束:
fun cpMustUseN(constraintFactory: ConstraintFactory): Constraint { return constraintFactory.forEach(MealMenu::class.java) .join(CpMustUse::class.java, equal({ mm -> mm.slottedCp!!.id }, CpMustUse::cpId)) .groupBy({ _, cpMustUse -> cpMustUse.numRequired }, countBi()) .filter { numRequired, count -> count < numRequired } .penalize(HardSoftScore.ONE_HARD) { numRequired, count -> numRequired - count } .asConstraint("cpMustUseN") } fun cpMustUseAtLeastOne(constraintFactory: ConstraintFactory): Constraint { return constraintFactory.forEach(CpMustUse::class.java) .ifNotExists(MealMenu::class.java, equal({ cpMustUse -> cpMustUse.cpId }, { mealMenu -> mealMenu.slottedCp!!.id })) .penalize(HardSoftScore.ONE_HARD, CpMustUse::numRequired) .asConstraint("cpMustUseAtLeastOne") } fun cpVariety(constraintFactory: ConstraintFactory): Constraint { return constraintFactory.forEachUniquePair( MealMenu::class.java, equal(MealMenu::slottedCp) ) .penalize(HardSoftScore.ONE_SOFT) .asConstraint("cpVariety") }
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

