2012-03-15 70 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