betweenness_centrality_test.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 520 行 · 第 1/2 页
CPP
520 行
template<typename Graph, typename VertexIndexMap, typename CentralityMap>void simple_unweighted_betweenness_centrality(const Graph& g, VertexIndexMap index, CentralityMap centrality){ typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex; typedef typename boost::graph_traits<Graph>::vertex_iterator vertex_iterator; typedef typename boost::graph_traits<Graph>::adjacency_iterator adjacency_iterator; typedef typename boost::graph_traits<Graph>::vertices_size_type vertices_size_type; typedef typename boost::property_traits<CentralityMap>::value_type centrality_type; vertex_iterator vi, vi_end; for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) put(centrality, *vi, 0); vertex_iterator si, si_end; for (tie(si, si_end) = vertices(g); si != si_end; ++si) { vertex s = *si; // S <-- empty stack std::stack<vertex> S; // P[w] <-- empty list, w \in V typedef std::vector<vertex> Predecessors; std::vector<Predecessors> predecessors(num_vertices(g)); // sigma[t] <-- 0, t \in V std::vector<vertices_size_type> sigma(num_vertices(g), 0); // sigma[s] <-- 1 sigma[get(index, s)] = 1; // d[t] <-- -1, t \in V std::vector<int> d(num_vertices(g), -1); // d[s] <-- 0 d[get(index, s)] = 0; // Q <-- empty queue std::queue<vertex> Q; // enqueue s --> Q Q.push(s); while (!Q.empty()) { // dequeue v <-- Q vertex v = Q.front(); Q.pop(); // push v --> S S.push(v); adjacency_iterator wi, wi_end; for (tie(wi, wi_end) = adjacent_vertices(v, g); wi != wi_end; ++wi) { vertex w = *wi; // w found for the first time? if (d[get(index, w)] < 0) { // enqueue w --> Q Q.push(w); // d[w] <-- d[v] + 1 d[get(index, w)] = d[get(index, v)] + 1; } // shortest path to w via v? if (d[get(index, w)] == d[get(index, v)] + 1) { // sigma[w] = sigma[w] + sigma[v] sigma[get(index, w)] += sigma[get(index, v)]; // append v --> P[w] predecessors[get(index, w)].push_back(v); } } } // delta[v] <-- 0, v \in V std::vector<centrality_type> delta(num_vertices(g), 0); // S returns vertices in order of non-increasing distance from s while (!S.empty()) { // pop w <-- S vertex w = S.top(); S.pop(); const Predecessors& w_preds = predecessors[get(index, w)]; for (typename Predecessors::const_iterator vi = w_preds.begin(); vi != w_preds.end(); ++vi) { vertex v = *vi; // delta[v] <-- delta[v] + (sigma[v]/sigma[w])*(1 + delta[w]) delta[get(index, v)] += ((centrality_type)sigma[get(index, v)]/sigma[get(index, w)]) * (1 + delta[get(index, w)]); } if (w != s) { // C_B[w] <-- C_B[w] + delta[w] centrality[w] += delta[get(index, w)]; } } } typedef typename graph_traits<Graph>::directed_category directed_category; const bool is_undirected = is_same<directed_category, undirected_tag>::value; if (is_undirected) { vertex_iterator v, v_end; for(tie(v, v_end) = vertices(g); v != v_end; ++v) { put(centrality, *v, get(centrality, *v) / centrality_type(2)); } }}template<typename Graph>void random_unweighted_test(Graph*, int n){ Graph g(n); { typename graph_traits<Graph>::vertex_iterator v, v_end; int index = 0; for (tie(v, v_end) = boost::vertices(g); v != v_end; ++v, ++index) { put(vertex_index, g, *v, index); } } randomly_add_edges(g, 0.20); std::cout << "Random graph with " << n << " vertices and " << num_edges(g) << " edges.\n"; std::cout << " Direct translation of Brandes' algorithm..."; std::vector<double> centrality(n); simple_unweighted_betweenness_centrality(g, get(vertex_index, g), make_iterator_property_map(centrality.begin(), get(vertex_index, g), double())); std::cout << "DONE.\n"; std::cout << " Real version, unweighted..."; std::vector<double> centrality2(n); brandes_betweenness_centrality(g, make_iterator_property_map(centrality2.begin(), get(vertex_index, g), double())); std::cout << "DONE.\n"; if (!std::equal(centrality.begin(), centrality.end(), centrality2.begin())) { for (std::size_t v = 0; v < centrality.size(); ++v) { double relative_error = centrality[v] == 0.0? centrality2[v] : (centrality2[v] - centrality[v]) / centrality[v]; if (relative_error < 0) relative_error = -relative_error; BOOST_CHECK(relative_error < error_tolerance); } } std::cout << " Real version, weighted..."; std::vector<double> centrality3(n); for (typename graph_traits<Graph>::edge_iterator ei = edges(g).first; ei != edges(g).second; ++ei) put(edge_weight, g, *ei, 1); brandes_betweenness_centrality(g, weight_map(get(edge_weight, g)) .centrality_map( make_iterator_property_map(centrality3.begin(), get(vertex_index, g), double()))); std::cout << "DONE.\n"; if (!std::equal(centrality.begin(), centrality.end(), centrality3.begin())) { for (std::size_t v = 0; v < centrality.size(); ++v) { double relative_error = centrality[v] == 0.0? centrality3[v] : (centrality3[v] - centrality[v]) / centrality[v]; if (relative_error < 0) relative_error = -relative_error; BOOST_CHECK(relative_error < error_tolerance); } }}int test_main(int, char*[]){ typedef adjacency_list<listS, listS, undirectedS, property<vertex_index_t, int>, EdgeProperties> Graph; typedef adjacency_list<listS, listS, directedS, property<vertex_index_t, int>, EdgeProperties> Digraph; struct unweighted_edge ud_edge_init1[5] = { { 0, 1 }, { 0, 3 }, { 1, 2 }, { 3, 2 }, { 2, 4 } }; double ud_centrality1[5] = { 0.5, 1.0, 3.5, 1.0, 0.0 }; run_unweighted_test((Graph*)0, 5, ud_edge_init1, 5, ud_centrality1); // Example borrowed from the JUNG test suite struct unweighted_edge ud_edge_init2[10] = { { 0, 1 }, { 0, 6 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 4 }, { 4, 5 }, { 5, 8 }, { 7, 8 }, { 6, 7 }, }; double ud_centrality2[9] = { 0.2142 * 28, 0.2797 * 28, 0.0892 * 28, 0.0892 * 28, 0.2797 * 28, 0.2142 * 28, 0.1666 * 28, 0.1428 * 28, 0.1666 * 28 }; double ud_edge_centrality2[10] = { 10.66666, 9.33333, 6.5, 6.5, 6.5, 6.5, 10.66666, 9.33333, 8.0, 8.0 }; run_unweighted_test((Graph*)0, 9, ud_edge_init2, 10, ud_centrality2, ud_edge_centrality2); weighted_edge dw_edge_init1[6] = { { 0, 1, 1.0 }, { 0, 3, 1.0 }, { 1, 2, 0.5 }, { 3, 1, 1.0 }, { 3, 4, 1.0 }, { 4, 2, 0.5 } }; double dw_centrality1[5] = { 0.0, 1.5, 0.0, 1.0, 0.5 }; run_weighted_test((Digraph*)0, 5, dw_edge_init1, 6, dw_centrality1); run_wheel_test((Graph*)0, 15); random_unweighted_test((Graph*)0, 300); return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?