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

Wim Vancroonenburg ikbenvanmars at gmail.com
Fri Feb 13 16:02:34 EST 2009


Thanks to everybody for the tips. I will see what I can do with them to 
squeeze out that last bit of performance.

To Geoffrey:

I just wanted to let you know that I'm the thesis student from KAHOSL that 
is using Drools Solver for the Patient Admission Scheduling-problem. The 
performance of Drools Solver isn't bad, but I'm trying to match my 
promotor's code. His code is substantialy faster at the moment (a 
hyperheuristic implementation). So I'm trying to squeeze out every bit of 
performance. Thanks for the tips and the quick response by the way.

Sincerely,

Wim Vancroonenburg.


----- Original Message ----- 
From: "Geoffrey De Smet" <ge0ffrey.spam at gmail.com>
Newsgroups: gmane.comp.java.drools.user
To: <rules-users at lists.jboss.org>
Sent: Friday, February 13, 2009 3:32 PM
Subject: Re: Drools-solver performance optimizations?


> 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
>
> _______________________________________________
> 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