Optaplanner异常:selectionList包含2次相同的选择

时间:2016-01-21 17:41:23

标签: java optaplanner

在构建我的问题实现后,运行Optaplanner时出现此问题:

java.lang.IllegalStateException: The selectionList contains 2 times the same selection (Edge to: MinMax1 from: s4,s5,) and (Edge to: Sum2 from: s3,s4,).
at org.optaplanner.core.impl.heuristic.selector.common.decorator.WeightFactorySelectionSorter.sort(WeightFactorySelectionSorter.java:58)
at org.optaplanner.core.impl.heuristic.selector.entity.decorator.SortingEntitySelector.constructCache(SortingEntitySelector.java:44)

我已在here中阅读了该问题,但没有任何对象null。我已修改了Entity类,即Edge,以实现AbstractPersistable,在此之前,我尝试覆盖equals()方法并获得相同的结果:

@PlanningEntity(difficultyWeightFactoryClass = EdgeDifficultyWeightFactory.class)
public class Edge extends AbstractPersistable{

/**
 * 
 */
private ArrayList<Node> from;
private Node to;
private double burstTime;


private BufferSize size;

public Edge(){
    from = new ArrayList<Node>();
    BufferSize p = new BufferSize();
    p.setSize(1);
    this.size = p;
            //new Random().nextInt(1000)+1;
    this.burstTime += this.size.getSize();
}

public void setFrom(Node from){
    this.from.add(from);
    this.calculateEdgeBurstTime();
}

public ArrayList<Node> getFrom(){
    return from;
}

public void setTo(Node to){
    this.to = to;
}

public Node getTo(){
    return to;
}

@PlanningVariable(valueRangeProviderRefs = {"bufferRange"})
public BufferSize getBufferSize(){
    return size;
}

public void setBufferSize(BufferSize size){
    this.size = size;
    System.out.println("Size has been set: "+size);
    this.calculateEdgeBurstTime();
}

public void calculateEdgeBurstTime(){
    for(Node node : this.from){
        this.burstTime+=this.size.getSize()*node.getNodeTime();
    }
}

public double getEdgeTime(){
    return burstTime;
}

@Override
public String toString(){
    StringBuffer sb = new StringBuffer();
    sb.append("Edge to: "+to.getID()+" from: ");
    for(Node node : this.from){
        sb.append(node.getID()+",");
    }
    return sb.toString();
}

@Override
public boolean equals(Object other){
    if (other == null) return false;
    if (other == this) return true;
    if (!(other instanceof Edge))return false;
    Edge otherMyClass = (Edge)other;
    boolean checkFrom = true;
    if(!(otherMyClass.getTo().getID().equals(this.getTo().getID()))) return false;
    for(Node node : otherMyClass.getFrom()){
        for(Node nd : this.getFrom()){
            if(!(node.getID().equals(nd.getID()))){
                checkFrom = false;
            }
        }
    }
    System.out.println("checked "+checkFrom+this.toString());
    return checkFrom;
}

@Override    
public int hashCode(){
    HashCodeBuilder builder = new HashCodeBuilder();
    builder.append(this.to.getID());
    builder.append(this.from);
    return builder.toHashCode();
}

}

为了更好地澄清问题,我的EdgeDifficultyWeight类以这种方式实现:

public class EdgeDifficultyWeightFactory implements SelectionSorterWeightFactory<SmartNodeGraph,Edge>{

public Comparable createSorterWeight(SmartNodeGraph graph, Edge edge) {

    int difficulty = edge.getFrom().size(); //Edges with more dependencies are more difficult to plan
    if(edge.getTo() instanceof NetworkNode){
        difficulty += difficulty; //Edges to NetworkNodes are more difficult to plan.
    }
    for(Node node : edge.getFrom()){
        if(node instanceof ProcessingNode){
            difficulty +=2; //If precedes form ProcessingNode is more difficult to optimise than sensors directly
        }else if(node instanceof SensorNode){
            difficulty +=1;
        }
    }
    return new EdgeDifficultyWeight(edge,difficulty);
}

public class EdgeDifficultyWeight implements Comparable<EdgeDifficultyWeight> {

    private final Edge edge;
    private final int difficulty;

    public EdgeDifficultyWeight(Edge edge, int difficulty){
        this.edge = edge;
        this.difficulty = difficulty;
    }

    public int compareTo(EdgeDifficultyWeight arg) {
        return new CompareToBuilder().append(arg.difficulty, this.difficulty).toComparison();
    }

    }

}

规划问题是这样的:我有几个独立的树结构,每棵树的根节点都有一个就绪时间,这取决于所有提供者节点。我想让所有根节点的时间相等,树的每个边都有一个缓冲区,可以修改它以改变父节点的时间。通过更改多个边缘中的缓冲区,我希望使所有树的根级别的时间相等。

关于解释,具有更多节点(以及其他约束)的边缘更难以分配。使用调试器,似乎问题在于这一行:

Comparable difficultyWeight = selectionSorterWeightFactory.createSorterWeight(solution, selection);

Comparable对象始终相同。

有人可以为此提供帮助吗?

1 个答案:

答案 0 :(得分:0)

.append(arg.edge.getId(), this.edge.getId())中添加EdgeDifficultyWeight,以区分具有不同边但具有相同难度的2个权重。

public class EdgeDifficultyWeight implements Comparable<EdgeDifficultyWeight> {

    private final Edge edge;
    private final int difficulty;

    public EdgeDifficultyWeight(Edge edge, int difficulty){
        this.edge = edge;
        this.difficulty = difficulty;
    }

    public int compareTo(EdgeDifficultyWeight arg) {
        return new CompareToBuilder()
                .append(arg.difficulty, this.difficulty)
                .append(arg.edge.getId(), this.edge.getId())
                .toComparison();
    }

}