Well figures out my self that the solution is not correct since if I increase the number
of required techs, I get invalid combinations...
Back to the drawing board.
-----------------
http://www.codessentials.com - Your essential software, for free!
Follow us at
http://twitter.com/#!/Codessentials
________________________________
From: Michiel Vermandel <mvermand(a)yahoo.com
To:
Geoffrey De Smet <ge0ffrey.spam(a)gmail.com>; Rules Users List
<rules-users(a)lists.jboss.org>
Sent: Monday, September 3, 2012 1:59 PM
Subject: Re: [rules-users] Best model for planning? technicians, airplanes and shifts
=> insertLogical problems
Hi,
I'm not keen on spending time on a temp solution if I cannot estimate - at this time -
how much time it will take me to build it correctly afterwards.
Budgets are limited... (as with anyone I guess :-)
Once again, it gives me a bad feeling that such a simple setup is giving me such a hard to
solve issue.
I had thought that - given the project is only a very few classes - it would be peanuts
for you or any other expert to pinpoint what I'm doing wrong.
Non the less...
I tried to have a look again to a number of examples and I changed my rules, with a
positive result!
I seem to get the correct solution. But... I do not know if my changes are valid.
I mean, is it possible that I threw a number of possible solutions away?
Maybe this will not show right now but will have it's effect when numbers grow
and possible solutions shrink.
So what I did is going from
rule "tasksInSameJobMustBeInSamePeriod"
when
$taskA : MaintenanceTask($id : id, $jobId : jobId, $periodId : periodId )
MaintenanceTask(id != $id, jobId == $jobId, periodId != $periodId ) //
<============ a != $a
then
System.out.println("r3: " + $taskA );
insertLogical(new
IntConstraintOccurrence("tasksInSameJobMustBeInSamePeriod", $taskA));
end
to
rule "tasksInSameJobMustBeInSamePeriod"
when
$taskA : MaintenanceTask($id : id, $jobId : jobId, $periodId : periodId )
MaintenanceTask(id > $id, jobId == $jobId, periodId > $periodId ) //
<================ a > $a
then
System.out.println("r3: " + $taskA );
insertLogical(new IntConstraintOccurrence("tasksInSameJobMustBeInSamePeriod",
$taskA));
end
Can you please tell me if this is THE solution or a dangerous move that works out now but
will give issues when numbers grow?
Thanks a lot.
Michiel
-----------------
http://www.codessentials.com - Your essential software, for free!
Follow us at
http://twitter.com/#!/Codessentials
________________________________
From: Geoffrey De Smet <ge0ffrey.spam(a)gmail.com
To:
Michiel Vermandel <mvermand(a)yahoo.com>; Rules Users List
<rules-users(a)lists.jboss.org>
Sent: Monday, September 3, 2012 11:56 AM
Subject: Re: Best model for planning? technicians, airplanes and shifts =>
insertLogical problems
Op 03-09-12 11:30, Michiel Vermandel schreef:
I did not really start on one example. I have scrolled through several to try to figure
out how to do it, then started from scratch for the POJO's and Rules.
The config file was copies from one of the examples because it contained too many things
that were hard to get right in the beginning.
I know that is a risk but I needed to start somewhere.
I am thinking how to standardize the getting started with planner experience.
The cloud balance quick start is the example I pushing at the
moment.
But for specific use case, it's better to start from an example
that's similar to the user's use case.
The trouble is, it's often hard to see which example is similar and
which is not.
3) What does "The workingMemory has 2 ConstraintOccurrence(s) in excess:" really
mean?
- Are the constraints there more than once?
No, it means that in a clean
WorkingMemory, those 2 ConstraintOccurrences aren't there,
but in the incremental WorkingMemory, they are there.
So they are in excess: they should have been automatically retracted
by the rule engine, but for some reason, they are not.
Read this section about incremental score calculation to understand
why this complexity is needed:
http://docs.jboss.org/drools/release/5.4.0.Final/drools-planner-docs/html...
If you just want to prove that a Planner POC works for now
(especially if you're close to giving up),
just take a few minutes to switch to a simple Java score calculator
for now:
http://docs.jboss.org/drools/release/5.4.0.Final/drools-planner-docs/html...
It will be _much_ slower especially when it scales out (but it
should still be faster than anything you can invent yourself within
reasonable time).
Once that works fine and you get a good result on your toy problem
and you can scale out to 100+ jobs,
then switch back to drools to scale out to 10000+ jobs and follow
the rest of this mail.
- has this something to do with the equals and hashcode (which I did implement (see
below))?
Likely. The equals/hashcode methods are used of all objects in the causes parameter.
It's a design issue in Planner that the planner entity's
equals/hashcode() needs to be used for the ConstraintOccurrence's
causes.
Compensation action
About the compensation action: is it already available on 5.4.0 final? Should I try
that?
The plumbing is there in Drools Expert, but in Planner there are no decent
examples, supporting code or even complex experiments yet.
It's a minefield, probably best to stay out until I get it done or
you have more Planner experience :/
4) I have been looking to the equals and hashcode, though found many examples that
implement solutionEquals and solutionHashcode instead.
Currently I implemented them like this:
@Override
public int hashCode() {
return id.hashCode(); //(*)
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (id == null || !(o instanceof MaintenanceTask)) {
return false;
} else {
MaintenanceTask other = (MaintenanceTask) o;
return id.equals(other.id);
}
}
Looks good
(*) id is a String property which is passed into the entity object through the
constructor and upon cloning it is passed from the clone source to the clone target:
public MaintenanceTask clone() {
System.out.println("Cloning task " + id);
MaintenanceTask clone = new MaintenanceTask(job, id);
clone.period = this.period;
clone.technician = this.technician;
return clone;
}
Looks good.
I am still confused about:
- Which ones do I need to implement (equals or solutionEquals, ...)?
because of
this code:
https://github.com/droolsjbpm/drools-planner/blob/master/drools-planner-c...
which is called by drools on insertLogical inserted objects (see
drools expert manual on insertLogical)
- Should an entity and a cloned entity have the same result for both equals and
hashcode? (I guess so)
Yes, definitely.
- Should only the entity objects have such implementations? (Planning variables are
never cloned, right?)
It looks good. Only the entity's are cloned indeed during
cloneSolution(): they are the only instances that change during planning.
>
>-----------------
>http://www.codessentials.com - Your essential software, for free!
>Follow us at
http://twitter.com/#!/Codessentials
>________________________________
> From: Geoffrey De Smet <ge0ffrey.spam(a)gmail.com
>To:
Rules Users List <rules-users(a)lists.jboss.org>
>Sent: Monday, September 3, 2012 10:44 AM
>Subject: Re: [rules-users] Best model for planning? technicians, airplanes and shifts
=> insertLogical problems
>
>Op 03-09-12 10:21, Michiel Vermandel schreef:
>> Hi Geoffrey,
>
>> Thanks for the support so far.
>> I understand that you do not provide full support on
this level.
> Though I have the feeling that this is really
> - a very basic solution setup
> - a beginners-mistake and since I'm looking into it now
for
about 3 days
> (since I started with planner) it seems to be not
obvious to find for a
> beginner.
> So I was trying my luck in offering the code.
> It could be an opportunity to enrich the documentation
;-) ;-)
>Good point, the score corruption problem is often a
beginner
problem and
>it's a PITA. I 'll write some more docs about.
>Do note that your 3 day implementation should be able to
scale out to
10000 planes pretty easily, so hang in there :)
I fear you might have started copying from the wrong example
nqueens (if
you did that) :/ Nurse rostering is a far more similar to
this kind of
problem. I am not sure which example to promote in the docs:
the nqueens
is simple enough to explain things on, but it's too simple
to copy from
>for real world stuff :/ Feedback welcome.
>
>
>>
Ok,
>
>> 1) adding the $t2 results in the same sort of
exception, only
>> planningEntity seems different:
>
>> with insertLogical(new
>
UnweightedConstraintOccurrence("tasksInSameJobMustBeInSamePeriod",
$t1,
>> $t2));
>
>> Exception in thread "main"
java.lang.IllegalStateException: Score
> corruption: the workingScore (-2) is not the
uncorruptedScore (0):
> The workingMemory has 2 ConstraintOccurrence(s) in
excess:
>
tasksInSameJobMustBeInSamePeriod/NEGATIVE_HARD:[Maintenance
of
> Boeing 737 - PJ23.I#1 73111693, Maintenance of Boeing
737 - PJ23.I#2
>> 427578167]
>
tasksInSameJobMustBeInSamePeriod/NEGATIVE_HARD:[Maintenance
of
> Boeing 737 - PJ23.I#2 427578167, Maintenance of Boeing
737 - PJ23.I#1
> 73111693]
> Check the score rules who created those
ConstraintOccurrences.
Verify
> that each ConstraintOccurrence's causes and weight is
correct.
>> at
>
org.drools.planner.core.score.director.AbstractScoreDirector.assertWorkingScore(AbstractScoreDirector.java:101)
>> at
>
org.drools.planner.core.constructionheuristic.greedyFit.decider.DefaultGreedyDecider.doMove(DefaultGreedyDecider.java:110)
>> at
>
org.drools.planner.core.constructionheuristic.greedyFit.decider.DefaultGreedyDecider.decideNextStep(DefaultGreedyDecider.java:78)
>> at
>
org.drools.planner.core.constructionheuristic.greedyFit.DefaultGreedyFitSolverPhase.solve(DefaultGreedyFitSolverPhase.java:63)
>> at
>
org.drools.planner.core.solver.DefaultSolver.runSolverPhases(DefaultSolver.java:183)
>> at
>
org.drools.planner.core.solver.DefaultSolver.solve(DefaultSolver.java:151)
>> at
>
be.axi.planner.domain.MaintenancePlanning.main(MaintenancePlanning.java:27)
>
>> with insertLogical(new
>
UnweightedConstraintOccurrence("tasksInSameJobMustBeInSamePeriod",
$t1));
>
>> Exception in thread "main"
java.lang.IllegalStateException: Score
> corruption: the workingScore (-2) is not the
uncorruptedScore (0):
> The workingMemory has 2 ConstraintOccurrence(s) in
excess:
>
tasksInSameJobMustBeInSamePeriod/NEGATIVE_HARD:[Maintenance
of
>> Airbus A350 - XJ34.I#2 778813475]
>
tasksInSameJobMustBeInSamePeriod/NEGATIVE_HARD:[Maintenance
of
> Airbus A350 - XJ34.I#0 225744121]
> Check the score rules who created those
ConstraintOccurrences.
Verify
> that each ConstraintOccurrence's causes and weight is
correct.
>> at
>
org.drools.planner.core.score.director.AbstractScoreDirector.assertWorkingScore(AbstractScoreDirector.java:101)
>> at
>
org.drools.planner.core.constructionheuristic.greedyFit.decider.DefaultGreedyDecider.doMove(DefaultGreedyDecider.java:110)
>> at
>
org.drools.planner.core.constructionheuristic.greedyFit.decider.DefaultGreedyDecider.decideNextStep(DefaultGreedyDecider.java:78)
>> at
>
org.drools.planner.core.constructionheuristic.greedyFit.DefaultGreedyFitSolverPhase.solve(DefaultGreedyFitSolverPhase.java:63)
>> at
>
org.drools.planner.core.solver.DefaultSolver.runSolverPhases(DefaultSolver.java:183)
>> at
>
org.drools.planner.core.solver.DefaultSolver.solve(DefaultSolver.java:151)
>> at
>
be.axi.planner.domain.MaintenancePlanning.main(MaintenancePlanning.java:27)
>
>
>> 2) You suggested to
replace
UnweightedConstraintOccurrence with
> IntConstraintOccurrence. I will.
> UnweightedConstraintOccurrence is used in the very
basic Queens
example
>> though...
>Yep, my mistake.
>
>> 3) Where is the best place
to read about what
insertLogical and
> IntConstraintOccurrence really do?
> What is the purpose of the Cause -objects, which should
be passed?
> => where is the best place to find explanation about
this?
>>
(
http://docs.jboss.org/drools/release/5.4.0.Final/drools-planner-docs/html...
>> doesn't really enlighten me on that part)
>Look for "insertLogical" in the Drools Expert
guide:
>http://docs.jboss.org/drools/release/5.4.0.Final/drools-expert-docs/html_single/index.html
>When rules do an insertLogical of an object A, it's
discarded if another
object B in the WorkingMemory equals object A (through
equals() and
through hashcode()). Because the ConstraintOccurrences need
to be unique
so they aren't discarded, they ruleId, constraintType and
causes are
>used for equals()/hashcode().
>Future work: "compensation action"
>Recently, drools introduced something called "compensation
action",
which can probably replace the use
insertLogical(ConstraintOccurrence)
and make the causes parameter obsolete.
It's also faster.
My first experiments look very promising, but I haven't got
time yet
to
experiment with it on all examples and make it easy for
users to use.
>It would allow us to do something like this in the then
part
of a rule:
> hardAndSoftScoreHelper.addHardScore(-5);
>or
> hardAndSoftScoreHelper.addSoftScore(- $sum);
>or
> simpleScoreHelper.addScore(-7);
>No need for causes, insertLogicals, no equals/hashcode()
worries, much
>more flexible, ...
>4) Does your MaintenanceTask
implement equals()/hashcode()
other than
>Object's original implementation?
>
>>
Thanks in advance.
>
>yw
>_______________________________________________
>rules-users mailing list
>rules-users(a)lists.jboss.org
>https://lists.jboss.org/mailman/listinfo/rules-users
>_______________________________________________
rules-users mailing list rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users