タイプdoubleのクラスを考えてみましょう
class path_cost {
double length;
double time;
};
のリストを辞書式順序で注文したい場合path_costs
、問題があります。読む :)
私がそのように同等性テストに完全に等しいを使用する場合
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;
}
次に、<演算子が推移的ではなくなったため、並べ替えアルゴリズムがひどく失敗する可能性があります(つまり、a<bおよびb<cの場合、a <cは成り立たない可能性があります)
何か案は?ソリューション?実数直線を分割して、各パーティション内の数が等しいと見なされるようにすることを考えましたが、それでも、同等性テストが失敗するが、失敗しない場合が多すぎます。
(James Curranによる更新、うまくいけば問題を説明します):数字を考えると:
- 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 Mose Hansenによる更新)これは純粋に理論的なものではありません。非推移的なソート演算子を指定すると、標準のソートアルゴリズムがクラッシュするか、悪化する傾向があります。そして、これはまさに私が争っていたものです(そして男の子はデバッグするのがとても楽しかったです;))