如何让 OptaPlanner Construction Heuristics 使用不同的值?
How can i get OptaPlanner Construction Heuristics to use different values?
当我使用 Construction Heuristics 时,我总是将相同的值分配给我的 PlanningVariables,这导致了一个糟糕的初始解决方案。
我很确定我在这里犯了一个错误,但看不出我在哪里失败了。
我的问题描述:
我尝试将资源分配给工单。一个 WorkOrder 可以有多个 ResourceAssignments。此 ResourceAssignment 是我的主要 PlanningEntity。
资源是 PlanningVariable。
WorkOrders 也是 PlanningEntities,但此处仅需要该信息来表明我有多个 PlanningEntity,因此不能使用更简单的 ConstructionHeuristic 配置。
我使用实体中的值范围提供程序,因此我可以为不同类型的资源分配返回不同的资源集。 (例如人类、叉车、手持扫描仪……)
我的问题是 Construction Heuristic 似乎总是将相同的资源分配给所有 ResourceAssignment。
这是 CH 的输出 - 如您所见,相同的人力资源 (id 100) 被分配给两个 ResourceAssignments。这对于以下所有 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}).
它似乎忽略了所有其他动作 - 当然我有一个规则,以硬分数惩罚同时使用相同的资源。
这是我的解决方案配置。
<?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>
我确定我在这里错过了 optaplanner 的一些核心概念。对于正确方向的任何提示,我将不胜感激。
看起来您现在有 FIRST_FIT 的详细配置。改用 FIRST_FIT_DECREASING,通过声明难度比较并使用该构造启发式类型。
<constructionHeuristic>
<constructionHeuristicType>FIRST_FIT_DECREASING</>
</>
请参阅文档中有关首次拟合递减的章节。通常情况下,FFD 明显优于 FF(例如 CloudBalancing 平均 4%),但使用本地搜索可以改进该解决方案。
如果您真的要寻找随机的不同 CH 结果(例如对于 GeneticAlgorithm 种群),请使用 selectionOrder RANDOM 而不是 ORGINAL。
当我使用 Construction Heuristics 时,我总是将相同的值分配给我的 PlanningVariables,这导致了一个糟糕的初始解决方案。
我很确定我在这里犯了一个错误,但看不出我在哪里失败了。
我的问题描述:
我尝试将资源分配给工单。一个 WorkOrder 可以有多个 ResourceAssignments。此 ResourceAssignment 是我的主要 PlanningEntity。 资源是 PlanningVariable。 WorkOrders 也是 PlanningEntities,但此处仅需要该信息来表明我有多个 PlanningEntity,因此不能使用更简单的 ConstructionHeuristic 配置。
我使用实体中的值范围提供程序,因此我可以为不同类型的资源分配返回不同的资源集。 (例如人类、叉车、手持扫描仪……)
我的问题是 Construction Heuristic 似乎总是将相同的资源分配给所有 ResourceAssignment。
这是 CH 的输出 - 如您所见,相同的人力资源 (id 100) 被分配给两个 ResourceAssignments。这对于以下所有 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}).
它似乎忽略了所有其他动作 - 当然我有一个规则,以硬分数惩罚同时使用相同的资源。
这是我的解决方案配置。
<?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>
我确定我在这里错过了 optaplanner 的一些核心概念。对于正确方向的任何提示,我将不胜感激。
看起来您现在有 FIRST_FIT 的详细配置。改用 FIRST_FIT_DECREASING,通过声明难度比较并使用该构造启发式类型。
<constructionHeuristic>
<constructionHeuristicType>FIRST_FIT_DECREASING</>
</>
请参阅文档中有关首次拟合递减的章节。通常情况下,FFD 明显优于 FF(例如 CloudBalancing 平均 4%),但使用本地搜索可以改进该解决方案。
如果您真的要寻找随机的不同 CH 结果(例如对于 GeneticAlgorithm 种群),请使用 selectionOrder RANDOM 而不是 ORGINAL。