Так что у меня этот компаратор:Java компаратор: Нарушает Генподрядные
import java.util.Comparator;
public class SolutionComparator implements Comparator<ExpressionTree> {
private final int target;
public SolutionComparator(int target) {
this.target = target;
}
@Override
public int compare(ExpressionTree o1, ExpressionTree o2) {
int v1 = o1.getValue();
int v2 = o2.getValue();
if (v1 == -1 && v2 == -1)
return 0;
else if (v1 == -1)
return 1;
else if (v2 == -1)
return -1;
else if (v1 == v2)
return (int)Math.signum(solutionCost(o1) - solutionCost(o2));
else
return (int)Math.signum(Math.abs(target-v1) - Math.abs(target-v2));
}
private int solutionCost(ExpressionTree v) {
int cost = 0;
Operation o = v.getOperator();
if (o != Operation.NONE) {
cost += o.getCost();
for (ExpressionTree e : v.getChildren())
cost += solutionCost(e);
}
return cost;
}
}
Я смотрел на этот код в течение нескольких месяцев, и я не могу понять, почему он нарушает компаратор генподряд.
Идея состоит в том, что каждый ExpressionTree может быть оценен по одному результату. (метод getValue()
). Если он возвращает -1, он всегда выше другого. Если значение отличается, сравните с тем, насколько оно близко к target
. Если значение такое же, сравните стоимость решения.
С помощью этого компаратора Java бросает IllegalStatesException. Но если я удалю сравнение затрат, это сработает.
EDIT: Исключение трассировки
Exception in thread "Thread-3" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(TimSort.java:868)
at java.util.TimSort.mergeAt(TimSort.java:485)
at java.util.TimSort.mergeCollapse(TimSort.java:408)
at java.util.TimSort.sort(TimSort.java:214)
at java.util.TimSort.sort(TimSort.java:173)
at java.util.Arrays.sort(Arrays.java:659)
at java.util.Collections.sort(Collections.java:217)
at ***.run(***:123)
at java.lang.Thread.run(Thread.java:722)
Вы можете разместить весь след исключения? – iamnotmaynard
У меня была такая же проблема здесь некоторое время назад. Это равная проблема.Я попытаюсь вспомнить, что это такое, и ответить вам. –
Вопрос обновлен с помощью следа исключений. – innocenat