Wolkenfels
Wolkenfels

Reputation: 43

How can i get OptaPlanner Construction Heuristics to use different values?

When i use the Construction Heuristics i always get the same values assigned to my PlanningVariables which leads to a bad initial solution.

I am quite sure i make an error here but cannot see where i fail.

My Problem Description:

I try to assign resources to WorkOrders. One WorkOrder can have several ResourceAssignments. This ResourceAssignment is my main PlanningEntity. The resource is the PlanningVariable. WorkOrders are also PlanningEntities but that information is only necessary here to show i have more than one PlanningEntity and therefore cannot go with the more simple ConstructionHeuristic configurations.

I use value range provider from entity so i can give back different sets of Resources for different types of ResourceAssignments. (e.g. Human, Forklift, Handscanner ...)

My problem is that the Construction Heuristic seems to assign always the same Resource to all ResourceAssignment.

Here is the output from the CH - as you can see the same Human Resource (id 100) is assigned to both ResourceAssignments. This is the same for all following PlanningEntities.

2015-07-23 10:57:12,291 [main] INFO  Solving started: time spent (185), best score (uninitialized/-9900hard/0soft), environment mode (FAST_ASSERT), random (JDK with seed 0).
2015-07-23 10:57:12,429 [main] DEBUG     CH step (0), time spent (325), score (-9900hard/0soft), selected move count (200), picked move (ResourceAssignment{id=0, workorder=WorkOrder{id=0, name=WO0, start=Thu Jul 23 12:57:11 CEST 2015, stop=Thu Jul 23 14:57:11 CEST 2015, offset=0}, resource=null, type=human} => Resource{type=human, id=100}).
2015-07-23 10:57:12,523 [main] DEBUG     CH step (1), time spent (419), score (-9900hard/0soft), selected move count (200), picked move (ResourceAssignment{id=1, workorder=WorkOrder{id=0, name=WO0, start=Thu Jul 23 12:57:11 CEST 2015, stop=Thu Jul 23 14:57:11 CEST 2015, offset=0}, resource=null, type=human} => Resource{type=human, id=100}).
2015-07-23 10:57:12,576 [main] DEBUG     CH step (2), time spent (472), score (-9900hard/0soft), selected move count (99), picked move (ResourceAssignment{id=2, workorder=WorkOrder{id=0, name=WO0, start=Thu Jul 23 12:57:11 CEST 2015, stop=Thu Jul 23 14:57:11 CEST 2015, offset=0}, resource=null, type=forklift} => Resource{type=forklift, id=0}).
2015-07-23 10:57:12,667 [main] DEBUG     CH step (3), time spent (563), score (-9900hard/0soft), selected move count (200), picked move (ResourceAssignment{id=3, workorder=WorkOrder{id=1, name=WO1, start=Thu Jul 23 12:57:11 CEST 2015, stop=Thu Jul 23 14:57:11 CEST 2015, offset=0}, resource=null, type=human} => Resource{type=human, id=100}).
2015-07-23 10:57:12,757 [main] DEBUG     CH step (4), time spent (653), score (-9900hard/0soft), selected move count (200), picked move (ResourceAssignment{id=4, workorder=WorkOrder{id=1, name=WO1, start=Thu Jul 23 12:57:11 CEST 2015, stop=Thu Jul 23 14:57:11 CEST 2015, offset=0}, resource=null, type=human} => Resource{type=human, id=100}).
2015-07-23 10:57:12,795 [main] DEBUG     CH step (5), time spent (691), score (-9900hard/0soft), selected move count (99), picked move (ResourceAssignment{id=5, workorder=WorkOrder{id=1, name=WO1, start=Thu Jul 23 12:57:11 CEST 2015, stop=Thu Jul 23 14:57:11 CEST 2015, offset=0}, resource=null, type=forklift} => Resource{type=forklift, id=0}).
2015-07-23 10:57:12,867 [main] DEBUG     CH step (6), time spent (763), score (-9900hard/0soft), selected move count (200), picked move (ResourceAssignment{id=6, workorder=WorkOrder{id=2, name=WO2, start=Thu Jul 23 12:57:11 CEST 2015, stop=Thu Jul 23 14:57:11 CEST 2015, offset=0}, resource=null, type=human} => Resource{type=human, id=100}).
2015-07-23 10:57:12,917 [main] DEBUG     CH step (7), time spent (813), score (-9900hard/0soft), selected move count (200), picked move (ResourceAssignment{id=7, workorder=WorkOrder{id=2, name=WO2, start=Thu Jul 23 12:57:11 CEST 2015, stop=Thu Jul 23 14:57:11 CEST 2015, offset=0}, resource=null, type=human} => Resource{type=human, id=100}).

It seems like it ignores all other moves - and of course i have a rule that punishes using the same resource at the same time with a hard score.

Here is my solution configuration.

<?xml version="1.0" encoding="UTF-8"?>
<solver>
  <environmentMode>FAST_ASSERT</environmentMode>
  <termination>
    <unimprovedSecondsSpentLimit>10000</unimprovedSecondsSpentLimit>
    <secondsSpentLimit>220000</secondsSpentLimit>
  </termination>

  <!-- Domain model configuration -->
  <solutionClass>com.opal.solver.resource.ResourceAssignmentSolution</solutionClass>
  <entityClass>com.opal.solver.resources.entity.ResourceAssignment</entityClass>
  <entityClass>com.opal.solver.resources.entity.WorkOrder</entityClass>
  <!-- Score configuration -->
  <scoreDirectorFactory>
    <scoreDefinitionType>HARD_SOFT</scoreDefinitionType>
    <scoreDrl>resourceAsssignmentRules.drl</scoreDrl>
  </scoreDirectorFactory>    
  <constructionHeuristic>
    <queuedEntityPlacer>
      <entitySelector id="placerEntitySelector">
        <cacheType>PHASE</cacheType>
        <entityClass>com.opal.solver.resources.entity.ResourceAssignment</entityClass>
      </entitySelector>
      <changeMoveSelector>
        <entitySelector mimicSelectorRef="placerEntitySelector"/>
        <valueSelector>
           <selectionOrder>ORIGINAL</selectionOrder>
          <variableName>resource</variableName>
        </valueSelector>
      </changeMoveSelector>
    </queuedEntityPlacer>
  </constructionHeuristic>
</solver>

I am sure I just miss some core concept of optaplanner here. I would be grateful for any hint into the right direction.

Upvotes: 1

Views: 838

Answers (1)

Geoffrey De Smet
Geoffrey De Smet

Reputation: 27312

Looks like you have a verbose configuration of FIRST_FIT right now. Use FIRST_FIT_DECREASING instead, by declaring difficulty comparison and using that construction heuristic type.

<constructionHeuristic>
  <constructionHeuristicType>FIRST_FIT_DECREASING</>
</>

See docs chapter on First Fit Decreasing. Normally, FFD is clearly better than FF (for example 4% on CloudBalancing on average), but use Local Search to improve upon that solution.

If you're really looking for random different CH results (for example for GeneticAlgorithm population) use selectionOrder RANDOM instead of ORGINAL.

Upvotes: 1

Related Questions