C++ 如何用BGL计算边介数

C++ 如何用BGL计算边介数,c++,boost,boost-graph,C++,Boost,Boost Graph,基于这篇文章,我能够编译这段代码 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>

基于这篇文章,我能够编译这段代码

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);
Graph\u-type newGraph(边数组复制、边数组复制+微动、传输延迟、微动);
boost::共享数组属性映射
边中心映射(num_顶点(newGraph),get(boost::顶点索引,newGraph));
brandes_中间性_中心性(newGraph,edge_centrality_map);

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

好的,我只是

在您当前的问题中,我看到了新的
edge\u arraynodupplicates
变量名,这表明您在某种程度上删除了重复的边

作为专业提示,我建议您无需任何手动操作即可获得相同的效果,方法是为边缘容器选择器选择
set
而不是
vecS

using Graph_type =
    boost::adjacency_list<boost::setS, boost::vecS, boost::bidirectionalS,
                          boost::no_property,
                          boost::property<boost::edge_weight_t, float>>;
首先,让我们现代化,避免重复类型信息:

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\u centrality\u map
作为单个map参数传递。检查告诉我唯一的2参数重载是

template<typename Graph, typename CentralityMap>
void
brandes_betweenness_centrality(const Graph& g, CentralityMap centrality_map);
这样,您就不必使用使用edge_索引(您还没有)进行间接寻址。您可以直接将其调整为属性映射:

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";
}

我认为我正确地实现了这一点,但我不确定“我们不能这样做,因为我们看不到它。你看到我对你的另一个问题的解决方案了吗?你在我昨天发布答案之前删除了这个问题?”?见
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";
}
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