class - Optaplanner 中车辆容量的 Drools 规则
问题描述
我正在使用 Optaplanner 进行 CVRP 并进行了一些更改,即想为车辆容量使用多个维度。我开设了一个新班级
public class Load {
protected int[] capacity;
protected int myDimension=1;}
它还有几种管理数据的方法,最重要的是
public void add (Load otherLoad) {
if (myDimension != otherLoad.myDimension) {
throw new IllegalArgumentException("Different load dimensions (" + myDimension +" / "+ otherLoad.myDimension + ").");
} else {
for (int i=0; i < myDimension; i++) {
capacity[i]+=otherLoad.capacity[i];
}
}
}
和
public boolean fitsInto (Load otherContainer) {
if (myDimension != otherContainer.myDimension) {
throw new IllegalArgumentException("Different load dimensions (" + myDimension +" / "+ otherContainer.myDimension + ").");
} else {
for (int i=0; i < myDimension; i++) {
if (capacity[i]>otherContainer.capacity[i]) return false;
}
}
return true;
}
目前我对 Drools 规则有困难,因为我对此完全陌生。旧规则是:
rule "vehicleCapacity"
when
$vehicle : Vehicle($capacity : capacity)
accumulate(
Customer(
vehicle == $vehicle,
$demand : demand);
$demandTotal : sum($demand);
$demandTotal > $capacity
)
then
scoreHolder.addHardConstraintMatch(kcontext, $capacity - $demandTotal);
结尾
我需要修改它,以便它使用 Load 类而不是整数,但不确定如何。在阅读了一些 Drools 文档后,我的蹩脚实验是这样的
rule "vehicleCapacity"
when
$demandTotal: Load
$vehicle : Vehicle($capacity : capacity)
accumulate(
Customer(
vehicle == $vehicle,
$demand : demand);
$demandTotal.add($demand);
not ($demandTotal.fitsInto($capacity))
)
then
scoreHolder.addHardConstraintMatch(kcontext, $capacity.sumValues() - $demandTotal.sumValues());
结尾
当然它没有通过,所以我很乐意得到一些提示和建议。谢谢!
解决方案
据我了解,您正在尝试将更多维度添加到demand
并因此添加到capacity
,其中限制是任何维度的容量都不能被超过。为此,您可以简单地Vehicle
修改Customers
如下
class Vehicle extends AbstractPersistable implements Standstill{
protected Location location;
protected List<Integer> capacities;
...
}
和
class Customer extends AbstractPersistable implements Standstill{
protected List<Integer> demands;
...
}
然后,在 Drools 中,您修改您的规则(绝对未经测试;特别是,您可能必须.intValue()
在 get 方法之后添加):
rule "vehicleCapacity"
when
$vehicle : Vehicle($capacity: capacities.get($loadType:lt))
accumulate(
Customer(
vehicle == $vehicle,
$demand : demands.get($loadType));
$demandTotal : sum($demand);
$demandTotal > $capacity
)
then
scoreHolder.addHardConstraintMatch(kcontext, $capacity - $demandTotal);
这将确保如果任何维度的需求超过容量,硬分就会对差异进行惩罚。只需确保使所有列表大小相同,其中的维度对应于 中的相同$loadType
维度。capacities
demands
您也可以尝试通过更改protected int capacity
为protected int[] capacities
inVehicle
和类似地 in Customer
with demand
,但我不确定您是否可以绑定到 Drools 中的数组元素。也许值得一试:Drools 规则然后运行(再次绝对未经测试):
rule "vehicleCapacity"
when
$vehicle : Vehicle($capacity: capacities[$lt:lt])
accumulate(
Customer(
vehicle == $vehicle,
$demand : demands[lt]);
$demandTotal : sum($demand);
$demandTotal > $capacity
)
then
scoreHolder.addHardConstraintMatch(kcontext, $capacity - $demandTotal);
(那么至少.intValue()
不需要)
推荐阅读
- android - Parcelable 在将活动实例作为 putExtra 发送到另一个活动时遇到 IOException 写入可序列化对象错误
- google-analytics - 从 Google Analytics 切换到 Google Tagmanager
- javascript - 定义二维数组 Javascript
- c# - 将多个 byte[] 合并为一个多页 Base64
- javascript - google.script.run.withSuccessHandler(function) 不返回数据
- jolt - 需要 JOLT spect 将 JSON 转换为预期的输出 json
- python - 如何减少模板匹配的图像搜索区域?
- node.js - “使用严格”在 Node 版本 14 中有用吗?
- sql - 记录类型匹配问题 Oracle 列表
- python - 回调中更新的 Dash 表不会显示