2012-03-15 73 views
0

我想在一个时间表中检测冲突的时间段:如果一位教师在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

发现融合的乐趣temporal operators。你的情况是他们使用的完美例子。

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

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 
+0

对不起,我使用Drools的规划师: - ( – aitchnyu 2012-03-15 13:14:51

+0

Drools Planner可以访问Drools平台上的所有内容,包括临时操作员,但您的原始规则也应该可以正常工作,您正在使用哪个版本的Drools和MVEL? – 2012-03-15 14:22:51