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