问题描述
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 算法返回的值。它甚至返回值吗?如果没有,我如何访问边缘介数?
解决方法
好的,我只是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.,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,而是 (Vertex)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