Накопление / сбор на основе временного оператора

Я пытаюсь написать правило, которое собирает / накапливает значения на основе временного оператора.

rule "Zone6 Overlap"
when
    $i1 : Instance ($e1 : event == " Vel : 20.99-23.98 km/h : " && $name1 : name) from entry-point "Stream"
    $i2 : Instance ($e2 : event && $name2 : name && $e2 == $e1 && $name2 != $name1 
    && this overlaps $i1) from entry-point "Stream"
then 
    System.out.println("** Overlap Event: Velocity Zone 6 ** \nPlayer1: " + $i1.getName() + "\nPlayer2: " 
    + $i2.getName() + "\nEvent: " + $i1.getEvent() + "\n" + "Start Time (P1): " 
    + $i1.getStart() + " - End Time: " + $i1.getEnd() + "\nStart Time (P2): " 
    + $i2.getStart() + " - End Time: " + $i2.getEnd() + "\n");
end

Это мое первоначальное правило, которое позволяет перекрывать две длительности.

Идея правила, которое я хочу создать, состоит в том, чтобы увидеть, есть ли какие-либо коллективные совпадения продолжительности игроков в футбольном матче. Я хочу увидеть, движется ли кто-нибудь из 9 игроков на поле с диапазоном скоростей, указанным в виде строки в переменной события, и все они перекрываются одновременно.

Я пробовал несколько вещей относительно накопления и сбора, но борюсь с тем, как собирать эти события, когда они происходят, и возвращать их в правую часть правила, чтобы их можно было распечатать в стандартном виде.

Пожалуйста помоги.

Спасибо.


person Stu    schedule 17.08.2016    source источник


Ответы (1)


Должно быть возможно создать правило, соответствующее вашим требованиям, но я думаю, вам нужно знать точное определение ключевого слова overlaps в Drools:

Оценщик перекрытий коррелирует два события и сопоставляет, когда текущее событие начинается до начала коррелированного события и заканчивается после начала коррелированного события, но до завершения коррелированного события. Другими словами, у обоих событий есть перекрывающийся период.

Это означает, что он не будет соответствовать какому-либо произвольному перекрытию, но только если одно событие начинается до начала другого события и заканчивается до его окончания. Предположим, у нас есть следующие 3 события:

A [11:19:00-11:19:30]
B [11:19:15-11:19:45]
C [11:19:20-11:19:40]

В этом случае A начинается до B и C, а также заканчивается перед обоими. Это означает, что A перекрывает B и C. Однако B не перекрывает C, потому что он начинается до C, но заканчивается после C. Полное определение каждого из доступных операторов см. В Документация по объединению Drools.

Если это соответствует вашему варианту использования, следующее правило будет собирать все события, которые перекрывают данное событие:

rule "Overlap"
when
    $i1 : Instance ($e1 : event == "some event" ) 
    $instances : List( size > 0 ) from collect ( Instance ( event == $e1, this != $i1, 
        this overlappedby $i1 ) )
then
    System.out.println("** Overlap Event for: " + $i1.getName());
    for (int i = 0; i < $instances.size(); i++) {
        System.out.println("Overlaps: " +  ((Instance)$instances.get(i)).getName());
    }
end

Как видите, здесь используется ключевое слово overlappedby, которое является обратным по отношению к перекрытиям.

person Ben Damer    schedule 17.08.2016
comment
Я понимаю. Да, в этом есть смысл. По сути, темпоральный оператор (перекрытия) был неправильным (должен перекрываться). И мне просто нужно было использовать функцию сбора вместо накопления. Документация Drools (включая книги, написанные packt), похоже, сильно подталкивает функцию накопления. Вот почему я не понимал, использовать это или нет. Тем не менее, спасибо за вашу помощь. - person Stu; 18.08.2016
comment
Выполнено. Просто интересно, можете ли вы ответить для меня на быстрый вопрос: я объявил глобальную переменную, которая представляет собой список, и заполнил его определенными объектами. Вы знаете, как вызывать методы для этих объектов в глобальном массиве на правой стороне правого места после выполнения условия? Спасибо. - person Stu; 18.08.2016
comment
Ps просто ваше объявление массива напомнило мне, что у меня была проблема с использованием глобального списка в моем проекте с точки зрения редактирования объектов. - person Stu; 18.08.2016
comment
Предполагая, что ваш глобальный объект имеет универсальный тип java.util.List, вам придется привести каждый объект, который он содержит, к фактическому типу. По сути, то же самое, что я делаю для списка $instances выше - приведите запись к классу Instance перед вызовом getName. - person Ben Damer; 18.08.2016