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(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users