我想知道流口水是如何在 Optaplanner 中积累元素的?似乎 sum() 函数没有返回我期望的值。我有两个简单的 POJO ProductionPackage
和 SKU
。
@PlanningEntity
public class ProductionPackage{
// This is a custom date object containing information about a date. Constant Date initialized on start.
// Custom date object NOT util.Date or sql.Date
private Date date;
// The number of units in this package. Constant value initialized on program start.
private int productionUnits;
// The ID of the production package
private int productionPackageId;
// The SKU assigned to this production package
@PlanningVariable(valueRangeProviderRefs = "skuRange")
private SKU sku;
// Getters, setters, constructors...
}
public class SKU {
// Unique identifier for this product.
private String sku;
//Getters, setters, constructors...
}
PlanningSolution
如下所示:
@PlanningSolution
public class ProductionPlan {
@ProblemFactCollectionProperty
@ValueRangeProvider(id = "skuRange")
private List<SKU> skuList;
@ProblemFactCollectionProperty
private List<Date> dateList;
@PlanningEntityCollectionProperty
List<ProductionPackage> ProductionPackageList;
//Getters, setters, constructors...
}
基本上我有很多 ProductionPackage
并且我正在尝试为每个生产包分配一个 SKU
。 'ProductionPackage' 的 productionUnits
字段指定必须生产多少分配的 SKU
。为简单起见,假设所有 productionUnits
的 productionPackage
为 1
(可以是任何大于 0 的整数)。
这个问题的一个限制是每个 SKU
每 Date
应该至少生产 10 个单位。我正在尝试使用 Drools 实现此约束,如下所示:
rule "At least 10 production units per SKU and per Day"
enabled true
when
// Bind SKU to variable
$sku : SKU()
// Bind Date object to variable
$date : Date()
accumulate(
ProductionPackage(sku == $sku,
date == $date,
$productionUnits : productionUnits);
$productionUnitsTotal : sum($productionUnits);
$productionUnitsTotal < 10
)
then
// For debugging purposes
System.out.println("SKU: " + $sku.toString());
System.out.println("Date: " + $date.toString());
System.out.println("ProductionUnits: " + $productionUnitsTotal);
scoreHolder.addHardConstraintMatch(kcontext, -1);
end
在 Drools 文档中指出,accumulate 元素迭代集合的所有元素。对我而言,此规则选择了 SKU
和 Date
的组合。然后它遍历包含 ProductionPackageList
对象的 ProductionPackage
。如果 Date
和 SKU
与之前选择的 SKU
和 Date
对象匹配,它会将 productionUnits
相加。我希望这会返回每个 SKU
和每个 Date
生产的总单位(看起来有时确实如此)。但是,我注意到 System.out.println("ProductionUnits: " + $productionUnitsTotal);
语句正在打印 0
。这对我来说真的很奇怪,因为 productionUnits
总是一个大于 0 的整数。它如何打印 0
?如果两个条件都匹配($date = date
和 $sku == sku
),则 SKU
不应有 0 个生产单位,因为它已分配给 productionUnits
> 0 的生产包。>
我认为错误源于我真的不明白 Optaplanner 或 Drools 在做什么。我打开了调试/跟踪模式,但这些对我没有多大帮助。