当前位置: 首页 > 知识库问答 >
问题:

如何在Optaplanner中实现不确定评分规则?

公良鸿禧
2023-03-14

我正在使用Optaplanner开发一个系统,它类似于示例——会议调度。将一些任务分配给一些机器并确定开始时间。我创建了一个类——TaskAssignment作为规划实体,字段——“机器”和“开始时间谷物”作为规划变量。

但在我的用例中,会议调度中不存在约束,我不知道如何实现。在某些情况下,任务前端可能有准备时间。这意味着,TaskA和TaskB是同一台机器上的连续任务,TaskB在TaskA完成之前不会启动(TaskA是TaskB的前一个任务),并且这些任务之间可能有准备时间,这意味着TaskA完成后,TaskA必须等待一段时间才能启动,但等待的时间并不固定,这取决于其前一个任务。

Possibly like following:
TaskA -> TaskB: TaskB's preparation time is 5 mins.
TaskC -> TaskB: TaskB's preparation time is 15 mins.
TaskC -> TaskA: TaskA's preparation time is 0 min.

所以。我根据任务之前的任务(从列表中读取)获得任务的准备时间,并计算两个任务之间的间隔。如果间隔小于准备时间,间隔减去准备时间作为惩罚分数。当我运行计划时,规则通过分数损坏异常。我发现原因是间隔和准备时间都不确定。

对于间隔,它取决于前一个任务的结束时间和它自己任务的开始时间,开始时间是计划变量,所以它是不确定的。

对于准备时间,每个任务中都有一个准备时间列表,可用的准备时间取决于前一个任务,由于开始时间在规划过程中不断变化,因此准备时间也不断变化。所以准备时间也不确定。在这种情况下,有什么方法可以实现吗?非常感谢

这是我的规则,但分数腐败例外出现。

rule "Make sure interval large than preparation time"
salience 1
    when
        $currentTA : TaskAssignment(
            $machine: machine != null, 
            startingTimeGrain != null,
            $lack : getIntervalLack() < 0L // in getIntervalLack(), interval minus preparation time
            ) 
    then
            scoreHolder.addHardConstraintMatch(kcontext,  $lack);
end

异常消息:

Exception in thread "main" java.lang.IllegalStateException: Score corruption: the workingScore (-17hard/0medium/0soft) is not the uncorruptedScore (-20hard/0medium/0soft) after completedAction ([TaskAssignment-5 {Machine-1([023]) -> Machine-1([023])}, TaskAssignment-5 {TimeGrain-2 -> TimeGrain-2}]):
  The corrupted scoreDirector has no ConstraintMatch(s) which are in excess.
  The corrupted scoreDirector has 1 ConstraintMatch(s) which are missing:
    com.esquel.configuration/Make sure interval large than preparation time/[TaskAssignment-4]=-3hard/0medium/0soft
  Check your score constraints.
    at org.optaplanner.core.impl.score.director.AbstractScoreDirector.assertWorkingScoreFromScratch(AbstractScoreDirector.java:496)
    at org.optaplanner.core.impl.solver.scope.DefaultSolverScope.assertWorkingScoreFromScratch(DefaultSolverScope.java:132)
    at org.optaplanner.core.impl.phase.scope.AbstractPhaseScope.assertWorkingScoreFromScratch(AbstractPhaseScope.java:167)
    at org.optaplanner.core.impl.constructionheuristic.decider.ConstructionHeuristicDecider.processMove(ConstructionHeuristicDecider.java:140)
    at org.optaplanner.core.impl.constructionheuristic.decider.ConstructionHeuristicDecider.doMove(ConstructionHeuristicDecider.java:126)
    at org.optaplanner.core.impl.constructionheuristic.decider.ConstructionHeuristicDecider.decideNextStep(ConstructionHeuristicDecider.java:99)
    at org.optaplanner.core.impl.constructionheuristic.DefaultConstructionHeuristicPhase.solve(DefaultConstructionHeuristicPhase.java:74)
    at org.optaplanner.core.impl.solver.AbstractSolver.runPhases(AbstractSolver.java:87)
    at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:167)
    at com.esquel.main.App.startPlan(App.java:94)
    at com.esquel.main.App.main(App.java:43)

共有2个答案

童铭晨
2023-03-14

背景概述:一些订单被发送到生产车间,一个订单被流程路由按顺序拆分为多个任务。订单的任务必须按顺序执行。每个任务只能在特定的机器上执行。开始一项任务之前可能有准备时间,准备时间是否存在,以及准备时间的长短,取决于同一台机器上它前面的任务。以下是难以实施的主要约束:

Hard constraints:
1. A task must be executed by the particular machine.
2. Tasks in an order must be executed by a particular sequence (tasks of an order, come from the processes of the order, usually they need to be executed by different machine).
3. The first task of an order has the earliest start time. It means when the order arrived the production workshop.
4. Some tasks in an order maybe have a request start time, means if the previous task finish, the next task has to start in a period. For example, TaskA is the previous task of TaskB in the same order, TaskB has to start in 16 hours after TaskA finish.
5. A task probably has a preparation time, depends on its previous task of in the same machine(usually, the same process from different order were assigned to the same machine). If there is the preparation time on the task, the task has to start after the preparation time. In other words, there is an interval between these tasks.
Soft constraints:
1. All task should be executed as soon as possible.
2. Minimize the preparation time, due to the different location of the tasks lead to the different relationship of the tasks, then the preparation times are different. 

因此,在规划过程中,解决方案中有两条“链”。Optaplanner为同一台机器中的任务生成了一条链。另一个“链”来自订单,在这个“链”中,任务将分配给不同的机器。两个“链”挂在一起。

我将机器中的链(由Optaplanner生成)命名为“机器链”,将订单中的“链”命名为“订单链”。

现在,你可以看到,由于两个“链”被挂在一起,一个任务作为节点同时存在于机器链和订单链中。

我尝试了“时间链”模式,出现了不可移动的腐败。我认为原因是当我更新机器链中的一个任务时,同一机器链中的以下任务也会更新,这些任务是顺序链的节点,一个连锁反应爆发了。

我认为我的案例类似于示例-项目作业调度。但区别在于,本例中的两条“链”永远不会挂在一起。

所以,我尝试了简单的模式,但我无法逃脱分数腐败的例外。

向泽语
2023-03-14

如果是硬约束,我会将其内置并使用阴影变量:

我可能会预先计算任务的依赖关系,所以taskB有一个对它的potentioalPreceding任务的引用(在您的示例中是taskA和taskC)。然后我会使用“通过时间链接”模式(参见文档)来确定任务执行的顺序。根据该顺序,开始时间是一个影子变量,它是realalPrecedingTask.endingTime lookUpPreperationTime(前面的任务,这个任务)。请参阅VRP中的arrivalTime侦听器,相同的原理。

如果是软约束,我仍然会使用相同的阴影变量,但将其称为desiredStartingTime,并添加一个软约束,以检查实际的startingTime是否等于或高于desiredStartingTime。

 类似资料:
  • 08:00:59得分10*5=>50 08:01:00得分9*5=>45 似乎在08:00:59计算分数,在08H01:00进行分数验证 此外,我看到移动是从当前代理到当前代理。这样可以吗?

  • 我想用Optaplanner实现一个多目标优化,我已经阅读了文档中的“帕累托评分”章节。我在optaplanner中理解了多目标规划的原理,但实际上不知道如何实现,有很多疑问: > 如何设计一个自定义的分数定义类,它应该从哪个类扩展,它基本上应该有什么文件? 作为一个多目标规划,我要给用户提供多个解决方案。但是最好的解决方案只有一个,我怎么能在计划的同时保持不止一个解决方案呢?这是否意味着,在be

  • 我正在使用Optaplanner解决一个类似于病人入院调度示例的问题。 我面临两个问题。 首先,当一个规划实体(类似于示例中的bedDesignation)被某人(而不是optaplanner)定位时,该规划实体像其他实体一样被打分。手工放置的计划实体变为不可移动的计划实体,但仍被打分为可移动的计划实体。正因为如此,它打破了一些硬性的限制。 BedDesignationPillarPartSwap

  • 我正在尝试限制可以与特定实体关联的计划变量。在 OptaPlanner 手册的第 4.3.4.2.2 节中,显示了一个示例,但不清楚应该如何生成变量列表。列表应包含哪些内容?这些计划变量本身吗?它们可以是副本吗?如果允许复制,那么如何比较它们?如果不是,则在定义计划实体时计划变量不在范围内 - 我意识到这是一个 Java 问题,但如何从计划实体定义访问计划变量列表并不明显。 这是早期版本不支持的6

  • 在为我的项目实现了一些规则之后,我做了一个“ScoreConsistencyCheck”,以确保规则得到了正确的实现。 表示实现我自己的方法,该方法将在我提前终止求解或通过配置终止后调用,输出预期分数。该方法的参数是一个实例,基于解决方案的状态计算预期分数,然后将其与来自解决方案实例的“分数”变量的分数进行比较。 当我使用时,它不会抛出异常,但是当我这样尝试时,我有时会在构建启发式或本地搜索的特定