Почему это сложное состояние не работает?
Я пытаюсь обнаружить противоречивые периоды в расписании: если учитель преподает в 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
Поэтому я попытался обнаружить такие периоды на основе timeStart
а также timeEnd
ценности и утверждение таких конфликтов, как 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 ответ
Откройте для себя радость временных операторов Fusion. Ваш случай - прекрасный пример для их использования.
Во-первых, вам нужно определить 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
как событие в вашем ДХО:
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