【问题标题】:How to calculate edge betweenness with BGL如何使用 BGL 计算边缘介数
【发布时间】:2021-07-08 00:41:54
【问题描述】:

根据this 的帖子,我能够编译此代码。

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);

我想要获得边缘中心图而不是中心图,我认为我正确地实现了这一点,但我不确定。 我希望从中得到的是能够使用调用brandes_betweenness_centrality(newGraph, edge_centrality_map) 的返回值并找到具有最高边缘介数的边缘,然后删除该边缘。我不知道如何访问调用brandes算法返回的值。它甚至返回值吗?如果不是,我如何访问边缘介数?

【问题讨论】:

  • “我认为我正确地实现了,但我不确定”我们不能这样做,因为我们看不到它
  • 您是否看到我对您在昨天发布答案之前删除的其他问题的解决方案?见side-by-side markdown diff

标签: c++ boost boost-graph


【解决方案1】:

好的,我只是posted the simplified graph reading code

在您当前的问题中,我看到了新的 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 作为单个映射参数传递。检查 the docs 告诉我唯一的 2 参数重载是

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

因此,无论您如何命名变量,它都不会是 EdgeCentralityMap,而是(顶点)CentralityMap。哎呀。这可能就是为什么你有 vertex_index 来让它编译的原因。

我建议使用常规映射而不是共享数组属性映射:

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

这样您就不必使用 edge_index 来使用间接(您还没有)。您可以直接将其改编为属性映射:

auto ecm = boost::make_assoc_property_map(edge_centralities);

然后您可以在算法中使用它。为了避免必须提供某种中心图,我们可以使用命名参数重载:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多