簡體   English   中英

使用std :: sort進行拓撲排序

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM