2015-05-28 28 views
2

OptaPlanner事實可以包含計劃實體嗎?我的猜測是答案是否定的,因爲它會違反事實不能改變的規則。OptaPlanner的事實可以包括計劃實體對象嗎?

如果確實支持,我在嘗試調用getter方法時遇到空指針異常。

以下是規則,school1是Parings事實的私有變量,其中包含關聯的Planning Entity。

when 
 
     Run($r : runId) 
 
     Pairings(runId1 == $r, $s1 : school1.adjustment.timeAdjustment) ...

這裏的堆棧跟蹤。

Exception in thread "main" Exception executing consequence for rule "maximizeLiftPairings" in org.optaplanner.examples.cloudbalancing.solver: java.lang.RuntimeException: cannot invoke getter: getSchool1 [declr.class: org.optaplanner.examples.cloudbalancing.domain.Pairings; act.class: org.optaplanner.examples.cloudbalancing.domain.Pairings] (see trace) 
 
\t at org.drools.core.runtime.rule.impl.DefaultConsequenceExceptionHandler.handleException(DefaultConsequenceExceptionHandler.java:39) 
 
\t at org.drools.core.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1027) 
 
\t at org.drools.core.phreak.RuleExecutor.fire(RuleExecutor.java:128) 
 
\t at org.drools.core.phreak.RuleExecutor.evaluateNetworkAndFire(RuleExecutor.java:70) 
 
\t at org.drools.core.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:935) 
 
\t at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1200) 
 
\t at org.drools.core.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:957) 
 
\t at org.drools.core.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:931) 
 
\t at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:256) 
 
\t at org.optaplanner.core.impl.score.director.drools.DroolsScoreDirector.calculateScore(DroolsScoreDirector.java:98) 
 
\t at org.optaplanner.core.impl.solver.scope.DefaultSolverScope.calculateScore(DefaultSolverScope.java:101) 
 
\t at org.optaplanner.core.impl.bestsolution.BestSolutionRecaller.solvingStarted(BestSolutionRecaller.java:58) 
 
\t at org.optaplanner.core.impl.solver.DefaultSolver.solvingStarted(DefaultSolver.java:177) 
 
\t at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:154) 
 
\t at org.optaplanner.examples.cloudbalancing.app.CloudBalancingHelloWorld.main(CloudBalancingHelloWorld.java:56) 
 
Caused by: java.lang.RuntimeException: cannot invoke getter: getSchool1 [declr.class: org.optaplanner.examples.cloudbalancing.domain.Pairings; act.class: org.optaplanner.examples.cloudbalancing.domain.Pairings] (see trace) 
 
\t at org.mvel2.optimizers.impl.refl.nodes.GetterAccessor.getValue(GetterAccessor.java:74) 
 
\t at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:108) 
 
\t at org.mvel2.MVELRuntime.execute(MVELRuntime.java:86) 
 
\t at org.mvel2.compiler.CompiledExpression.getDirectValue(CompiledExpression.java:123) 
 
\t at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:119) 
 
\t at org.mvel2.MVEL.executeExpression(MVEL.java:954) 
 
\t at org.drools.core.base.extractors.MVELNumberClassFieldReader.getValue(MVELNumberClassFieldReader.java:102) 
 
\t at org.drools.core.rule.Declaration.getValue(Declaration.java:229) 
 
\t at org.optaplanner.examples.cloudbalancing.solver.Rule_maximizeLiftPairings143464364DefaultConsequenceInvokerGenerated.evaluate(Unknown Source) 
 
\t at org.optaplanner.examples.cloudbalancing.solver.Rule_maximizeLiftPairings143464364DefaultConsequenceInvoker.evaluate(Unknown Source) 
 
\t at org.drools.core.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1016) 
 
\t ... 13 more 
 
Caused by: java.lang.RuntimeException: unable to invoke method: org.optaplanner.examples.cloudbalancing.domain.School.getAdjustment: target of method is null 
 
\t at org.mvel2.optimizers.impl.refl.nodes.GetterAccessor.getValue(GetterAccessor.java:66) 
 
\t at org.mvel2.optimizers.impl.refl.nodes.GetterAccessor.getValue(GetterAccessor.java:40) 
 
\t ... 23 more 
 
Caused by: java.lang.NullPointerException 
 
\t at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source) 
 
\t at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
 
\t at java.lang.reflect.Method.invoke(Method.java:497) 
 
\t at org.mvel2.optimizers.impl.refl.nodes.GetterAccessor.getValue(GetterAccessor.java:40) 
 
\t ... 24 more

+0

你的堆棧跟蹤說空指針異常來自於它不能調用getAdjustment的事實。我猜「調整」是規劃實體? –

+0

其實,它是包含計劃實體的school1。看起來,這個問題已經有了一個答案,可以通過猜疑來證實。 – user2952819

+0

我看到了,難怪這被拋出:'java.lang.RuntimeException:無法調用getter:getSchool1' –

回答

0

這個答案是備案。布魯斯回答在本質上是:)

這是可能的更好,但在大多數情況下,但不建議。有一些陷阱。有兩種方法:

A)將問題事實類轉換爲影子計劃實體類。影子計劃實體類是隻有影子計劃變量的類(因此沒有真正的計劃變量)。當然,請確保在解算器配置中註冊該類並正確註釋它。但在這種情況下,它應該非常有效(包括計劃克隆等)。

B)破解它(不推薦!)。將它作爲一個問題事實類來保存,但是要自定義計劃克隆器以便克隆計劃(因爲它可能不會被克隆)。確保您首先清楚瞭解「規劃克隆」的含義(請參閱文檔)。它不是一個淺層克隆,它不是一個深層克隆,它是介於兩者之間的東西(邏輯取決於規劃註釋等)。這種破解將很難+正確實施(可能不是未來證明)的痛苦。

2

你的預感是正確的,答案是沒有

documentation

在OptaPlanner所有問題的事實和規劃實體是舊的JavaBeans(POJO的)。您可以從數據庫(JDBC/JPA/JDO),XML文件,數據存儲庫甚至noSQL雲中加載它們。 OptaPlanner不在乎。

規劃實體:

一個規劃實體是一個JavaBean(POJO)解決,例如改變到另一行女王期間變化。計劃問題有多個計劃實體,例如對於單個女王問題,每個女王是一個計劃實體。但通常只有1個計劃實體類,例如Queen類。

@PlanningEntity 
public class Queen { 


private Column column; 


// Planning variables: changes during planning, between score calculations. 

private Row row; 


// ... getters and setters 

} 

問題事實:

的問題其實是任何的JavaBean(POJO)的getter是不打算期間改變。推薦實現接口Serializable(但不是必需的)。例如,在N皇后,列和行是問題的事實:

public class Column implements Serializable { 


private int index; 


// ... getters 

} 
相關問題