如何使一个“与equals不一致”的TreeSet(How to have a TreeSet which is “inconsistent with equals”)
我已经阅读了很多关于TreeSet,Comparable / Comparator Interfaces,equals,compareTo,compare方法的帖子,我知道API说你必须让你的命令“与equals一致”或者可能发生奇怪的事情。
但在我的情况下,我认为这是一个相当普遍的情况,我确实需要一个“与equals不一致”的TreeSet排序。
假设我们正在进行某种启发式搜索,并且我们正在从根(初始)状态开始扩展(或生成)新状态。 我们将新的(扩展/生成)状态放入TreeSet中,我们通常称之为打开列表。 我们想使用TreeSet容器,因为我们不希望在打开的列表中有重复的状态。
生成/扩展的每个状态都由成本函数评估,并给出显示状态质量的启发式值。 我们想要按此值排序的TreeSet(打开列表)。 我们希望在TreeSet的顶部具有最佳状态(具有最佳成本值)。
现在问题来了。 为了适应成本值的排序,我们需要为TreeSet提供一个比较成本值的比较器。 但是,两个不同的状态可以具有相同的成本/启发式值。 我希望在我的公开名单上有这两种状态,因为它们并不“平等”。 但比较器需要从比较方法返回0,因为它们具有相同的成本值。 因此,具有相同成本值的不同状态将不会插入到列表中。
我想举一个简单的例子来说明这一点更容易理解。 假设我们的状态是显示二进制数据的字符串,而cost函数计算字符串中“1”的数量。
让我们说这些是生成的状态和它们各自的成本值。
No State Cost 1 01001001 3 2 01101001 4 3 10001001 3 4 01001111 5
正如您所看到的,这4个州都不同。 他们“不平等”。 但即使state-1和state-3不同,它们也具有相同的成本值“3”。 因此,当我们按成本订购TreeSet时,state-3将不会添加到TreeSet中,因为已经存在具有相同成本值的元素。 但是我们需要将该状态添加到列表中,因为它是完全有效的,不同的新状态。
我怎样才能克服这个问题?
谢谢。
I have read numerous posts about TreeSets, Comparable/Comparator Interfaces, equals, compareTo, compare methods and I know that API says you have to make your ordering "consistent with equals" or weird things might happen.
But in my case and I think this is a fairly general case, I really do need a TreeSet ordering which is "inconsistent with equals".
Lets say we are doing some kind of heuristic search and we are expanding (or generating) new states starting from a root(initial) state. And we put new (expanded/generated) states into a TreeSet which we usually call open list. We would like to use the TreeSet container because we dont want duplicate states in our open list.
Every state generated/expanded is evaluated by a cost function and given a heuristic value which shows the quality of the state. We want the TreeSet (open list) ordered by this value. We want to have the best states (which has the best cost value) at the top of the TreeSet.
Now here comes the problem. To accommodate the ordering by cost value we need to give the TreeSet a comparator which compares the cost values. But, two different states can have the same cost/heuristic value. I want to have both of these states on my open list because they are not "equal". But comparator needs to return 0 from the compare method because they have the same cost value. And because this, different states with the same cost value will not be inserted into the list.
I want to give a simple example to make this more understandable. Lets say our states are strings showing binary data and the cost function counts the number of "1"s in the string.
Lets say these are the generated states and their respective cost values.
No State Cost 1 01001001 3 2 01101001 4 3 10001001 3 4 01001111 5
As you can see all these 4 states are different. They are "not equal". But even though state-1 and state-3 are different, they have the same cost value "3". So when we order our TreeSet by cost, state-3 will not be added to the TreeSet because there is already an element with the same cost value. But we need that state to be added to the list because it is perfectly valid, different, new state.
How can I overcome this problem?
Thanks.
原文:https://stackoverflow.com/questions/26019123
最满意答案
for
表达式的最后一个子句在每次迭代中进行评估。 您可以在该空间中放置多个可变增量。for(int i=1; i<array.length; i++) { int checks = 1; // There is always one more check than iterations, the last check being the one which ends the iteration for (int j=i; (j>0) && (array[j]<(array[j-1])); j--, checks++) { Sort.swap(array, j, j-1); swaps++; } System.out.println(checks); }
The last clause of a
for
expression is evaluated every iteration. You can put more than one variable increment in that space.for(int i=1; i<array.length; i++) { int checks = 1; // There is always one more check than iterations, the last check being the one which ends the iteration for (int j=i; (j>0) && (array[j]<(array[j-1])); j--, checks++) { Sort.swap(array, j, j-1); swaps++; } System.out.println(checks); }
相关问答
更多-
按终止顺序打印?(Print in order of termination?)[2022-04-03]
您的代码按照您在接下来的waitpid()调用中提供的顺序等待pid。 如果您将waitpid()的第一个参数传递给-1 (或者如果您只是调用wait() ),那么您将得到内核通知您的第一个子进程,而不是您特别要求通知的那个子进程。 检查返回值以查看它是哪个孩子(或者如果发生错误)。 childid保持为0因为您正在从等待状态中提取WTERMSIG ,而不是WEXITSTATUS 。 Your code is waiting on the pids in the order you are providin ... -
//给人家作业答案对任何人都不好:\ 只需添加一个额外的总和变量并从循环中删除额外的++。 public class MyClass { public static void main(String args[]) { System.out.println(sumGenerator(100, 10)); // 450 } private static int sumGenerator(int termination, int increment) { int i = 0, sum ...
-
你的逻辑不在这里,因为i通过第一个维度和j到第二个维度:你真正想要的是什么 for(int i = 0; i < board.length; i++) { for(int j = 0; j < board[i].length; j++) { board[i][j] = '-'; } } 这个问题当然是在以下几行: for (int j = 0; j < board[j].length; j++) 您正在使用j作为板阵列第一维的索引,但将其定义为一个值,该值最大长度 ...
-
在循环中使用XPath表达式(Using XPath Expression in Loop)[2022-12-17]
你在错误的地方得到了报价,试试: String expression = "/templatedatabase/datatypes/integers/integer[" + index + "]/@defaultvalue"; 这将包括index参数的值到XPath表达式中,而不是文字字符串"index" 。 尽管如此 - 在处理像index这样的数字变量时,使用字符串连接动态构造XPath表达式是很好的,但如果要为表达式提供任意用户指定的字符串参数,则使用静态XPath表达式会更安全像XPath变量一样 ... -
我在你的问题中间的某个地方迷路了(如果我错误地解释了它,请告诉我,我会重新考虑它),但我认为这就是你所追求的: public static Expression ForEach(Expression collection, ParameterExpression loopVar, Expression loopContent) { var elementType = loopVar.Type; var enumerableType = typeof(IEnumerable<>).MakeGe ...
-
在VC ++ 6中,“for循环”的终止条件是否刷新?(Does the termination condition of a 'for loop' refresh in VC++ 6?)[2022-11-17]
为了清楚起见,不要在循环刷新任何东西方面考虑它。 每次检查条件时(在每次循环开始时),都会在stlVector变量上调用size()方法,并返回向量的当前大小。 erase()方法减小了向量的大小,因此下次调用size()时,返回的值将更小。 Just to be clear, don't think of it in terms of the loop refreshing anything. Every time the condition is checked (at the start of eac ... -
Ada任务和终止(Ada tasks and termination)[2022-08-03]
改进了诊断后,很明显在启动时,两个Select备选方案都没有立即可用,因此Queue任务直接进入Else部分,并在1秒延迟后等待接受Quit 。 同时主要任务是阻止它的第一个(无条件的,不定时的!) Push入口调用,以便它永远不会发出Quit入口调用。 结果:死锁。 解决方案(在Burns&Welling ,第108页中描述)只是将ELSE更改为OR以便第三个(延迟)选项仍然是Select选项。 然后在每次迭代中,将接受最早的(推,弹出或延迟)。 Having improved the diagnosti ... -
每次在for循环中检查终止表达式时递增int(Increment int each time the termination expression is checked in a for loop)[2023-01-23]
for表达式的最后一个子句在每次迭代中进行评估。 您可以在该空间中放置多个可变增量。 for(int i=1; i0) && (array[j]<(array[j-1])); ... -
那不会编译。 第二个参数不能有以逗号分隔的列表。 这将编译: for(int i=0, j=0; i<10 && j<14; i++, j=j+2){} That's not going to compile. You can't have a comma separated list for the second parameter. This will compile: for(int i=0, j=0; i<10 && j<14; i++, j=j+2){}
-
for循环总是可以转换为while循环,如下所示: for(initialization; condition; step) { block; } 至 initialization; while (condition) { block; step; } 因此,如果您的条件是i == upperBound ,则循环将永远不会运行,因为条件不会以true开头。 但是,<=会做你想做的事。 A for loop can always be translated to a while loop ...