我有一个vrp变体,可以最大限度地降低一组液体交付的成本。我被要求将单位成本降到最低。
成本是:每小时的车辆成本,从静止状态,回到仓库(只是从VRP的例子到上一次静止的时间和到仓库的时间,乘以车辆每小时的速度),加上产品的成本。
交付的数量取决于解决方案,但可以通过对每辆车的交付量进行求和来计算。
所以我有三个成本流和一个单位计数流。有没有一种方法可以把它们合起来,然后把这两个总和除以?或者影子变量是唯一的方法吗?
对于影子变量方法,我将为每个客户添加"成本",然后使用单个约束替换所有软约束,如下所示:
protected Constraint costPerUnit(ConstraintFactory factory) {
return factory.forEach(Customer.class)
.groupBy( c->sumLong(c.getCost()), sumLong(c.getLitres))
.penalizeLong(
HardSoftLongScore.ONE_SOFT,
(cost, amount) -> cost / amount)
.asConstraint("costOfProduct");
}
看起来会很慢。
编辑:考虑到这一点更多,是否有一个性能的原因使用约束流,而不是仅仅计算分数在监听器,然后使用一个简单的约束流规则的所有软约束?
尽管,通过大量的关注和注意,您可能可以实现一个非常快速的侦听器来处理这类问题,但我怀疑它是否会像适当的增量解决方案一样快。
现在这个解决方案需要使用约束流实现吗?不。对于小问题,EasyScoreCalculator
将会很容易,但是对于小问题,您不需要OptaPlanner。对于规模较大但分数计算方式简单的问题,您可能想要查看IncrementalScoreCalculator
-这些很难实现,但一旦您掌握了正确的方法,就没有办法更快了。设计良好的增量计算器在性能方面通常优于约束流。