的字典序考虑如果我要为了字典序的path_costs
列表的类类型的双打多个双打
class path_cost {
double length;
double time;
};
,我有一个问题。请继续阅读:)
如果我使用确切的相等,等价测试,像这样
bool operator<(const path_cost& rhs) const {
if (length == rhs.length) return time < rhs.time;
return length < rhs.length;
}
产生的顺序很可能是错误的,因为一个小的偏差(例如,由于在的计算数值不准确长度)可能导致长度测试失败,例如
{ 231.00000000000001, 40 } < { 231.00000000000002, 10 }
错误地持有。
如果我替代地使用像这样
bool operator<(const path_cost& rhs) const {
if (std::fabs(length-rhs.length)<1-e6)) return time < rhs.time;
return length < rhs.length;
}
的公差,则排序算法可以可怕失败由于< - 运算符不再传递(即,如果一个< B和B < C,则一个< c可能不成立)
任何想法?解决方案?我曾考虑过划分实际行,以便每个分区内的数字都被认为是相等的,但这仍然会在平等测试失败但是不应该出现太多情况。
(由James柯伦,希望解释问题UPDATE): 给出的数字:
- A = {231.0000001200,10}
- B = {231.0000000500,40}
C = {231.0000000100,60}
- 则为a.length & b.length个通过7-E7不同,所以我们使用时间,和A < B.
- b.length个& C.Length由4-E7不同,所以我们使用时间,和B < C.
- 则为a.length & C.Length 1.1-E6不同,所以我们使用长度,A > C.
(由Esben摩西汉森更新) 这不是纯粹的理论。当给定非传递式排序算子时,标准排序算法往往会崩溃或更糟糕。这正是我一直在争论的(和男孩是有趣的调试;))
这实际上并不是一个坏主意,尽管很简单。需要做一些工作才能做到恰到好处,但这绝对是可以做到的。 – 2010-07-14 19:07:28