123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 |
- #ifndef BOOST_GRAPH_SLOAN_HPP
- #define BOOST_GRAPH_SLOAN_HPP
- #define WEIGHT1 1
- #define WEIGHT2 2
- #include <boost/config.hpp>
- #include <vector>
- #include <queue>
- #include <algorithm>
- #include <limits>
- #include <boost/pending/queue.hpp>
- #include <boost/graph/graph_traits.hpp>
- #include <boost/graph/breadth_first_search.hpp>
- #include <boost/graph/properties.hpp>
- #include <boost/pending/indirect_cmp.hpp>
- #include <boost/property_map/property_map.hpp>
- #include <boost/graph/visitors.hpp>
- #include <boost/graph/adjacency_list.hpp>
- #include <boost/graph/cuthill_mckee_ordering.hpp>
- namespace boost
- {
- template < class Distance > typename Distance::value_type RLS_depth(Distance& d)
- {
- typename Distance::value_type h_s = 0;
- typename Distance::iterator iter;
- for (iter = d.begin(); iter != d.end(); ++iter)
- {
- if (*iter > h_s)
- {
- h_s = *iter;
- }
- }
- return h_s;
- }
- template < class Distance, class my_int >
- typename Distance::value_type RLS_max_width(Distance& d, my_int depth)
- {
- typedef typename Distance::value_type Degree;
-
- std::vector< Degree > dummy_width(depth + 1, 0);
- typename std::vector< Degree >::iterator my_it;
- typename Distance::iterator iter;
- Degree w_max = 0;
- for (iter = d.begin(); iter != d.end(); ++iter)
- {
- dummy_width[*iter]++;
- }
- for (my_it = dummy_width.begin(); my_it != dummy_width.end(); ++my_it)
- {
- if (*my_it > w_max)
- w_max = *my_it;
- }
- return w_max;
- }
- template < class Graph, class ColorMap, class DegreeMap >
- typename graph_traits< Graph >::vertex_descriptor sloan_start_end_vertices(
- Graph& G, typename graph_traits< Graph >::vertex_descriptor& s,
- ColorMap color, DegreeMap degree)
- {
- typedef typename property_traits< DegreeMap >::value_type Degree;
- typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
- typedef typename std::vector<
- typename graph_traits< Graph >::vertices_size_type >::iterator vec_iter;
- typedef typename graph_traits< Graph >::vertices_size_type size_type;
- typedef typename property_map< Graph, vertex_index_t >::const_type VertexID;
- s = *(vertices(G).first);
- Vertex e = s;
- Vertex i;
- Degree my_degree = get(degree, s);
- Degree dummy, h_i, h_s, w_i, w_e;
- bool new_start = true;
- Degree maximum_degree = 0;
-
-
- std::vector< typename graph_traits< Graph >::vertices_size_type > dist(
- num_vertices(G), 0);
-
- boost::iterator_property_map< vec_iter, VertexID, size_type, size_type& >
- dist_pmap(dist.begin(), get(vertex_index, G));
-
- typename property_map< Graph, vertex_index_t >::type index_map
- = get(vertex_index, G);
-
- typedef indirect_cmp< DegreeMap, std::greater< Degree > > Compare;
- Compare comp(degree);
- std::priority_queue< Vertex, std::vector< Vertex >, Compare > degree_queue(
- comp);
-
-
- typename graph_traits< Graph >::vertex_iterator ui, ui_end;
- for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
- {
- dummy = get(degree, *ui);
- if (dummy < my_degree)
- {
- my_degree = dummy;
- s = *ui;
- }
- if (dummy > maximum_degree)
- {
- maximum_degree = dummy;
- }
- }
-
- do
- {
- new_start = false;
-
-
- for (typename std::vector< typename graph_traits<
- Graph >::vertices_size_type >::iterator iter
- = dist.begin();
- iter != dist.end(); ++iter)
- *iter = 0;
-
- breadth_first_search(G, s,
- visitor(
- make_bfs_visitor(record_distances(dist_pmap, on_tree_edge()))));
-
-
-
- h_s = RLS_depth(dist);
-
-
-
- std::vector< bool > shrink_trace(maximum_degree, false);
- for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
- {
- dummy = get(degree, *ui);
- if ((dist[index_map[*ui]] == h_s) && (!shrink_trace[dummy]))
- {
- degree_queue.push(*ui);
- shrink_trace[dummy] = true;
- }
- }
-
-
-
- w_e = (std::numeric_limits< Degree >::max)();
-
-
-
- while (!degree_queue.empty())
- {
- i = degree_queue.top();
-
- degree_queue.pop();
-
-
- for (typename std::vector< typename graph_traits<
- Graph >::vertices_size_type >::iterator iter
- = dist.begin();
- iter != dist.end(); ++iter)
- *iter = 0;
- breadth_first_search(G, i,
- boost::visitor(make_bfs_visitor(
- record_distances(dist_pmap, on_tree_edge()))));
-
- h_i = RLS_depth(dist);
- w_i = RLS_max_width(dist, h_i);
-
- if ((h_i > h_s) && (w_i < w_e))
- {
- h_s = h_i;
- s = i;
- while (!degree_queue.empty())
- degree_queue.pop();
- new_start = true;
- }
- else if (w_i < w_e)
- {
- w_e = w_i;
- e = i;
- }
- }
-
- } while (new_start);
- return e;
- }
- template < class Graph, class OutputIterator, class ColorMap, class DegreeMap,
- class PriorityMap, class Weight >
- OutputIterator sloan_ordering(Graph& g,
- typename graph_traits< Graph >::vertex_descriptor s,
- typename graph_traits< Graph >::vertex_descriptor e,
- OutputIterator permutation, ColorMap color, DegreeMap degree,
- PriorityMap priority, Weight W1, Weight W2)
- {
-
- typedef typename property_traits< PriorityMap >::value_type Degree;
- typedef typename property_traits< ColorMap >::value_type ColorValue;
- typedef color_traits< ColorValue > Color;
- typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
- typedef typename std::vector<
- typename graph_traits< Graph >::vertices_size_type >::iterator vec_iter;
- typedef typename graph_traits< Graph >::vertices_size_type size_type;
- typedef typename property_map< Graph, vertex_index_t >::const_type VertexID;
-
- typename std::vector< typename graph_traits< Graph >::vertices_size_type >
- dist(num_vertices(g), 0);
-
- boost::iterator_property_map< vec_iter, VertexID, size_type, size_type& >
- dist_pmap(dist.begin(), get(vertex_index, g));
- breadth_first_search(g, e,
- visitor(make_bfs_visitor(record_distances(dist_pmap, on_tree_edge()))));
-
- typename property_map< Graph, vertex_index_t >::type index_map
- = get(vertex_index, g);
-
- Degree cdeg;
- typename graph_traits< Graph >::vertex_iterator ui, ui_end;
- for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
- {
- put(color, *ui, Color::white());
- cdeg = get(degree, *ui) + 1;
- put(priority, *ui, W1 * dist[index_map[*ui]] - W2 * cdeg);
- }
-
- typedef indirect_cmp< PriorityMap, std::greater< Degree > > Compare;
- Compare comp(priority);
- std::list< Vertex > priority_list;
-
- typename graph_traits< Graph >::out_edge_iterator ei, ei_end, ei2, ei2_end;
- Vertex u, v, w;
- put(color, s,
- Color::green());
- priority_list.push_front(s);
- while (!priority_list.empty())
- {
- priority_list.sort(comp);
-
- u = priority_list
- .front();
- priority_list
- .pop_front();
- if (get(color, u) == Color::green())
- {
-
- for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei)
- {
- v = target(*ei, g);
- put(priority, v, get(priority, v) + W2);
- if (get(color, v)
- == Color::white())
- {
- put(color, v,
- Color::green());
- priority_list.push_front(
- v);
- }
- }
- }
-
- *permutation++
- = u;
- put(color, u, Color::black());
-
- for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei)
- {
- v = target(*ei, g);
- if (get(color, v) == Color::green())
- {
- put(color, v,
- Color::red());
- put(priority, v, get(priority, v) + W2);
-
- for (boost::tie(ei2, ei2_end) = out_edges(v, g); ei2 != ei2_end;
- ++ei2)
- {
- w = target(*ei2, g);
- if (get(color, w) != Color::black())
- {
- put(priority, w,
- get(priority, w) + W2);
- if (get(color, w) == Color::white())
- {
- put(color, w, Color::green());
-
- priority_list.push_front(
- w);
- }
- }
- }
- }
- }
- }
- return permutation;
- }
- template < class Graph, class OutputIterator, class ColorMap, class DegreeMap,
- class PriorityMap >
- OutputIterator sloan_ordering(Graph& g,
- typename graph_traits< Graph >::vertex_descriptor s,
- typename graph_traits< Graph >::vertex_descriptor e,
- OutputIterator permutation, ColorMap color, DegreeMap degree,
- PriorityMap priority)
- {
- return sloan_ordering(
- g, s, e, permutation, color, degree, priority, WEIGHT1, WEIGHT2);
- }
- template < class Graph, class OutputIterator, class Color, class Degree,
- class Priority, class Weight >
- inline OutputIterator sloan_ordering(Graph& G, OutputIterator permutation,
- Color color, Degree degree, Priority priority, Weight W1, Weight W2)
- {
- typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex;
- Vertex s, e;
- e = sloan_start_end_vertices(G, s, color, degree);
- return sloan_ordering(
- G, s, e, permutation, color, degree, priority, W1, W2);
- }
- template < class Graph, class OutputIterator, class Color, class Degree,
- class Priority >
- inline OutputIterator sloan_ordering(Graph& G, OutputIterator permutation,
- Color color, Degree degree, Priority priority)
- {
- return sloan_ordering(
- G, permutation, color, degree, priority, WEIGHT1, WEIGHT2);
- }
- }
- #endif
|