annotate DEPENDENCIES/generic/include/boost/graph/gursoy_atun_layout.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright 2004 The Trustees of Indiana University.
Chris@16 2
Chris@16 3 // Distributed under the Boost Software License, Version 1.0.
Chris@16 4 // (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 5 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6
Chris@16 7 // Authors: Jeremiah Willcock
Chris@16 8 // Douglas Gregor
Chris@16 9 // Andrew Lumsdaine
Chris@16 10 #ifndef BOOST_GRAPH_GURSOY_ATUN_LAYOUT_HPP
Chris@16 11 #define BOOST_GRAPH_GURSOY_ATUN_LAYOUT_HPP
Chris@16 12
Chris@16 13 // Gursoy-Atun graph layout, based on:
Chris@16 14 // "Neighbourhood Preserving Load Balancing: A Self-Organizing Approach"
Chris@16 15 // in EuroPar 2000, p. 234 of LNCS 1900
Chris@16 16 // http://springerlink.metapress.com/link.asp?id=pcu07ew5rhexp9yt
Chris@16 17
Chris@16 18 #include <boost/config/no_tr1/cmath.hpp>
Chris@16 19 #include <boost/throw_exception.hpp>
Chris@16 20 #include <boost/assert.hpp>
Chris@16 21 #include <vector>
Chris@16 22 #include <exception>
Chris@16 23 #include <algorithm>
Chris@16 24
Chris@16 25 #include <boost/graph/visitors.hpp>
Chris@16 26 #include <boost/graph/properties.hpp>
Chris@16 27 #include <boost/random/uniform_01.hpp>
Chris@16 28 #include <boost/random/linear_congruential.hpp>
Chris@16 29 #include <boost/shared_ptr.hpp>
Chris@16 30 #include <boost/graph/breadth_first_search.hpp>
Chris@16 31 #include <boost/graph/dijkstra_shortest_paths.hpp>
Chris@16 32 #include <boost/graph/named_function_params.hpp>
Chris@16 33 #include <boost/graph/topology.hpp>
Chris@16 34
Chris@16 35 namespace boost {
Chris@16 36
Chris@16 37 namespace detail {
Chris@16 38
Chris@16 39 struct over_distance_limit : public std::exception {};
Chris@16 40
Chris@16 41 template <typename PositionMap, typename NodeDistanceMap, typename Topology,
Chris@16 42 typename Graph>
Chris@16 43 struct update_position_visitor {
Chris@16 44 typedef typename Topology::point_type Point;
Chris@16 45 PositionMap position_map;
Chris@16 46 NodeDistanceMap node_distance;
Chris@16 47 const Topology& space;
Chris@16 48 Point input_vector;
Chris@16 49 double distance_limit;
Chris@16 50 double learning_constant;
Chris@16 51 double falloff_ratio;
Chris@16 52
Chris@16 53 typedef boost::on_examine_vertex event_filter;
Chris@16 54
Chris@16 55 typedef typename graph_traits<Graph>::vertex_descriptor
Chris@16 56 vertex_descriptor;
Chris@16 57
Chris@16 58 update_position_visitor(PositionMap position_map,
Chris@16 59 NodeDistanceMap node_distance,
Chris@16 60 const Topology& space,
Chris@16 61 const Point& input_vector,
Chris@16 62 double distance_limit,
Chris@16 63 double learning_constant,
Chris@16 64 double falloff_ratio):
Chris@16 65 position_map(position_map), node_distance(node_distance),
Chris@16 66 space(space),
Chris@16 67 input_vector(input_vector), distance_limit(distance_limit),
Chris@16 68 learning_constant(learning_constant), falloff_ratio(falloff_ratio) {}
Chris@16 69
Chris@16 70 void operator()(vertex_descriptor v, const Graph&) const
Chris@16 71 {
Chris@16 72 #ifndef BOOST_NO_STDC_NAMESPACE
Chris@16 73 using std::pow;
Chris@16 74 #endif
Chris@16 75
Chris@16 76 if (get(node_distance, v) > distance_limit)
Chris@16 77 BOOST_THROW_EXCEPTION(over_distance_limit());
Chris@16 78 Point old_position = get(position_map, v);
Chris@16 79 double distance = get(node_distance, v);
Chris@16 80 double fraction =
Chris@16 81 learning_constant * pow(falloff_ratio, distance * distance);
Chris@16 82 put(position_map, v,
Chris@16 83 space.move_position_toward(old_position, fraction, input_vector));
Chris@16 84 }
Chris@16 85 };
Chris@16 86
Chris@16 87 template<typename EdgeWeightMap>
Chris@16 88 struct gursoy_shortest
Chris@16 89 {
Chris@16 90 template<typename Graph, typename NodeDistanceMap, typename UpdatePosition>
Chris@16 91 static inline void
Chris@16 92 run(const Graph& g, typename graph_traits<Graph>::vertex_descriptor s,
Chris@16 93 NodeDistanceMap node_distance, UpdatePosition& update_position,
Chris@16 94 EdgeWeightMap weight)
Chris@16 95 {
Chris@16 96 boost::dijkstra_shortest_paths(g, s, weight_map(weight).
Chris@16 97 visitor(boost::make_dijkstra_visitor(std::make_pair(
Chris@16 98 boost::record_distances(node_distance, boost::on_edge_relaxed()),
Chris@16 99 update_position))));
Chris@16 100 }
Chris@16 101 };
Chris@16 102
Chris@16 103 template<>
Chris@16 104 struct gursoy_shortest<dummy_property_map>
Chris@16 105 {
Chris@16 106 template<typename Graph, typename NodeDistanceMap, typename UpdatePosition>
Chris@16 107 static inline void
Chris@16 108 run(const Graph& g, typename graph_traits<Graph>::vertex_descriptor s,
Chris@16 109 NodeDistanceMap node_distance, UpdatePosition& update_position,
Chris@16 110 dummy_property_map)
Chris@16 111 {
Chris@16 112 boost::breadth_first_search(g, s,
Chris@16 113 visitor(boost::make_bfs_visitor(std::make_pair(
Chris@16 114 boost::record_distances(node_distance, boost::on_tree_edge()),
Chris@16 115 update_position))));
Chris@16 116 }
Chris@16 117 };
Chris@16 118
Chris@16 119 } // namespace detail
Chris@16 120
Chris@16 121 template <typename VertexListAndIncidenceGraph, typename Topology,
Chris@16 122 typename PositionMap, typename Diameter, typename VertexIndexMap,
Chris@16 123 typename EdgeWeightMap>
Chris@16 124 void
Chris@16 125 gursoy_atun_step
Chris@16 126 (const VertexListAndIncidenceGraph& graph,
Chris@16 127 const Topology& space,
Chris@16 128 PositionMap position,
Chris@16 129 Diameter diameter,
Chris@16 130 double learning_constant,
Chris@16 131 VertexIndexMap vertex_index_map,
Chris@16 132 EdgeWeightMap weight)
Chris@16 133 {
Chris@16 134 #ifndef BOOST_NO_STDC_NAMESPACE
Chris@16 135 using std::pow;
Chris@16 136 using std::exp;
Chris@16 137 #endif
Chris@16 138
Chris@16 139 typedef typename graph_traits<VertexListAndIncidenceGraph>::vertex_iterator
Chris@16 140 vertex_iterator;
Chris@16 141 typedef typename graph_traits<VertexListAndIncidenceGraph>::vertex_descriptor
Chris@16 142 vertex_descriptor;
Chris@16 143 typedef typename Topology::point_type point_type;
Chris@16 144 vertex_iterator i, iend;
Chris@16 145 std::vector<double> distance_from_input_vector(num_vertices(graph));
Chris@16 146 typedef boost::iterator_property_map<std::vector<double>::iterator,
Chris@16 147 VertexIndexMap,
Chris@16 148 double, double&>
Chris@16 149 DistanceFromInputMap;
Chris@16 150 DistanceFromInputMap distance_from_input(distance_from_input_vector.begin(),
Chris@16 151 vertex_index_map);
Chris@16 152 std::vector<double> node_distance_map_vector(num_vertices(graph));
Chris@16 153 typedef boost::iterator_property_map<std::vector<double>::iterator,
Chris@16 154 VertexIndexMap,
Chris@16 155 double, double&>
Chris@16 156 NodeDistanceMap;
Chris@16 157 NodeDistanceMap node_distance(node_distance_map_vector.begin(),
Chris@16 158 vertex_index_map);
Chris@16 159 point_type input_vector = space.random_point();
Chris@16 160 vertex_descriptor min_distance_loc
Chris@16 161 = graph_traits<VertexListAndIncidenceGraph>::null_vertex();
Chris@16 162 double min_distance = 0.0;
Chris@16 163 bool min_distance_unset = true;
Chris@16 164 for (boost::tie(i, iend) = vertices(graph); i != iend; ++i) {
Chris@16 165 double this_distance = space.distance(get(position, *i), input_vector);
Chris@16 166 put(distance_from_input, *i, this_distance);
Chris@16 167 if (min_distance_unset || this_distance < min_distance) {
Chris@16 168 min_distance = this_distance;
Chris@16 169 min_distance_loc = *i;
Chris@16 170 }
Chris@16 171 min_distance_unset = false;
Chris@16 172 }
Chris@16 173 BOOST_ASSERT (!min_distance_unset); // Graph must have at least one vertex
Chris@16 174 boost::detail::update_position_visitor<
Chris@16 175 PositionMap, NodeDistanceMap, Topology,
Chris@16 176 VertexListAndIncidenceGraph>
Chris@16 177 update_position(position, node_distance, space,
Chris@16 178 input_vector, diameter, learning_constant,
Chris@16 179 exp(-1. / (2 * diameter * diameter)));
Chris@16 180 std::fill(node_distance_map_vector.begin(), node_distance_map_vector.end(), 0);
Chris@16 181 try {
Chris@16 182 typedef detail::gursoy_shortest<EdgeWeightMap> shortest;
Chris@16 183 shortest::run(graph, min_distance_loc, node_distance, update_position,
Chris@16 184 weight);
Chris@16 185 } catch (detail::over_distance_limit) {
Chris@16 186 /* Thrown to break out of BFS or Dijkstra early */
Chris@16 187 }
Chris@16 188 }
Chris@16 189
Chris@16 190 template <typename VertexListAndIncidenceGraph, typename Topology,
Chris@16 191 typename PositionMap, typename VertexIndexMap,
Chris@16 192 typename EdgeWeightMap>
Chris@16 193 void gursoy_atun_refine(const VertexListAndIncidenceGraph& graph,
Chris@16 194 const Topology& space,
Chris@16 195 PositionMap position,
Chris@16 196 int nsteps,
Chris@16 197 double diameter_initial,
Chris@16 198 double diameter_final,
Chris@16 199 double learning_constant_initial,
Chris@16 200 double learning_constant_final,
Chris@16 201 VertexIndexMap vertex_index_map,
Chris@16 202 EdgeWeightMap weight)
Chris@16 203 {
Chris@16 204 #ifndef BOOST_NO_STDC_NAMESPACE
Chris@16 205 using std::pow;
Chris@16 206 using std::exp;
Chris@16 207 #endif
Chris@16 208
Chris@16 209 typedef typename graph_traits<VertexListAndIncidenceGraph>::vertex_iterator
Chris@16 210 vertex_iterator;
Chris@16 211 vertex_iterator i, iend;
Chris@16 212 double diameter_ratio = (double)diameter_final / diameter_initial;
Chris@16 213 double learning_constant_ratio =
Chris@16 214 learning_constant_final / learning_constant_initial;
Chris@16 215 std::vector<double> distance_from_input_vector(num_vertices(graph));
Chris@16 216 typedef boost::iterator_property_map<std::vector<double>::iterator,
Chris@16 217 VertexIndexMap,
Chris@16 218 double, double&>
Chris@16 219 DistanceFromInputMap;
Chris@16 220 DistanceFromInputMap distance_from_input(distance_from_input_vector.begin(),
Chris@16 221 vertex_index_map);
Chris@16 222 std::vector<int> node_distance_map_vector(num_vertices(graph));
Chris@16 223 typedef boost::iterator_property_map<std::vector<int>::iterator,
Chris@16 224 VertexIndexMap, double, double&>
Chris@16 225 NodeDistanceMap;
Chris@16 226 NodeDistanceMap node_distance(node_distance_map_vector.begin(),
Chris@16 227 vertex_index_map);
Chris@16 228 for (int round = 0; round < nsteps; ++round) {
Chris@16 229 double part_done = (double)round / (nsteps - 1);
Chris@16 230 // fprintf(stderr, "%2d%% done\n", int(rint(part_done * 100.)));
Chris@16 231 int diameter = (int)(diameter_initial * pow(diameter_ratio, part_done));
Chris@16 232 double learning_constant =
Chris@16 233 learning_constant_initial * pow(learning_constant_ratio, part_done);
Chris@16 234 gursoy_atun_step(graph, space, position, diameter, learning_constant,
Chris@16 235 vertex_index_map, weight);
Chris@16 236 }
Chris@16 237 }
Chris@16 238
Chris@16 239 template <typename VertexListAndIncidenceGraph, typename Topology,
Chris@16 240 typename PositionMap, typename VertexIndexMap,
Chris@16 241 typename EdgeWeightMap>
Chris@16 242 void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph,
Chris@16 243 const Topology& space,
Chris@16 244 PositionMap position,
Chris@16 245 int nsteps,
Chris@16 246 double diameter_initial,
Chris@16 247 double diameter_final,
Chris@16 248 double learning_constant_initial,
Chris@16 249 double learning_constant_final,
Chris@16 250 VertexIndexMap vertex_index_map,
Chris@16 251 EdgeWeightMap weight)
Chris@16 252 {
Chris@16 253 typedef typename graph_traits<VertexListAndIncidenceGraph>::vertex_iterator
Chris@16 254 vertex_iterator;
Chris@16 255 vertex_iterator i, iend;
Chris@16 256 for (boost::tie(i, iend) = vertices(graph); i != iend; ++i) {
Chris@16 257 put(position, *i, space.random_point());
Chris@16 258 }
Chris@16 259 gursoy_atun_refine(graph, space,
Chris@16 260 position, nsteps,
Chris@16 261 diameter_initial, diameter_final,
Chris@16 262 learning_constant_initial, learning_constant_final,
Chris@16 263 vertex_index_map, weight);
Chris@16 264 }
Chris@16 265
Chris@16 266 template <typename VertexListAndIncidenceGraph, typename Topology,
Chris@16 267 typename PositionMap, typename VertexIndexMap>
Chris@16 268 void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph,
Chris@16 269 const Topology& space,
Chris@16 270 PositionMap position,
Chris@16 271 int nsteps,
Chris@16 272 double diameter_initial,
Chris@16 273 double diameter_final,
Chris@16 274 double learning_constant_initial,
Chris@16 275 double learning_constant_final,
Chris@16 276 VertexIndexMap vertex_index_map)
Chris@16 277 {
Chris@16 278 gursoy_atun_layout(graph, space, position, nsteps,
Chris@16 279 diameter_initial, diameter_final,
Chris@16 280 learning_constant_initial, learning_constant_final,
Chris@16 281 vertex_index_map, dummy_property_map());
Chris@16 282 }
Chris@16 283
Chris@16 284 template <typename VertexListAndIncidenceGraph, typename Topology,
Chris@16 285 typename PositionMap>
Chris@16 286 void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph,
Chris@16 287 const Topology& space,
Chris@16 288 PositionMap position,
Chris@16 289 int nsteps,
Chris@16 290 double diameter_initial,
Chris@16 291 double diameter_final = 1.0,
Chris@16 292 double learning_constant_initial = 0.8,
Chris@16 293 double learning_constant_final = 0.2)
Chris@16 294 {
Chris@16 295 gursoy_atun_layout(graph, space, position, nsteps, diameter_initial,
Chris@16 296 diameter_final, learning_constant_initial,
Chris@16 297 learning_constant_final, get(vertex_index, graph));
Chris@16 298 }
Chris@16 299
Chris@16 300 template <typename VertexListAndIncidenceGraph, typename Topology,
Chris@16 301 typename PositionMap>
Chris@16 302 void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph,
Chris@16 303 const Topology& space,
Chris@16 304 PositionMap position,
Chris@16 305 int nsteps)
Chris@16 306 {
Chris@16 307 #ifndef BOOST_NO_STDC_NAMESPACE
Chris@16 308 using std::sqrt;
Chris@16 309 #endif
Chris@16 310
Chris@16 311 gursoy_atun_layout(graph, space, position, nsteps,
Chris@16 312 sqrt((double)num_vertices(graph)));
Chris@16 313 }
Chris@16 314
Chris@16 315 template <typename VertexListAndIncidenceGraph, typename Topology,
Chris@16 316 typename PositionMap>
Chris@16 317 void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph,
Chris@16 318 const Topology& space,
Chris@16 319 PositionMap position)
Chris@16 320 {
Chris@16 321 gursoy_atun_layout(graph, space, position, num_vertices(graph));
Chris@16 322 }
Chris@16 323
Chris@16 324 template<typename VertexListAndIncidenceGraph, typename Topology,
Chris@16 325 typename PositionMap, typename P, typename T, typename R>
Chris@16 326 void
Chris@16 327 gursoy_atun_layout(const VertexListAndIncidenceGraph& graph,
Chris@16 328 const Topology& space,
Chris@16 329 PositionMap position,
Chris@16 330 const bgl_named_params<P,T,R>& params)
Chris@16 331 {
Chris@16 332 #ifndef BOOST_NO_STDC_NAMESPACE
Chris@16 333 using std::sqrt;
Chris@16 334 #endif
Chris@16 335
Chris@16 336 std::pair<double, double> diam(sqrt(double(num_vertices(graph))), 1.0);
Chris@16 337 std::pair<double, double> learn(0.8, 0.2);
Chris@16 338 gursoy_atun_layout(graph, space, position,
Chris@16 339 choose_param(get_param(params, iterations_t()),
Chris@16 340 num_vertices(graph)),
Chris@16 341 choose_param(get_param(params, diameter_range_t()),
Chris@16 342 diam).first,
Chris@16 343 choose_param(get_param(params, diameter_range_t()),
Chris@16 344 diam).second,
Chris@16 345 choose_param(get_param(params, learning_constant_range_t()),
Chris@16 346 learn).first,
Chris@16 347 choose_param(get_param(params, learning_constant_range_t()),
Chris@16 348 learn).second,
Chris@16 349 choose_const_pmap(get_param(params, vertex_index), graph,
Chris@16 350 vertex_index),
Chris@16 351 choose_param(get_param(params, edge_weight),
Chris@16 352 dummy_property_map()));
Chris@16 353 }
Chris@16 354
Chris@16 355 } // namespace boost
Chris@16 356
Chris@16 357 #endif // BOOST_GRAPH_GURSOY_ATUN_LAYOUT_HPP