簡體   English   中英

如何使用 BGL 計算邊緣介數

[英]How to calculate edge betweenness with BGL

根據這篇文章,我能夠編譯這段代碼。

Graph_type newGraph(edge_arrayNoDuplicates, edge_arrayNoDuplicates + numEdges, transmission_delay, numVertices);

boost::shared_array_property_map<double, boost::property_map<Graph_type, vertex_index_t>::const_type>
            edge_centrality_map(num_vertices(newGraph), get(boost::vertex_index, newGraph));
    brandes_betweenness_centrality(newGraph, edge_centrality_map);

我想獲得邊緣中心性 map 而不是中心性 map,我認為我正確地實現了這一點,但我不確定。 我希望從中得到的是能夠使用調用brandes_betweenness_centrality(newGraph, edge_centrality_map)的返回值並找到具有最高邊緣介數的邊緣,然后刪除該邊緣。 我不知道如何訪問調用brandes算法返回的值。 它甚至返回值嗎? 如果沒有,我如何訪問邊緣介數?

好的,我剛剛發布了簡化的圖形閱讀代碼

在您當前的問題中,我看到了新的edge_arrayNoDuplicates變量名稱,這表明您在一定程度上刪除了重復的邊緣。

作為一個專業提示,我建議您通過為邊緣容器選擇器選擇setS而不是vecS來獲得相同的效果,而無需任何手動操作

using Graph_type =
    boost::adjacency_list<boost::setS, boost::vecS, boost::bidirectionalS,
                          boost::no_property,
                          boost::property<boost::edge_weight_t, float>>;

改了兩個字母,就搞定了。 實際上,出於性能考慮,您可能仍希望保留vecS ,但您可能應該看到分析器告訴您的內容。 如果它足夠快,我不會打擾。


然后中介算法的代碼出現了一些問題。

boost::shared_array_property_map<
    double,
    boost::property_map<Graph_type, boost::vertex_index_t>::const_type>
    edge_centrality_map(num_vertices(g), get(boost::vertex_index, g));

首先,讓我們變得現代,避免重復類型信息:

auto edge_centrality_map = boost::make_shared_array_property_map(
    num_vertices(g), 1., get(boost::vertex_index, g));

接下來,它的問題是它使用頂點索引,你最多需要一個邊緣索引。 但讓我們先進一步看:

brandes_betweenness_centrality(g, edge_centrality_map);

您將edge_centrality_map作為單個 map 參數傳遞。 檢查文檔告訴我,唯一的 2 參數重載是

template<typename Graph, typename CentralityMap>
void
brandes_betweenness_centrality(const Graph& g, CentralityMap centrality_map);

因此,無論您如何命名變量,它都不會是 EdgeCentralityMap,而是(頂點)CentralityMap。 哎呀。 這可能就是為什么您在那里有vertex_index以使其完全編譯的原因。

我建議使用常規 map 而不是共享數組屬性 map:

std::map<Graph_type::edge_descriptor, double> edge_centralities;

這樣您就不必使用 edge_index 使用間接(您還沒有)。 您可以直接將其改編為屬性映射:

auto ecm = boost::make_assoc_property_map(edge_centralities);

然后您可以在算法中使用它。 為了避免必須提供某種中心性 map,我們可以使用命名參數重載:

brandes_betweenness_centrality(g, boost::edge_centrality_map(ecm));

要轉儲結果:

for (auto edge : boost::make_iterator_range(edges(g))) {
    auto s = invmap.at(source(edge, g));
    auto t = invmap.at(target(edge, g));
    std::cout << "Betweenness for " << s << "-" << t << " "
              << edge_centralities.at(edge) << "\n";
}

現場演示

Live On Coliru (數據源: put_data_here.txt

該示例使用更大的圖並顯示具有最高中心性的前 10 條邊:

int main() {
    Mappings mappings;
    Graph_type g = readInGraph("put_data_here.txt", mappings);

    using ECMap = std::map<Graph_type::edge_descriptor, double>;
    using ECEntry = ECMap::value_type;
    ECMap ecm;
    brandes_betweenness_centrality(
        g, boost::edge_centrality_map(boost::make_assoc_property_map(ecm)));

    std::vector<std::reference_wrapper<ECEntry>> ranking(ecm.begin(), ecm.end());

    {
        // top-n
        auto n = std::min(10ul, ranking.size());
        auto first = ranking.begin(), middle = first + n, last = ranking.end();
        std::partial_sort(
                first, middle, last,
                [](ECEntry const& a, ECEntry const& b) { return a.second > b.second; });

        ranking.erase(middle, last);
    }

    auto& edgenames = mappings.right;

    for (ECEntry const& entry : ranking) {
        auto [edge, centrality] = entry;
        auto s = edgenames.at(source(edge, g));
        auto t = edgenames.at(target(edge, g));
        std::cout << s << "-" << t << " centrality " << centrality << "\n";
    }
}

印刷

J-Q centrality 35.1
J-H centrality 20.5905
N-H centrality 18.0905
C-P centrality 16.1
H-B centrality 14.5571
P-S centrality 13.6024
J-C centrality 13.3833
H-E centrality 12.8905
Q-R centrality 12.6
L-G centrality 12.5333

暫無
暫無

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

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