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

OptaPlanner中动态Placement列表的处理方案及示例需求

解决方案:调整建模思路,基于物料拆分单元构建规划实体

OptaPlanner的规划实体集合在初始化时必须是固定大小的,不支持动态扩展。因此你需要调整模型,将物料的拆分单元作为规划实体,而非动态的放置步骤。以下是具体实现方案:

1. 重新定义规划实体:MaterialAllocation

每个MaterialAllocation代表一份可分配的物料单元(可按最小单位拆分,或合并为合理批次),OptaPlanner将为每个单元分配目标容器。

@PlanningEntity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MaterialAllocation {
    // 唯一标识,用于区分不同分配单元
    private Long id;
    // 关联的原始物料(标记为@PlanningPin,避免OptaPlanner修改)
    @PlanningPin
    private Material material;
    // 当前单元的物料数量(可固定为最小单位,如1,或按需设置批次大小)
    private int quantity;
    // 规划变量:该单元分配到的容器
    @PlanningVariable(valueRangeProviderRefs = "containerRange")
    private Container container;
}

2. 调整规划解决方案模型

将原placement列表替换为固定数量的MaterialAllocation集合,初始时根据物料总数量生成足够的分配单元:

@PlanningSolution
@Data
@AllArgsConstructor
@ToString
@NoArgsConstructor
public class AllocationSolution {
    // 规划实体集合:所有待分配的物料单元
    @PlanningEntityCollectionProperty
    private List<MaterialAllocation> materialAllocations;
    
    // 容器范围提供者,供规划变量使用
    @ValueRangeProvider(id = "containerRange")
    @ProblemFactCollectionProperty
    private List<Container> containers;
    
    // 原始物料信息(作为问题事实)
    @ProblemFactCollectionProperty
    private List<Material> materials;
    
    // 评分结果
    @PlanningScore
    private HardSoftScore score;
}

3. 初始化解决方案

根据每个物料的总数量,生成对应的MaterialAllocation实体。例如,若某物料总数量为150,可拆分为150个数量为1的单元,或15个数量为10的批次:

public static AllocationSolution createInitialSolution(List<Container> containers, List<Material> materials) {
    List<MaterialAllocation> allocations = new ArrayList<>();
    long idCounter = 0;
    for (Material material : materials) {
        int totalQuantity = material.getTotalQuantity();
        // 按最小单位拆分(可根据业务调整为批次拆分)
        for (int i = 0; i < totalQuantity; i++) {
            allocations.add(new MaterialAllocation(idCounter++, material, 1, null));
        }
    }
    return new AllocationSolution(allocations, containers, materials, null);
}

4. 定义约束规则

通过约束确保分配逻辑符合业务需求,例如:

  • 硬约束:每个容器的总物料数量不超过其最大容量(若容器容量已知)
  • 硬约束:同一物料的所有分配单元数量总和等于原始物料总数量(避免遗漏或超额)
  • 软约束:尽量减少使用的容器数量(若容器数量可变)
  • 软约束:优先将同类型物料分配到同一容器(按需添加)

示例约束(使用ConstraintStream API):

public class AllocationConstraintProvider implements ConstraintProvider {
    @Override
    public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
        return new Constraint[] {
            // 硬约束:容器总容量不超限
            containerCapacityLimit(constraintFactory),
            // 软约束:减少空容器使用
            minimizeEmptyContainers(constraintFactory)
        };
    }

    private Constraint containerCapacityLimit(ConstraintFactory constraintFactory) {
        return constraintFactory.from(MaterialAllocation.class)
                .groupBy(MaterialAllocation::getContainer, sum(MaterialAllocation::getQuantity))
                .filter((container, totalQuantity) -> totalQuantity > container.getMaxCapacity())
                .penalize("Container capacity exceeded", HardSoftScore.ONE_HARD);
    }

    private Constraint minimizeEmptyContainers(ConstraintFactory constraintFactory) {
        return constraintFactory.from(Container.class)
                .filter(container -> constraintFactory.from(MaterialAllocation.class)
                        .filter(allocation -> container.equals(allocation.getContainer()))
                        .count() == 0)
                .penalize("Empty container", HardSoftScore.ONE_SOFT);
    }
}

5. 处理容器数量未知的场景

若你不确定需要多少个容器,可预先生成足够多的空容器(数量大于预估最大值),然后通过minimizeEmptyContainers软约束惩罚空容器,OptaPlanner会自动优化为最少的容器使用量。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 07:23:15