Drools I';因为一个奇怪的NullPointerException,我在我的项目上坚持了几个小时

Drools I';因为一个奇怪的NullPointerException,我在我的项目上坚持了几个小时,drools,optaplanner,Drools,Optaplanner,运行问题求解器时,我收到以下错误消息: Exception executing consequence for rule "addMarks" in com.abcdl.be.solver: [Error: getEndTime(): null] [Near : {... getEndTime() ....}] ... 消息说规则“addMarks”中的getEndTime()方法返回null。 这是drools文件: // #####################

运行问题求解器时,我收到以下错误消息:

    Exception executing consequence for rule "addMarks" in com.abcdl.be.solver: [Error: getEndTime(): null]
    [Near : {... getEndTime() ....}] 
...
消息说规则“addMarks”中的getEndTime()方法返回null。 这是drools文件:

    // ############################################################################
// Hard constraints
// ############################################################################

rule "RespectDependencies" // Respect all the dependencies in the input file

    when
        Dependency(respected() ==  false)
    then
        scoreHolder.addHardConstraintMatch(kcontext, 0, -1);

end

rule "addMarks" //insert a Mark each time a process chain starts or ends

    when
        Node($startTime : getStartTime(), $endTime : getEndTime())

    then
        insertLogical(new Mark($startTime));
        insertLogical(new Mark($endTime));

end

rule "resourcesLimit" // At any time, The number of resources used must not exceed the total number of resources available

    when
        Mark($startTime: time)
        Mark(time > $startTime, $endTime : time)
        not Mark(time > $startTime, time < $endTime)
        $total : Number(intValue > Global.getInstance().getAvailableResources() ) from  
            accumulate(Node(getEndTime() >=$endTime, getStartTime()<= $startTime, $res : resources), sum($res))
    then
            scoreHolder.addHardConstraintMatch(kcontext, 1,  (Global.getInstance().getAvailableResources() - $total.intValue()) * ($endTime - $startTime));             
end

rule "masterDataManagement"  // Parallel loading is forbidden

    when
        $n1 : Node(md != "", $md : md, $id : id)
        $n2 : Node(id > $id, md == $md)  // We make sure to check only different nodes through the condition "id > $id"
        eval(Graph.getInstance().getPaths($n1, $n2).size() == 0)

    then
        scoreHolder.addHardConstraintMatch(kcontext, 2, -1);    
end

// ############################################################################
// Soft constraints
// ############################################################################

rule "MaximizeResources" //Maximize use of available resources at any time

    when
        Mark($startTime: time)
        Mark(time > $startTime, $endTime : time)
        not Mark(time > $startTime, time < $endTime)
        $total : Number(intValue < Global.getInstance().getAvailableResources() ) from  
            accumulate(Node(getEndTime() >=$endTime, getStartTime()<= $startTime, $res : resources), sum($res))

    then
        scoreHolder.addHardConstraintMatch(kcontext, 0, ($total.intValue() - Global.getInstance().getAvailableResources()) * ($endTime - $startTime)); 
end 



rule "MinimizeTotalTime" // Minimize the total process time
    when
        Problem($totalTime : getTotalTime())
    then
        scoreHolder.addSoftConstraintMatch(kcontext, 1, -$totalTime);
end
//############################################################################
//硬约束
// ############################################################################
规则“尊重依赖项”//尊重输入文件中的所有依赖项
什么时候
依赖项(尊重()==false)
然后
记分员.addHardConstraintMatch(kcontext,0,-1);
结束
规则“添加标记”//每次流程链开始或结束时插入一个标记
什么时候
节点($startTime:getStartTime(),$endTime:getEndTime())
然后
insertLogical(新标记($startTime));
insertLogical(新标记($endTime));
结束
规则“resourcesLimit”//在任何时候,使用的资源数量不得超过可用资源的总数
什么时候
马克($startTime:time)
标记(时间>$startTime,$endTime:time)
不标记(时间>开始时间,时间<$结束时间)
$total:Number(intValue>Global.getInstance().getAvailableResources())来自
累积(Node(getEndTime()>=$endTime,getStartTime()$id,md==$md)//我们确保通过条件“id>$id”只检查不同的节点
eval(Graph.getInstance().getPath($n1,$n2).size()=0)
然后
记分员。添加硬约束匹配(kcontext,2,-1);
结束
// ############################################################################
//软约束
// ############################################################################
规则“最大化资源”//随时最大限度地利用可用资源
什么时候
马克($startTime:time)
标记(时间>$startTime,$endTime:time)
不标记(时间>开始时间,时间<$结束时间)
$total:Number(intValue累积(Node)(getEndTime()>=$endTime,getStartTime()您正在重载
Node.equals()
,但不是
Node.hashCode()

您正在使用map:Node to times(如果我相信您使用的名称的话)


这违反了在HashMap中将对象用作键的约定。

你说得对。我不知道hashcode()。非常感谢。
@PlanningEntity(difficultyComparatorClass = NodeDifficultyComparator.class)
        public class Node extends ProcessChain {

    private Node parent; // Planning variable: changes during planning, between score calculations

private int id; // Used as an identifier for each node. Different nodes cannot have the same id

public Node(String name, String type, int time, int resources, String md, int id)
{
    super(name, "", time, resources, "", type, md);
    this.delay = "";
    this.id = id;
}

public Node()
{
    super();
    this.delay = "";
}

@PlanningVariable(valueRangeProviderRefs = {"parentRange"}, nullable = false) 
public Node getParent() {
    return parent;
}

public void setParent(Node parent) {
    this.parent = parent;
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String toString()
{
    if(this.type.equals("AND"))
        return delay;
    if(!this.md.isEmpty())
        return Tools.excerpt(name+" : "+this.md);

     return Tools.excerpt(name);
}

public boolean equals( Object o ) {
    if (o == this)
        return true;

    if (o instanceof Node) {
        return  
            this.name.equals(((Node)o).name);  
    } else {
        return false;
    }
}
 // ************************************************************************
// Complex methods
// ************************************************************************

 public int getStartTime()
 {
    return Graph.getInstance().getNode2times().get(this).getFirst();        
 }


public int getEndTime()
{ 
    return  Graph.getInstance().getNode2times().get(this).getSecond();   
}

 @ValueRangeProvider(id = "parentRange")
 public Collection<Node> getPossibleParents()
 {  
     Collection<Node> nodes = Graph.getInstance().getNodes();
     nodes.remove(this); // We remove this node from the list
     nodes.remove(Graph.getInstance().getParents(this)); // We remove its parents from the list
     return nodes;
 }

/**
 * The normal methods {@link #equals(Object)} and {@link #hashCode()} cannot be used because the rule engine already
 * requires them (for performance in their original state).
 * @see #solutionHashCode()
 */
public boolean solutionEquals(Object o) {
    if (this == o) {
        return true;
    } else if (o instanceof Node) {
        Node other = (Node) o;
        return new EqualsBuilder()
                .append(name, other.name)
                .isEquals();
    } else {
        return false;
    }
}

/**
 * The normal methods {@link #equals(Object)} and {@link #hashCode()} cannot be used because the rule engine already
 * requires them (for performance in their original state).
 * @see #solutionEquals(Object)
 */
public int solutionHashCode() {
    return new HashCodeBuilder()
            .append(name)
            .toHashCode();
}
public class Graph {
 private ArrayList<Node> nodes;
...

 public void test()
{
   for(Node node : nodes)
    {
        int time = 0;
         try{
             time =  getNode2times().get(node).getFirst();
             System.out.print(node+"   :  "+"Start time  = "+time);
         }
         catch(NullPointerException e)
         {
             System.out.println("StartTime is null for node : " +node);
         }
         try{
         time = node.getEndTime();
         System.out.println("    End time = "+time);
     }
     catch(NullPointerException e)
     {
         System.out.println("EndTime is null for node : " +node);
     }

    }
}

...
}