Почему это сложное состояние не работает? - PullRequest
0 голосов
/ 15 марта 2012

Я пытаюсь обнаружить противоречивые периоды в расписании: если учитель преподает за Period (timeStart=1400,timeEnd=1500,dayOfWeek="Monday",class="c1"), он не может преподавать Period(1305,1405,dayOfWeek="Monday",class="c2"), потому что ему придется посещать два класса одновременно в течение определенного промежутка времени (да, этоconstrived).

Пример одного периода и наличия конфликтов между другими периодами:

          ---------                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 Ответ

1 голос
/ 15 марта 2012

Откройте для себя радость 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
...