我目前正试图掌握OptaPlanner,因为它似乎是我有个问题的完美解决方案。
基本上,项目作业调度示例就是我想要的,但由于我只知道我的Java基础知识,这是一种复杂的方法。因此,我试图从一个非常有限的例子开始,从这里开始我的工作:
我有一个持续时间和一个定义的前身的任务。计划实体是每个任务开始的时间。
我有一个很难的分数,那就是惩罚从它的前身的starttime+duration开始的任务。我也有一个软得分,试图缩小差距,保持整个过程尽可能短。
public HardSoftScore calculateScore(Schedule schedule) {
int hardScore = 0;
int softScore = 0;
for (Task task : schedule.getTaskList()) {
int endTime = task.getAllocation().getStartTime() + task.getDuration();
softScore = -endTime;
for (Task task2 : schedule.getTaskList()) {
if(task.getId()!=task2.getId()){
if( task2.getPredecessorId()==task.getId()) {
if (endTime > task2.getAllocation().getStartTime()) {
hardScore += task2.getAllocation().getStartTime() - endTime;
}
}
}
}
}
return HardSoftScore.valueOf(hardScore, softScore);
}这是解决程序的配置:
<?xml version="1.0" encoding="UTF-8"?>
<solver>
<!--<environmentMode>FAST_ASSERT</environmentMode>-->
<!-- Domain model configuration -->
<solutionClass>com.foo.scheduler.domain.Schedule</solutionClass>
<planningEntityClass>com.foo.scheduler.domain.Task</planningEntityClass>
<!-- Score configuration -->
<scoreDirectorFactory>
<scoreDefinitionType>HARD_SOFT</scoreDefinitionType>
<simpleScoreCalculatorClass>com.foo.scheduler.solver.score.SchedulingSimpleScoreCalculator</simpleScoreCalculatorClass>
</scoreDirectorFactory>
<!-- Optimization algorithms configuration -->
<termination>
<maximumSecondsSpend>100</maximumSecondsSpend>
</termination>
<constructionHeuristic>
<constructionHeuristicType>FIRST_FIT</constructionHeuristicType>
</constructionHeuristic>
<localSearch>
<acceptor>
<entityTabuSize>7</entityTabuSize>
</acceptor>
<forager>
<acceptedCountLimit>1000</acceptedCountLimit>
</forager>
</localSearch>
</solver>,问题是,只要我有困难的分数,这个效果就很好。但当然,它也有差距。一旦我把软分数加进去,每件事都会在大约10步后陷入困境。为什么?
[...]
2014-05-03 20:01:31,966 [main] DEBUG Step index (10), time spend (495), score (-35hard/-66soft), best score (-34hard/-68soft), accepted/selected move count (1000/19884) for picked step (com.foo.scheduler.domain.Task@35480096 => com.foo.scheduler.domain.Allocation@f9a4520).
2014-05-03 20:03:11,471 [main] DEBUG Step index (11), time spend (100000), score (-35hard/-65soft), best score (-34hard/-68soft), accepted/selected move count (0/105934687) for picked step (com.foo.scheduler.domain.Task@7050c91f => com.foo.scheduler.domain.Allocation@47c44bd4).发布于 2014-05-05 06:55:59
步骤11中的105934687的选定移动计数清楚地表明没有接受任何移动。不过,我看不出软分数怎么会触发这种局面。只有一个解释:
EntityTabuAcceptor不接受任何移动,因为它们都是tabu,这意味着每个移动的计划实体都在tabu列表中。如果您有非常小的数据集(14或较少的计划实体),这是可能的。打开跟踪日志,日志将确认这一点。这些解决方案中的每一个都应该解决这个问题:
<entityTabuRatio>而不是<entityTabuSize><entityTabuSize>的数据集大小处理SolverFactory.getSolverConfig()。不推荐!为什么少于14个规划实体?
因为默认情况下,您将得到一个<changeMoveSelector>和一个<swapMoveSelector>。<swapMoveSelector>交换2个实体,如果它赢了一步,就同时做两个tabu。tabu列表的大小是步骤的数量,所以如果7个交换移动在一行中赢得了步骤,那么tabu列表中可以有14个实体。
https://stackoverflow.com/questions/23448116
复制相似问题