Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/graph/sloan_ordering.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // | |
2 //======================================================================= | |
3 // Copyright 2002 Marc Wintermantel (wintermantel@even-ag.ch) | |
4 // ETH Zurich, Center of Structure Technologies (www.imes.ethz.ch/st) | |
5 // | |
6 // Distributed under the Boost Software License, Version 1.0. (See | |
7 // accompanying file LICENSE_1_0.txt or copy at | |
8 // http://www.boost.org/LICENSE_1_0.txt) | |
9 //======================================================================= | |
10 // | |
11 | |
12 #ifndef BOOST_GRAPH_SLOAN_HPP | |
13 #define BOOST_GRAPH_SLOAN_HPP | |
14 | |
15 #define WEIGHT1 1 //default weight for the distance in the Sloan algorithm | |
16 #define WEIGHT2 2 //default weight for the degree in the Sloan algorithm | |
17 | |
18 #include <boost/config.hpp> | |
19 #include <vector> | |
20 #include <queue> | |
21 #include <algorithm> | |
22 #include <limits> | |
23 #include <boost/pending/queue.hpp> | |
24 #include <boost/graph/graph_traits.hpp> | |
25 #include <boost/graph/breadth_first_search.hpp> | |
26 #include <boost/graph/properties.hpp> | |
27 #include <boost/pending/indirect_cmp.hpp> | |
28 #include <boost/property_map/property_map.hpp> | |
29 #include <boost/graph/visitors.hpp> | |
30 #include <boost/graph/adjacency_list.hpp> | |
31 #include <boost/graph/cuthill_mckee_ordering.hpp> | |
32 | |
33 | |
34 //////////////////////////////////////////////////////////// | |
35 // | |
36 //Sloan-Algorithm for graph reordering | |
37 //(optimzes profile and wavefront, not primiraly bandwidth | |
38 // | |
39 //////////////////////////////////////////////////////////// | |
40 | |
41 namespace boost { | |
42 | |
43 ///////////////////////////////////////////////////////////////////////// | |
44 // Function that returns the maximum depth of | |
45 // a rooted level strucutre (RLS) | |
46 // | |
47 ///////////////////////////////////////////////////////////////////////// | |
48 template<class Distance> | |
49 typename Distance::value_type RLS_depth(Distance& d) | |
50 { | |
51 typename Distance::value_type h_s = 0; | |
52 typename Distance::iterator iter; | |
53 | |
54 for (iter = d.begin(); iter != d.end(); ++iter) | |
55 { | |
56 if(*iter > h_s) | |
57 { | |
58 h_s = *iter; | |
59 } | |
60 } | |
61 | |
62 return h_s; | |
63 } | |
64 | |
65 | |
66 | |
67 ///////////////////////////////////////////////////////////////////////// | |
68 // Function that returns the width of the largest level of | |
69 // a rooted level strucutre (RLS) | |
70 // | |
71 ///////////////////////////////////////////////////////////////////////// | |
72 template<class Distance, class my_int> | |
73 typename Distance::value_type RLS_max_width(Distance& d, my_int depth) | |
74 { | |
75 | |
76 typedef typename Distance::value_type Degree; | |
77 | |
78 //Searching for the maximum width of a level | |
79 std::vector<Degree> dummy_width(depth+1, 0); | |
80 typename std::vector<Degree>::iterator my_it; | |
81 typename Distance::iterator iter; | |
82 Degree w_max = 0; | |
83 | |
84 for (iter = d.begin(); iter != d.end(); ++iter) | |
85 { | |
86 dummy_width[*iter]++; | |
87 } | |
88 | |
89 for(my_it = dummy_width.begin(); my_it != dummy_width.end(); ++my_it) | |
90 { | |
91 if(*my_it > w_max) w_max = *my_it; | |
92 } | |
93 | |
94 return w_max; | |
95 | |
96 } | |
97 | |
98 | |
99 ///////////////////////////////////////////////////////////////////////// | |
100 // Function for finding a good starting node for Sloan algorithm | |
101 // | |
102 // This is to find a good starting node. "good" is in the sense | |
103 // of the ordering generated. | |
104 ///////////////////////////////////////////////////////////////////////// | |
105 template <class Graph, class ColorMap, class DegreeMap> | |
106 typename graph_traits<Graph>::vertex_descriptor | |
107 sloan_start_end_vertices(Graph& G, | |
108 typename graph_traits<Graph>::vertex_descriptor &s, | |
109 ColorMap color, | |
110 DegreeMap degree) | |
111 { | |
112 typedef typename property_traits<DegreeMap>::value_type Degree; | |
113 typedef typename graph_traits<Graph>::vertex_descriptor Vertex; | |
114 typedef typename std::vector< typename graph_traits<Graph>::vertices_size_type>::iterator vec_iter; | |
115 typedef typename graph_traits<Graph>::vertices_size_type size_type; | |
116 | |
117 typedef typename property_map<Graph, vertex_index_t>::const_type VertexID; | |
118 | |
119 s = *(vertices(G).first); | |
120 Vertex e = s; | |
121 Vertex i; | |
122 Degree my_degree = get(degree, s ); | |
123 Degree dummy, h_i, h_s, w_i, w_e; | |
124 bool new_start = true; | |
125 Degree maximum_degree = 0; | |
126 | |
127 //Creating a std-vector for storing the distance from the start vertex in dist | |
128 std::vector<typename graph_traits<Graph>::vertices_size_type> dist(num_vertices(G), 0); | |
129 | |
130 //Wrap a property_map_iterator around the std::iterator | |
131 boost::iterator_property_map<vec_iter, VertexID, size_type, size_type&> dist_pmap(dist.begin(), get(vertex_index, G)); | |
132 | |
133 //Creating a property_map for the indices of a vertex | |
134 typename property_map<Graph, vertex_index_t>::type index_map = get(vertex_index, G); | |
135 | |
136 //Creating a priority queue | |
137 typedef indirect_cmp<DegreeMap, std::greater<Degree> > Compare; | |
138 Compare comp(degree); | |
139 std::priority_queue<Vertex, std::vector<Vertex>, Compare> degree_queue(comp); | |
140 | |
141 //step 1 | |
142 //Scan for the vertex with the smallest degree and the maximum degree | |
143 typename graph_traits<Graph>::vertex_iterator ui, ui_end; | |
144 for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) | |
145 { | |
146 dummy = get(degree, *ui); | |
147 | |
148 if(dummy < my_degree) | |
149 { | |
150 my_degree = dummy; | |
151 s = *ui; | |
152 } | |
153 | |
154 if(dummy > maximum_degree) | |
155 { | |
156 maximum_degree = dummy; | |
157 } | |
158 } | |
159 //end 1 | |
160 | |
161 do{ | |
162 new_start = false; //Setting the loop repetition status to false | |
163 | |
164 //step 2 | |
165 //initialize the the disance std-vector with 0 | |
166 for(typename std::vector<typename graph_traits<Graph>::vertices_size_type>::iterator iter = dist.begin(); iter != dist.end(); ++iter) *iter = 0; | |
167 | |
168 //generating the RLS (rooted level structure) | |
169 breadth_first_search | |
170 (G, s, visitor | |
171 ( | |
172 make_bfs_visitor(record_distances(dist_pmap, on_tree_edge() ) ) | |
173 ) | |
174 ); | |
175 | |
176 //end 2 | |
177 | |
178 //step 3 | |
179 //calculating the depth of the RLS | |
180 h_s = RLS_depth(dist); | |
181 | |
182 //step 4 | |
183 //pushing one node of each degree in an ascending manner into degree_queue | |
184 std::vector<bool> shrink_trace(maximum_degree, false); | |
185 for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) | |
186 { | |
187 dummy = get(degree, *ui); | |
188 | |
189 if( (dist[index_map[*ui]] == h_s ) && ( !shrink_trace[ dummy ] ) ) | |
190 { | |
191 degree_queue.push(*ui); | |
192 shrink_trace[ dummy ] = true; | |
193 } | |
194 } | |
195 | |
196 //end 3 & 4 | |
197 | |
198 | |
199 // step 5 | |
200 // Initializing w | |
201 w_e = (std::numeric_limits<Degree>::max)(); | |
202 //end 5 | |
203 | |
204 | |
205 //step 6 | |
206 //Testing for termination | |
207 while( !degree_queue.empty() ) | |
208 { | |
209 i = degree_queue.top(); //getting the node with the lowest degree from the degree queue | |
210 degree_queue.pop(); //ereasing the node with the lowest degree from the degree queue | |
211 | |
212 //generating a RLS | |
213 for(typename std::vector<typename graph_traits<Graph>::vertices_size_type>::iterator iter = dist.begin(); iter != dist.end(); ++iter) *iter = 0; | |
214 | |
215 breadth_first_search | |
216 (G, i, boost::visitor | |
217 ( | |
218 make_bfs_visitor(record_distances(dist_pmap, on_tree_edge() ) ) | |
219 ) | |
220 ); | |
221 | |
222 //Calculating depth and width of the rooted level | |
223 h_i = RLS_depth(dist); | |
224 w_i = RLS_max_width(dist, h_i); | |
225 | |
226 //Testing for termination | |
227 if( (h_i > h_s) && (w_i < w_e) ) | |
228 { | |
229 h_s = h_i; | |
230 s = i; | |
231 while(!degree_queue.empty()) degree_queue.pop(); | |
232 new_start = true; | |
233 } | |
234 else if(w_i < w_e) | |
235 { | |
236 w_e = w_i; | |
237 e = i; | |
238 } | |
239 } | |
240 //end 6 | |
241 | |
242 }while(new_start); | |
243 | |
244 return e; | |
245 } | |
246 | |
247 ////////////////////////////////////////////////////////////////////////// | |
248 // Sloan algorithm with a given starting Vertex. | |
249 // | |
250 // This algorithm requires user to provide a starting vertex to | |
251 // compute Sloan ordering. | |
252 ////////////////////////////////////////////////////////////////////////// | |
253 template <class Graph, class OutputIterator, | |
254 class ColorMap, class DegreeMap, | |
255 class PriorityMap, class Weight> | |
256 OutputIterator | |
257 sloan_ordering(Graph& g, | |
258 typename graph_traits<Graph>::vertex_descriptor s, | |
259 typename graph_traits<Graph>::vertex_descriptor e, | |
260 OutputIterator permutation, | |
261 ColorMap color, | |
262 DegreeMap degree, | |
263 PriorityMap priority, | |
264 Weight W1, | |
265 Weight W2) | |
266 { | |
267 //typedef typename property_traits<DegreeMap>::value_type Degree; | |
268 typedef typename property_traits<PriorityMap>::value_type Degree; | |
269 typedef typename property_traits<ColorMap>::value_type ColorValue; | |
270 typedef color_traits<ColorValue> Color; | |
271 typedef typename graph_traits<Graph>::vertex_descriptor Vertex; | |
272 typedef typename std::vector<typename graph_traits<Graph>::vertices_size_type>::iterator vec_iter; | |
273 typedef typename graph_traits<Graph>::vertices_size_type size_type; | |
274 | |
275 typedef typename property_map<Graph, vertex_index_t>::const_type VertexID; | |
276 | |
277 | |
278 //Creating a std-vector for storing the distance from the end vertex in it | |
279 typename std::vector<typename graph_traits<Graph>::vertices_size_type> dist(num_vertices(g), 0); | |
280 | |
281 //Wrap a property_map_iterator around the std::iterator | |
282 boost::iterator_property_map<vec_iter, VertexID, size_type, size_type&> dist_pmap(dist.begin(), get(vertex_index, g)); | |
283 | |
284 breadth_first_search | |
285 (g, e, visitor | |
286 ( | |
287 make_bfs_visitor(record_distances(dist_pmap, on_tree_edge() ) ) | |
288 ) | |
289 ); | |
290 | |
291 //Creating a property_map for the indices of a vertex | |
292 typename property_map<Graph, vertex_index_t>::type index_map = get(vertex_index, g); | |
293 | |
294 //Sets the color and priority to their initial status | |
295 Degree cdeg; | |
296 typename graph_traits<Graph>::vertex_iterator ui, ui_end; | |
297 for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) | |
298 { | |
299 put(color, *ui, Color::white()); | |
300 cdeg=get(degree, *ui)+1; | |
301 put(priority, *ui, W1*dist[index_map[*ui]]-W2*cdeg ); | |
302 } | |
303 | |
304 //Priority list | |
305 typedef indirect_cmp<PriorityMap, std::greater<Degree> > Compare; | |
306 Compare comp(priority); | |
307 std::list<Vertex> priority_list; | |
308 | |
309 //Some more declarations | |
310 typename graph_traits<Graph>::out_edge_iterator ei, ei_end, ei2, ei2_end; | |
311 Vertex u, v, w; | |
312 | |
313 put(color, s, Color::green()); //Sets the color of the starting vertex to gray | |
314 priority_list.push_front(s); //Puts s into the priority_list | |
315 | |
316 while ( !priority_list.empty() ) | |
317 { | |
318 priority_list.sort(comp); //Orders the elements in the priority list in an ascending manner | |
319 | |
320 u = priority_list.front(); //Accesses the last element in the priority list | |
321 priority_list.pop_front(); //Removes the last element in the priority list | |
322 | |
323 if(get(color, u) == Color::green() ) | |
324 { | |
325 //for-loop over all out-edges of vertex u | |
326 for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) | |
327 { | |
328 v = target(*ei, g); | |
329 | |
330 put( priority, v, get(priority, v) + W2 ); //updates the priority | |
331 | |
332 if (get(color, v) == Color::white() ) //test if the vertex is inactive | |
333 { | |
334 put(color, v, Color::green() ); //giving the vertex a preactive status | |
335 priority_list.push_front(v); //writing the vertex in the priority_queue | |
336 } | |
337 } | |
338 } | |
339 | |
340 //Here starts step 8 | |
341 *permutation++ = u; //Puts u to the first position in the permutation-vector | |
342 put(color, u, Color::black() ); //Gives u an inactive status | |
343 | |
344 //for loop over all the adjacent vertices of u | |
345 for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) { | |
346 | |
347 v = target(*ei, g); | |
348 | |
349 if (get(color, v) == Color::green() ) { //tests if the vertex is inactive | |
350 | |
351 put(color, v, Color::red() ); //giving the vertex an active status | |
352 put(priority, v, get(priority, v)+W2); //updates the priority | |
353 | |
354 //for loop over alll adjacent vertices of v | |
355 for (boost::tie(ei2, ei2_end) = out_edges(v, g); ei2 != ei2_end; ++ei2) { | |
356 w = target(*ei2, g); | |
357 | |
358 if(get(color, w) != Color::black() ) { //tests if vertex is postactive | |
359 | |
360 put(priority, w, get(priority, w)+W2); //updates the priority | |
361 | |
362 if(get(color, w) == Color::white() ){ | |
363 | |
364 put(color, w, Color::green() ); // gives the vertex a preactive status | |
365 priority_list.push_front(w); // puts the vertex into the priority queue | |
366 | |
367 } //end if | |
368 | |
369 } //end if | |
370 | |
371 } //end for | |
372 | |
373 } //end if | |
374 | |
375 } //end for | |
376 | |
377 } //end while | |
378 | |
379 | |
380 return permutation; | |
381 } | |
382 | |
383 ///////////////////////////////////////////////////////////////////////////////////////// | |
384 // Same algorithm as before, but without the weights given (taking default weights | |
385 template <class Graph, class OutputIterator, | |
386 class ColorMap, class DegreeMap, | |
387 class PriorityMap> | |
388 OutputIterator | |
389 sloan_ordering(Graph& g, | |
390 typename graph_traits<Graph>::vertex_descriptor s, | |
391 typename graph_traits<Graph>::vertex_descriptor e, | |
392 OutputIterator permutation, | |
393 ColorMap color, | |
394 DegreeMap degree, | |
395 PriorityMap priority) | |
396 { | |
397 return sloan_ordering(g, s, e, permutation, color, degree, priority, WEIGHT1, WEIGHT2); | |
398 } | |
399 | |
400 | |
401 ////////////////////////////////////////////////////////////////////////// | |
402 // Sloan algorithm without a given starting Vertex. | |
403 // | |
404 // This algorithm finds a good starting vertex itself to | |
405 // compute Sloan-ordering. | |
406 ////////////////////////////////////////////////////////////////////////// | |
407 | |
408 | |
409 | |
410 template < class Graph, class OutputIterator, | |
411 class Color, class Degree, | |
412 class Priority, class Weight> | |
413 inline OutputIterator | |
414 sloan_ordering(Graph& G, | |
415 OutputIterator permutation, | |
416 Color color, | |
417 Degree degree, | |
418 Priority priority, | |
419 Weight W1, | |
420 Weight W2 ) | |
421 { | |
422 typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex; | |
423 | |
424 Vertex s, e; | |
425 e = sloan_start_end_vertices(G, s, color, degree); | |
426 | |
427 return sloan_ordering(G, s, e, permutation, color, degree, priority, W1, W2); | |
428 } | |
429 | |
430 ///////////////////////////////////////////////////////////////////////////////////////// | |
431 // Same as before, but without given weights (default weights are taken instead) | |
432 template < class Graph, class OutputIterator, | |
433 class Color, class Degree, | |
434 class Priority > | |
435 inline OutputIterator | |
436 sloan_ordering(Graph& G, | |
437 OutputIterator permutation, | |
438 Color color, | |
439 Degree degree, | |
440 Priority priority) | |
441 { | |
442 return sloan_ordering(G, permutation, color, degree, priority, WEIGHT1, WEIGHT2); | |
443 } | |
444 | |
445 | |
446 } // namespace boost | |
447 | |
448 | |
449 #endif // BOOST_GRAPH_SLOAN_HPP |