我是 optaplanner 的新手。尝试实施垃圾箱包装解决方案将电子商务订单物品包装到纸箱容器中,我们有不同的容器尺寸来容纳所有物品。
来自 optaplanner,我按照 cloudbalance 的示例案例来实现此装箱。 https://www.optaplanner.org/docs/optaplanner/latest/use-cases-and-examples/cloud-balancing/cloud-balancing.html
当我第一次得出结果时。似乎不是一个优化的解决方案,不确定代码哪里出了问题。
public void run() throws IOException {
SolverFactory<CartonizationSolution> solverFactory = SolverFactory.create(new SolverConfig()
.withSolutionClass(CartonizationSolution.class)
.withEntityClasses(OrderItem.class)
.withConstraintProviderClass(CartonizationConstraintProvider.class)
.withTerminationConfig(new TerminationConfig().withUnimprovedSecondsSpentLimit(5L)));
Solver<CartonizationSolution> solver = solverFactory.buildSolver();
CartonizationSolution solution = load();
CartonizationSolution solvedSolution = solver.solve(solution);
ScoreManager<CartonizationSolution, HardSoftScore> scoreManager = ScoreManager.create(solverFactory);
ScoreExplanation<CartonizationSolution, HardSoftScore> cartonizationSolutionHardSoftScoreScoreExplanation = scoreManager.explainScore(solution);
System.out.println(scoreManager.getSummary(solution));
System.out.println("Planning items: " + solution.getOrderItems().size());
System.out.println("Planning cartons: " + solution.getCartonRange().size());
System.out.println("\nSolved CartonizationSolution:\n"
+ toDisplayString(solvedSolution));
}
Total Container be grouped: 4
Type: Small -> 4
CartonContainer#Small#3: 8 items
Volume Usage 97.005356% 13037520/13440000
Weight Usage 34.233334% 5135/15000
CartonContainer#Small#1: 10 items
Volume Usage 99.417336% 13361690/13440000
Weight Usage 24.633333% 3695/15000
CartonContainer#Small#4: 11 items
Volume Usage 75.845314% 10193610/13440000
Weight Usage 27.333334% 4100/15000
CartonContainer#Small#2: 12 items
Volume Usage 99.58103% 13383690/13440000
Weight Usage 91.64% 13746/15000
Total Volum: 53760000
public class CartonizationConstraintProvider implements ConstraintProvider {
@Override
public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
return new Constraint[]{
requiredWeightTotal(constraintFactory),
requiredVolumeTotal(constraintFactory),
computerCost(constraintFactory)
};
}
Constraint requiredWeightTotal(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(OrderItem.class)
.groupBy(OrderItem::getContainer, sum(OrderItem::getWeight))
.filter((container, requiredWeight) -> requiredWeight > container.getMaxWeight())
.penalize(HardSoftScore.ONE_HARD,
(container, requiredWeight) -> requiredWeight - container.getMaxWeight())
.asConstraint("requiredWeightTotal");
}
Constraint requiredVolumeTotal(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(OrderItem.class)
.groupBy(OrderItem::getContainer, sum(OrderItem::getVolume))
.filter((container, requiredVolume) -> requiredVolume > container.getMaxVolume())
.penalize(HardSoftScore.ONE_HARD,
(container, requiredVolume) -> requiredVolume - container.getMaxVolume())
.asConstraint("requiredVolumeTotal");
}
Constraint computerCost(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(CartonContainer.class)
.ifExists(OrderItem.class, equal(Function.identity(), OrderItem::getContainer))
.penalize(HardSoftScore.ONE_SOFT, CartonContainer::getMaxVolume)
.asConstraint("overallVolume");
}
}
使用 google 的 OR-Tools 运行类似数据。
我可以得到以下结果。
Number of Items be planning: 41
Number of Carton be planning: 30
<generator object cartonize.<locals>.<genexpr> at 0x1057f3530>
Bin number #0 Small
Items packed: 9
Total weight: 42% 6.2909999999999995 / 15.0
Total volume: 99% 13320.85 / 13440.0
Bin number #15 Small
Items packed: 14
Total weight: 78% 11.686000000000002 / 15.0
Total volume: 99% 13269.66 / 13440.0
Bin number #25 Medium
Items packed: 18
Total weight: 58% 8.698999999999998 / 15.0
Total volume: 99% 23386.0 / 23520.0
Number of bins used: 3
Total volume 50400.0
Time = 1138 milliseconds
由于总体积较低,是否应该以 OR 工具得出接近的解决方案