Class Optaplanner中车辆容量的下降规则
我正在为CVRP使用Optaplanner,并做了一些更改,即希望为车辆容量使用多个尺寸。 我开设了一个新班级Class Optaplanner中车辆容量的下降规则,class,drools,rules,optaplanner,Class,Drools,Rules,Optaplanner,我正在为CVRP使用Optaplanner,并做了一些更改,即希望为车辆容量使用多个尺寸。 我开设了一个新班级 public class Load { protected int[] capacity; protected int myDimension=1;} 它还有几种管理数据的方法,最重要的是 public void add (Load otherLoad) { if (myDimension != otherLoad.myDimension) { throw n
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];
}
}
}
结束
我需要修改它,以便它将使用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());
结束
当然不会通过,所以我很乐意得到一些提示和建议。
谢谢大家! 据我所知,您正试图为需求增加更多维度,从而增加容量,其中限制条件是任何维度的容量都不能超过。为了实现这一点,您只需修改车辆和客户,如下所示
class Vehicle extends AbstractPersistable implements Standstill{
protected Location location;
protected List<Integer> capacities;
...
}
这将确保如果需求超过任何维度的容量,硬分数将惩罚差异。只需确保所有列表的大小相同,容量中的维度$loadType对应于需求中的相同维度
您也可以尝试将车辆中的protected int capacity更改为protected int[]capacity,并根据需要在Customer中进行类似更改,但我不确定您是否可以绑定到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是不必要的我无法解决这个问题,所以我实际上只是将容量复制到int capacity1,int capacity2,并相应地复制和修改了规则。
它既不优雅,也不可扩展,但到目前为止,它确实做到了这一点 谢谢你的评论。我尝试了第二个int[]版本,但是,我得到了一些错误。我猜$lt附近出了点问题,但不太确定,主线程java.lang.IllegalStateException中出现了什么异常。IllegalStateException:分数中有错误DRL:错误消息:消息[id=1,kieBase=defaultKieBase,level=ERROR,path=org/optaplanner/examples/vehiclerouting/solver/vehicleRoutingScoreRules.drl,line=42,column=0 text=无法分析表达式容量[$lt:lt]:[ERROR:无法使用严格模式解析方法:org.optaplanner.examples.vehiclerouting.domain.Vehicle.$lt][Near:{……容量[$lt:lt]]我无法解决这个问题,所以我实际上只是将容量复制到int capacity1,int capacity2,并相应地复制和修改了规则。遗憾的是,您必须这样做。Drools明确提供了绑定到列表中元素的可能性,请参阅第8.8.3节。它没有说明任何关于数组的内容,但我认为它会相同。您尝试过解决方案1吗?顺便说一句,应该是需求:需求[$lt]和$。
class Vehicle extends AbstractPersistable implements Standstill{
protected Location location;
protected List<Integer> capacities;
...
}
class Customer extends AbstractPersistable implements Standstill{
protected List<Integer> demands;
...
}
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);
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);