[rules-users] Re: Drools-solver performance optimizations?

Geoffrey De Smet ge0ffrey.spam at gmail.com
Fri Feb 13 09:32:01 EST 2009


Take a look at some of the tricks in the ITC2007 examination example:

- <relativeSelection>0.002</relativeSelection> Real-world problems are 
so big that you can't evaluate all moves for every step. You need to 
take a random percentage (for example 0.2%) of all moves to evaluate.
If you aren't using this, use it and you should see a big difference.
Once you're a 100% confident in your score function, use the benchmarker 
to determine the perfect relativeSelection.

- I calculate a TopicConflict list before starting the solver and use it 
in my score drl, because none of the move change the result of that 
calculation - and it's used a lot.

- avoid backwards chaining functions when possible, like accumulate, 
exists, collect, ... Forward chaining = free score delta calculation.

- Use the most limiting facts first, so
   $room : Room(sexRestriction == Sex.Dependent && capacity > 1);
before
   $n : Night();


Most of your rules look good. I do recommend turning them off one by one 
to see if none outclasses all others in CPU consumption, so you know 
which one to put your time into.

I would rewrite the patientsToBeAssignedToRoomsOfAppropriateSex as such

rule "patientsToBeAssignedToRoomsOfAppropriateSex"
         when
                 $room : Room(sexRestriction == Sex.Dependent && 
capacity > 1);
                 ps1 : PatientStay(bed.room == $room, n : night, $leftId 
: id, g : patient.admission.sex)
                 ps2 : PatientStay(bed.room == $room, night == $n, 
patient.admission.sex != $g, id > $leftId)
         then
                 insertLogical(new 
IntConstraintOccurrence("patientsToBeAssignedToRoomsOfAppropriateSex",ConstraintType.NEGATIVE_HARD, 
50, $ps1, $ps2));
end

I do the id thing because otherwise it would match twice, once for A and 
B and once for B and A

PS: be carefull with "PatientStay(bed.room == ...), IIRC it gets MVEL'ed 
(= a bit performance loss) or flattening is a problem because the move 
only does an update(PatientStay) (=> score gets corrupted on second 
calculation)
PatientStay(room == ...) with PatiantStay.getRoom(){return 
getBed().getRoom()) isn't dangerous
Mark or Edson could probably answer this question.


With kind regards,
Geoffrey De Smet


Wim Vancroonenburg schreef:
> Hi,
> 
> I'm a student currently evaluating Drools Solver for my dissertation. I 
> am currently trying to solve an optimization problem with two different 
> solvers (one of which is Drools Solver) and I am comparing the results 
> with earlier obtained results from literature. However I am having some 
> troubles with the performance of Drools Solver, and I was hoping if 
> someone could look at my rules to see if they could be tuned:
> 
> rule "patientsToBeAssignedToRoomsOfAppropriateSex"
>         when
>                 $n : Night();
>                 $room : Room(sexRestriction == Sex.Dependent && capacity 
>  > 1);
>                 $genders : ArrayList(size>1) from collect( 
> PatientStay(bed.room == $room, night == $n) );

>                 exists PatientStay(bed.room == $room, night == $n, $a : 
> admission, 
> eval(((PatientStay)$genders.get(0)).getAdmission().getPatient().getSex() 
> != $a.getPatient().getSex()));
>         then
>                 insertLogical(new 
> IntConstraintOccurrence("patientsToBeAssignedToRoomsOfAppropriateSex",ConstraintType.NEGATIVE_HARD,50,$room,$n));
> end
> 
> rule "hasRequiredRoomProperties"
>         when
>                 $pr : RequiredRoomPropertiesConstraint($a : admission, 
> $r : room, $w : weight );
>                 $ps : PatientStay(admission == $a, bed.room == $r);
>         then
>                 insertLogical(new 
> IntConstraintOccurrence("hasPreferredRoomProperties",ConstraintType.NEGATIVE_SOFT,50*$w,$ps));
> end
> 
> rule "unplannedTransfers"
>         when
>                 $ps : PatientStay($a : admission, $b : bed, $n : night);
>                 $ps2 : PatientStay(admission == $a, bed != $b, $n2 : 
> night,eval($n.getIndex()+1 == $n2.getIndex()));
>         then
>                 insertLogical(new 
> IntConstraintOccurrence("unplannedTransfers",ConstraintType.NEGATIVE_SOFT,110,$ps,$ps2));
> end
> 
> rule "hasPreferredRoomProperties"
>         when
>                 $pr : PreferredRoomPropertiesConstraint($a : admission, 
> $r : room, $w : weight );
>                 $ps : PatientStay(admission == $a, bed.room == $r);
>         then
>                 insertLogical(new 
> IntConstraintOccurrence("hasPreferredRoomProperties",ConstraintType.NEGATIVE_SOFT,20*$w,$ps));
> end
> 
> rule "meetsRoomPreference"
>         when
>                 $mr : MeetsRoomPreferenceConstraint($a : admission, $r : 
> room);
>                 $ps : PatientStay(admission == $a, bed.room == $r);
>         then
>                 insertLogical(new 
> IntConstraintOccurrence("meetsRoomPreference",ConstraintType.NEGATIVE_SOFT,8,$ps));
> end
> 
> rule "inGoodDepartment"
>         when
>                 $gd : GoodDepartmentConstraint($a : admission, $d : 
> department);
>                 $ps : PatientStay(admission == $a, $b : bed, 
> eval($b.getRoom().getDepartment().equals($d)));
>         then
>                 insertLogical(new 
> IntConstraintOccurrence("inGoodDepartment",ConstraintType.NEGATIVE_SOFT,10,$ps));
> end
> 
> rule "inGoodRoom"
>         when
>                 $gr : GoodRoomConstraint($a : admission, $r : room, $w : 
> weight);
>                 $ps : PatientStay(admission == $a, bed.room == $r);
>         then
>                 insertLogical(new 
> IntConstraintOccurrence("inGoodRoom",ConstraintType.NEGATIVE_SOFT,10*$w,$ps));        
>        
> end
> 
> rule "calcScore"
> salience -10
>         when
>                 $count : Number() from accumulate( 
> IntConstraintOccurrence($w : weight) ,
>                                                                         
>          sum($w) );
>         then
>                 scoreCalculator.setScore(-$count.doubleValue());
> end
> 
> The classes with **Constraint in it are possible combinations that cause 
> a constraint to be violated, and are calculated and inserted at 
> initialization time (and are never changed). I know that the rule 
> "patientsToBeAssignedToRoomsOfAppropriateSex" is fairly complex, but 
> even when I remove it, the performance is not fantastic. Is there 
> anything else I can do to get better performance? I'm already using JDK 
> 1.6 and -server mode. Furthermore, all classes used here have their 
> default equals and hashCode methods, so they don't have an impact on 
> performance.
> 
> Sincerely,
> 
> Wim Vancroonenburg
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users




More information about the rules-users mailing list