| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 | 
							- //
 
- //=======================================================================
 
- // Copyright 2002 Marc Wintermantel (wintermantel@even-ag.ch)
 
- // ETH Zurich, Center of Structure Technologies
 
- // (https://web.archive.org/web/20050307090307/http://www.structures.ethz.ch/)
 
- //
 
- // Distributed under 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)
 
- //=======================================================================
 
- //
 
- #ifndef BOOST_GRAPH_SLOAN_HPP
 
- #define BOOST_GRAPH_SLOAN_HPP
 
- #define WEIGHT1 1 // default weight for the distance in the Sloan algorithm
 
- #define WEIGHT2 2 // default weight for the degree in the Sloan algorithm
 
- #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>
 
- ////////////////////////////////////////////////////////////
 
- //
 
- // Sloan-Algorithm for graph reordering
 
- //(optimzes profile and wavefront, not primiraly bandwidth
 
- //
 
- ////////////////////////////////////////////////////////////
 
- namespace boost
 
- {
 
- /////////////////////////////////////////////////////////////////////////
 
- // Function that returns the maximum depth of
 
- // a rooted level strucutre (RLS)
 
- //
 
- /////////////////////////////////////////////////////////////////////////
 
- 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;
 
- }
 
- /////////////////////////////////////////////////////////////////////////
 
- // Function that returns the width of the largest level of
 
- // a rooted level strucutre (RLS)
 
- //
 
- /////////////////////////////////////////////////////////////////////////
 
- template < class Distance, class my_int >
 
- typename Distance::value_type RLS_max_width(Distance& d, my_int depth)
 
- {
 
-     typedef typename Distance::value_type Degree;
 
-     // Searching for the maximum width of a level
 
-     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;
 
- }
 
- /////////////////////////////////////////////////////////////////////////
 
- // Function for finding a good starting node for Sloan algorithm
 
- //
 
- // This is to find a good starting node. "good" is in the sense
 
- // of the ordering generated.
 
- /////////////////////////////////////////////////////////////////////////
 
- 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;
 
-     // Creating a std-vector for storing the distance from the start vertex in
 
-     // dist
 
-     std::vector< typename graph_traits< Graph >::vertices_size_type > dist(
 
-         num_vertices(G), 0);
 
-     // Wrap a property_map_iterator around the std::iterator
 
-     boost::iterator_property_map< vec_iter, VertexID, size_type, size_type& >
 
-         dist_pmap(dist.begin(), get(vertex_index, G));
 
-     // Creating a property_map for the indices of a vertex
 
-     typename property_map< Graph, vertex_index_t >::type index_map
 
-         = get(vertex_index, G);
 
-     // Creating a priority queue
 
-     typedef indirect_cmp< DegreeMap, std::greater< Degree > > Compare;
 
-     Compare comp(degree);
 
-     std::priority_queue< Vertex, std::vector< Vertex >, Compare > degree_queue(
 
-         comp);
 
-     // step 1
 
-     // Scan for the vertex with the smallest degree and the maximum degree
 
-     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;
 
-         }
 
-     }
 
-     // end 1
 
-     do
 
-     {
 
-         new_start = false; // Setting the loop repetition status to false
 
-         // step 2
 
-         // initialize the the disance std-vector with 0
 
-         for (typename std::vector< typename graph_traits<
 
-                  Graph >::vertices_size_type >::iterator iter
 
-              = dist.begin();
 
-              iter != dist.end(); ++iter)
 
-             *iter = 0;
 
-         // generating the RLS (rooted level structure)
 
-         breadth_first_search(G, s,
 
-             visitor(
 
-                 make_bfs_visitor(record_distances(dist_pmap, on_tree_edge()))));
 
-         // end 2
 
-         // step 3
 
-         // calculating the depth of the RLS
 
-         h_s = RLS_depth(dist);
 
-         // step 4
 
-         // pushing one node of each degree in an ascending manner into
 
-         // degree_queue
 
-         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;
 
-             }
 
-         }
 
-         // end 3 & 4
 
-         // step 5
 
-         // Initializing w
 
-         w_e = (std::numeric_limits< Degree >::max)();
 
-         // end 5
 
-         // step 6
 
-         // Testing for termination
 
-         while (!degree_queue.empty())
 
-         {
 
-             i = degree_queue.top(); // getting the node with the lowest degree
 
-                                     // from the degree queue
 
-             degree_queue.pop(); // ereasing the node with the lowest degree from
 
-                                 // the degree queue
 
-             // generating a RLS
 
-             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()))));
 
-             // Calculating depth and width of the rooted level
 
-             h_i = RLS_depth(dist);
 
-             w_i = RLS_max_width(dist, h_i);
 
-             // Testing for termination
 
-             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;
 
-             }
 
-         }
 
-         // end 6
 
-     } while (new_start);
 
-     return e;
 
- }
 
- //////////////////////////////////////////////////////////////////////////
 
- // Sloan algorithm with a given starting Vertex.
 
- //
 
- // This algorithm requires user to provide a starting vertex to
 
- // compute Sloan ordering.
 
- //////////////////////////////////////////////////////////////////////////
 
- 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<DegreeMap>::value_type Degree;
 
-     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;
 
-     // Creating a std-vector for storing the distance from the end vertex in it
 
-     typename std::vector< typename graph_traits< Graph >::vertices_size_type >
 
-         dist(num_vertices(g), 0);
 
-     // Wrap a property_map_iterator around the std::iterator
 
-     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()))));
 
-     // Creating a property_map for the indices of a vertex
 
-     typename property_map< Graph, vertex_index_t >::type index_map
 
-         = get(vertex_index, g);
 
-     // Sets the color and priority to their initial status
 
-     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);
 
-     }
 
-     // Priority list
 
-     typedef indirect_cmp< PriorityMap, std::greater< Degree > > Compare;
 
-     Compare comp(priority);
 
-     std::list< Vertex > priority_list;
 
-     // Some more declarations
 
-     typename graph_traits< Graph >::out_edge_iterator ei, ei_end, ei2, ei2_end;
 
-     Vertex u, v, w;
 
-     put(color, s,
 
-         Color::green()); // Sets the color of the starting vertex to gray
 
-     priority_list.push_front(s); // Puts s into the priority_list
 
-     while (!priority_list.empty())
 
-     {
 
-         priority_list.sort(comp); // Orders the elements in the priority list in
 
-                                   // an ascending manner
 
-         u = priority_list
 
-                 .front(); // Accesses the last element in the priority list
 
-         priority_list
 
-             .pop_front(); // Removes the last element in the priority list
 
-         if (get(color, u) == Color::green())
 
-         {
 
-             // for-loop over all out-edges of vertex u
 
-             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); // updates the priority
 
-                 if (get(color, v)
 
-                     == Color::white()) // test if the vertex is inactive
 
-                 {
 
-                     put(color, v,
 
-                         Color::green()); // giving the vertex a preactive status
 
-                     priority_list.push_front(
 
-                         v); // writing the vertex in the priority_queue
 
-                 }
 
-             }
 
-         }
 
-         // Here starts step 8
 
-         *permutation++
 
-             = u; // Puts u to the first position in the permutation-vector
 
-         put(color, u, Color::black()); // Gives u an inactive status
 
-         // for loop over all the adjacent vertices of u
 
-         for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei)
 
-         {
 
-             v = target(*ei, g);
 
-             if (get(color, v) == Color::green())
 
-             { // tests if the vertex is inactive
 
-                 put(color, v,
 
-                     Color::red()); // giving the vertex an active status
 
-                 put(priority, v, get(priority, v) + W2); // updates the priority
 
-                 // for loop over alll adjacent vertices of v
 
-                 for (boost::tie(ei2, ei2_end) = out_edges(v, g); ei2 != ei2_end;
 
-                      ++ei2)
 
-                 {
 
-                     w = target(*ei2, g);
 
-                     if (get(color, w) != Color::black())
 
-                     { // tests if vertex is postactive
 
-                         put(priority, w,
 
-                             get(priority, w) + W2); // updates the priority
 
-                         if (get(color, w) == Color::white())
 
-                         {
 
-                             put(color, w, Color::green()); // gives the vertex a
 
-                                                            // preactive status
 
-                             priority_list.push_front(
 
-                                 w); // puts the vertex into the priority queue
 
-                         } // end if
 
-                     } // end if
 
-                 } // end for
 
-             } // end if
 
-         } // end for
 
-     } // end while
 
-     return permutation;
 
- }
 
- /////////////////////////////////////////////////////////////////////////////////////////
 
- // Same algorithm as before, but without the weights given (taking default
 
- // weights
 
- 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);
 
- }
 
- //////////////////////////////////////////////////////////////////////////
 
- // Sloan algorithm without a given starting Vertex.
 
- //
 
- // This algorithm finds a good starting vertex itself to
 
- // compute Sloan-ordering.
 
- //////////////////////////////////////////////////////////////////////////
 
- 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);
 
- }
 
- /////////////////////////////////////////////////////////////////////////////////////////
 
- // Same as before, but without given weights (default weights are taken instead)
 
- 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);
 
- }
 
- } // namespace boost
 
- #endif // BOOST_GRAPH_SLOAN_HPP
 
 
  |