java - 寻找在 OptaPlanner 中使用“DoubleValueRange”的正确方法
问题描述
我正在学习如何通过解决线性规划来使用 OptaPlanner。我知道有很多 LP 求解器,但我认为这是我理解建模的一个很好的起点。
但是当我开始研究它时,我遇到了一个问题,它看起来实体计划变量只能是可数的。
例外情况如下:
The selector is not countable, check the ValueRanges involved.
Verify that a ValueRangeProvider does not return ValueRange when it can return CountableValueRange or Collection.
我可以知道吗:
使用“DoubleValueRange”的“合法”方式是什么?
OptaPlanner 中是否有 LP 的“最佳实践”?
谢谢你。
我的解决方案:
@PlanningSolution
public class Solution {
@PlanningEntityProperty
private Entity entity;
@PlanningScore
private HardSoftScore score = HardSoftScore.ZERO;
public Solution(Entity entity) {
this.entity = entity;
}
@ValueRangeProvider(id = "x_1")
public ValueRange<Double> getX1Range() {
return ValueRangeFactory.createDoubleValueRange(0.0, 100.0);
}
@ValueRangeProvider(id = "x_2")
public ValueRange<Double> getX2Range() {
return ValueRangeFactory.createDoubleValueRange(0.0, 100.0);
}
...<getters setters>...
我的实体:
@PlanningEntity
public class Entity {
private long id;
@PlanningVariable(valueRangeProviderRefs = "x_1")
private Double x1;
@PlanningVariable(valueRangeProviderRefs = "x_2")
private Double x2;
...<getters setters>...
我的限制:
...
private Constraint c1(ConstraintFactory constraintFactory) {
return constraintFactory.from(Entity.class)
.filter(e -> !(3.0 * e.getX1() + 5.0 * e.getX2() < 5.0 ))
.penalize("C1", HardSoftScore.ONE_HARD);
}
private Constraint c2(ConstraintFactory constraintFactory) {
return constraintFactory.from(Entity.class)
.filter(e -> !(2.0 * e.getX1() - 6.0 * e.getX2() > 0.0 ))
.penalize("C2", HardSoftScore.ONE_HARD);
}
private Constraint min(ConstraintFactory constraintFactory) {
return constraintFactory.from(Entity.class)
.penalize("MIN", HardSoftScore.ONE_SOFT, e -> (int)(-e.getX1() + 6.0 * e.getX2()));
}
...
解决方案
查看 ValueRangeFactory 的 createXXXValueRange() 方法集中的返回类型,我注意到除了一个之外,所有的返回类型都返回一个Countable ValueRange。该规则的一个例外是 createDoubleValueRange(),它返回一个“纯粹的”ValueRange (ValueRange)。
您的错误指向同一个方向:ValueRange 不被视为有效的可数ValueRange。这对我来说很有意义:OptaPlanner 想要从一组离散值中进行选择来进行移动。所以我认为没有任何“合法”的方式可以将它用于 OptaPlanner 的求解器 Move's。
由于一个我无法确定的原因,我自己不会将 OptaPlanner 作为解决 LP 问题的首选,因为可以计算出一组可行的解决方案。但是无论如何使用OptaPlanner(就像你的情况一样),然后我会处理离散值的倍数(10、100、1000,...)(在结果计算中将它们除以10、100、1000,...) . 并且/但与此同时,我会非常谨慎地避免分数腐败,这种危险永远不会很远。
推荐阅读
- c++ - std::vector 构造与元素的就地构造
- android - 将 X509CertificateHolder 对象转换为 X509certificate 时出现以下异常
- excel-formula - 总结每月销售额的Excel公式
- php - 当私钥保存在文件中时,php openssl 不起作用
- sql - 如何根据每个帐户的最大中继策略发送邮件
- testing - ENDPOINT_AUTH_PARAMETER_SYSTEMVSSCONNECTION_ACCESSTOKEN 在哪里配置?
- c# - 如何设置 MyPackage.targets 文件以将所有 dll 添加到 bin/debug 或 bin/Release 文件夹中?
- java - 在 SashForm 中添加到运行时的 Composite 的自动适配
- go - 使用 golang 生成嵌套 JSON
- python - 如何在 docker compose 中构建和定义两个 python 服务器