[rules-users] Comparing 2 Lists [Planner]

Geoffrey De Smet ge0ffrey.spam at gmail.com
Thu Feb 21 05:00:44 EST 2013


There's a bit too many issues being taken on at the same time for me to 
grasp the problem,
but my first advice would be:

Apply "separation of concerns" on the constraints. Tackle each problem 
individually.
These 3 constraints are defined/implemented individually, isolated 
basically:

1) Required skill: A Workorder's engineer need to have the skill to 
fulfill the workorder.

2) Workload: An engineer's total WorkOrders count needs to be below a 
threshold.
   Important: punish by the (threshold - totalCount), not just -1 if 
above it. See this image:
https://hudson.jboss.org/hudson/view/Drools%20jBPM/job/drools-planner/lastSuccessfulBuild/artifact/drools-planner-docs/target/docbook/publish/en-US/html_single/index.html#scoreTrap

3) Priority: This one is a bit more difficult.
Basically, you're stating that some tasks have priorities over others.
There are different ways you can implement this, depending on how you 
define priority.

3a) One way is to ignore all the other constraints and just state that 
every unassigned tasks infers a penalty based on it's priority.
This implies that the optimal solution will still break a lot of these 
constraints: it will just break the least of them.
This might also not be perfect because the lower priority workorders 
might add up to beat a higher priority workorder (which may or may not 
be the behavior you want):
https://hudson.jboss.org/hudson/view/Drools%20jBPM/job/drools-planner/lastSuccessfulBuild/artifact/drools-planner-docs/target/docbook/publish/en-US/html_single/images/Chapter-Score_calculation/scoreFoldingIsBroken.png

3b) Another way is to keep the other constraints in mind:
When there is an unassigned WorkOrder, they should not be second 
WorkOrder, which is different, is assigned, has a higher priority AND 
that can be done by the same Engineer (=> check skill for the second 
WorkOrder).
Notice that we don't re-implement "1) Required skill" here for the 
unassigned WorkOrder, but we do check the skill for the second WorkOrder.

3c) Do a) and b) with a separate score level per priority. Without 6.0's 
BendableScore, it means you would have to write your own 
ScoreDefinition. Probably overkill (just ignore this for now).

I 'd recommend 3b) over 3a) and 3c)

Op 20-02-13 13:50, André Fróes schreef:
> Thanks for the answer Armand, I'll try to explain better the model, 
> since there's more people asking me about it here by e-mail (Ana 
> Kuzjminska and others).
>
> Before that, I tried what you passed me, I had already tried that 
> aproach, but didn't work, it sorts, but doesn't give the engineer the 
> proper workorder.
>
> About the model I am trying to create, it is a simple distribution of 
> workorder to engineers (for any kind of company), where workorder is 
> considered to be any kind of problem, and it has a priority to be 
> respected and, sometimes, one or more skills, that are required to do 
> that work, for example, an engineer that must fix an antena must know 
> how to fix that, otherwise, there's no reason to send him there.
>
> An engineer may have none or several skills. Everyone has a worktime 
> to be respected (this is working at the model, but I'm not using Date 
> attribute yet, it will be another step).
>
> The model classes:
>
> Engineer
> -- worktime (int)
> -- name (string)
> -- skillEngineerList (List<SkillEngineerList>)
>
> Workorder (PlanningEntity)
> -- requiredWorktime (int)
> -- priority (Priority)
> -- requiredSkills (List<SkillWorkOrder>)
> -- engineer (engineer)
>
> SkillEngineerList
> -- engineer (engineer)
> -- skill (skill)
>
> SkillWorkOrder
> -- workorder (workorder)
> -- skill (skill)
>
> Skill
> -- name (string)
>
> Priority (enum)
> -- code (string)
> -- deadline (double)
>
> As you can see, a workorder may have none to several skills, same's 
> for engineer, there's where I am at the moment. By scorecalculator i 
> was able to make it work, but it is not excluding the workorders that 
> exceed engineers time:
>
> Engineer 1, worktime 8 - skill ABC1, ABC2
>
> WorkOrder 1, worktime 8 - requiredSkills ABC2
> WorkOrder 2, worktime 8 - requiredSkills ABC1
>
> only one should be assigned to it, since he can do both, but when 
> running my model, the hard constraint of time is being broken, and 
> both are assigned.
>
> After that works, the next step to this model would be implement the 
> priority, the lower the deadline is, the more important it is, and it 
> will work directly with a date property that i'll insert in worktime 
> object later, because the workorder will have to be answered from the 
> moment it is registered according to its priority.
>
> It would be something like this:
>
> Workorder (PlanningEntity)
> -- requiredWorktime (int)
> -- created (Date) <--
> -- priority (Priority)
> -- requiredSkills (List<SkillWorkOrder>)
> -- engineer (engineer)
>
> so, if a workorder is registered at 10:00 am and priority is P1 with 
> deadline of 1 hour, it should be answered right away, based on 
> engineer worktime either.
>
> The solution I found by scorecalculator:
> public HardAndSoftScore calculateScore(Distributor distributor) {
> int hardScore = 0;
> int softScore = 0;
> for (Engineer e : distributor.getEngineerList()){
> int requiredWorktime = 0;
> List<Skill> requiredSkillList = new ArrayList<Skill>();
> for (WorkOrder o : distributor.getWorkOrderList()){
> if (e.equals(o.getEngineer())){
> requiredWorktime += o.getRequiredWorktime();
> for (SkillWorkOrder swo : o.getRequiredSkills()){
> requiredSkillList.add(swo.getSkill());
> }
> }
> }
> int engineerAvailableTime = e.getWorktime() - requiredWorktime;
> if (engineerAvailableTime < 0 ){
> hardScore += engineerAvailableTime;
> }
> int commonSkillCount = 0;
> for (SkillEngineer se : e.getSkillEngineerList()){
> for (Skill s : requiredSkillList){
> if (se.getSkill().getId() == s.getId()){
> commonSkillCount++;
> }
> }
> }
> if (commonSkillCount != 0){
> hardScore += commonSkillCount;
> }
> }
> return DefaultHardAndSoftScore.valueOf(hardScore, softScore);
> }
>
> but as I said, every workorder is being assigned exceeding engineer's 
> worktime.
>
>
> 2013/2/19 Welsh, Armand <AWelsh at statestreet.com 
> <mailto:AWelsh at statestreet.com>>
>
>     I would consider using comparable lists, where
>     workorderSkill.compareTo(employeeSkills) can be true for the same
>     skill.
>
>     When
>
>     $workorder : WorkOrder( $requiredSkills : skills)
>
>     $workorderSkill : Skill ( ) from $requiredSkills
>
>     $employee : Employee( skills contains $workorderSkill)
>
>     then
>
>     // do whatever, for each employee with a matching skill for all
>     work orders, this rule will file.
>
>     // if you need to limit only one employee with matching skill to
>     workorder, then more logic will need to be built
>
>     End
>
>     In this scenario, you are collecting all the workorder, and
>     required skills.  Then you check each employee to see if their
>     list of skills contains any of the required skills (not all skill
>     are required in this case, just one skill like your example
>     suggested).
>
>     *From:*rules-users-bounces at lists.jboss.org
>     <mailto:rules-users-bounces at lists.jboss.org>
>     [mailto:rules-users-bounces at lists.jboss.org
>     <mailto:rules-users-bounces at lists.jboss.org>] *On Behalf Of *André
>     Fróes
>     *Sent:* Monday, February 18, 2013 10:52 AM
>
>
>     *To:* Rules Users List
>     *Subject:* Re: [rules-users] Comparing 2 Lists [Planner]
>
>     I found (i guess) a way to iterate over list, but it is not
>     comparing and assigning the workorder now. I tried this way:
>
>     -----------------
>
>     rule "requiredSkill"
>
>        when
>
>            There is an unassigned workorder
>
>            and the workorder has a requiredSkill other than null
>
>            and there is an engineer
>
>            and the engineer has a skill other than null
>
>            and engineer skill is the same as workorder skill
>
>        then
>
>            assign workorder to engineer
>
>     engineer
>
>     -----------------
>
>     this is how i tried implementing;
>
>     -----------------
>
>     rule "requiredSkill"
>
>                 when
>
>     $workOrder : WorkOrder()
>
>      $woReqSkill : SkillWorkOrder($requiredSkillWO : skill ,
>     eval(skill != null)) from $workOrder.requiredSkills
>
>                    $engineer : Engineer()
>
>      $engineerSkill : SkillEngineer($engSkill : skill, eval(skill !=
>     null)) from $engineer.skillEngineerList
>
>                    exists SkillEngineer( $engineerSkill.skill ==
>     $woReqSkill.skill )
>
>                 then
>
>     insertLogical(new IntConstraintOccurrence("requiredSkill",
>     ConstraintType.NEGATIVE_HARD,
>
>     1, $engineer));
>
>     end
>
>     -----------------
>
>     But all workorders are going to the same one, it is not validating
>     if one is equals to other.
>
>     2013/2/18 André Fróes <arfmoraes at gmail.com
>     <mailto:arfmoraes at gmail.com>>
>
>     Hello everyone!
>
>     How can I compare 2 lists with a rule?
>
>     I upgraded my basic model to a more complex one now, but now I hit
>     a wall. My WorkOrder have a List of skills, and my Engineer also
>     have a list of Skills and I have to compare one with another.
>
>     Example:
>
>     Engineer A have skill ABC 1
>
>     Engineer B have skill ABC 2
>
>     Engineer C have skill ABC 3
>
>     WorkOrder A needs an engineer with skill ABC 3
>
>     WorkOrder B needs an engineer with skill ABC 1
>
>     WorkOrder C needs an engineer with skill ABC 2
>
>     The result should be this:
>
>     Engineer A will receive WorkOrder B
>
>     Engineer B will receive WorkOrder C
>
>     Engineer C will receive WorkOrder A
>
>     ---------------
>
>     I am able to sort it by time, but not by skill, and I don't know
>     how to loop over each list to find if one have the skills needed
>     to fulful the other. These are my classes involved:
>
>     WorkOrder attributes:
>
>     --------
>
>     private int requiredWorktime;
>
>     private Priority priority;(enum)
>
>     private Severity severity;(enum)
>
>     private List<SkillWorkOrder> requiredSkills;
>
>     --------
>
>     Engineer attributes:
>
>     --------
>
>     private int worktime;
>
>     private String name;
>
>     private List<SkillEngineer> skillEngineerList;
>
>     --------
>
>     Skill attributes:
>
>     --------
>
>     private String name;
>
>     --------
>
>     both SkillEngineer and SkillWorkOrder are classes that simple
>     receives the named class and a Skill:
>
>     Eg:
>
>     private Engineer engineer; //Or WorkOrder
>
>     private Skill skill;
>
>     Is it possible to iterate over these 2 lists, by drool rule, to
>     check wich engineer have most coincidences with an workorder? (Eg:
>     if and Engineer have skill ABC1, ABC2 and a WorkOrder needs an
>     engineer with skill ABC1, ABC2 and ABC3 he would be choseng among
>     the others because his skills)
>
>
>     _______________________________________________
>     rules-users mailing list
>     rules-users at lists.jboss.org <mailto:rules-users at lists.jboss.org>
>     https://lists.jboss.org/mailman/listinfo/rules-users
>
>
>
>
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20130221/a0b4cafb/attachment-0001.html 


More information about the rules-users mailing list