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