Установка глобальных переменных в рабочей памяти в планировщике Drools
Как добавить глобальную переменную в рабочую память в решателе планировщика drools, чтобы можно было использовать ее в счетах drool. Это похоже на https://issues.jboss.org/browse/JBRULES-2700 но найти решение не удалось.
3 ответа
Возможно, вы ищете @ProblemFactProperty
. Цитата из документации:
Все объекты, возвращаемые этими [аннотированными] методами, будут вставлены в сеанс ConstraintStreams или Drools, так что пары ограничений или правила оценки могут получить к ним доступ.
Мои собственные слова: вы можете содержать ссылку на свой глобальный объект в своем @PlanningSolution
учебный класс. Если вы аннотируете егоgetter
с @ProblemFactProperty
вы можете получить к нему доступ из своего файла слюнявчиков.
После установки задачи планирования:
solver.setPlanningProblem(planningProblem);
Вы можете получить доступ к рабочей памяти через solutionDirector(HACK):
DefaultSolutionDirector solutionDirector = ((DefaultSolver)solver).getSolverScope().getSolutionDirector();
solutionDirector.getWorkingMemory().setGlobal("list", new ArrayList<String>());
Ура!
Сначала небольшая проповедь: использование службы (заданной как глобальная) для вычисления части оценки нарушит вычисление оценки на основе дельты (см. Раздел руководства по этой теме), что приведет к гораздо меньшим вычислениям оценки в секунду (скажем, 50 вместо 5000 за второй по большим наборам данных).
Затем решение HACK: в StartingSolutionInitializer (вскоре известный как CustomSolverPhaseCommand) выполните solverScope.getWorkingMemory().setGlobal("key", value)
,
Тогда реальное, долгосрочное решение: не могли бы вы объяснить, почему вам нужно это сделать? Мы можем подумать о добавлении поддержки для этого с чем-то вроде дополнительного WorkingMemoryPreperator
,
Если вам нужно использовать некоторые вспомогательные методы в правилах планировщика, попробуйте следующий подход, который я использовал в своем проекте:
- Создайте служебный класс, который включает вспомогательные методы.
- Импортируйте служебный класс в файл правил так же, как импортируйте его в 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