我正在解决类似于员工名册的问题。我还有其他限制。员工具有分配给他们的“类型”值。每天至少要有每种类型的至少1名员工是一个严格的约束。我将其建模如下:
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文件中对其进行迭代?
编辑:我想出了一种方法,但感觉像是在破解。初始化日期字符串列表时,我还将其分配给静态变量。然后,我可以使用类似于枚举的静态变量。
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
但是不要以为这是正确的方法。
答案 0 :(得分:0)
您的方法可行,但是必须在类的静态属性中定义动态配置听起来并不正确(就像您指出的那样)。
一种解决方案是要么在会话中使用全局变量,要么使用指定此配置的事实类。
使用全局
如果您决定采用这种方法,则需要在DRL中定义类型为List<String>
的全局变量,然后将其与memberOf
运算符结合使用在规则中:
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
插入会话中之前为全局设置值:
List<String> dates = //get the List from somewhere
ksession.setGlobal("dates", dates);
使用实况类
除了全局变量,您还可以将配置建模为一个类。如果您想例如在规则内部修改配置,这将使事情变得容易。
对于这种方法,您首先需要具有一个包含List<String>
的类。从理论上讲,您可以插入List<String>
而不必将其包装在任何类中,但这会使内容难以阅读和维护。
public class DatesConfiguration {
private List<String> dates;
//... getters + setters
}
然后,您需要实例化此类的对象并将其插入到会话中:
DatesConfiguration dc = new DatesConfiguration();
dc.setDates(...);
ksession.insert(dc);
此时,您创建的对象只是Drools的另一个事实,可以在您的规则中使用:
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
希望有帮助,