为什么调用 move.doMove(guiScoreDirector) 时 optaplanner 为空指针;
Why optaplanner null pointer when calling move.doMove(guiScoreDirector);
我的 optaplanner 网络应用程序有问题。此应用程序基于 vehiclerouting 演示网络示例。我想在课程时间表的 Web 示例中实现手动 doChangeMove 函数。我的代码(courseTimeTablingManager.java)如下:
public synchronized boolean solve(final String sessionId) {
//final Solver<CourseSchedule> solver = solverFactory.buildSolver();
Solver<CourseSchedule> solver;
if(sessionSolverMap.containsKey(sessionId)){
solver = sessionSolverMap.get(sessionId);
}else{
solver = solverFactory.buildSolver();
}
//solver = solverFactory.buildSolver();
solver.addEventListener(new SolverEventListener<CourseSchedule>() {
@Override
public void bestSolutionChanged(BestSolutionChangedEvent<CourseSchedule> event) {
CourseSchedule bestSolution = event.getNewBestSolution();
synchronized (CourseTimeTablingManager.this) {
sessionSolutionMap.put(sessionId, bestSolution);
}
}
});
if (sessionSolverMap.containsKey(sessionId)) {
return false;
}
sessionSolverMap.put(sessionId, solver);
final CourseSchedule solution = retrieveOrCreateSolution(sessionId, xml);
executor.submit(new Runnable() {
@Override
public void run() {
Solver<CourseSchedule> solver = sessionSolverMap.get(sessionId);
CourseSchedule bestSolution = solver.solve(solution);
synchronized (CourseTimeTablingManager.this) {
sessionSolutionMap.put(sessionId, bestSolution);
//sessionSolverMap.remove(sessionId);
}
}
});
return true;
}
public synchronized boolean terminateEarly(String sessionId) {
//Solver<CourseSchedule> solver = sessionSolverMap.remove(sessionId);
Solver<CourseSchedule> solver = sessionSolverMap.get(sessionId);
if (solver != null) {
solver.terminateEarly();
return true;
} else {
return false;
}
}
public synchronized ChangeMove createChangeMove(Object entity, String variableName, Object toPlanningValue, String sessionId) {
// TODO Solver should support building a ChangeMove
Solver<CourseSchedule> solver = sessionSolverMap.get(sessionId);
ScoreDirectorFactory scoreDirectorFactory = solver.getScoreDirectorFactory();
guiScoreDirector = scoreDirectorFactory.buildScoreDirector();
InnerScoreDirector guiInnerScoreDirector = (InnerScoreDirector) this.guiScoreDirector;
SolutionDescriptor solutionDescriptor = guiInnerScoreDirector.getSolutionDescriptor();
GenuineVariableDescriptor variableDescriptor = solutionDescriptor.findGenuineVariableDescriptorOrFail(
entity, variableName);
if (variableDescriptor.isChained()) {
SupplyManager supplyManager = guiInnerScoreDirector.getSupplyManager();
SingletonInverseVariableSupply inverseVariableSupply = supplyManager.demand(
new SingletonInverseVariableDemand(variableDescriptor));
return new ChainedChangeMove(entity, variableDescriptor, inverseVariableSupply, toPlanningValue);
} else {
return new ChangeMove(entity, variableDescriptor, toPlanningValue);
}
}
public synchronized void doChangeMove(Object entity, String variableName, Object toPlanningValue, String sessionId) {
ChangeMove move = createChangeMove(entity, variableName, toPlanningValue, sessionId);
doMove(move, sessionId);
}
public synchronized void doMove(Move move, String sessionId) {
Solver<CourseSchedule> solver = sessionSolverMap.get(sessionId);
if (solver.isSolving()) {
//logger.error("Not doing user move ({}) because the solver is solving.", move);
System.out.println("!!!!!!!!!!!!!!!!!! Not doing user move ({}) because the solver is solving.");
return;
}
if (!move.isMoveDoable(guiScoreDirector)) {
System.out.println("################## Not doing user move ({}) because it is not doable.");
return;
}
//System.out.println("------------------ doing user move ({}) .");
move.doMove(guiScoreDirector); // <----- Here, crash with NULL pointer!!
System.out.println("------------------ doing user move done ({}), try update score ... .");
guiScoreDirector.calculateScore();
}
每次我 运行 应用程序,它都会在函数 doMove 的 move.doMove(guiScoreDirector) 处崩溃。例外是:
Caused by: java.lang.NullPointerException
at org.optaplanner.core.impl.score.director.drools.DroolsScoreDirector.update(DroolsScoreDirector.java:157)
at org.optaplanner.core.impl.score.director.drools.DroolsScoreDirector.afterVariableChanged(DroolsScoreDirector.java:152)
at org.optaplanner.core.impl.heuristic.selector.move.generic.ChangeMove.doMoveOnGenuineVariables(ChangeMove.java:69)
at org.optaplanner.core.impl.heuristic.move.AbstractMove.doMove(AbstractMove.java:34)
at org.optaplanner.webexamples.tt.rest.cdi.CourseTimeTablingManager.doMove(CourseTimeTablingManager.java:232)
at org.optaplanner.webexamples.tt.rest.cdi.CourseTimeTablingManager.doChangeMove(CourseTimeTablingManager.java:217)
at org.optaplanner.webexamples.tt.rest.cdi.CourseTimeTablingManager$Proxy$_$$_WeldClientProxy.doChangeMove(Unknown Source)
at org.optaplanner.webexamples.tt.rest.service.DefaultCourseTimeTablingRestService.move(DefaultCourseTimeTablingRestService.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:137)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:296)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:250)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:237)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:356)
... 32 more
有人可以帮忙吗?提前致谢!
我假设实体(讲座?)为空。通过为 NullPointerException 添加调试断点来验证这一点。
注意:一旦 SolverManager 存在,您就不再需要大部分 courseTimeTablingManager。
我的 optaplanner 网络应用程序有问题。此应用程序基于 vehiclerouting 演示网络示例。我想在课程时间表的 Web 示例中实现手动 doChangeMove 函数。我的代码(courseTimeTablingManager.java)如下:
public synchronized boolean solve(final String sessionId) {
//final Solver<CourseSchedule> solver = solverFactory.buildSolver();
Solver<CourseSchedule> solver;
if(sessionSolverMap.containsKey(sessionId)){
solver = sessionSolverMap.get(sessionId);
}else{
solver = solverFactory.buildSolver();
}
//solver = solverFactory.buildSolver();
solver.addEventListener(new SolverEventListener<CourseSchedule>() {
@Override
public void bestSolutionChanged(BestSolutionChangedEvent<CourseSchedule> event) {
CourseSchedule bestSolution = event.getNewBestSolution();
synchronized (CourseTimeTablingManager.this) {
sessionSolutionMap.put(sessionId, bestSolution);
}
}
});
if (sessionSolverMap.containsKey(sessionId)) {
return false;
}
sessionSolverMap.put(sessionId, solver);
final CourseSchedule solution = retrieveOrCreateSolution(sessionId, xml);
executor.submit(new Runnable() {
@Override
public void run() {
Solver<CourseSchedule> solver = sessionSolverMap.get(sessionId);
CourseSchedule bestSolution = solver.solve(solution);
synchronized (CourseTimeTablingManager.this) {
sessionSolutionMap.put(sessionId, bestSolution);
//sessionSolverMap.remove(sessionId);
}
}
});
return true;
}
public synchronized boolean terminateEarly(String sessionId) {
//Solver<CourseSchedule> solver = sessionSolverMap.remove(sessionId);
Solver<CourseSchedule> solver = sessionSolverMap.get(sessionId);
if (solver != null) {
solver.terminateEarly();
return true;
} else {
return false;
}
}
public synchronized ChangeMove createChangeMove(Object entity, String variableName, Object toPlanningValue, String sessionId) {
// TODO Solver should support building a ChangeMove
Solver<CourseSchedule> solver = sessionSolverMap.get(sessionId);
ScoreDirectorFactory scoreDirectorFactory = solver.getScoreDirectorFactory();
guiScoreDirector = scoreDirectorFactory.buildScoreDirector();
InnerScoreDirector guiInnerScoreDirector = (InnerScoreDirector) this.guiScoreDirector;
SolutionDescriptor solutionDescriptor = guiInnerScoreDirector.getSolutionDescriptor();
GenuineVariableDescriptor variableDescriptor = solutionDescriptor.findGenuineVariableDescriptorOrFail(
entity, variableName);
if (variableDescriptor.isChained()) {
SupplyManager supplyManager = guiInnerScoreDirector.getSupplyManager();
SingletonInverseVariableSupply inverseVariableSupply = supplyManager.demand(
new SingletonInverseVariableDemand(variableDescriptor));
return new ChainedChangeMove(entity, variableDescriptor, inverseVariableSupply, toPlanningValue);
} else {
return new ChangeMove(entity, variableDescriptor, toPlanningValue);
}
}
public synchronized void doChangeMove(Object entity, String variableName, Object toPlanningValue, String sessionId) {
ChangeMove move = createChangeMove(entity, variableName, toPlanningValue, sessionId);
doMove(move, sessionId);
}
public synchronized void doMove(Move move, String sessionId) {
Solver<CourseSchedule> solver = sessionSolverMap.get(sessionId);
if (solver.isSolving()) {
//logger.error("Not doing user move ({}) because the solver is solving.", move);
System.out.println("!!!!!!!!!!!!!!!!!! Not doing user move ({}) because the solver is solving.");
return;
}
if (!move.isMoveDoable(guiScoreDirector)) {
System.out.println("################## Not doing user move ({}) because it is not doable.");
return;
}
//System.out.println("------------------ doing user move ({}) .");
move.doMove(guiScoreDirector); // <----- Here, crash with NULL pointer!!
System.out.println("------------------ doing user move done ({}), try update score ... .");
guiScoreDirector.calculateScore();
}
每次我 运行 应用程序,它都会在函数 doMove 的 move.doMove(guiScoreDirector) 处崩溃。例外是:
Caused by: java.lang.NullPointerException
at org.optaplanner.core.impl.score.director.drools.DroolsScoreDirector.update(DroolsScoreDirector.java:157)
at org.optaplanner.core.impl.score.director.drools.DroolsScoreDirector.afterVariableChanged(DroolsScoreDirector.java:152)
at org.optaplanner.core.impl.heuristic.selector.move.generic.ChangeMove.doMoveOnGenuineVariables(ChangeMove.java:69)
at org.optaplanner.core.impl.heuristic.move.AbstractMove.doMove(AbstractMove.java:34)
at org.optaplanner.webexamples.tt.rest.cdi.CourseTimeTablingManager.doMove(CourseTimeTablingManager.java:232)
at org.optaplanner.webexamples.tt.rest.cdi.CourseTimeTablingManager.doChangeMove(CourseTimeTablingManager.java:217)
at org.optaplanner.webexamples.tt.rest.cdi.CourseTimeTablingManager$Proxy$_$$_WeldClientProxy.doChangeMove(Unknown Source)
at org.optaplanner.webexamples.tt.rest.service.DefaultCourseTimeTablingRestService.move(DefaultCourseTimeTablingRestService.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:137)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:296)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:250)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:237)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:356)
... 32 more
有人可以帮忙吗?提前致谢!
我假设实体(讲座?)为空。通过为 NullPointerException 添加调试断点来验证这一点。
注意:一旦 SolverManager 存在,您就不再需要大部分 courseTimeTablingManager。