OptaPlanner在引入新的问题事实时开始违反硬约束(并且表示硬分数为0)。

huangapple go评论72阅读模式
英文:

OptaPlanner starts violating hard constraints if I introduce a new problem fact (and says the hard score is 0)

问题

我对此非常困惑。即使ChatGPT也不确定出了什么问题。所以我需要求助于真正的专家。

我的项目可以在这里找到:https://github.com/matthewjd24/OptaPlanner-Scheduler

这段代码是从Hello world quick start中适配而来的。简而言之,我有一个作业车间调度问题,但没有'项目' - 每个作业只需要通过一台机器一次,然后就完成了。我的硬性和软性约束都正常工作,但如果我尝试添加一个新的问题事实/规划变量,它会开始破坏硬性约束,并表现得好像它没有(也就是说,结果解决方案中的硬性分数为0)。我会向您展示一些相关的代码片段:

这是我的规划解决方案类:

@PlanningSolution
public class TimeTable {

@ValueRangeProvider
@ProblemFactCollectionProperty
private List<Cycle> timeslotList;
@ValueRangeProvider
@ProblemFactCollectionProperty
private List<Machine> machineList;
@ValueRangeProvider
@ProblemFactCollectionProperty
private List<Mold> moldList;
@PlanningEntityCollectionProperty
private List<Job> lessonList;

@PlanningScore
private HardSoftScore score;

这是我的规划实体,Job类:

@PlanningEntity
public class Job {

@PlanningId
private Long id;

public String jobName;
public Integer width;
public Integer height;
public Integer weight;

@PlanningVariable(nullable = true)
private Cycle timeslot;
@PlanningVariable(nullable = true)
private Machine machine;
@PlanningVariable(nullable = true)
private Mold mold;

public Job() {
}

public Job(Long id, String jobName, Integer width, Integer height, Integer weight) {
    this.id = id;
    this.jobName = jobName;
    this.width = width;
    this.height = height;
    this.weight = weight;
}

我的约束是在两个作业具有相同的时间槽、相同的机器和不同的ID时施加硬性得分惩罚:

private Constraint machineProcessOneJobAtATime(ConstraintFactory constraintFactory) {
    return constraintFactory
        .forEach(Job.class)
        .join(Job.class,
            Joiners.equal(Job::getTimeslot),
            Joiners.equal(Job::getMachine),
            Joiners.lessThan(Job::getId))
        .penalize(HardSoftScore.ONE_HARD)
        .asConstraint("一次为一台机器安排多个作业");
}

如果我在规划解决方案中将moldList的@ValueRangeProvider和@ProblemFactCollectionProperty修饰符注释掉,并且在Job类中将@PlanningVariable(nullable = true)注释掉,约束将正常工作。但是一旦我将模具列表作为变量添加进去,OptaPlanner就会开始破坏这个硬性约束,并且说硬性分数为0(基本上表现得好像它没有违反约束)。有没有人知道为什么当添加了模具规划变量时,machineProcessOneJobAtATime会停止正常工作?我对此非常困惑。谢谢。

英文:

I'm very confused about this. Even ChatGPT is unsure of what's wrong. So I need to turn to the real experts.

My project can be found here: https://github.com/matthewjd24/OptaPlanner-Scheduler

This code has been adapted from the Hello world quick start. In summary, I have a job shop scheduling problem, but there are no 'projects' - each job just needs to pass through a machine once and it's done. My hard and soft constraints work fine, but if I attempt to add a new problem fact/planning variable, it starts breaking the hard constraints and acting like it hasn't (as in, the hard score in the resulting solution is 0). I'll show you some relevant snippets of code:

This is my Planning Solution class:

@PlanningSolution
public class TimeTable {

@ValueRangeProvider
@ProblemFactCollectionProperty
private List&lt;Cycle&gt; timeslotList;
@ValueRangeProvider
@ProblemFactCollectionProperty
private List&lt;Machine&gt; machineList;
@ValueRangeProvider
@ProblemFactCollectionProperty
private List&lt;Mold&gt; moldList;
@PlanningEntityCollectionProperty
private List&lt;Job&gt; lessonList;

@PlanningScore
private HardSoftScore score;

This is my Planning Entity, the Job class:

@PlanningEntity
public class Job {

@PlanningId
private Long id;

public String jobName;
public Integer width;
public Integer height;
public Integer weight;

@PlanningVariable(nullable = true)
private Cycle timeslot;
@PlanningVariable(nullable = true)
private Machine machine;
@PlanningVariable(nullable = true)
private Mold mold;

public Job() {
}

public Job(Long id, String jobName, Integer width, Integer height, Integer weight) {
    this.id = id;
    this.jobName = jobName;
    this.width = width;
    this.height = height;
    this.weight = weight;
}

My constraint that applies a hard score penalty when two jobs have the same timeslot, same machine, and different IDs:

private Constraint machineProcessOneJobAtATime(ConstraintFactory constraintFactory) {
    return constraintFactory
        .forEach(Job.class)
        .join(Job.class,
            Joiners.equal(Job::getTimeslot),
            Joiners.equal(Job::getMachine),
            Joiners.lessThan(Job::getId))
        .penalize(HardSoftScore.ONE_HARD)
        .asConstraint(&quot;Multiple jobs scheduled for a machine at once&quot;);
}

If I comment out the @ValueRangeProvider and @ProblemFactCollectionProperty modifiers for the moldList in the planning solution, and @PlanningVariable(nullable = true) in the Job class, the constraint works fine. But the moment I add in the mold list as a variable, OptaPlanner starts breaking this hard constraint and saying the hard score is 0 (essentially acting like it hasn't broken the constraint). I have no constraints set up that interact with the Mold variable. Does anyone know why the machineProcessOneJobAtATime would stop working properly when the Mold planning variable is added? I'm very confused about this. Thank you.

答案1

得分: 1

你所描述的情况听起来很像分数损坏。启用[FULL_ASSERT][1]来确认一下。一旦确认,通过排除法找出导致分数损坏的约束条件。(很少情况下是多个约束条件的组合,通常可以缩小到一个。)

一旦确定是哪一个,我们可以讨论原因。

英文:

What you're describing sounds a lot like a score corruption. Enable [FULL_ASSERT][1] to confirm that. Once confirmed, through a process of elimination, find the constraint which causes the score corruption. (Only rarely is it a combination of multiple constraints, it can usually be narrowed down to one.)

Once you know which one it is, we can discuss why.

huangapple
  • 本文由 发表于 2023年7月13日 23:50:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76681267.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定