使用计算值计算分数时分数损坏
Score corruption when using computed values to calculate score
我有一个用例:
- 一份工作可以有多种类型,A、B 和 C 说。
- 一个工具可以配置为一个类型:A、B 和 C
- 可以将作业分配给工具。作业的结束时间取决于当前配置的工具类型。如果工具当前配置的类型与作业的类型不同,则需要添加时间来更改当前工具配置。
我的@PlanningEntity是Allocation,startTime和工具是@PlanningVariable。我试图在 Allocation 中添加 currentConfiguredToolType 作为 @CustomShadowVariable 并更新 toolType 在 shadowListener 的 afterVariableChanged() 方法中,这样我就有了正确的 toolType 用于分配给工具的下一个作业.但是,它给了我不一致的结果。
[编辑]:我做了一些调试以查看 toolType 是否设置正确。我发现 toolType 在 afterVariableChanged() 方法中设置正确。但是,当我查看分配给该工具的下一个作业时,我发现 toolType 没有改变。是因为多线程在执行这个流程吗?一个线程第一次更改工具的 toolType,然后第二个线程同时第二次分配时间,而不考虑第一个线程所做的更改。
[编辑]:我之前使用的是 6.3.0 Final(直到昨天)。我今天切换到 6.5.0 Final。我也看到类似的结果,其中 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");
}
[编辑]:当我进行一些调试时,看起来机器中为一个分配设置的工具类型用于计算属于不同评估集的分配的类型更改时间。不确定如何避免这种情况。
如果情况确实如此,那么对项目状态影响所用时间的此类问题建模的好方法是什么?或者我完全离开了。我想我完全迷失在这里了。
[编辑]:这不是关于如何调用 Optaplanner 的问题,而是分数损坏,当添加了基于 endTime 对其进行惩罚的规则时。更多详情见评论。
[编辑]:我一一注释掉规则中指定的规则,发现只有当计算的分数取决于计算值时才会发生分数损坏:endTime
和 toolTypeChange
.当分数取决于 startTime
时,这是很好的,它是单独的 planningVariable
。但是,这并没有给我最好的结果。它给了我一个硬分数为负的解决方案,这意味着它违反了 rule
不在同一时间将同一工具分配给不同工作的规定。
计算值不能用于分数计算吗?
非常感谢任何帮助或指点。
最佳,
爱丽丝
ToolTypeVariableListener
似乎缺少 class 到 before/after
方法,这可能会导致分数损坏。打开 FULL_ASSERT
进行验证。
我有一个用例:
- 一份工作可以有多种类型,A、B 和 C 说。
- 一个工具可以配置为一个类型:A、B 和 C
- 可以将作业分配给工具。作业的结束时间取决于当前配置的工具类型。如果工具当前配置的类型与作业的类型不同,则需要添加时间来更改当前工具配置。
我的@PlanningEntity是Allocation,startTime和工具是@PlanningVariable。我试图在 Allocation 中添加 currentConfiguredToolType 作为 @CustomShadowVariable 并更新 toolType 在 shadowListener 的 afterVariableChanged() 方法中,这样我就有了正确的 toolType 用于分配给工具的下一个作业.但是,它给了我不一致的结果。
[编辑]:我做了一些调试以查看 toolType 是否设置正确。我发现 toolType 在 afterVariableChanged() 方法中设置正确。但是,当我查看分配给该工具的下一个作业时,我发现 toolType 没有改变。是因为多线程在执行这个流程吗?一个线程第一次更改工具的 toolType,然后第二个线程同时第二次分配时间,而不考虑第一个线程所做的更改。
[编辑]:我之前使用的是 6.3.0 Final(直到昨天)。我今天切换到 6.5.0 Final。我也看到类似的结果,其中 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");
}
[编辑]:当我进行一些调试时,看起来机器中为一个分配设置的工具类型用于计算属于不同评估集的分配的类型更改时间。不确定如何避免这种情况。
如果情况确实如此,那么对项目状态影响所用时间的此类问题建模的好方法是什么?或者我完全离开了。我想我完全迷失在这里了。
[编辑]:这不是关于如何调用 Optaplanner 的问题,而是分数损坏,当添加了基于 endTime 对其进行惩罚的规则时。更多详情见评论。
[编辑]:我一一注释掉规则中指定的规则,发现只有当计算的分数取决于计算值时才会发生分数损坏:endTime
和 toolTypeChange
.当分数取决于 startTime
时,这是很好的,它是单独的 planningVariable
。但是,这并没有给我最好的结果。它给了我一个硬分数为负的解决方案,这意味着它违反了 rule
不在同一时间将同一工具分配给不同工作的规定。
计算值不能用于分数计算吗?
非常感谢任何帮助或指点。
最佳,
爱丽丝
ToolTypeVariableListener
似乎缺少 class 到 before/after
方法,这可能会导致分数损坏。打开 FULL_ASSERT
进行验证。