在构建我的问题实现后,运行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对象始终相同。
有人可以为此提供帮助吗?
答案 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();
}
}