betweenness_centrality_test.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 520 行 · 第 1/2 页
CPP
520 行
// Copyright 2004 The Trustees of Indiana University.// Use, modification and distribution is subject to the Boost Software// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)// Authors: Douglas Gregor// Andrew Lumsdaine#include <boost/graph/betweenness_centrality.hpp>#include <boost/graph/adjacency_list.hpp>#include <vector>#include <stack>#include <queue>#include <boost/property_map.hpp>#include <boost/test/minimal.hpp>#include <boost/random/uniform_01.hpp>#include <boost/random/linear_congruential.hpp>using namespace boost;const double error_tolerance = 0.001;typedef property<edge_weight_t, double, property<edge_index_t, std::size_t> > EdgeProperties;struct weighted_edge { int source, target; double weight;};template<typename Graph>void run_weighted_test(Graph*, int V, weighted_edge edge_init[], int E, double correct_centrality[]){ Graph g(V); typedef typename graph_traits<Graph>::vertex_descriptor Vertex; typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator; typedef typename graph_traits<Graph>::edge_descriptor Edge; std::vector<Vertex> vertices(V); { 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); vertices[index] = *v; } } std::vector<Edge> edges(E); for (int e = 0; e < E; ++e) { edges[e] = add_edge(vertices[edge_init[e].source], vertices[edge_init[e].target], g).first; put(edge_weight, g, edges[e], 1.0); } std::vector<double> centrality(V); brandes_betweenness_centrality( g, centrality_map( make_iterator_property_map(centrality.begin(), get(vertex_index, g), double())) .vertex_index_map(get(vertex_index, g)).weight_map(get(edge_weight, g))); for (int v = 0; v < V; ++v) { BOOST_CHECK(centrality[v] == correct_centrality[v]); }}struct unweighted_edge { int source, target;};template<typename Graph>void run_unweighted_test(Graph*, int V, unweighted_edge edge_init[], int E, double correct_centrality[], double* correct_edge_centrality = 0){ Graph g(V); typedef typename graph_traits<Graph>::vertex_descriptor Vertex; typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator; typedef typename graph_traits<Graph>::edge_descriptor Edge; std::vector<Vertex> vertices(V); { 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); vertices[index] = *v; } } std::vector<Edge> edges(E); for (int e = 0; e < E; ++e) { edges[e] = add_edge(vertices[edge_init[e].source], vertices[edge_init[e].target], g).first; put(edge_weight, g, edges[e], 1.0); put(edge_index, g, edges[e], e); } std::vector<double> centrality(V); std::vector<double> edge_centrality1(E); brandes_betweenness_centrality( g, centrality_map( make_iterator_property_map(centrality.begin(), get(vertex_index, g), double())) .edge_centrality_map( make_iterator_property_map(edge_centrality1.begin(), get(edge_index, g), double())) .vertex_index_map(get(vertex_index, g))); std::vector<double> centrality2(V); std::vector<double> edge_centrality2(E); brandes_betweenness_centrality( g, vertex_index_map(get(vertex_index, g)).weight_map(get(edge_weight, g)) .centrality_map( make_iterator_property_map(centrality2.begin(), get(vertex_index, g), double())) .edge_centrality_map( make_iterator_property_map(edge_centrality2.begin(), get(edge_index, g), double()))); std::vector<double> edge_centrality3(E); brandes_betweenness_centrality( g, edge_centrality_map( make_iterator_property_map(edge_centrality3.begin(), get(edge_index, g), double()))); for (int v = 0; v < V; ++v) { BOOST_CHECK(centrality[v] == centrality2[v]); double relative_error = correct_centrality[v] == 0.0? centrality[v] : (centrality[v] - correct_centrality[v]) / correct_centrality[v]; if (relative_error < 0) relative_error = -relative_error; BOOST_CHECK(relative_error < error_tolerance); } for (int e = 0; e < E; ++e) { BOOST_CHECK(edge_centrality1[e] == edge_centrality2[e]); BOOST_CHECK(edge_centrality1[e] == edge_centrality3[e]); if (correct_edge_centrality) { double relative_error = correct_edge_centrality[e] == 0.0? edge_centrality1[e] : (edge_centrality1[e] - correct_edge_centrality[e]) / correct_edge_centrality[e]; if (relative_error < 0) relative_error = -relative_error; BOOST_CHECK(relative_error < error_tolerance); if (relative_error >= error_tolerance) { std::cerr << "Edge " << e << " has edge centrality " << edge_centrality1[e] << ", should be " << correct_edge_centrality[e] << std::endl; } } }}template<typename Graph>voidrun_wheel_test(Graph*, int V){ typedef typename graph_traits<Graph>::vertex_descriptor Vertex; typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator; typedef typename graph_traits<Graph>::edge_descriptor Edge; Graph g(V); Vertex center = *boost::vertices(g).first; std::vector<Vertex> vertices(V); { 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); vertices[index] = *v; if (*v != center) { Edge e = add_edge(*v, center, g).first; put(edge_weight, g, e, 1.0); } } } std::vector<double> centrality(V); brandes_betweenness_centrality( g, make_iterator_property_map(centrality.begin(), get(vertex_index, g), double())); std::vector<double> centrality2(V); brandes_betweenness_centrality( g, centrality_map( make_iterator_property_map(centrality2.begin(), get(vertex_index, g), double())) .vertex_index_map(get(vertex_index, g)).weight_map(get(edge_weight, g))); relative_betweenness_centrality( g, make_iterator_property_map(centrality.begin(), get(vertex_index, g), double())); relative_betweenness_centrality( g, make_iterator_property_map(centrality2.begin(), get(vertex_index, g), double())); for (int v = 0; v < V; ++v) { BOOST_CHECK(centrality[v] == centrality2[v]); BOOST_CHECK((v == 0 && centrality[v] == 1) || (v != 0 && centrality[v] == 0)); } double dominance = central_point_dominance( g, make_iterator_property_map(centrality2.begin(), get(vertex_index, g), double())); BOOST_CHECK(dominance == 1.0);}template<typename MutableGraph>void randomly_add_edges(MutableGraph& g, double edge_probability){ typedef typename graph_traits<MutableGraph>::directed_category directed_category; const bool is_undirected = is_same<directed_category, undirected_tag>::value; minstd_rand gen; uniform_01<minstd_rand, double> rand_gen(gen); typedef typename graph_traits<MutableGraph>::vertex_descriptor vertex; typename graph_traits<MutableGraph>::vertex_iterator vi, vi_end; for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { vertex v = *vi; typename graph_traits<MutableGraph>::vertex_iterator wi = is_undirected? vi : vertices(g).first; while (wi != vi_end) { vertex w = *wi++; if (v != w) { if (rand_gen() < edge_probability) add_edge(v, w, g); } } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?