1 // This is brl/bbas/bgrl2/bgrl2_graph.hxx
2 #ifndef bgrl2_graph_hxx_
3 #define bgrl2_graph_hxx_
4 //:
5 // \file
6
7 #include <iostream>
8 #include <vector>
9 #include "bgrl2_graph.h"
10
11 #include <cassert>
12 #ifdef _MSC_VER
13 # include <vcl_msvc_warnings.h>
14 #endif
15
16 //-------------------------------------------------------------------
17 // Graph building functions
18 //-------------------------------------------------------------------
19
20 //: Adds a new vertex to the graph
21 template<class V, class E>
add_vertex(V_sptr v)22 bool bgrl2_graph<V,E>::add_vertex(V_sptr v)
23 {
24 if (!v) return false;
25 vertices_.push_back(v);
26
27 return true; //not doing a duplicate check anymore
28 }
29
30 //: check existence
31 template<class V, class E>
exists(V_sptr v)32 bool bgrl2_graph<V,E>::exists(V_sptr v)
33 {
34 for ( vertex_iterator v_itr = vertices_.begin();
35 v_itr != vertices_.end(); ++v_itr )
36 {
37 if ((*v_itr) == v)
38 return true;
39 }
40 return false;
41 }
42
43
44 //: Deletes a vertex in the graph
45 template<class V, class E>
remove_vertex(V_sptr v)46 bool bgrl2_graph<V,E>::remove_vertex(V_sptr v)
47 {
48 if (!v) return false;
49
50 vertices_.remove(v);
51
52 //delete all the edges connected to this vertex
53 while (v->out_edges().size()>0)
54 remove_edge(*v->out_edges_begin());
55
56 while (v->in_edges().size()>0)
57 remove_edge(*v->in_edges_begin());
58
59 return true;
60 }
61
62 //: Add an edge
63 template<class V, class E>
add_edge(E_sptr e)64 bool bgrl2_graph<V,E>::add_edge(E_sptr e)
65 {
66 // verify that this edge is not already present
67 vertex_edge_iterator e_itr = e->source()->out_edges_begin();
68 for (; e_itr != e->source()->out_edges_end(); ++e_itr )
69 if ((*e_itr)->target() == e->target())
70 return false;
71
72 edges_.push_back(e);
73 return true;
74 }
75
76 //: Add an edge with no duplicate checking
77 template<class V, class E>
add_edge_no_check(E_sptr e)78 bool bgrl2_graph<V,E>::add_edge_no_check(E_sptr e)
79 {
80 if (!e)
81 return false;
82 edges_.push_back(e);
83 return true;
84 }
85
86
87 //: Add an edge between \p v1 and \p v2
88 template<class V, class E>
add_edge(V_sptr v1,V_sptr v2)89 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::add_edge(V_sptr v1, V_sptr v2)
90 {
91 if (!v1 || !v2)
92 return nullptr;
93 if (v1==v2)
94 return nullptr; //can't add the edge to itself
95
96 //add the vertices first
97 if (!this->exists(v1))
98 this->add_vertex(v1);
99 if (!this->exists(v2))
100 this->add_vertex(v2);
101
102 //if ( vertices_.count(v1) == 0 && !this->add_vertex(v1) )
103 // return false;
104 //if ( vertices_.count(v2) == 0 && !this->add_vertex(v2) )
105 // return false;
106
107 //set the source and target nodes
108 E_sptr e = new E(v1, v2);
109
110 if (this->add_edge(e)){
111 //if this is a valid edge, add the links from the nodes to this edge
112 v1->add_outgoing_edge(e);
113 v2->add_incoming_edge(e);
114
115 return e;
116 }
117
118 return nullptr; //edge wasn't added
119 }
120
121 //: Remove an edge
122 template<class V, class E>
remove_edge(E_sptr e)123 bool bgrl2_graph<V,E>::remove_edge(E_sptr e)
124 {
125 if (!e) return false;
126
127 edges_.remove(e);
128
129 //update connectivity from nodes
130 bool success = e->source()->del_out_edge(e);
131
132 //the edge might not have a target node
133 if (e->target())
134 success = success && e->target()->del_in_edge(e);
135
136 return success;
137 }
138
139 //: Remove the edge between \p v1 and \p v2
140 // \todo {finish this.}
141 template<class V, class E>
remove_edge(V_sptr v1,V_sptr v2)142 bool bgrl2_graph<V,E>::remove_edge(V_sptr v1, V_sptr v2 )
143 {
144 if (!v1 || !v2) return false;
145
146 // verify that this edge is not already present
147 vertex_edge_iterator e_itr = v1->out_edges_begin();
148 for (; e_itr != v1->out_edges_end(); ++e_itr )
149 {
150 if ((*e_itr)->target() == v2){
151 E_sptr e = (*e_itr);
152
153 return remove_edge(e);
154 }
155 }
156
157 return false;
158 }
159
160 //: delete all the vertices
161 template<class V, class E>
del_all_vertices()162 void bgrl2_graph<V,E>::del_all_vertices()
163 {
164 while (vertices_.size()>0){
165 remove_vertex(*vertices_.begin());
166 }
167 }
168
169 //: delete all the edges
170 template<class V, class E>
del_all_edges()171 void bgrl2_graph<V,E>::del_all_edges()
172 {
173 while (edges_.size()>0){
174 remove_edge(*edges_.begin());
175 }
176 }
177
178 //: delete all vertices in the graph that are not adjacent to any edges
179 template<class V, class E>
purge_isolated_vertices()180 void bgrl2_graph<V,E>::purge_isolated_vertices()
181 {
182 std::vector<V_sptr> vert_to_del;
183 for ( vertex_iterator v_itr = vertices_.begin();
184 v_itr != vertices_.end(); ++v_itr )
185 {
186 if ((*v_itr)->degree()==0)
187 vert_to_del.push_back(*v_itr);
188 }
189
190 //is there a better way to do this ???
191 for (unsigned int i=0; i<vert_to_del.size(); i++)
192 remove_vertex(vert_to_del[i]);
193
194 vert_to_del.clear();
195 }
196
197 //: return all vertices with degree one
198 template<class V, class E>
get_all_degree_one_vertices(std::vector<V_sptr> & vertices)199 void bgrl2_graph<V,E>::get_all_degree_one_vertices(std::vector<V_sptr>& vertices)
200 {
201 for ( vertex_iterator v_itr = vertices_.begin();
202 v_itr != vertices_.end(); ++v_itr )
203 {
204 if ((*v_itr)->degree()==1)
205 vertices.push_back(*v_itr);
206 }
207 }
208
209 //: clear all the nodes and edges of this graph
210 template<class V, class E>
clear()211 void bgrl2_graph<V,E>::clear()
212 {
213 del_all_edges();
214 del_all_vertices();
215 }
216
217 //-------------------------------------------------------------------
218 // Directed graph operations
219 //-------------------------------------------------------------------
220
221 //: returns the successor of edge e in the adjacency list of node source(e) (nil if it does not exist).
222 template<class V, class E>
adj_succ(E_sptr e)223 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::adj_succ(E_sptr e)
224 {
225 return adj_succ(e, e->source());
226 }
227
228 //: returns the predecessor of edge e in the adjacency list of node source(e) (nil if it does not exist).
229 template<class V, class E>
adj_pred(E_sptr e)230 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::adj_pred(E_sptr e)
231 {
232 return adj_pred(e, e->source());
233 }
234
235 //: returns the cyclic successor of edge e in the adjacency list of node source(e).
236 template<class V, class E>
cyclic_adj_succ(E_sptr e)237 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::cyclic_adj_succ(E_sptr e)
238 {
239 return cyclic_adj_succ(e, e->source());
240 }
241
242 //: returns the cyclic predecessor of edge e in the adjacency list of node source(e).
243 template<class V, class E>
cyclic_adj_pred(E_sptr e)244 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::cyclic_adj_pred(E_sptr e)
245 {
246 return cyclic_adj_pred(e, e->source());
247 }
248
249 //: returns the first edge of in_edges(v) (nil if this list is empty).
250 template<class V, class E>
first_in_edge(V_sptr v)251 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::first_in_edge(V_sptr v)
252 {
253 if (v->in_edges().size()>0)
254 return v->in_edges().front();
255 else
256 return nullptr;
257 }
258
259 //: returns the last edge of in_edges(v) (nil if this list is empty).
260 template<class V, class E>
last_in_edge(V_sptr v)261 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::last_in_edge(V_sptr v)
262 {
263 if (v->in_edges().size()>0)
264 return v->in_edges().back();
265 else
266 return nullptr;
267 }
268
269 //: returns the first edge of out_edges(v) (nil if this list is empty).
270 template<class V, class E>
first_out_edge(V_sptr v)271 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::first_out_edge(V_sptr v)
272 {
273 if (v->out_edges().size()>0)
274 return v->out_edges().front();
275 else
276 return nullptr;
277 }
278
279 //: returns the last edge of out_edges(v) (nil if this list is empty).
280 template<class V, class E>
last_out_edge(V_sptr v)281 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::last_out_edge(V_sptr v)
282 {
283 if (v->out_edges().size()>0)
284 return v->out_edges().back();
285 else
286 return nullptr;
287 }
288
289 //: returns the successor of edge e in in_edges(target(e)) (nil if it does not exist).
290 template<class V, class E>
in_succ(E_sptr e)291 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::in_succ(E_sptr e)
292 {
293 return adj_succ(e, e->target());
294 }
295
296 //: returns the predecessor of edge e in in_edges(target(e)) (nil if it does not exist).
297 template<class V, class E>
in_pred(E_sptr e)298 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::in_pred(E_sptr e)
299 {
300 return adj_pred(e, e->target());
301 }
302
303 //: returns the cyclic successor of edge e in in_edges(target(e)) (nil if it does not exist).
304 template<class V, class E>
cyclic_in_succ(E_sptr e)305 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::cyclic_in_succ(E_sptr e)
306 {
307 return cyclic_adj_succ(e, e->target());
308 }
309
310 //: returns the cyclic predecessor of edge e in in_edges(target(e)) (nil if it does not exist).
311 template<class V, class E>
cyclic_in_pred(E_sptr e)312 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::cyclic_in_pred(E_sptr e)
313 {
314 return cyclic_adj_pred(e, e->target());
315 }
316
317 //-------------------------------------------------------------------
318 // Undirected graph operations
319 //-------------------------------------------------------------------
320
321 // IMPORTANT WARNING to users of this graph class to work with DIRECTED graphs:
322 // e.g. you have the following graph with times of creation of the edges
323 // as noted by the numbers
324 // 2
325 // ^
326 // |
327 // 1 -> A <- 3
328 // |
329 // v
330 // 4
331 // Ideally, cyclic_adj_succ(1,A) should return 2
332 // however, in this implementation it returns 3 (the next in_edge)
333 // (When this class is used for shock_graphs because of special properties
334 // of shock_graphs, this is not a problem, i.e. the case in our example
335 // never happens in a shock graph, it is against the nature of flows
336 // that gives rise to directed shock graphs.)
337 //
338 // This should be noted and corrected or undirected graph operations
339 // should never be used on directed graphs where the example case can occur
340
341 //: returns the first edge in the adjacency list of v (nil if this list is empty).
342 template<class V, class E>
first_adj_edge(V_sptr v)343 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::first_adj_edge(V_sptr v)
344 {
345 if (first_in_edge(v))
346 return first_in_edge(v);
347 else
348 return first_out_edge(v);
349 }
350
351 //: returns the last edge in the adjacency list of v (nil if this list is empty).
352 template<class V, class E>
last_adj_edge(V_sptr v)353 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::last_adj_edge(V_sptr v)
354 {
355 if (last_out_edge(v))
356 return last_out_edge(v);
357 else
358 return last_in_edge(v);
359 }
360
361 //: returns the successor of edge e in the adjacency list of v.
362 // Precondition: e is incident to v.
363 template<class V, class E>
adj_succ(E_sptr,V_sptr)364 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::adj_succ(E_sptr /*e*/, V_sptr /*v*/)
365 {
366 return nullptr;
367 }
368
369 //: returns the predecessor of edge e in the adjacency list of v.
370 // Precondition: e is incident to v.
371 template<class V, class E>
adj_pred(E_sptr,V_sptr)372 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::adj_pred(E_sptr /*e*/, V_sptr /*v*/)
373 {
374 return nullptr;
375 }
376
377 //: returns the cyclic successor(CW) of edge e in the adjacency list of v.
378 // Precondition: e is incident to v.
379 // if this is a leaf edge, it should return itself
380 template<class V, class E>
cyclic_adj_succ(E_sptr e,V_sptr v)381 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::cyclic_adj_succ(E_sptr e, V_sptr v)
382 {
383 E_sptr adj_edge=nullptr;
384
385 //find the edge e in the adjacency list of v
386
387 //look in the in_edges list first
388 for ( vertex_edge_iterator itr = v->in_edges_begin();
389 itr != v->in_edges_end(); ++itr )
390 {
391 if ((*itr) == e) //edge found
392 {
393 itr++;
394 if (itr != v->in_edges_end()){
395 adj_edge = (*itr);
396 }
397 else { //last in_edge, check out_edges
398 if (v->out_edges().size()>0)
399 adj_edge = v->out_edges().front();
400 else //no out_edges
401 adj_edge = v->in_edges().front();
402 }
403 break;
404 }
405 }
406
407 //if not found look in the out_edges
408 if (!adj_edge)
409 {
410 for ( vertex_edge_iterator itr = v->out_edges_begin();
411 itr != v->out_edges_end(); ++itr )
412 {
413 if ((*itr) == e) //edge found
414 {
415 itr++;
416 if (itr != v->out_edges_end())
417 adj_edge = (*itr);
418 else //last out_edge, check in_edges
419 {
420 if (v->in_edges().size()>0)
421 adj_edge = v->in_edges().front();
422 else //no in_edges
423 adj_edge = v->out_edges().front();
424 }
425 break;
426 }
427 }
428 }
429
430 //make sure we found it
431 //assert (adj_edge);
432
433 return adj_edge;
434 }
435
436 //: returns the cyclic predecessor(CW) of edge e in the adjacency list of v.
437 // Precondition: e is incident to v.
438 // if this is a leaf edge, it should return itself
439 template<class V, class E>
cyclic_adj_pred(E_sptr e,V_sptr v)440 typename bgrl2_graph<V,E>::E_sptr bgrl2_graph<V,E>::cyclic_adj_pred(E_sptr e, V_sptr v)
441 {
442 E_sptr adj_edge=nullptr;
443
444 //find the edge e in the adjacency list of v
445
446 //look in the in_edges list first
447 for ( vertex_edge_iterator itr = v->in_edges_begin();
448 itr != v->in_edges_end(); ++itr )
449 {
450 if ((*itr) == e) //edge found
451 {
452 if (itr == v->in_edges_begin())
453 {
454 //first in_edge, look in out_edges
455 if (v->out_edges().size()>0)
456 adj_edge = v->out_edges().back();
457 else //no out_edges
458 adj_edge = v->in_edges().back();
459 }
460 else {
461 itr--;
462 adj_edge = (*itr);
463 }
464 break;
465 }
466 }
467
468 //if not found look in the out_edges
469 if (!adj_edge)
470 {
471 for ( vertex_edge_iterator itr = v->out_edges_begin();
472 itr != v->out_edges_end(); ++itr )
473 {
474 if ((*itr) == e) //edge found
475 {
476 if (itr == v->out_edges_begin())
477 {
478 //first out_edge, check in_edges
479 if (v->in_edges().size()>0)
480 adj_edge = v->in_edges().back();
481 else //no in_edges
482 adj_edge = v->out_edges().back();
483 }
484 else {
485 itr--;
486 adj_edge = (*itr);
487 }
488 break;
489 }
490 }
491 }
492
493 //make sure we found it
494 assert (adj_edge);
495
496 return adj_edge;
497 }
498
499 //-------------------------------------------------------------------
500 // Standard Graph functions
501 //-------------------------------------------------------------------
502
503 //: Return true if the graph contains a cycle
504 // This method can go to bgrl2_algo
505 template<class V, class E>
has_cycle()506 bool bgrl2_graph<V,E>::has_cycle()
507 {
508 //: Theorem: given an undirected graph G(V,E), there exists a cycle within the graph if |E| >= |V|
509 if (edges_.size() >= vertices_.size())
510 return true;
511 else
512 return false;
513 }
514
515 //-------------------------------------------------------------------
516 // Miscellaneous
517 //-------------------------------------------------------------------
518
519 //: Print an ascii summary to the stream
520 template<class V, class E>
print_summary(std::ostream & os) const521 void bgrl2_graph<V,E>::print_summary( std::ostream& os ) const
522 {
523 os << this->number_of_vertices() << " vertices";
524 }
525
526 #if 0 // these I/O methods commented out!
527
528 //: Return IO version number
529 short bgrl2_graph<V,E>::version() const
530 {
531 return 1;
532 }
533
534 //: Binary save self to stream.
535 void bgrl2_graph<V,E>::b_write(vsl_b_ostream &os) const
536 {
537 vsl_b_write(os, version());
538 vsl_b_write(os, vertices_);
539 vsl_b_write(os, edges_);
540 }
541
542 //: Binary load self from stream.
543 void bgrl2_graph<V,E>::b_read(vsl_b_istream &is)
544 {
545 if (!is) return;
546
547 short ver;
548 vsl_b_read(is, ver);
549 switch (ver)
550 {
551 case 1:
552 {
553 vsl_b_read(is, vertices_);
554 vsl_b_read(is, edges_);
555 break;
556 }
557 default:
558 std::cerr << "I/O ERROR: bgrl2_graph<V,E>::b_read(vsl_b_istream&)\n"
559 << " Unknown version number "<< ver << '\n';
560 is.is().clear(std::ios::badbit); // Set an unrecoverable IO error on stream
561 }
562 return;
563 }
564 #endif // 0
565
566 #define BGRL2_GRAPH_INSTANTIATE(V, E) \
567 template class bgrl2_graph<V , E >
568
569 #endif // bgrl2_graph_hxx_
570