OptaPlanner:如何添加规划实体集合求和作为优化约束?
OptaPlanner 总和超限硬约束实现方案
你需要实现的是当所有规划实体的x贡献值总和超过阈值X时,触发HARD级别的分数惩罚,原代码的问题在于没有正确对总和进行过滤判断,以下是修正后的实现:
基础实现(固定惩罚)
如果只要总和超限就罚固定1个HARD分,代码如下:
Constraint constraintX(ConstraintFactory constraintFactory) { int thresholdX = 100; // 替换为你的实际阈值X return constraintFactory .forEach(PlanningEntity.class) // 可选:如果仅需统计x不为0的实体,保留此filter;否则删除 .filter(entity -> entity.getX() > 0) .sum(PlanningEntity::getX) // 计算符合条件的实体x值总和 .filter(sum -> sum > thresholdX) // 判断总和是否超过阈值 .penalize("Sum of xs exceeds X", HardMediumSoftScore.ONE_HARD); }
进阶实现(按超限差值惩罚)
如果需要根据超限的具体数值来惩罚(比如每超过1单位罚1个HARD分),可以调整penalize的第三个参数:
Constraint constraintX(ConstraintFactory constraintFactory) { int thresholdX = 100; return constraintFactory .forEach(PlanningEntity.class) .filter(entity -> entity.getX() > 0) .sum(PlanningEntity::getX) .filter(sum -> sum > thresholdX) // 按超出部分的数值计算惩罚分数 .penalize("Sum of xs exceeds X", HardMediumSoftScore.ONE_HARD, sum -> sum - thresholdX); }
关键说明
forEach(PlanningEntity.class):遍历所有规划实体sum(PlanningEntity::getX):聚合计算目标字段的总和- 第二个
filter:判断总和是否触发约束条件 penalize:定义触发约束时的惩罚规则,包括惩罚名称、分数级别和可选的惩罚权重计算逻辑
内容的提问来源于stack exchange,提问作者Rayamon
相关产品推荐
相关产品推荐

