簡體   English   中英

設計Boost圖庫中的捆綁屬性

[英]Designing around bundled properties in the Boost Graph Library

我正在從Python(networkx)和C ++(BGL)中移植一些圖形代碼。 在我的Python代碼中,圖的頂點和邊是實現已建立接口的客戶端定義的對象; 我繼續在他們身上調用一堆方法。 一切都好。

天真地看來,BGL似乎是為了支持具有“捆綁屬性”的類似設計模式。 這些基本上允許通過傳遞某些模板參數來定義頂點和邊的自定義類型:

adjacency_list<OutEdgeList, VertexList,
               Directed, VertexProperties,
               EdgeProperties, GraphProperties,
               EdgeList>

此處的自定義頂點和邊緣類型由VertexPropertiesEdgeProperties

在這個端口上工作時我注意到一些事情讓我覺得BGL的捆綁屬性接口實際上只是為了支持(或多或少)不可變類型:

  • 邊和頂點“描述符”

    如果你把某些東西放到圖表中,你會得到一個“描述符”,你必須用它來從那里引用它。 有邊和頂點的描述符,它們是圖中的“鍵” - 實現為不可變的。 因此,如果您有一個頂點並且想要找到相鄰頂點,則必須(a)獲取當前頂點描述符,(b)使用BGL方法查找其鄰居的描述符,最后(c)引用每個鄰居通過各自的描述符。

    所有這些簿記的最終結果顯然需要額外的容器 - 例如std::map - 提供從頂點和邊緣(再次,類型VertexPropertyEdgeProperty )到其描述符的反向查找。

  • “BGL並不意味着存儲指針。”

    我在一個類似的SO問題中發現了這個主張,但是無法在任何地方的Boost文檔中對其進行驗證。 從隨后的討論中我可以推測,約束實際上可能更強一些:“BGL並不意味着直接引用堆。” 但是,這似乎並不完全合理,因為容器類型是可配置的( OutEdgeListVertexList ,上面)和默認標准的東西,如矢量。

我是一個BGL的n00b和我無法理解有什么打算捆綁特性。 (坦率地說,我覺得編程模型有點不知所措 - “屬性”,“概念”,“特征”,“描述符”, AHHHH! )問題:

  1. BGL圖是否有效地支持VertexPropertyEdgeProperty復雜和可能的堆綁定類型? 或者這些是不可變數據的輕量級容器?

  2. 如果是前者,有沒有辦法繞過所有描述符簿記?

  3. 如果是后者,處理大型復雜事物的“正確方法”是什么,我們可能想要堅持BGL圖?

  1. BGL圖是否有效地支持VertexProperty和EdgeProperty的復雜和可能的堆綁定類型? 或者這些是不可變數據的輕量級容器?

當然。 無論如何你都可以做到。 以防萬一:你可以讓bundle擁有一個(不可變的或可變的)指向堆分配的“復雜”類型的指針 - 當然 - 它是完全可變的。 現在,

我建議使用您首選的所有權適配器(unique_ptr,scoped_ptr,shared_ptr,什么不是)。 看看std::string :它也是“基於堆的”,但你不擔心在屬性包中使用它,是嗎?

  1. 如果是前者,有沒有辦法繞過所有描述符簿記?

沒有嚴格的“描述符簿記”。 可能取決於圖模型。 但一般來說,描述符實際上是底層容器迭代器模型的抽象 (不是說這可能是跨多個容器的迭代器,例如edges(EdgeListgraph) ,而不是adjacency_list<> out_edges(v, IncidenceGraph)

關鍵是要將邏輯與存儲模型的假設分離。 即使有一些非常難看的void*傳遞,編譯器也應該將其編譯為與直接迭代器訪問相同的代碼。 在這個意義上的“簿記”通常感性 ,你就可能在具有額外的概念層的心理負荷回升。

  1. 如果是后者,處理大型復雜事物的“正確方法”是什么,我們可能想要堅持BGL圖?

哎呀。 我想我在1下意外地解決了這個問題。使用的絕對最簡單的事情可能是refcounted sharing。 您的具體情況可能會提供更有效的解決方案。


CAPITA SELECTA

  • “BGL並不意味着存儲指針。”

好吧,也許不是捆綁。 即使在這里,它也完全取決於你如何管理指定者的所有權/生命周期。

我認為相關的答案非常好。 它與我上面所說的相矛盾。

  • 因此,如果您有一個頂點並且想要找到相鄰頂點,則必須(a)獲取當前頂點描述符,(b)使用BGL方法查找其鄰居的描述符,最后(c)引用每個鄰居通過各自的描述符。

大多數BGL算法依賴於vertex_index_t屬性的存在(或者需要指定一個屬性作為參數)以確保這些是低成本操作。 實際上,如果使用vecS則頂點索引是頂點向量的索引,因此反向和正向查找非常簡單。 (您始終可以查看生成的程序集,並啟用優化以查看是否有任何意外)。

這個答案可能是鼓舞人心的: Boost Graph Library:可以將Bundled Properties與Interior Properties結合起來嗎?


TL; DR /摘要

我有一種來自Python的感覺,你可能會在模板繁重的通用庫代碼中低估C ++優化編譯器。

當你在實踐中篩選通用機器的層次時,在編譯時蒸發了什么。 當然,這樣做的缺點是難以看清抽象。 但這也意味着功率和抽象級別不會受到影響。

BGL是一個庫,允許您切換到完全不同的圖形模型,存儲布局等,只需很少的代碼更改。 這里的目標不是“易用性”或“做我的意思”(使用Java或python)。

目標是通過將每個實現細節硬編碼到整個代碼庫中來選擇C ++ / not /刪除所有敏捷性。 相反,在圖書館概念層面工作,並從您保留的自由中受益,以便隨着需求的變化來嘗試/改變您的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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