Optaplanner:遍历drools规则文件中的列表变量 [英] Optaplanner: Iterate over list variable in drools rule file
问题描述
我正在解决类似于员工名册的问题.我还有其他限制.员工具有分配给他们的类型"值.每天至少要有每种"类型的至少1名员工在这里,这是一个严格的约束.我将其建模如下:
I am solving a problem similar to employee rostering. I have an additional constraint. The employees have a "type" value assigned to them. It's a hard constraint that atleast 1 employee of each "type" be there everyday. I have modelled it as follows:
rule "All employee types must be covered"
when
$type: Constants.EmployeeType() from Constants.EmployeeType.values()
not Shift(employeeId != null, $employee: getEmployee(), $employee.getType() == $type.getValue())
then
scoreHolder.addHardConstraintMatch(kcontext, -100);
end
但是,此规则不认为每天都满足约束条件.我有一个日期字符串列表.如何以与EmployeeType枚举相同的方式在drools文件中对其进行迭代?
This rule however, does not consider that the constraint be satisfied on each day. I have a list of date strings. How can I iterate over them in the drools file in the same manner that I am on the EmployeeType enum?
编辑:我想出了一种方法,但感觉像是在破解.在初始化日期字符串列表时,我还将其分配给静态变量.然后,我可以使用类似于枚举的静态变量.
I figured out a way but it feels like a hack. When initialising the list of date strings, I also assign it to a static variable. Then I am able to use the static variable similar to the enum.
rule "All employee types must be covered"
when
$type: Constants.EmployeeType() from Constants.EmployeeType.values()
$date: String() from Constants.dateStringList;
not Shift(employeeId != null, $date == getDate(), $employee: getEmployee(), $employee.getType() == $type.getValue())
then
scoreHolder.addHardConstraintMatch(kcontext, -100);
end
但是不要以为这是正确的方法.
Don't think this is the correct approach though.
推荐答案
您的方法行得通,但是必须在类的静态属性中定义动态配置听起来并不正确(就像您指出的那样).
Your approach works, but having to define dynamic configurations in a static property of a class doesn't sound right (like you pointed out).
一种解决方案是要么在会话中使用全局变量,要么使用指定此配置的事实类.
One solution would be to either use a global in the session, or to have a fact class that specify this configuration.
使用全局
如果您决定采用这种方法,则需要在DRL中定义类型为List<String>
的全局变量,然后将其与memberOf
运算符结合使用在规则中:
If you decide to take this approach, then you need to define a global of type List<String>
in your DRL and then use it in your rules in combination with the memberOf
operator:
global List<String> dates;
rule "All employee types must be covered"
when
$type: Constants.EmployeeType() from Constants.EmployeeType.values()
not Shift(
employeeId != null,
date memberOf dates,
$employee: getEmployee(),
$employee.getType() == $type.getValue()
)
then
scoreHolder.addHardConstraintMatch(kcontext, -100);
end
建议在将任何事实Shift
插入会话之前,先为global设置值:
It is recommended to set the value for global before you insert any fact Shift
into you session:
List<String> dates = //get the List from somewhere
ksession.setGlobal("dates", dates);
使用实况类
除了全局变量外,还可以将配置建模为一个类.如果您想例如在规则内部修改配置,这将使事情变得容易.
Other than a global, you can model your configuration as a class. This makes things easier if you want for example to modify the configuration inside the rules themselves.
对于这种方法,您首先需要具有一个包含List<String>
的类.从理论上讲,您可以插入List<String>
而不将其包装在任何类中,但这会使内容难以阅读和维护.
for this approach you will need to have a class containing the List<String>
first. You could in theory insert the List<String>
without wrapping it in any class, but this will make things hard to read and maintain.
public class DatesConfiguration {
private List<String> dates;
//... getters + setters
}
然后,您需要实例化此类的对象并将其插入到会话中:
Then, you need to instantiate an object of this class and to insert it into your session:
DatesConfiguration dc = new DatesConfiguration();
dc.setDates(...);
ksession.insert(dc);
这时,您创建的对象只是Drools的另一个事实,可以在您的规则中使用:
At this point, the object you have created is just another fact for Drools and can be used in your rules:
rule "All employee types must be covered"
when
$type: Constants.EmployeeType() from Constants.EmployeeType.values()
DatesConfiguration($dates: dates)
not Shift(
employeeId != null,
date memberOf $dates,
$employee: getEmployee(),
$employee.getType() == $type.getValue()
)
then
scoreHolder.addHardConstraintMatch(kcontext, -100);
end
希望有帮助,
这篇关于Optaplanner:遍历drools规则文件中的列表变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!