Optaplanner 7.9.0和添加多线程:相同的planningId异常 [英] Optaplanner 7.9.0 and Adding Multithreading: same planningId exception

查看:74
本文介绍了Optaplanner 7.9.0和添加多线程:相同的planningId异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个optaplanner项目工作了一段时间,该项目正在使用所有用Java编写的各种评分属性将作业分配给工人列表.我对它的工作方式感到满意,因此我决定从7.7.0更新到7.9.0,然后打开新的多线程选项,看看它是否能更快地工作.但是,我现在收到以下错误:

I've had an optaplanner project working for a while now that is allocating jobs to a list of workers using various scoring properties all written in java. Happy with the way it was working I decided to update from 7.7.0 to 7.9.0 and turn on the new multithreading option and see if it works any faster. However, I now get the following error:

线程"Thread-8"中的异常java.lang.IllegalStateException:具有moveThreadIndex(0)的移动线程引发了异常.在父线程中中继到这里. 原因:java.lang.IllegalArgumentException:无法查找externalObject(... Worker @ 72d2327a). 也许给类(Worker类)一个PlanningId注释,或者更改PlanningSolution注释的LookUpStrategyType,或者不依赖依赖于ScoreDirector.lookUpWorkingObject()的功能.

Exception in thread "Thread-8" java.lang.IllegalStateException: The move thread with moveThreadIndex (0) has thrown an exception. Relayed here in the parent thread. Caused by: java.lang.IllegalArgumentException: The externalObject (...Worker@72d2327a) cannot be looked up. Maybe give the class (class Worker) a PlanningId annotation or change the PlanningSolution annotation's LookUpStrategyType or don't rely on functionality that depends on ScoreDirector.lookUpWorkingObject().

所以我尝试将@PlanningId添加到worker类的唯一标识符中,然后得到:

So I tried adding @PlanningId to the unique identifier of the worker class and I get:

线程"Thread-7"中的异常java.lang.IllegalStateException:workObjects(Worker @ 4438b624,Worker @ 4438b624)具有相同的planningId((类Worker,50)).工作对象必须是唯一的.

...但是看起来它正在将Worker对象与其自身进行比较,所以它的ID相同吗??

...but it looks like it's comparing a Worker object with itself, so of course it's the same id????

也许这取决于我的java代码中的assign/unassign方法,但是我不知道这个问题来自何处,有人有什么想法吗?

Perhaps this is down to my java code in the assign/unassign methods but I don't understand where this issue is coming from, anyone have any ideas?

修改: 因此,在@ n1ck的大量帮助下,我终于改变了@PlanningSolution类中的方法,该方法返回Workers列表以每次创建具有相同值的新实例.这会将错误更改为:'... workingObjects(Worker @ 1eba2b4d,Worker @ 67a7ef08)具有相同的planningId ...'将其与先前调用的实例进行比较.但是,这至少可以确认返回的每个列表都没有重复项.因此,然后我将计划ID更改为一个新的(Long)字段,其值始终从创建的最后一个实例开始增加,即首次调用的工作ID为1-10,下一次调用的ID为11-20,依此类推.这完全绕过了错误,但是现在没有任何东西分配给工人.它进行初始设置并分配空值,然后停止直到达到求解器的时间限制.我仍然认为这是我没有正确设置的事情,但错误可能有点像是鲱鱼,但是正如我所看到的,按照要求的完整堆栈跟踪信息是:

So after a lot of help from @n1ck I got as far as changing the method in the @PlanningSolution class that returns the list of Workers to create new instances each time but with the same values. This the changes the error to be : '...The workingObjects (Worker@1eba2b4d, Worker@67a7ef08) have the same planningId...' So it's no longer comparing identical instances but does seem to be comparing it to an instance from a previous call. This does however at least confirm there is no duplication per List returned. So I then changed the planning id to be a new (Long) field whose value is always incremented from the last instance created i.e. first call Worker ids are 1-10, next call 11-20 and so on. This bypasses the error altogether but now nothing gets allocated to the Workers. It does the initial set up and null assigns and then stops until the time limit on the solver is reached. I still think this is something I haven't set right but the error is possibly a bit of a red herring, however as requested the full stack trace as I can see it is:

线程"Thread-10"中的异常java.lang.IllegalStateException:workingObjects(Worker @ 42094cc1,Worker @ 647a1c5c)具有相同的planningId((Worker类,50)).工作对象必须是唯一的. 在org.optaplanner.core.impl.domain.lookup.PlanningIdLookUpStrategy.addWorkingObject(PlanningIdLookUpStrategy.java:40) 在org.optaplanner.core.impl.domain.lookup.LookUpManager.addWorkingObject(LookUpManager.java:49) 在org.optaplanner.core.impl.domain.lookup.LookUpManager.resetWorkingObjects(LookUpManager.java:43) 在org.optaplanner.core.impl.score.director.AbstractScoreDirector.setWorkingSolution(AbstractScoreDirector.java:167) 在org.optaplanner.core.impl.score.director.incremental.IncrementalScoreDirector.setWorkingSolution(IncrementalScoreDirector.java:62) 在org.optaplanner.core.impl.solver.scope.DefaultSolverScope.setWorkingSolutionFromBestSolution(DefaultSolverScope.java:230)处 在org.optaplanner.core.impl.solver.AbstractSolver.solvingStarted(AbstractSolver.java:75) 在org.optaplanner.core.impl.solver.DefaultSolver.solvingStarted(DefaultSolver.java:210) 在org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:190) 在SolverThread.run(SolverThread.java:86)

Exception in thread "Thread-10" java.lang.IllegalStateException: The workingObjects (Worker@42094cc1, Worker@647a1c5c) have the same planningId ((class Worker,50)). Working objects must be unique. at org.optaplanner.core.impl.domain.lookup.PlanningIdLookUpStrategy.addWorkingObject(PlanningIdLookUpStrategy.java:40) at org.optaplanner.core.impl.domain.lookup.LookUpManager.addWorkingObject(LookUpManager.java:49) at org.optaplanner.core.impl.domain.lookup.LookUpManager.resetWorkingObjects(LookUpManager.java:43) at org.optaplanner.core.impl.score.director.AbstractScoreDirector.setWorkingSolution(AbstractScoreDirector.java:167) at org.optaplanner.core.impl.score.director.incremental.IncrementalScoreDirector.setWorkingSolution(IncrementalScoreDirector.java:62) at org.optaplanner.core.impl.solver.scope.DefaultSolverScope.setWorkingSolutionFromBestSolution(DefaultSolverScope.java:230) at org.optaplanner.core.impl.solver.AbstractSolver.solvingStarted(AbstractSolver.java:75) at org.optaplanner.core.impl.solver.DefaultSolver.solvingStarted(DefaultSolver.java:210) at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:190) at SolverThread.run(SolverThread.java:86)

编辑:@PlanningSolution类,根据要求:

Edit: @PlanningSolution class as requested:

package code.test.scheduler;

import org.optaplanner.core.api.domain.solution.PlanningEntityCollectionProperty;
import org.optaplanner.core.api.domain.solution.PlanningScore;
import org.optaplanner.core.api.domain.solution.PlanningSolution;
import org.optaplanner.core.api.domain.solution.drools.ProblemFactCollectionProperty;
import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider;
import org.optaplanner.core.api.score.buildin.hardmediumsoft.HardMediumSoftScore;
import org.optaplanner.persistence.xstream.api.score.buildin.hardmediumsoft.HardMediumSoftScoreXStreamConverter;
import com.thoughtworks.xstream.annotations.XStreamConverter;

@PlanningSolution
public class Planner
{       
@ProblemFactCollectionProperty
private java.util.List<Worker> _workerList;
@ValueRangeProvider(id="workerRange")
@ProblemFactCollectionProperty
public java.util.List<Worker> getWorkerList() {
    return _workerList;
}
public void setWorkerList(java.util.List<Worker> newWorkerList) {
    _workerList = newWorkerList;
}
public int getWorkerListSize() {
    return _workerList.size();
}

@ProblemFactCollectionProperty
private int[][] _travelTimes;
@ValueRangeProvider(id="travelTimes")
@ProblemFactCollectionProperty
public int[][] getTravelTimes() {
    return _travelTimes;
}
public void setTravelTimes(int[][] newTravelTimes) {
    _travelTimes = newTravelTimes;
}

@PlanningEntityCollectionProperty
private java.util.List<Job> _jobList;
public java.util.List<Job> getJobList() {
    return _jobList;        
}
public void setJobList(java.util.List<Job> newJobList) {
    _jobList = newJobList;
}

@XStreamConverter(HardMediumSoftScoreXStreamConverter.class)
private HardMediumSoftScore _score;

@PlanningScore
public HardMediumSoftScore getScore() {
    return _score;
}

public void setScore(HardMediumSoftScore score) {
    _score = score;     
}
}

推荐答案

我认为您的PlanningEntityCollection中有一些重复的实体.您确定此列表中的所有Worker对象都是唯一的(例如,不是同一实例)?

I think you have some duplicate entities in your PlanningEntityCollection. Are you sure all Worker objects in this list are unique (as in, not the same instance)?

我故意在实体集合中复制了一个实体,并遇到了相同的错误.

I duplicated an entity in my entity collection on purpose, and got the same error.

编辑:事实证明,问题是在字段和getter上方声明了@ProblemFactCollectionProperty批注.仅应在一个或另一个之上声明它.结合使用@PlanningId批注在字段和getter上方声明它,将导致工作对象必须唯一"错误.

Edit: it turned out the issue was declaring the @ProblemFactCollectionProperty annotation above both the field and getter. It should only be declared above one or the other. Declaring it above both the field and getter, in conjunction with using the @PlanningId annotation, will result in the 'Working objects must be unique' error.

这篇关于Optaplanner 7.9.0和添加多线程:相同的planningId异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆