如何在 drools planner 的求解器中将全局变量添加到工作内存中,以便能够在分数 drool 中使用。这类似于https://issues.jboss.org/browse/JBRULES-2700但找不到解决方案。
4 回答
您可能正在寻找的是一个@ProblemFactProperty
. 引用文档:
这些 [annotated] 方法返回的所有对象都将插入到 ConstraintStreams 或 Drools 会话中,因此约束流或评分规则可以访问它们。
用我自己的话来说:你可以在你的类中保存对你的全局对象的引用@PlanningSolution
。如果你注释它getter
,@ProblemFactProperty
你可以从你的 drools 文件中访问它。
首先是一些说教:使用服务(设置为全局)来计算部分分数将打破基于增量的分数计算(阅读关于该主题的手册部分),导致每秒的分数计算要少得多(比如 50 而不是 5000 每在大数据集上排名第二)。
然后是 HACK 解决方案:在 StartingSolutionInitializer(很快称为 CustomSolverPhaseCommand)中执行solverScope.getWorkingMemory().setGlobal("key", value)
.
然后是一个真正的、长期的解决方案:你能激发你为什么需要能够做到这一点吗?我们可以考虑使用类似 optional 的东西来添加对此的支持WorkingMemoryPreperator
。
设置好规划后的问题:
solver.setPlanningProblem(planningProblem);
您可以通过 solutionDirector(HACK) 访问workingMemory:
DefaultSolutionDirector solutionDirector = ((DefaultSolver)solver).getSolverScope().getSolutionDirector();
solutionDirector.getWorkingMemory().setGlobal("list", new ArrayList<String>());
干杯!
如果您需要在规划器规则中使用一些辅助方法,请尝试我在项目中使用的以下方法:
- 创建一个包含辅助方法的实用程序类。
- 在规则文件中导入实用程序类,就像在 java 类中导入它一样。
- 在规则中使用辅助方法。如果要在条件中使用辅助方法,请使用 eval() 进行包装。如果您想在 then 部分中使用辅助方法,只需将其用作普通的 java 方法调用即可。
例如,假设您有一个名为 PlanningUtil 的实用程序类,如下所示:
public class PlanningUtil {
public boolean isGood() {return true;}
public void doSomething() {//...}
}
然后在规则文件中导入实用程序类,
import PlanningUtil;
在规则中使用实用方法
rule "MyRule"
when
eval(PlanningUtil.isGood())
then
PlanningUtil.doSomething(); // note the ';' is a must.
end