我开始使用optaplanner来做一个poc,我会想出一个问题。 我实现了硬约束,没关系。使用中等约束执行相同操作以处理可空的计划实体并且没关系。 但是,我添加了一个软约束,我对最佳解决方案不满意。让我解释一下。
没有软约束,我得分为0 / -2 / 0,它是根据数据集的最佳解决方案。当我实现软约束时,我得到0 / -8 / -13。但对我来说,我宁愿有0 / -2 / -700。
我该如何管理这种行为?如何最小化介质,然后注意柔软?
用真实的例子:
对我来说,我更喜欢分配每项服务(如果可能),而不是优化偏好日期和作业之间的差异。
下面是规则
//###########################################################################
// Medium constraints
//###########################################################################
rule "unassigned score"
when
accumulate( ServiceRequestAssignment(resource == null);
$cnt: count(1))
then
scoreHolder.addMediumConstraintMatch(kcontext, -toIntExact($cnt));
end
// ############################################################################
// Soft constraints
// ############################################################################
rule "dateDeviance"
when
$request : ServiceRequestAssignment(fixDate != true, $dateDeviance: dateDeviance);
then
scoreHolder.addSoftConstraintMatch(kcontext, -toIntExact($dateDeviance));
end
然后,配置:
<constructionHeuristic>
<constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType>
</constructionHeuristic>
<localSearch>
<unionMoveSelector>
<changeMoveSelector/>
<swapMoveSelector/>
</unionMoveSelector>
<acceptor>
<lateAcceptanceSize>600</lateAcceptanceSize>
</acceptor>
<forager>
<acceptedCountLimit>4</acceptedCountLimit>
</forager>
</localSearch>
感谢您的帮助。
答案 0 :(得分:1)
在一个步骤中,OptaPlanner总是更喜欢0/-2/-700
而不是0/-8/-13
,就像您想要的那样。
问题是,由于得分功能的变化,它会沿着另一条路走下去,并且它不能同时达到相同的分数。可能有两个原因
在任何情况下 - 不添加这些软评分规则不是推荐的方法。虽然这可以工作(首先在没有软约束的情况下解决它,然后再从上一个解决方案中再次解决它),这将是一个黑客。真正的,良好的,长期的解决方案是只添加它们,看看是否可以提高它们的效率,设置基准测试程序(现在只需几行)并找出可以获得哪种自定义移动您从0/-8/-13
到0/-7/-9999
。
答案 1 :(得分:0)
我认为你可以让规则获得更小的中等分数或获得更大的软分数。例如:
//###########################################################################
// Medium constraints
//###########################################################################
rule "unassigned score"
when
accumulate( ServiceRequestAssignment(resource == null);
$cnt: count(1))
then
scoreHolder.addMediumConstraintMatch(kcontext, -toIntExact($cnt)*100);
end
// ############################################################################
// Soft constraints
// ############################################################################
rule "dateDeviance"
when
$request : ServiceRequestAssignment(fixDate != true, $dateDeviance: dateDeviance);
then
scoreHolder.addSoftConstraintMatch(kcontext, -toIntExact($dateDeviance));
end
答案 2 :(得分:0)
根据杰弗里的评论,我再次检查了我的规则并发现问题是&#34; dateDeviance&#34;规则。 目前,我不知道如何编写规则以符合我的目标。但它似乎更多地与定义错误相关而不是瓶颈或陷入局部最优。
我想计算整个解决方案的全局日期偏差,并使用此值减少分数。我可以从Java方法计算这个分数,但是drools不是使用@PlanningSolution(ServiceAssignmentSolution.class)而是使用@PlanningEntity(ServiceRequestAssignment.class)。所以从一个举动来看,我目前无法计算这个值。
我尝试使用累积和求和:
rule "dateDeviance"
when
accumulate(ServiceRequestAssignment($dateDeviance : dateDeviance); $sum : sum($dateDeviance))
then
scoreHolder.addSoftConstraintMatch(kcontext, -$sum);
end
但是,得分与我的初始职位0 / -8 / -13完全相同。
我需要根据所有任务考虑最佳解决方案。 是否可以在drools文件中使用注释为@PlanningSolution的类?或者使用kcontext变量并检索这个变量以便以Java方式计算?