You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何设置OptaPlanner中Request的EntityList按ID正序排列?

问题描述

我有两个标注@PlanningEntity的类:Entity和Request,二者关联方式如下:

Request类代码

public class Request {
    @PlanningListVariable
    private List<Entity> EntityList;
}

Entity类代码

public class Entity{
    @InverseRelationShadowVariable(sourceVariableName = "EntityList")
    private Request Request;
}

Solution类结构

public class Solution implements Serializable {
    @PlanningId
    private Long id;

    @PlanningEntityCollectionProperty
    private List<Request> RequestList;

    @ValueRangeProvider
    @ProblemFactCollectionProperty
    private List<Entity> Entities;
}

我期望解决方案中RequestList里的每个Request的EntityList按ID正序排列,但实际结果始终是倒序。尝试添加约束限制顺序但未生效,请问该如何设置实现需求?


解决方案

1. 修正约束逻辑

如果之前的约束未生效,大概率是逻辑未覆盖所有相邻元素的顺序检查。正确的硬约束写法如下,强制列表中每个相邻元素都按ID正序排列:

private Constraint enforceEntityListOrder(ConstraintFactory constraintFactory) {
    return constraintFactory.forEach(Request.class)
            .flatMap(request -> {
                List<Entity> entityList = request.getEntityList();
                List<Tuple<Entity, Entity>> adjacentPairs = new ArrayList<>();
                for (int i = 0; i < entityList.size() - 1; i++) {
                    adjacentPairs.add(Tuple.of(entityList.get(i), entityList.get(i+1)));
                }
                return adjacentPairs.stream();
            })
            .filter(pair -> pair.getFirst().getId() > pair.getSecond().getId())
            .penalize("Entity list out of order", HardSoftScore.ONE_HARD);
}

2. 用软约束引导排序(推荐)

若硬约束导致规划无解,可改用软约束引导规划器生成正序列表,既保证解的可行性,又能趋近目标顺序:

private Constraint rewardEntityListOrder(ConstraintFactory constraintFactory) {
    return constraintFactory.forEach(Request.class)
            .flatMap(request -> {
                List<Entity> entityList = request.getEntityList();
                List<Tuple<Entity, Entity>> adjacentPairs = new ArrayList<>();
                for (int i = 0; i < entityList.size() - 1; i++) {
                    adjacentPairs.add(Tuple.of(entityList.get(i), entityList.get(i+1)));
                }
                return adjacentPairs.stream();
            })
            .filter(pair -> pair.getFirst().getId() < pair.getSecond().getId())
            .reward("Entity in correct order", HardSoftScore.ONE_SOFT);
}

3. 配置列表变量的排序策略

直接在@PlanningListVariable注解中指定比较器,让规划器分配元素时优先按ID正序选择,从根源上减少逆序:

public class Request {
    @PlanningListVariable(valueRangeProviderRefs = "Entities", 
                          comparator = EntityByIdComparator.class)
    private List<Entity> EntityList;
}

// 自定义比较器类
public class EntityByIdComparator implements Comparator<Entity>, Serializable {
    @Override
    public int compare(Entity e1, Entity e2) {
        return Long.compare(e1.getId(), e2.getId());
    }
}

4. 规划后主动排序(兜底)

如果上述方法均不生效,可在获取最终解决方案后,对每个Request的EntityList手动排序:

Solution bestSolution = solver.getBestSolution();
bestSolution.getRequestList().forEach(request -> {
    request.getEntityList().sort(Comparator.comparing(Entity::getId));
});

内容的提问来源于stack exchange,提问作者romee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 00:42:24