好的,我只是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