编辑:为什么我认为这不是重复的:正如 biziclop 所写的那样,这里的问题不是不敏感(a>b & b>c => a>c)
,就像这里提到的其他问题一样,但是条款{{ 1}}被违反,所以它是一个不同的问题。
我收到以下错误消息:
a>b => -(b>a)
这就是它发生的地方:
Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(Unknown Source)
at java.util.TimSort.mergeAt(Unknown Source)
at java.util.TimSort.mergeForceCollapse(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at construct.Repair.regretRepair(Repair.java:101)
at lns.One.repaired(One.java:122)
at lns.One.segment(One.java:68)
at lns.One.lnsSolution(One.java:35)
at lns.All.lnsSolutions(All.java:22)
at barter.Genetic.initialPopulation(Genetic.java:36)
at barter.Genetic.run(Genetic.java:26)
at program.Main.main(Main.java:22)
这是定义RegretProfit对象的类:
Arrays.sort(regretProfits, new Comparator<RegretProfit>(){
@Override
public int compare(RegretProfit first, RegretProfit second){
if (first.possibleRoutes <= 0){
if (second.possibleRoutes > 0){
return 1;
}
return 0;
}
if (first.possibleRoutes < solution.schedule.size() - kay + 1){
if (first.possibleRoutes < second.possibleRoutes){
return -1;
}
if (first.possibleRoutes > second.possibleRoutes){
return 1;
}
if (first.profit > second.profit){
return -1;
}
if (first.profit < second.profit){
return 1;
}
}
if (first.regret > second.regret){
return -1;
}
if (first.regret < second.regret){
return 1;
}
return 0;
}
;});
错误仅在每几千次迭代中发生。如果有人知道问题可能是什么,我会非常感激。我已经读过,不和谐会引起这种异常,但我真的无法弄清楚我可能出错的地方。
解决了它,感谢 biziclop !
public class RegretProfit {
public int[] order;
public double regret;
public double profit;
public int possibleRoutes;
}
答案 0 :(得分:4)
传递性不是这里的关键问题,违反合同的部分是sgn(compare(x, y)) == -sgn(compare(y, x))
如果你有这些记录,例如:
first.possibleRoutes = -1; first.regret = 1
second.possibleRoutes = 1; second.regret = -1
您的比较器返回1.但如果您交换它们:
first.possibleRoutes = 1; first.regret = -1
second.possibleRoutes = -1; second.regret = 1
您的比较器仍可能返回1.
查看代码有两个可疑的非对称结构:
if (first.possibleRoutes <= 0){
if (second.possibleRoutes > 0){
return 1;
}
return 0;
}
如果first
和second
被撤销,那么这里没有匹配的-1返回。您还可以将possibleRoutes <= 0
的所有项目视为相等,这可能不是您想要的。
if (first.possibleRoutes < solution.schedule.size() - kay + 1){
在此输入一个纯粹基于first
值的分支,这意味着此分支也可能导致sgn(compare(x, y)) != -sgn(compare(y, x))
。
当然有可能在整个系统的额外限制下,两个问题相互抵消(显然他们不会在这种情况下),但它是设计比较器的一种非常脆弱的方式。我建议你确保所有分支都是对称的。它可以更容易地推断出代码的正确性。