为什么这种复杂的情况不起作用?

时间:2012-03-15 12:05:22

标签: drools

我正试图在时间表中检测出相互冲突的时期:如果教师在Period (timeStart=1400,timeEnd=1500,dayOfWeek="Monday",class="c1")教授,他不能教Period(1305,1405,dayOfWeek="Monday",class="c2"),因为他必须在一个时间间隔内同时参加两个班级(是的,它被解决了。)

一个时期的例子以及其他时期是否发生冲突:

          ---------                left_period (timeStart=1400,timeEnd=1500)

 ---------                        right_period (1300,1400) NO conflict
  ---------                       right_period (1305,1405) conflict
                   ---------      right_period (1500,1600) NO conflict
                 ---------        right_period (1555,1555) NO conflict

因此,我尝试根据timeStarttimeEnd值检测此类期间,并将此类冲突声明为PeriodTimeConflict(left_period,right_period)

rule "insertPeriodTimeConflict"
    when
    $day_of_week : DayOfWeek()
    $left_period : Period(  $lp_id : id,
                dayOfWeek==$day_of_week,
                $lp_time_start : timeStart,
                $lp_time_end : timeEnd
                )
    $right_period : Period( id > $lp_id,
                dayOfWeek==$day_of_week,
                (   (timeStart>=$lp_time_start && timeStart<$lp_time_end)||
                    (timeEnd>$lp_time_start && timeEnd<=$lp_time_end)
                    )
                )
    then
    insertLogical(new PeriodTimeConflict($left_period,$right_period));
end

然而,甚至没有发现任何一次冲突,Drools对此事保持沉默。我的规则有什么问题?

1 个答案:

答案 0 :(得分:1)

发现融合的快乐temporal operators。您的案例是他们使用的完美范例。

首先,您需要在duration课程中定义Period成员。构造函数可以计算开始和结束时间的持续时间,例如

private final int duration;
// ... other fields

public Period(int id, DayOfWeek dayOfWeek, Date timeStart, Date timeEnd) {
  // ... set other fields
  duration = timeEnd.getTime() - timeStart.getTime();
}

现在将Period声明为您的DRL中的事件:

declare Period
  @role(event)
  @timestamp(startTime)
  @duration(duration)
end

然后您的规则可以轻松确定两个时段是否重叠:

rule "detect-overlap"
  when
    $left_period : Period( )
    $right_period : Period( this overlappedby $left_period )
  then
    ...
end