简体   繁体   English

TreeSet没有正确排序

[英]TreeSet not sorting properly

I need to keep a sorted list of nodes, starting from the first, which then gets us all the adjacent nodes. 我需要保留一个排序的节点列表,从第一个节点开始,然后获取所有相邻节点。 The first node, and all other nodes carry a seed value used to determine which node will be used next depending on the lowest seed value, once a node is used to get adjacent nodes it is marked as used, so it doesn't get expanded again even if it has the lowest seed. 第一个节点和所有其他节点携带一个种子值,用于确定接下来将使用哪个节点,具体取决于最低种子值,一旦使用一个节点获取它被标记为已使用的相邻节点,因此它不会被扩展即使它的种子最低也是如此。

My issue is that the used values seem to creep up to the top and halt the search entirely because after 3 iterations the top node will have been a used node that keeps expanding. 我的问题是使用的值似乎爬到顶部并完全停止搜索,因为在3次迭代后,顶部节点将是一个不断扩展的已使用节点。 here's my TreeSet code as well as an example of the numbers creeping up 这是我的TreeSet代码以及爬行数字的一个例子

private static TreeSet<Node> nodelist = new TreeSet<Node>(
        new Comparator<Node>() {
            @Override
            public int compare(Node o1, Node o2) {
                if (o1.totalVal > o2.totalVal) {
                    if (o2.isValid)
                        return +1;
                    else
                        return -1;
                } else if (o1.totalVal < o2.totalVal)
                    return -1;
                else
                    return 0;
            }
        });

here's the iterations of TreeSet after every set of inserts, everything after the fourth is identical to the fourth, as no new elements can ever read. 这是在每组插入之后TreeSet的迭代,第四组之后的所有内容都与第四组相同,因为没有新元素可以读取。

first set
true, 37.24913792078372
true, 38.12142238654117
true, 38.57602191449718
true, 38.57658845611187
true, 39.427369179869515
false, 36.6742416417845

second set
true, 37.84689665786984
false, 37.24913792078372
true, 38.12142238654117
true, 38.57602191449718
true, 38.57658845611187
true, 39.18376618407356
true, 39.427369179869515
false, 36.6742416417845

third set
true, 38.4682957019364
false, 37.84689665786984
false, 37.24913792078372
true, 38.12142238654117
true, 38.57602191449718
true, 38.57658845611187
true, 39.18376618407356
true, 39.427369179869515
true, 39.814763008775685
false, 36.6742416417845

fourth set
false, 38.4682957019364
false, 37.84689665786984
false, 37.24913792078372
true, 38.12142238654117
true, 38.57602191449718
true, 38.57658845611187
true, 38.590228543643214
true, 39.11409973215888
true, 39.18376618407356
true, 39.427369179869515
true, 39.814763008775685
true, 40.469726317012984
false, 36.6742416417845

so far I reasoned that it has to do with the tree structure, but can't really understand why it's doing this. 到目前为止,我推断它与树结构有关,但不能真正理解它为什么这样做。 I have tried using a similar approach with a priorityqueue, and sorted arraylist implementation and both did the same, albeit they would get about 2 more iterations before grinding to a halt. 我尝试过使用类似的方法和优先级,并对arraylist实现排序,两者都做了同样的事情,尽管他们在停止之前会再进行2次迭代。

any help? 任何帮助?

The contract for Comparator requires that comparison is stable - ie if compare(a,b) < 0 then compare(b,a) > 0 etc. It looks like you are not doing that. Comparator的合同要求比较是稳定的 - 即如果compare(a,b) < 0compare(b,a) > 0等。看起来你没有这样做。 I suspect you should test o1.isvalid in your else block somehow but there isn't enough code to be sure. 我怀疑你应该以某种方式测试你的else块中的o1.isvalid但是没有足够的代码来确定。

You may be better off with something more like: 你可能会更喜欢更喜欢的东西:

private static TreeSet<Node> nodelist = new TreeSet<Node>(
        new Comparator<Node>() {
            @Override
            public int compare(Node o1, Node o2) {
                if ( o1.isValid == o2.isValid ) {
                    // Both valid/invalid - it's the totals that control the order.
                    return o1.totalVal - o2.totalVal;
                } else {
                    // One valid, one not, move all invalids to one end.
                    return o1.isValid ? -1 : 1;
                }
            }
        });

You should probably avoid trying to write your own compare method, because they can be hard to reason about. 您应该避免尝试编写自己的比较方法,因为它们很难推理。 With Google Guava : 使用Google Guava

private static final TreeSet<Node> treeSet = new TreeSet<>(nodeOrdering);

Where nodeOrdering is defined as: 其中nodeOrdering定义为:

Comparator<Node> nodeOrdering = Ordering.natural()
    .onResultOf(isValidFunction)
    .compound(Ordering.natural().onResultOf(totalValueFunction));

isValidFunction is defined like this: isValidFunction的定义如下:

Function<Node, Boolean> isValidFunction = new Function<>() {
  @Override public Boolean apply(Node input) { return input.isValid; }
};

totalValueFunction is defined similarly: totalValueFunction的定义类似:

Function<Node, Double> totalValueFunction = new Function<>() {
  @Override public Double apply(Node input) { return input.totalVal; }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM