[rules-users] best rule for grouping planning entities?

Michiel Vermandel mvermand at yahoo.com
Wed Jan 23 03:08:29 EST 2013


Hi,

I need to group a number of entities together and I'm not sure if my rule is optimal.

My planning entities represent maintenance tasks on airplanes.
Every planning entity is a discreet task (check tires, refuel, check engines...) but the maintenance of an airplane exists of a number of these tasks and they need to be grouped together.
Every task has a duration depending on its type (checking engine takes longer than checking tires).
The optimal solution is that all tasks of a maintenance are in the smallest amount of time (time between start of first task till end of last task).
Though, the smaller the better, at least all tasks should be sequential (without gaps between the tasks).
Dependencies on the tasks are availability of the plain, availability of the technicians...

(The rules beneath only check that the tasks are chained together, not (yet) that the time span is minimal => I thought to make a soft-constraint for that).

First I had this rule:

rule "tasksInSameMaintenanceJobMustBeChained"
    when
        $task : Task( $jobId: jobId )
        not ( Task( jobId== $jobId, id != $task.id, ($task.startPeriodId-1) <= endPeriodId && ($task.endPeriodId+1) >= startPeriodId ) )
    then // we have a gap!
        insertLogical(new IntConstraintOccurrence("tasksInSameMaintenanceJobMustBeChained", ConstraintType.NEGATIVE_HARD, Importance.chainedPeriod, $jobId, $task));
end


After adding this rule I started struggling with what I believe is to be a score trap.
After advice from Geoffrey and reading some more, I thought my rule suffered from having a penalty which did not change depending on the amount of spread of the tasks.

So I rewrote the task to:
(I have now put all MaintenanceJobs into the working memory and I created a Class TaskSet() which is capable of calculating the nr of periods between all tasks of a job = gapCount)

rule "tasksInSameMaintenanceJobMustBeChained"
   when
        $job: MaintenanceJob()
        $taskset : TaskSet( gapCount > 0 )
                   from accumulate( $task : Task(jobId== $job.id),
                                    init( TaskSet taskset = new TaskSet(); ),
                                    action( taskset.addTask( $task ); ),
                                    reverse( taskset.removeTask( $task ); ),
                                    result( taskset ) );
   then
        insertLogical(new IntConstraintOccurrence("tasksInSameMaintenanceJobMustBeChained", ConstraintType.NEGATIVE_HARD, Importance.chainedPeriod * $taskset.getGapCount(), $job, $taskset));
end

 
I see a difference in score but still not optimal and terminated on time limit reached.

1) Is this rule as good as it can be? Or am I creating some issue here?

A Task (planning entity) has 3 different planning variables.
2) When I analyze the Trace logging I see that during the first steps the 3 variables  are switched during moves, but then after a while only one of the 3 variables gets changed and the other variables of all tasks remain as they are.

Should I conclude something out of that?

This is my local search config:

    <localSearch>
        <termination>
            <terminationCompositionStyle>OR</terminationCompositionStyle>
            <maximumSecondsSpend>3600</maximumSecondsSpend>
            <scoreAttained>0hard/0soft</scoreAttained>
        </termination>
        <unionMoveSelector>
            <changeMoveSelector>
                <valueSelector>
                      <!-- **  -->
                    <planningVariableName>role</planningVariableName>
                </valueSelector>
            </changeMoveSelector>
            <changeMoveSelector>
                <valueSelector>
                     <!-- entity var technician:who will execute the task -->
                    <planningVariableName>technician</planningVariableName>
                </valueSelector>
            </changeMoveSelector>
            <changeMoveSelector>
                <valueSelector>
                     <!-- entity var period: when will the plane get maintenance -->
                    <planningVariableName>period</planningVariableName>
                </valueSelector>
            </changeMoveSelector>
            <swapMoveSelector>
            </swapMoveSelector>
        </unionMoveSelector>

        <acceptor>
          <!-- 3 => small amount of planning entities in unit test -->
          <planningEntityTabuSize>3</planningEntityTabuSize>
        </acceptor>
        <forager>
            <minimalAcceptedSelection>1000</minimalAcceptedSelection>
        </forager>
    </localSearch>

(**) entity var role: every maintenance job has one lead task (role == lead),
 all other tasks in that job must have role = member. The technician 
assigned to the lead task will file the maintenance report.
One of the constraints (checked in other rule) is that no technician should be lead-technician twice in a row on two sequential maintenance jobs.

Thanks in advance.

Michiel

-----------------
http://www.codessentials.com - Your essential software, for free!
Follow us at http://twitter.com/#!/Codessentials
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20130123/bfeb36db/attachment-0001.html 


More information about the rules-users mailing list