使用计算值计算得分时评分损坏

时间:2017-02-27 22:13:40

标签: drools optaplanner

我有一个用例:

  1. A,B和C表示,工作可以有多种类型。
  2. 可以将工具配置为类型:A,B和C
  3. 可以将作业分配给工具。作业的结束时间取决于当前配置的工具类型。如果工具的当前配置类型与作业类型不同,则需要添加时间来更改当前工具配置。
  4. 我的@ PlanningEntity 是分配,其中startTime和工具为@ PlanningVariable 。我尝试在 Allocation 中添加 currentConfiguredToolType 作为@ CustomShadowVariable ,并在shadowListener&#39中更新 toolType ; s afterVariableChanged ()方法,以便为分配给该工具的下一个作业提供正确的 toolType 。但是,它给了我不一致的结果。

    [编辑]:我做了一些调试,看看 toolType 是否设置正确。我发现在 afterVariableChanged ()方法中正确设置了 toolType 。但是,当我查看分配给该工具的下一个作业时,我发现 toolType 没有更改。是因为多个线程执行此流程?一个线程第一次更改工具的 toolType ,然后第二个线程同时第二次分配时间,而不考虑第一个线程所做的更改。

    [编辑]:我之前使用的是6.3.0决赛(直到昨天)。我今天转到6.5.0决赛。我也看到了类似的结果,其中toolType似乎在 afterVariableChanged ()方法中正确设置,但在该工具的下一次分配时没有考虑到。

    [编辑]:域代码如下所示:

    @PlanningEntity
    public class Allocation {
    
    private Job job;
    
    // planning variables
    private LocalDateTime startTime;
    private Tool tool;
    
     //shadow variable
     private ToolType toolType;
    
     private LocalDateTime endTime;
    
     @PlanningVariable(valueRangeProviderRefs = TOOL_RANGE)
     public Tool getTool() {
        return  this.tool;
     }
    
     @PlanningVariable(valueRangeProviderRefs = START_TIME_RANGE)
     public LocalDateTime getStartTime() {
        return this.startTime;
     }
    
     @CustomShadowVariable(variableListenerClass = ToolTypeVariableListener.class,
            sources = {@CustomShadowVariable.Source(variableName = "tool")})
     public ToolType getCurrentToolType() {
       return this.toolType;
     }
    
     private void setToolType(ToolType type) {
        this.toolType = type;
        this.tool.setToolType(type);
     } 
    
     private setStartTime(LocalDateTime startTime) {
        this.startTime = startTime;
        this.endTime = getTimeTakenForJob() + getTypeChangeTime();
        ...
     }
    
     private LocalDateTime getTypeChangeTime() {
     //typeChangeTimeMap is available and is populated with data
        return typeChangeTimeMap.get(tool.getType);
     }
    

    }

    public class Tool {
     ...
    private ToolType toolType;
    getter and setter for this.
    
    public void setToolType() { ...}
    
    public ToolType getToolType() { ...}
    
    }
    
    
    public class ToolTypeVariableListener implements VariableListener<Allocation> {
    ...
    @Override
    public void afterVariableChanged(ScoreDirector scoreDirector, Allocation entity) {
      scoreDirector.afterVariableChanged(entity, "currentToolType");
      if (entity.getTool() != null && entity.getStartTime() != null) {
         entity.setCurrentToolType(entity.getJob().getType());
      }
      scoreDirector.afterVariableChanged(entity, "currentToolType");
    }
    

    [编辑]:当我进行一些调试时,看起来机器中为一次分配设置的toolType用于计算属于不同评估集的分配的类型更改时间。不知道如何避免这种情况。

    如果情况确实如此,那么在项目状态影响所花费的时间的情况下,对这样的问题进行建模的好方法是什么?或者我完全离开了。我想我完全迷失了。

    [编辑]:这不是Optaplanner如何被调用的问题,而是在添加基于endTime惩罚它的规则时得分损坏。评论中的更多细节。

    [编辑]:我逐一评论了规则中指定的规则,并发现只有在计算的分数取决于计算值endTimetoolTypeChange时才会发生分数损坏。当得分取决于startTime时,这是合适的,planningVariable仅为rule。但是,这并没有给我最好的结果。它给了我一个具有负面硬分的解决方案,这意味着它违反了{{1}}不同时为不同的工作分配相同工具的{{1}}。 计算值不能用于分数计算吗?

    非常感谢任何帮助或指针。

    最好的,

    爱丽丝

1 个答案:

答案 0 :(得分:1)

ToolTypeVariableListener似乎缺少before/after方法的类,这会导致分数损坏。打开FULL_ASSERT进行验证。