<html><body><div style="color:#000; background-color:#fff; font-family:tahoma, new york, times, serif;font-size:10pt"><div><span>Hi,</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><br><span></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>I did not add it yet (no clue of what it all means... two days ago I never even heart of Drools Planner (or other planners)).</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>I added it now, but it does not change a thing.</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style:
normal;"><br><span></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>I added some logging and I saw that other periods do get thrown into the equation, though they never make it to the best solution.</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><br><span></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>Forgive me for my persistent nagging, but I do keep the feeling that something is wrong.</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span><br></span></div><div style="color: rgb(0, 0, 0);
font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>The planner does not find a solution with score 0 in 10 minutes and I can - on sight - in less than a few seconds (given the current amount of data (planes, technicians, periods ).</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><br></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;">Failing plan-attempt:</div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><br><span></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style:
normal;"><span>I have 4 (non-overlapping) available periods and three planes to maintain.</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>plane 1 needs 5 techs</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>plane 2 needs 3 techs</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>plane 3 needs 3 techs</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><br><span></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color:
transparent; font-style: normal;"><span>10 techs are available, all the time.</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><br><span></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>Planner takes 10 minutes to come up with score -2 (1 tech double planned).</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><br><span></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>though solution is that simple.</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new
york,times,serif; background-color: transparent; font-style: normal;"><br><span></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>Plane 1 => Period 1, use 5 techs (choose any set of 5)</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>Plane 2 => Period 2, use 3 techs <br></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>Plane 3 => Period 3, use 3 techs</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><br><span></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px;
font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>That is only one of the x optimal solutions.</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>It seems so easy...<br></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><br><span></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>Well... </span></div><div> </div><div>-----------------<br>http://www.codessentials.com - Your essential software, for free!<br>Follow us at http://twitter.com/#!/Codessentials<br></div> <div style="font-family: tahoma, new york, times, serif; font-size: 10pt;"> <div
style="font-family: times new roman, new york, times, serif; font-size: 12pt;"> <div dir="ltr"> <font face="Arial" size="2"> <hr size="1"> <b><span style="font-weight:bold;">From:</span></b> Geoffrey De Smet <ge0ffrey.spam@gmail.com><br> <b><span style="font-weight: bold;">To:</span></b> rules-users@lists.jboss.org <br> <b><span style="font-weight: bold;">Sent:</span></b> Friday, August 31, 2012 5:43 PM<br> <b><span style="font-weight: bold;">Subject:</span></b> Re: [rules-users] Best model for planning? technicians, airplanes and shifts<br> </font> </div> <br>Add a generic swap move factory too, if you haven't already.<br>change move factory alone doesn't suffice<br><br>Op 31-08-12 17:08, Michiel Vermandel schreef:<br>> The run of 600 seconds ended too with a score of -2.<br>><br>> It seems as if the planner never gets away from Period 1.<br>><br>> The planner finds a solution quit quickly if there are enough<br>> technicians
to plan all maintenance tasks in P1 (Period 1).<br>> The moment I have more maintenance tasks than different technicians then<br>> the planner does not come up with a feasible solution.<br>> Though the solution should be quit simple if one or two maintenance<br>> tasks were planned on P2 or P3...<br>><br>> Any idea why P2,... never show up in the best solution?<br>><br>> Thanks<br>><br>> -----------------<br>> <a href="http://www.codessentials.com/" target="_blank">http://www.codessentials.com</a> - Your essential software, for free!<br>> Follow us at <a href="http://twitter.com/#!/Codessentials" target="_blank">http://twitter.com/#!/Codessentials</a><br>> ------------------------------------------------------------------------<br>> *From:* Michiel Vermandel <<a ymailto="mailto:mvermand@yahoo.com" href="mailto:mvermand@yahoo.com">mvermand@yahoo.com</a>><br>> *To:* Rules Users List <<a
ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>><br>> *Sent:* Friday, August 31, 2012 4:52 PM<br>> *Subject:* Re: [rules-users] Best model for planning? technicians,<br>> airplanes and shifts<br>><br>> My excuses,<br>><br>> The solution does give a valid solution with a period assigned to the task.<br>> My last change wasn't that great ;-)<br>><br>> Though the score is now -2 and obviously is not a feasible solution.<br>> A given technician is assigned to two tasks in the same period.<br>><br>> Maybe 60 seconds is too short?<br>> Trying now with 600 seconds...<br>><br>> Can you please confirm that my way of working is correct?<br>> So it is just a matter of giving more time to it?<br>><br>> Thank you,<br>><br>> Michiel<br>> -----------------<br>> <a href="http://www.codessentials.com/"
target="_blank">http://www.codessentials.com</a> - Your essential software, for free!<br>> Follow us at <a href="http://twitter.com/#!/Codessentials" target="_blank">http://twitter.com/#!/Codessentials</a><br>> ------------------------------------------------------------------------<br>> *From:* Michiel Vermandel <<a ymailto="mailto:mvermand@yahoo.com" href="mailto:mvermand@yahoo.com">mvermand@yahoo.com</a>><br>> *To:* Rules Users List <<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>><br>> *Sent:* Friday, August 31, 2012 3:52 PM<br>> *Subject:* Re: [rules-users] Best model for planning? technicians,<br>> airplanes and shifts<br>><br>> Thank you for the quick response, Geoffrey.<br>><br>> So basically what I do is correct?<br>><br>> I'm still curious why<br>> a) 3 planes, 2 techs 4 periods ends in 3 seconds with<br>>
isEveryProblemFactChangeProcessed: true<br>> isTerminateEarly: false<br>> score: 0<br>><br>> b) 3 planes, 3 techs 4 periods keeps running for ?? time<br>><br>> I changed the termination parameter to 60 seconds.<br>> After 60 seconds best-solution gives a score of 0 but my<br>> planningEntities have no period assigned; only a technician.<br>><br>><br>> -----------------<br>> <a href="http://www.codessentials.com/" target="_blank">http://www.codessentials.com</a> - Your essential software, for free!<br>> Follow us at <a href="http://twitter.com/#!/Codessentials" target="_blank">http://twitter.com/#!/Codessentials</a><br>> ------------------------------------------------------------------------<br>> *From:* Geoffrey De Smet <<a ymailto="mailto:ge0ffrey.spam@gmail.com" href="mailto:ge0ffrey.spam@gmail.com">ge0ffrey.spam@gmail.com</a>><br>> *To:* <a ymailto="mailto:rules-users@lists.jboss.org"
href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>> *Sent:* Friday, August 31, 2012 3:29 PM<br>> *Subject:* Re: [rules-users] Best model for planning? technicians,<br>> airplanes and shifts<br>><br>> Op 31-08-12 15:07, Michiel Vermandel schreef:<br>> > Hi, me once more.<br>> ><br>> > I guess you figured out by now that I am quite a newbie to Drools<br>> > (planning).<br>> > Problem is I need to write a POC in max 3 to 4 days...<br>> > I'm drifting, so please help...<br>> ><br>> > I have written a basic solution for planning plane-maintenance.<br>> > I stripped it to it's very basics and it works... if I keep the number<br>> > of planes, periods and technicians to a very minimum.<br>> > I removed all additional constraints like skill matching and<br>> > availability
during a period...<br>> ><br>> > Planning maintenance for 3 planes with each 2 required technicians, 4<br>> > available periods and a list of 10 available technicians delivers a<br>> > solution in about 3 seconds.<br>> It probably stopped early because basically all solutions had been seen.<br>><br>> > Simply increasing the number of technicians per plane from 2 to 3<br>> > results in an indefinite solving time (I did not wait longer than a few<br>> > minutes).<br>> you got:<br>> <maximumSecondsSpend>700</maximumSecondsSpend><br>> so it will run for over 11 minutes.<br>> Turn that to just 60 seconds (or see manual about alternative<br>> termination methods).<br>><br>> The problem is NP-complete, so as you scale up to thousands (and more)<br>> planes/techs/periods, no software (and certainly no human being) can<br>> find the
optimal solution in reasonable time (see first chatper in<br>> manual). Planner will find you the best solution in the time you (can)<br>> give it.<br>><br>> > Decreasing the numbers obviously works, at an elapsed time slightly<br>> > under 3 seconds.<br>> ><br>> > I finally need to plan about 500 plane maintenance jobs (3 to 4<br>> > technicians per maintenance job) over 12 available periods with about<br>> > 400 available technicians..<br>> > So there must be something wrong/incomplete in my solution.<br>> ><br>> > What I did:<br>> ><br>> > I have created a planningEntity MaintenanceTask with two planning<br>> > variables (technician and period) and a simple rule file.<br>> > (See all below)<br>> > Running this solution thus results in such poor solving
time.<br>> ><br>> > Can you please advice me in what I am doing wrong?<br>> ><br>> > Many thanks!!<br>> ><br>> > PlanningEntity (MaintenanceTask .java):<br>> ><br>> > @PlanningEntity(difficultyWeightFactoryClass =<br>> > TaskDifficultyWeightFactory.class)<br>> > public class MaintenanceTask {<br>> ><br>> > private Period period;<br>> > private Project project;<br>> > private Technician technician;<br>> ><br>> > public MaintenanceTask (Project aProject) {<br>> > this.project = aProject;<br>> > }<br>> ><br>> > public String getId(){<br>> >
return project.getId()+"-"+hashCode();<br>> > }<br>> ><br>> > @PlanningVariable<br>> > @ValueRange(type = ValueRangeType.FROM_SOLUTION_PROPERTY,<br>> > solutionProperty = "technicians")<br>> > public Technician getTechnician() {<br>> > return technician;<br>> > }<br>> ><br>> > public void setTechnician(Technician aTechnician) {<br>> > this.technican= aTechnician;<br>> > }<br>> ><br>> > @PlanningVariable<br>> > @ValueRange(type = ValueRangeType.FROM_SOLUTION_PROPERTY,<br>> > solutionProperty = "periods")<br>> >
public Period getPeriod() {<br>> > return period;<br>> > }<br>> ><br>> > public void setPeriod(Period aPeriod) {<br>> > this.period = aPeriod;<br>> > }<br>> ><br>> > public String getPeriodId(){<br>> > return period == null ? null : period.getId();<br>> > }<br>> ><br>> > public String getProjectId(){<br>> > return project == null ? null : project.getId();<br>> > }<br>> ><br>> > public MaintenanceTask clone() {<br>> > MaintenanceTask clone = new
MaintenanceTask (project);<br>> > clone.period = this.period;<br>> > clone.technician= this.technician;<br>> > return clone;<br>> > }<br>> ><br>> > }<br>> ><br>> > Project.java<br>> ><br>> > public class Project {<br>> > private Plane plane;<br>> ><br>> > public Project(Plane aPlane) {<br>> > this.plane = aPlane;<br>> > }<br>> ><br>> > public Plane getPlane() {<br>> > return plane;<br>> > }<br>> ><br>> >
public String getId() {<br>> > return getPlane().getName();<br>> > }<br>> ><br>> > public int getTechnicianLoad(){<br>> > return getPlane().getTechnicianLoad();<br>> > }<br>> ><br>> > public List<MaintenanceTask> getTasks() {<br>> > List<MaintenanceTask> tasks = new ArrayList<MaintenanceTask>();<br>> > for (int i = 0; i < getTechnicianLoad(); i++) {<br>> > tasks.add(new MaintenanceTask(this));<br>> > }<br>> > return tasks;<br>> >
}<br>> > }<br>> ><br>> > Technician.java and Period.java are at this moment basically just<br>> > classes having an getId and getName method, nothing more.<br>> > Plane.java has a method getTechnicianLoad that returns the number of<br>> > required technicians for the maintenance.<br>> ><br>> > This is the config file (basically copy from one of the examples)<br>> ><br>> > <?xml version="1.0" encoding="UTF-8"?><br>> > <solver><br>> > <!-- Domain model configuration --><br>> ><br>> <solutionClass>be.axi.planner.domain.MaintenanceSchedule</solutionClass><br>> ><br>> ><br>> <planningEntityClass>be.axi.planner.domain.MaintenanceTask</planningEntityClass><br>> ><br>> > <!--
Score configuration --><br>> > <scoreDirectorFactory><br>> > <scoreDefinitionType>SIMPLE</scoreDefinitionType><br>> > <scoreDrl>/maintenancePlannerRules.drl</scoreDrl><br>> > </scoreDirectorFactory><br>> ><br>> > <termination><br>> > <maximumSecondsSpend>700</maximumSecondsSpend><br>> > </termination><br>> ><br>> > <constructionHeuristic><br>> ><br>> ><br>> <constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType><br>> ><br>> ><br>> <constructionHeuristicPickEarlyType>FIRST_LAST_STEP_SCORE_EQUAL_OR_IMPROVING</constructionHeuristicPickEarlyType><br>> >
</constructionHeuristic><br>> > <localSearch><br>> > <selector><br>> ><br>> ><br>> <moveFactoryClass>org.drools.planner.core.move.generic.GenericChangeMoveFactory</moveFactoryClass><br>> > <!-- GenericChangeMoveFactory is the generic form of<br>> > RowChangeMoveFactory: --><br>> ><br>> ><br>> <!--<moveFactoryClass>org.drools.planner.examples.nqueens.solver.move.factory.RowChangeMoveFactory</moveFactoryClass>--><br>> > </selector><br>> > <acceptor><br>> > <solutionTabuSize>1000</solutionTabuSize><br>> >
<planningEntityTabuSize>7</planningEntityTabuSize><br>> > </acceptor><br>> > <forager><br>> > <minimalAcceptedSelection>800</minimalAcceptedSelection><br>> > </forager><br>> > </localSearch><br>> > </solver><br>> ><br>> > this is the rules file:<br>> ><br>> > package org.drools.planner.examples.pas.solver;<br>> > dialect "java"<br>> ><br>> > import org.drools.planner.core.score.buildin.simple.SimpleScoreHolder;<br>> > import org.drools.planner.core.score.constraint.IntConstraintOccurrence;<br>> > import<br>> > org.drools.planner.core.score.constraint.UnweightedConstraintOccurrence<br>>
> import org.drools.planner.core.score.constraint.ConstraintType;<br>> ><br>> > import be.axi.planner.domain.MaintenanceTask;<br>> ><br>> > global SimpleScoreHolder scoreHolder;<br>> ><br>> > //<br>> ><br>> ############################################################################<br>> > // Hard constraints<br>> > //<br>> ><br>> ############################################################################<br>> ><br>> > rule "noMultipleAssignmentsInOnePeriod"<br>> > when<br>> > $t1 : MaintenanceTask($id : id, $periodId : periodId,<br>> > $technician : technician )<br>> > $t2 : MaintenanceTask(id != $id, periodId == $periodId,<br>> > technician ==
$technician)<br>> > then<br>> > insertLogical(new<br>> > UnweightedConstraintOccurrence("noMultipleAssignmentsInOnePeriod", $t1,<br>> > $t2));<br>> > end<br>> ><br>> > rule "tasksInSameProjectMustBeInSamePeriod"<br>> > when<br>> > $t1 : MaintenanceTask($id : id, $periodId : periodId,<br>> > $projectId : projectId )<br>> > $t2 : MaintenanceTask(id != $id, periodId != $periodId, projectId ==<br>> > $projectId)<br>> > then<br>> > insertLogical(new<br>> > UnweightedConstraintOccurrence("tasksInSameProjectMustBeInSamePeriod",<br>> > $t1, $t2));<br>> > end<br>> ><br>> >
//<br>> ><br>> ############################################################################<br>> > // Calculate score<br>> > //<br>> ><br>> ############################################################################<br>> ><br>> > rule "hardConstraintsBroken"<br>> > when<br>> > $occurrenceCount : Number() from accumulate(<br>> > $unweightedConstraintOccurrence :<br>> > UnweightedConstraintOccurrence(),<br>> > count($unweightedConstraintOccurrence)<br>> > )<br>> > then<br>> > scoreHolder.setScore(- $occurrenceCount.intValue());<br>> > end<br>>
><br>> > Solution file:<br>> ><br>> > package be.axi.planner.domain;<br>> ><br>> > import java.util.ArrayList;<br>> > import java.util.Collection;<br>> > import java.util.List;<br>> ><br>> > import<br>> > org.drools.planner.api.domain.solution.PlanningEntityCollectionProperty;<br>> > import org.drools.planner.core.score.buildin.simple.SimpleScore;<br>> > import org.drools.planner.core.solution.Solution;<br>> ><br>> ><br>> > public class MaintenanceSchedule implements Solution<SimpleScore>{<br>> ><br>> > private SimpleScore score;<br>> > private List<MaintenanceTask> maintenanceTasks;<br>> > private List<Period> periods;<br>> >
private List<Technician> technicians;<br>> ><br>> > public MaintenanceSchedule cloneSolution() {<br>> > MaintenanceSchedule clone = new MaintenanceSchedule();<br>> > clone.periods = this.periods;<br>> > clone.technicians = this.technicians;<br>> > List<MaintenanceTask> clonedTasks = new<br>> ArrayList<MaintenanceTask>(<br>> > maintenanceTasks.size());<br>> > for (MaintenanceTask task : maintenanceTasks) {<br>> > MaintenanceTask clonedTask = task.clone();<br>> >
clonedTasks.add(clonedTask);<br>> > }<br>> > clone.maintenanceTasks = clonedTasks;<br>> > clone.score = this.score;<br>> ><br>> > return clone;<br>> > }<br>> ><br>> > public Collection<? extends Object> getProblemFacts() {<br>> > System.out.println(">>getting problemfacts");<br>> > List<Object> facts = new ArrayList<Object>();<br>> > facts.addAll(periods);<br>> > facts.addAll(technicians);<br>> > // Do not add the planning entity's (maintenaceTasks)
because<br>> > that will be done automatically<br>> > return facts;<br>> > }<br>> ><br>> > public SimpleScore getScore() {<br>> > return this.score;<br>> > }<br>> ><br>> > public void setScore(SimpleScore aScore) {<br>> > this.score = aScore;<br>> > if (aScore != null){<br>> > System.out.println("Score set to " + aScore.getScore());<br>> > }<br>> > }<br>> ><br>> > @PlanningEntityCollectionProperty<br>> > public List<MaintenanceTask>
getMaintenanceTasks() {<br>> > System.out.println("getting tasks: #" +maintenanceTasks.size());<br>> > return maintenanceTasks;<br>> > }<br>> ><br>> > public void setMaintenanceTasks(List<MaintenanceTask><br>> > aMaintenanceTasks) {<br>> > System.out.println("setting tasks");<br>> > this.maintenanceTasks = aMaintenanceTasks;<br>> > }<br>> ><br>> > public void setTechnicians(List<Technician> aTechnicians) {<br>> > System.out.println("setting Technicians");<br>> > this.technicians = aTechnicians;<br>>
> }<br>> ><br>> > public List<Technician> getTechnicians() {<br>> > System.out.println("Getting Technicians: #"+technicians.size());<br>> > return technicians;<br>> > }<br>> ><br>> > public List<Period> getPeriods() {<br>> > System.out.println("getting periods");<br>> > return periods;<br>> > }<br>> ><br>> > public void setPeriods(List<Period> periods) {<br>> > this.periods = periods;<br>> > }<br>> ><br>> > }<br>> ><br>> ><br>> ><br>>
><br>> > -----------------<br>> > <a href="http://www.codessentials.com/" target="_blank">http://www.codessentials.com</a> <<a href="http://www.codessentials.com/" target="_blank">http://www.codessentials.com/</a>> - Your<br>> essential software, for free!<br>> > Follow us at <a href="http://twitter.com/#!/Codessentials" target="_blank">http://twitter.com/#!/Codessentials</a><br>> > ------------------------------------------------------------------------<br>> > *From:* Geoffrey De Smet <<a ymailto="mailto:ge0ffrey.spam@gmail.com" href="mailto:ge0ffrey.spam@gmail.com">ge0ffrey.spam@gmail.com</a><br>> <mailto:<a ymailto="mailto:ge0ffrey.spam@gmail.com" href="mailto:ge0ffrey.spam@gmail.com">ge0ffrey.spam@gmail.com</a>>><br>> > *To:* <a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>
<mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>><br>> > *Sent:* Friday, August 31, 2012 10:54 AM<br>> > *Subject:* Re: [rules-users] Best model for planning? technicians,<br>> > airplanes and shifts<br>> ><br>> > Op 31-08-12 09:46, Michiel Vermandel schreef:<br>> > > Thank you for the response.<br>> > > I think I forgot one level of complexity (?):<br>> > ><br>> > > The moment of maintenance of a plane is not fixed.<br>> > ><br>> > > We have 12 "periods" per year for maintenance.<br>> > > One period every month.<br>> > ><br>> > > We need to make the planning in such way that the list of planes is<br>> >
> planned somewhere in these 12 periods.<br>> > > But it is not important that a specific plane is maintained at a<br>> > > specific period.<br>> > > It has though a calendar of unavailability.<br>> > ><br>> > > So the job (==Shift) of the Task (==ShiftAssignment) has no hard<br>> > > constraint on period.<br>> > ><br>> > > We need to find that combination with the best match between required<br>> > > skills for the job and available technicians.<br>> > > It's better to plan the job on a later period if at that time a more<br>> > > skilled technician is available.<br>> > ><br>> > > I hope this is a bit clear.<br>> > ><br>> > > So, given this
addition, should I take as planning variables:<br>> > ><br>> > > 1) Period (List of 12 periods)<br>> > > 2) Technician<br>> ><br>> > Good idea<br>> ><br>> > ><br>> > > Then use period to check availability on both plane and technician<br>> > > (hard-constraint)<br>> > I see 3:<br>> > - plane availability<br>> > - technician conflicts (2 tasks at the same time)<br>> > - technician availability<br>> > > Then give a better weight on skill-match (soft-constrain)?<br>> ><br>> > yes (and possible others, such as work load, technician desires, ...)<br>> ><br>> > ><br>> > > Thank you.<br>> > ><br>> > >
Michiel<br>> > ><br>> > > -----------------<br>> > > <a href="http://www.codessentials.com/" target="_blank">http://www.codessentials.com</a> <<a href="http://www.codessentials.com/" target="_blank">http://www.codessentials.com/</a>> -<br>> Your essential software, for free!<br>> > > Follow us at <a href="http://twitter.com/#!/Codessentials" target="_blank">http://twitter.com/#!/Codessentials</a><br>> > ><br>> ------------------------------------------------------------------------<br>> > > *From:* Geoffrey De Smet <<a ymailto="mailto:ge0ffrey.spam@gmail.com" href="mailto:ge0ffrey.spam@gmail.com">ge0ffrey.spam@gmail.com</a><br>> <mailto:<a ymailto="mailto:ge0ffrey.spam@gmail.com" href="mailto:ge0ffrey.spam@gmail.com">ge0ffrey.spam@gmail.com</a>><br>> > <mailto:<a
ymailto="mailto:ge0ffrey.spam@gmail.com" href="mailto:ge0ffrey.spam@gmail.com">ge0ffrey.spam@gmail.com</a> <mailto:<a ymailto="mailto:ge0ffrey.spam@gmail.com" href="mailto:ge0ffrey.spam@gmail.com">ge0ffrey.spam@gmail.com</a>>>><br>> > > *To:* <a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>>><br>> > > *Sent:* Friday, August 31, 2012 9:08 AM<br>> > > *Subject:* Re: [rules-users] Best model
for planning? technicians,<br>> > > airplanes and shifts<br>> > ><br>> > > Op 30-08-12 18:02, mvermand schreef:<br>> > > > Hi,<br>> > > ><br>> > > > I'd like some advice on how to make my model.<br>> > > ><br>> > > > I need to plan maintenance-schedules for - let's say - airplanes.<br>> > > > Constraints are:<br>> > > > - planes are only at given moments available for maintenance (when<br>> > not in<br>> > > > the air ;-)<br>> > > > - maintenance of a planes requires a number of techniciens (with<br>> > specific<br>> > > > skills).<br>> > > > -
techniciens have skills and also shifts and vacation.<br>> > > ><br>> > ><br>> > > Sounds like the nurse rostering example in Planner :)<br>> > > In nurse rostering, such a Shift has a ShiftDate and a ShiftType.<br>> > > The difference is, you need to assign jobs instead of shifts.<br>> > ><br>> > > > Now, first I tought to make the maintenance of a plane the<br>> > > planningEntity.<br>> > > > But I did not know how to populate and match the techniciens.<br>> > ><br>> > > I wouldn't make plane the planningEntity either, it's on the one<br>> side of<br>> > > the manyToOne relation.<br>> > ><br>> > > ><br>> >
> > So, second I tought to make a new Task-class the planningEntity.<br>> > > > A Task is a job that needs to be done by a technicien with specific<br>> > > skills.<br>> > > > Maintaining a plane requires then a number of tasks.<br>> > ><br>> > > Good idea. In nurse rostering, a Task is called a ShiftAssignment.<br>> > > You can generate all Tasks in advance based on the Planes and<br>> their jobs<br>> > > and the number of technicians needed by each job.<br>> > ><br>> > > I recommend to make separate Task instances for multiple technicians<br>> > > that perform the same job together on the same plane. In nurse<br>> rostering<br>> > > there are also multiple ShiftAssignments (=tasks) per
Shift (=job).<br>> > ><br>> > > ><br>> > > > If I choose this model, I think I'll have to pass two Plannings<br>> > > variables to<br>> > > > the Task planningEntity:<br>> > > > 1) a Maintenance-fact (Plane + Period + list of required tasks) and<br>> > ><br>> > > I don't think this is a planner variable on the planning entity Task.<br>> > > It really defines the Task: what job on what plane (and some of<br>> sort of<br>> > > requiredTechnicanCountIndex)<br>> > ><br>> > > > 2) a Technicien-fact (?)<br>> > > This is a planning variable.<br>> > > You're assigning task to techinicians.<br>> > > Each
task has exactly 1 technician (because a job has multiple tasks,<br>> > > one per required technician).<br>> > > Each technician can work on multiple tasks, but the hard/soft<br>> > > constraints make sure that it's not at the same time.<br>> > ><br>> > > ><br>> > > > Then I'll need to check if availabity of plane and availability of<br>> > > > technicien match and also skill-requirement of task and skills of<br>> > > > technicien.<br>> > ><br>> > > Yep, with constraints<br>> > ><br>> > > ><br>> > > > Do you think this second model is the right one?<br>> > > ><br>> > > >
Will it perform well?<br>> > > > => ? matching all combinations of plane availabilty and<br>> > > > techniciens-availability and -skills.<br>> > ><br>> > > It should, see the nurse rostering problem.<br>> > > In Planner 5.5.0.Beta1, I would add a filter on the swap move selector<br>> > > to prevent it from swapping 2 technicians assigned to different<br>> tasks on<br>> > > the same job.<br>> > ><br>> > ><br>> ><br>> <a href="https://github.com/droolsjbpm/drools-planner/blob/master/drools-planner-examples/src/main/java/org/drools/planner/examples/curriculumcourse/solver/move/DifferentCourseSwapMoveFilter.javatd"
target="_blank">https://github.com/droolsjbpm/drools-planner/blob/master/drools-planner-examples/src/main/java/org/drools/planner/examples/curriculumcourse/solver/move/DifferentCourseSwapMoveFilter.javatd</a><br>> > ><br>> > > ><br>> > > > Thanks in advance<br>> > > ><br>> > > ><br>> > > ><br>> > > > --<br>> > > > View this message in context:<br>> > ><br>> <a href="http://drools.46999.n3.nabble.com/Best-model-for-planning-tp4019464.html" target="_blank">http://drools.46999.n3.nabble.com/Best-model-for-planning-tp4019464.html</a><br>> > > > Sent from the Drools: User forum mailing list archive at Nabble.com<br>> > > <<a href="http://nabble.com/"
target="_blank">http://nabble.com/</a>>.<br>> > > > _______________________________________________<br>> > > > rules-users mailing list<br>> > > > <a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>>><br>> > <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>> <mailto:<a
ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>>>><br>> > > > <a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>> > > ><br>> > ><br>> > ><br>> > > _______________________________________________<br>> > > rules-users mailing list<br>> > > <a ymailto="mailto:rules-users@lists.jboss.org"
href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>><br>> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>>><br>> > <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>> <mailto:<a
ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>>>><br>> > > <a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>> > ><br>> > ><br>> > ><br>> > ><br>> > > _______________________________________________<br>> > > rules-users mailing list<br>> > > <a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>><br>> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>
<mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>>><br>> > > <a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>> > ><br>> ><br>> ><br>> > _______________________________________________<br>> > rules-users mailing list<br>> > <a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>><br>> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org"
href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>>><br>> > <a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>> ><br>> ><br>> ><br>> ><br>> > _______________________________________________<br>> > rules-users mailing list<br>> > <a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>><br>> > <a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>> ><br>><br>><br>> _______________________________________________<br>> rules-users
mailing list<br>> <a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>><br>> <a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>><br>><br>><br>><br>><br>> _______________________________________________<br>> rules-users mailing list<br>> <a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a> <mailto:<a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>><br>> <a href="https://lists.jboss.org/mailman/listinfo/rules-users"
target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>><br>><br>><br>><br>> _______________________________________________<br>> rules-users mailing list<br>> <a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>> <a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>><br><br><br>_______________________________________________<br>rules-users mailing list<br><a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br><a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br><br><br> </div> </div> </div></body></html>