Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Source code: https://github.com/SocraticGrid/sg-agents/tree/master/drools-agents/SIM

Drools Planner (aka Optaplanner)

Drools planner is a planning engine that optimizes planning problems. It combines optimization heuristics and metaheuristics with very efficient score calculation.

...

  • NP-Complete: any given solution to can be verified quickly (in polynomial time) but there is no known efficient way to locate a solution in the first place.
  • Has Constraints: Negative Hard Constraints (Must not be broken by a solution); Negative/Positive Soft Constraints (Could be broken by a solution).
  • Huge Search space

Domain Model

Planning Entity: class(es) that changes during the planning.
Planning Variable: The properties that change during planning. The set of possible values must be provided. 2 different approaches:

...

For the calculation of the score, Planner uses Drools.

SIM-Agent

Class Diagram

 


Problem Facts

The following is the list of Problem Facts:

...


The number and type of Providers and Patients is fixed in the application:

...

The different providers associated to a Patient are never set by planner!

Planning Entity

Only 1 planning Entity is defined: Visit.
The current implementation starts with a predefined set of Visits for each Patient. The number and type of Visits depends on the Patient's severity:

...

As we can see, the Type and Patient of a Visit are fixed and never change during the planning.
The planning variables in this case are VisitDate and Provider.

Moves

VisitDateChangeMoveFactory: Creates all the possible combinations of Visits and Dates.
VisitTimeSwapMoveFactory: Creates a permutation of all the Visits to swap their Dates. (It is not clear to me if all these moves are not already included in the previous factory)
AssignCareProviderMoveFactory: Creates a combination of all the Providers for the different Visits.

Hard Constraints

...


Code Block
rule "PTSD therapy must be provided either by a Therapist (non-MD) or a Psychiatrist (MD)"
salience 10
when
    $vis : Visit( type == VisitType.THERAPY, $pro : provider)
    Provider( this == $pro, role != ProviderRole.THERAPIST && != ProviderRole.PSYCHIATRIST )
then
    insertLogical( new IntConstraintOccurrence( drools.getRule().getName(), ConstraintType.NEGATIVE_HARD, 1, $vis, $pro ) );
end
 
rule "Therapy sessions must be scheduled regularly"
when
    $vis : Visit( type == VisitType.THERAPY, $date : date != null, $expectedWeek : expectedWeek > 0,
    $actualWeek : date.weekIndex, date.weekIndex != $expectedWeek )
then
    insertLogical( new IntConstraintOccurrence( drools.getRule().getName(), ConstraintType.NEGATIVE_HARD, 10, $vis ) );
end
 
rule "A patient getting Group Therapy should receive 6 sessions total @ 1/wk"
when
    $vis1 : Visit( type == VisitType.GROUP, $date1 : date != null, $seqNum : seqNum, $pat : patient,
                   $onWeek : date.weekIndex )
    $vis2 : Visit( this != $vis1, type == VisitType.GROUP, $date2 : date != null, patient == $pat, seqNum == $seqNum + 1,
                   $nextWeek : date.weekIndex, date.weekIndex != $onWeek + 1 )
then
    insertLogical( new IntConstraintOccurrence( drools.getRule().getName(), ConstraintType.NEGATIVE_HARD, 10, $vis1, $vis2 ) );
end
 
rule "No two therapy visits on the same day in the same week (for severe cases)"
when
    $vis1 : Visit( type == VisitType.THERAPY, $date1 : date != null, $pro : provider, $pat : patient,
                   $onWeek : date.weekIndex, $onDay : date.dayIndex )
    $vis2 : Visit( this != $vis1, type == VisitType.THERAPY, $date2 : date != null, provider == $pro, patient == $pat,
                   date.weekIndex == $onWeek, date.dayIndex == $onDay )
then
    insertLogical( new IntConstraintOccurrence( drools.getRule().getName(), ConstraintType.NEGATIVE_HARD, 1, $vis1, $vis2 ) );
end
 
rule "Therapist and Psychiatrists can see a maximum of 8 PTSD therapy patients a week"
when
    $bus : BusyWeek( $pro : provider, $week : weekIndex )
    accumulate ( $vis : Visit( type == VisitType.THERAPY, provider == $pro, $date : date != null,
                 date.weekIndex == $week ),
                 $num : count( $vis );
                 $num > 8 )
then
    insertLogical( new IntConstraintOccurrence( drools.getRule().getName(), ConstraintType.NEGATIVE_HARD, 1, $bus ) );
end

...


Soft Constraints

...


Code Block
rule "Patient should see the same provider"
when
    $vis1 : Visit( $type : type, $pro : provider != null, $pat : patient )
    $vis2 : Visit( this != $vis1, $date2 : date != null, type == $type,
                   patient == $pat, provider != null, provider != $pro )
then
    insertLogical( new IntConstraintOccurrence( drools.getRule().getName(), ConstraintType.NEGATIVE_SOFT, 4, $vis1, $vis2 ) );
end
 
rule "Therapy sessions should be scheduled at the same day and time over weeks"
when
    $vis1 : Visit( type == VisitType.THERAPY, $date1 : date != null, $pro : provider, $pat : patient,
                   $onWeek : date.weekIndex, $onDay : date.dayIndex, $morn : date.morning )
    $vis2 : Visit( this != $vis1, type == VisitType.THERAPY, $date2 : date != null, provider == $pro, patient == $pat,
                   date.weekIndex != $onWeek, date.dayIndex != $onDay || date.morning != $morn )
then
    insertLogical( new IntConstraintOccurrence( drools.getRule().getName(), ConstraintType.NEGATIVE_SOFT, 10, $vis1, $vis2 ) );
end
 
rule "a patient being seen for Group Therapy should not have their session on the same day as Individual therapy"
when
    $vis1 : Visit( type == VisitType.GROUP, $date1 : date != null, $pat : patient,
                   $onWeek : date.weekIndex, $onDay : date.dayIndex )
    $vis2 : Visit( type == VisitType.THERAPY, $date2 : date != null, patient == $pat,
                   date.weekIndex == $onWeek, date.dayIndex == $onDay )
then
    insertLogical( new IntConstraintOccurrence( drools.getRule().getName(), ConstraintType.NEGATIVE_SOFT, 3, $vis1, $vis2 ) );
end

...


Initial State Sample vs. Final State Sample

Visit{patient=patient 0, seqNum=1, expWeek=1, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=1, expWeek=1, type=THERAPY, provider=Dr. 2, MD, date=Week 1 || Mon PM}
Visit{patient=patient 0, seqNum=2, expWeek=2, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=2, expWeek=2, type=THERAPY, provider=Dr. 2, MD, date=Week 2 || Mon PM}
Visit{patient=patient 0, seqNum=3, expWeek=3, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=3, expWeek=3, type=THERAPY, provider=Dr. 2, MD, date=Week 3 || Mon PM}
Visit{patient=patient 0, seqNum=4, expWeek=4, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=4, expWeek=4, type=THERAPY, provider=Dr. 2, MD, date=Week 4 || Mon PM}
Visit{patient=patient 0, seqNum=5, expWeek=5, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=5, expWeek=5, type=THERAPY, provider=Dr. 2, MD, date=Week 5 || Mon PM}
Visit{patient=patient 0, seqNum=6, expWeek=6, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=6, expWeek=6, type=THERAPY, provider=Dr. 2, MD, date=Week 6 || Mon PM}
Visit{patient=patient 0, seqNum=7, expWeek=7, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=7, expWeek=7, type=THERAPY, provider=Dr. 2, MD, date=Week 7 || Mon PM}
Visit{patient=patient 0, seqNum=8, expWeek=8, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=8, expWeek=8, type=THERAPY, provider=Dr. 2, MD, date=Week 8 || Mon PM}
Visit{patient=patient 0, seqNum=9, expWeek=9, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=9, expWeek=9, type=THERAPY, provider=Dr. 2, MD, date=Week 9 || Mon PM}
Visit{patient=patient 0, seqNum=10, expWeek=10, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=10, expWeek=10, type=THERAPY, provider=Dr. 2, MD, date=Week 10 || Mon PM}
Visit{patient=patient 0, seqNum=11, expWeek=11, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=11, expWeek=11, type=THERAPY, provider=Dr. 2, MD, date=Week 11 || Mon PM}
Visit{patient=patient 0, seqNum=12, expWeek=12, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=12, expWeek=12, type=THERAPY, provider=Dr. 2, MD, date=Week 12 || Mon PM}
Visit{patient=patient 0, seqNum=13, expWeek=13, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=13, expWeek=13, type=THERAPY, provider=Dr. 2, MD, date=Week 13 || Mon PM}
Visit{patient=patient 0, seqNum=14, expWeek=14, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=14, expWeek=14, type=THERAPY, provider=Dr. 2, MD, date=Week 14 || Mon PM}
Visit{patient=patient 0, seqNum=15, expWeek=15, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=15, expWeek=15, type=THERAPY, provider=Dr. 2, MD, date=Week 15 || Mon PM}
Visit{patient=patient 0, seqNum=16, expWeek=17, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=16, expWeek=17, type=THERAPY, provider=Dr. 2, MD, date=Week 17 || Mon PM}
Visit{patient=patient 0, seqNum=17, expWeek=19, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=17, expWeek=19, type=THERAPY, provider=Dr. 2, MD, date=Week 19 || Mon PM}
Visit{patient=patient 0, seqNum=18, expWeek=21, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=18, expWeek=21, type=THERAPY, provider=Dr. 2, MD, date=Week 21 || Mon PM}
Visit{patient=patient 0, seqNum=19, expWeek=23, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=19, expWeek=23, type=THERAPY, provider=Dr. 2, MD, date=Week 23 || Mon PM}
Visit{patient=patient 0, seqNum=20, expWeek=25, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 0, seqNum=20, expWeek=25, type=THERAPY, provider=Dr. 2, MD, date=Week 25 || Mon PM}
Visit{patient=patient 0, seqNum=1, type=COUNSELING, provider=null, date=null} -> Visit{patient=patient 0, seqNum=1, type=COUNSELING, provider=Mr. 0, date=Week 1 || Mon PM}
Visit{patient=patient 0, seqNum=2, type=COUNSELING, provider=null, date=null} -> Visit{patient=patient 0, seqNum=2, type=COUNSELING, provider=Mr. 0, date=Week 24 || Tue AM}
Visit{patient=patient 0, seqNum=3, type=COUNSELING, provider=null, date=null} -> Visit{patient=patient 0, seqNum=3, type=COUNSELING, provider=Mr. 0, date=Week 9 || Mon PM}
Visit{patient=patient 0, seqNum=4, type=COUNSELING, provider=null, date=null} -> Visit{patient=patient 0, seqNum=4, type=COUNSELING, provider=Mr. 0, date=Week 13 || Mon PM}
Visit{patient=patient 0, seqNum=5, type=COUNSELING, provider=null, date=null} -> Visit{patient=patient 0, seqNum=5, type=COUNSELING, provider=Mr. 0, date=Week 17 || Mon PM}
Visit{patient=patient 0, seqNum=6, type=COUNSELING, provider=null, date=null} -> Visit{patient=patient 0, seqNum=6, type=COUNSELING, provider=Mr. 0, date=Week 21 || Mon PM}
Visit{patient=patient 0, seqNum=1, type=GROUP, provider=null, date=null} -> Visit{patient=patient 0, seqNum=1, type=GROUP, provider=Dr. 0, MD, date=Week 2 || Tue PM}
Visit{patient=patient 0, seqNum=2, type=GROUP, provider=null, date=null} -> Visit{patient=patient 0, seqNum=2, type=GROUP, provider=Dr. 0, MD, date=Week 3 || Tue PM}
Visit{patient=patient 0, seqNum=3, type=GROUP, provider=null, date=null} -> Visit{patient=patient 0, seqNum=3, type=GROUP, provider=Dr. 0, MD, date=Week 4 || Tue PM}
Visit{patient=patient 0, seqNum=4, type=GROUP, provider=null, date=null} -> Visit{patient=patient 0, seqNum=4, type=GROUP, provider=Dr. 0, MD, date=Week 5 || Tue PM}
Visit{patient=patient 0, seqNum=5, type=GROUP, provider=null, date=null} -> Visit{patient=patient 0, seqNum=5, type=GROUP, provider=Dr. 0, MD, date=Week 6 || Tue PM}
Visit{patient=patient 0, seqNum=6, type=GROUP, provider=null, date=null} -> Visit{patient=patient 0, seqNum=6, type=GROUP, provider=Dr. 0, MD, date=Week 7 || Tue PM}
Visit{patient=patient 1, seqNum=1, expWeek=1, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=1, expWeek=1, type=THERAPY, provider=Dr. 2, date=Week 1 || Mon PM}
Visit{patient=patient 1, seqNum=2, expWeek=1, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=2, expWeek=1, type=THERAPY, provider=Dr. 2, date=Week 1 || Tue PM}
Visit{patient=patient 1, seqNum=3, expWeek=2, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=3, expWeek=2, type=THERAPY, provider=Dr. 2, date=Week 2 || Mon PM}
Visit{patient=patient 1, seqNum=4, expWeek=2, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=4, expWeek=2, type=THERAPY, provider=Dr. 2, date=Week 2 || Tue PM}
Visit{patient=patient 1, seqNum=5, expWeek=3, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=5, expWeek=3, type=THERAPY, provider=Dr. 2, date=Week 3 || Mon PM}
Visit{patient=patient 1, seqNum=6, expWeek=3, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=6, expWeek=3, type=THERAPY, provider=Dr. 2, date=Week 3 || Tue PM}
Visit{patient=patient 1, seqNum=7, expWeek=4, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=7, expWeek=4, type=THERAPY, provider=Dr. 2, date=Week 4 || Mon PM}
Visit{patient=patient 1, seqNum=8, expWeek=4, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=8, expWeek=4, type=THERAPY, provider=Dr. 2, date=Week 4 || Tue PM}
Visit{patient=patient 1, seqNum=9, expWeek=5, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=9, expWeek=5, type=THERAPY, provider=Dr. 2, date=Week 5 || Mon PM}
Visit{patient=patient 1, seqNum=10, expWeek=5, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=10, expWeek=5, type=THERAPY, provider=Dr. 2, date=Week 5 || Tue PM}
Visit{patient=patient 1, seqNum=11, expWeek=6, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=11, expWeek=6, type=THERAPY, provider=Dr. 2, date=Week 6 || Mon PM}
Visit{patient=patient 1, seqNum=12, expWeek=6, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=12, expWeek=6, type=THERAPY, provider=Dr. 2, date=Week 6 || Tue PM}
Visit{patient=patient 1, seqNum=13, expWeek=7, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=13, expWeek=7, type=THERAPY, provider=Dr. 2, date=Week 7 || Mon PM}
Visit{patient=patient 1, seqNum=14, expWeek=7, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=14, expWeek=7, type=THERAPY, provider=Dr. 2, date=Week 7 || Tue PM}
Visit{patient=patient 1, seqNum=15, expWeek=8, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=15, expWeek=8, type=THERAPY, provider=Dr. 2, date=Week 8 || Mon PM}
Visit{patient=patient 1, seqNum=16, expWeek=8, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=16, expWeek=8, type=THERAPY, provider=Dr. 2, date=Week 8 || Tue PM}
Visit{patient=patient 1, seqNum=17, expWeek=9, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=17, expWeek=9, type=THERAPY, provider=Dr. 2, date=Week 9 || Mon PM}
Visit{patient=patient 1, seqNum=18, expWeek=9, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=18, expWeek=9, type=THERAPY, provider=Dr. 2, date=Week 9 || Tue PM}
Visit{patient=patient 1, seqNum=19, expWeek=10, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=19, expWeek=10, type=THERAPY, provider=Dr. 2, date=Week 10 || Mon PM}
Visit{patient=patient 1, seqNum=20, expWeek=10, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=20, expWeek=10, type=THERAPY, provider=Dr. 2, date=Week 10 || Tue PM}
Visit{patient=patient 1, seqNum=21, expWeek=11, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=21, expWeek=11, type=THERAPY, provider=Dr. 2, date=Week 11 || Mon PM}
Visit{patient=patient 1, seqNum=22, expWeek=12, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=22, expWeek=12, type=THERAPY, provider=Dr. 2, date=Week 12 || Mon PM}
Visit{patient=patient 1, seqNum=23, expWeek=13, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=23, expWeek=13, type=THERAPY, provider=Dr. 2, date=Week 13 || Mon PM}
Visit{patient=patient 1, seqNum=24, expWeek=14, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=24, expWeek=14, type=THERAPY, provider=Dr. 2, date=Week 14 || Mon PM}
Visit{patient=patient 1, seqNum=25, expWeek=15, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=25, expWeek=15, type=THERAPY, provider=Dr. 2, date=Week 15 || Mon PM}
Visit{patient=patient 1, seqNum=26, expWeek=17, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=26, expWeek=17, type=THERAPY, provider=Dr. 2, date=Week 17 || Mon PM}
Visit{patient=patient 1, seqNum=27, expWeek=19, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=27, expWeek=19, type=THERAPY, provider=Dr. 2, date=Week 19 || Mon PM}
Visit{patient=patient 1, seqNum=28, expWeek=21, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=28, expWeek=21, type=THERAPY, provider=Dr. 2, date=Week 21 || Mon PM}
Visit{patient=patient 1, seqNum=29, expWeek=25, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=29, expWeek=25, type=THERAPY, provider=Dr. 2, date=Week 25 || Mon PM}
Visit{patient=patient 1, seqNum=30, expWeek=29, type=THERAPY, provider=null, date=null} -> Visit{patient=patient 1, seqNum=30, expWeek=29, type=THERAPY, provider=Dr. 2, date=Week 29 || Mon PM}
Visit{patient=patient 1, seqNum=1, type=COUNSELING, provider=null, date=null} -> Visit{patient=patient 1, seqNum=1, type=COUNSELING, provider=Mr. 0, date=Week 23 || Thu AM}
Visit{patient=patient 1, seqNum=2, type=COUNSELING, provider=null, date=null} -> Visit{patient=patient 1, seqNum=2, type=COUNSELING, provider=Mr. 0, date=Week 11 || Mon PM}
Visit{patient=patient 1, seqNum=3, type=COUNSELING, provider=null, date=null} -> Visit{patient=patient 1, seqNum=3, type=COUNSELING, provider=Mr. 0, date=Week 12 || Mon PM}
Visit{patient=patient 1, seqNum=4, type=COUNSELING, provider=null, date=null} -> Visit{patient=patient 1, seqNum=4, type=COUNSELING, provider=Mr. 0, date=Week 13 || Mon PM}
Visit{patient=patient 1, seqNum=5, type=COUNSELING, provider=null, date=null} -> Visit{patient=patient 1, seqNum=5, type=COUNSELING, provider=Mr. 0, date=Week 17 || Mon PM}
Visit{patient=patient 1, seqNum=6, type=COUNSELING, provider=null, date=null} -> Visit{patient=patient 1, seqNum=6, type=COUNSELING, provider=Mr. 0, date=Week 21 || Mon PM}
Visit{patient=patient 1, seqNum=7, type=COUNSELING, provider=null, date=null} -> Visit{patient=patient 1, seqNum=7, type=COUNSELING, provider=Mr. 0, date=Week 25 || Mon PM}
Visit{patient=patient 1, seqNum=1, type=MEDICATION, provider=null, date=null} -> Visit{patient=patient 1, seqNum=1, type=MEDICATION, provider=Dr. 0, MD, date=Week 1 || Mon PM}
Visit{patient=patient 1, seqNum=2, type=MEDICATION, provider=null, date=null} -> Visit{patient=patient 1, seqNum=2, type=MEDICATION, provider=Dr. 0, MD, date=Week 5 || Mon PM}
Visit{patient=patient 1, seqNum=3, type=MEDICATION, provider=null, date=null} -> Visit{patient=patient 1, seqNum=3, type=MEDICATION, provider=Dr. 0, MD, date=Week 9 || Mon PM}
Visit{patient=patient 1, seqNum=4, type=MEDICATION, provider=null, date=null} -> Visit{patient=patient 1, seqNum=4, type=MEDICATION, provider=Dr. 0, MD, date=Week 13 || Mon PM}
Visit{patient=patient 1, seqNum=5, type=MEDICATION, provider=null, date=null} -> Visit{patient=patient 1, seqNum=5, type=MEDICATION, provider=Dr. 0, MD, date=Week 17 || Mon PM}
Visit{patient=patient 1, seqNum=6, type=MEDICATION, provider=null, date=null} -> Visit{patient=patient 1, seqNum=6, type=MEDICATION, provider=Dr. 0, MD, date=Week 21 || Mon PM}
Visit{patient=patient 1, seqNum=7, type=MEDICATION, provider=null, date=null} -> Visit{patient=patient 1, seqNum=7, type=MEDICATION, provider=Dr. 0, MD, date=Week 25 || Mon PM}