![](/img/trans.png)
[英]could std::sort with not strict weak ordering comparator work as topological sorting?
[英]Topological sorting using std::sort
注意:在寫這個問題時,我想我已經找到了答案。 隨意修改或附加更好的版本。 我認為記錄我的問題可能會很好。 編輯我錯了,我的aswer不正確。
考慮一個整數對列表:我想根據部分排序對它們進行拓撲排序。 這類似於偏序,與總數相比,足以構建堆? ,但我想使用std :: sort而不是std :: priority_queue。
為此,我寫了這段代碼:
#include <iostream>
#include <vector>
#include <algorithm>
struct pair {
int a, b;
pair(int a, int b) : a(a), b(b) {}
std::ostream &print(std::ostream &out) const {
return (out << "(" << a << ", " << b << ")");
}
};
std::ostream &operator<<(std::ostream &out, const pair &p) { return p.print(out); }
struct topological_pair_comparator {
bool operator()(const pair &p, const pair &q) const { return p.a<q.a && p.b<q.b; }
} tpc;
std::vector<pair> pairs = {
pair(1,1),
pair(1,2),
pair(2,1),
pair(3,1),
pair(1,3),
pair(5,5),
pair(2,2),
pair(4,0)
};
int main() {
std::sort(pairs.begin(), pairs.end(), tpc);
for(const pair &p : pairs) std::cout << p << " ";
std::cout << std::endl;
return 0;
}
資料來源: http : //ideone.com/CxOVO0
導致:
(1, 1) (1, 2) (2, 1) (3, 1) (1, 3) (2, 2) (4, 0) (5, 5)
這幾乎是拓撲排序的(通過示例證明;)。
但是,部分排序根據tpc創建了!((1,2)<(2,1))和!((1,2)>(2,1)),因此可以得出結論(1,2 )==(2,1)。 但是,c ++標准(2012年1月工作草案)第25.4.3段規定:
對於采用Compare的所有算法,都有一個使用operator <的版本。 也就是說,comp(* i,* j)!= false默認為* i <* j!= false。 對於25.4.3中描述的算法之外的算法,如果算法正常工作,comp必須對值進行嚴格的弱排序。
編輯:根據ecatmur的有效答案:部分排序不一定是嚴格的弱排序; 它打破了不可比性的傳遞性。 所以我想放棄我的推理,即部分排序總是嚴格的弱排序和相關的問題,並添加問題:我注定要編寫自己的拓撲排序算法或使用boost實現,這需要我構建圖形?
解決方案:一個關於ecatmur的聰明建議:
struct topological_pair_comparator {
bool operator()(const pair &p, const pair &q) const { return (p.a + p.b) < (q.a + q.b); }
} tpc;
資料來源: http : //ideone.com/uooxNC
請注意,有關堆的SO沒有明確提到std :: sort在拓撲上排序; 除了一條評論,沒有論證支持。
考慮價值觀
pair
x{0, 1},
y{2, 0},
z{1, 2};
這里,
!tpc(x, y) && !tpc(y, x);
!tpc(y, z) && !tpc(z, y);
然而,
tpc(x, z);
因此,您的比較器不會強制執行嚴格的弱排序,如果您將其與std::sort
一起使用,或者在需要嚴格弱排序的任何其他角色中,則行為未定義。
一個嚴格弱的比較器, 是比較器的改進,它將是:
struct refined_comparator {
bool operator()(const pair &p, const pair &q) const { return p.a + p.b < q.a + q.b; }
} rc;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.