Open
Graph Drawing
Framework

 v.2012.07
 

simple_graph_alg.h
Go to the documentation of this file.
1 /*
2  * $Revision: 2593 $
3  *
4  * last checkin:
5  * $Author: gutwenger $
6  * $Date: 2012-07-15 15:33:53 +0200 (So, 15. Jul 2012) $
7  ***************************************************************/
8 
44 #ifdef _MSC_VER
45 #pragma once
46 #endif
47 
48 #ifndef OGDF_SIMPLE_GRAPH_ALG_H
49 #define OGDF_SIMPLE_GRAPH_ALG_H
50 
51 
52 #include <ogdf/basic/EdgeArray.h>
53 #include <ogdf/basic/SList.h>
55 
56 namespace ogdf {
57 
58 
59 //---------------------------------------------------------
60 // Methods for loops
61 //---------------------------------------------------------
62 
64 
68 OGDF_EXPORT bool isLoopFree(const Graph &G);
69 
71 
76 template<class NODELIST>
77 void makeLoopFree(Graph &G, NODELIST &L)
78 {
79  L.clear();
80 
81  edge e, eNext;
82  for (e = G.firstEdge(); e; e = eNext) {
83  eNext = e->succ();
84  if (e->isSelfLoop()) {
85  L.pushBack(e->source());
86  G.delEdge(e);
87  }
88  }
89 }
90 
91 
93 
96 OGDF_EXPORT void makeLoopFree(Graph &G);
97 
98 
99 //---------------------------------------------------------
100 // Methods for parallel edges
101 //---------------------------------------------------------
102 
104 
108 OGDF_EXPORT void parallelFreeSort(const Graph &G, SListPure<edge> &edges);
109 
110 
112 
120 OGDF_EXPORT bool isParallelFree(const Graph &G);
121 
122 
124 
133 OGDF_EXPORT int numParallelEdges(const Graph &G);
134 
135 
137 
147 template <class EDGELIST>
148 void makeParallelFree(Graph &G, EDGELIST &parallelEdges)
149 {
150  parallelEdges.clear();
151  if (G.numberOfEdges() <= 1) return;
152 
153  SListPure<edge> edges;
154  parallelFreeSort(G,edges);
155 
156  SListConstIterator<edge> it = edges.begin();
157  edge ePrev = *it++, e;
158  bool bAppend = true;
159  while(it.valid()) {
160  e = *it++;
161  if (ePrev->source() == e->source() && ePrev->target() == e->target()) {
162  G.delEdge(e);
163  if (bAppend) { parallelEdges.pushBack(ePrev); bAppend = false; }
164  } else {
165  ePrev = e; bAppend = true;
166  }
167  }
168 }
169 
170 
172 
179 inline void makeParallelFree(Graph &G) {
180  List<edge> parallelEdges;
181  makeParallelFree(G,parallelEdges);
182 }
183 
184 
185 
187 
197  const Graph &G,
198  SListPure<edge> &edges,
199  EdgeArray<int> &minIndex,
200  EdgeArray<int> &maxIndex);
201 
202 
204 
211 OGDF_EXPORT bool isParallelFreeUndirected(const Graph &G);
212 
213 
215 
223 OGDF_EXPORT int numParallelEdgesUndirected(const Graph &G);
224 
225 
227 
237 template <class EDGELIST>
238 void makeParallelFreeUndirected(Graph &G, EDGELIST &parallelEdges)
239 {
240  parallelEdges.clear();
241  if (G.numberOfEdges() <= 1) return;
242 
243  SListPure<edge> edges;
244  EdgeArray<int> minIndex(G), maxIndex(G);
245  parallelFreeSortUndirected(G,edges,minIndex,maxIndex);
246 
247  SListConstIterator<edge> it = edges.begin();
248  edge ePrev = *it++, e;
249  bool bAppend = true;
250  while(it.valid()) {
251  e = *it++;
252  if (minIndex[ePrev] == minIndex[e] && maxIndex[ePrev] == maxIndex[e]) {
253  G.delEdge(e);
254  if (bAppend) { parallelEdges.pushBack(ePrev); bAppend = false; }
255  } else {
256  ePrev = e; bAppend = true;
257  }
258  }
259 }
260 
261 
263 
271  List<edge> parallelEdges;
272  makeParallelFreeUndirected(G,parallelEdges);
273 }
274 
275 
277 
291 template <class EDGELIST>
293  Graph &G,
294  EDGELIST &parallelEdges,
295  EdgeArray<int> &cardPositive,
296  EdgeArray<int> &cardNegative)
297 {
298  parallelEdges.clear();
299  cardPositive.fill(0);
300  cardNegative.fill(0);
301  if (G.numberOfEdges() <= 1) return;
302 
303  SListPure<edge> edges;
304  EdgeArray<int> minIndex(G), maxIndex(G);
305  parallelFreeSortUndirected(G,edges,minIndex,maxIndex);
306 
307  SListConstIterator<edge> it = edges.begin();
308  edge ePrev = *it++, e;
309  bool bAppend = true;
310  int counter = 0;
311  while(it.valid())
312  {
313  e = *it++;
314  if (minIndex[ePrev] == minIndex[e] && maxIndex[ePrev] == maxIndex[e])
315  {
316  if (ePrev->source() == e->source() && ePrev->target() == e->target())
317  cardPositive[ePrev]++;
318  else if (ePrev->source() == e->target() && ePrev->target() == e->source())
319  cardNegative[ePrev]++;
320  G.delEdge(e);
321  if (bAppend)
322  {
323  parallelEdges.pushBack(ePrev);
324  bAppend = false;
325  }
326  }
327  else
328  {
329  ePrev = e; bAppend = true;
330  }
331  }
332 }
333 
334 
336 
345 template <class EDGELIST>
347 {
348  if (G.numberOfEdges() <= 1) return;
349 
350  SListPure<edge> edges;
351  EdgeArray<int> minIndex(G), maxIndex(G);
352  parallelFreeSortUndirected(G,edges,minIndex,maxIndex);
353 
354  SListConstIterator<edge> it = edges.begin();
355  edge ePrev = *it++, e;
356  while(it.valid())
357  {
358  e = *it++;
359  if (minIndex[ePrev] == minIndex[e] && maxIndex[ePrev] == maxIndex[e])
360  parallelEdges[ePrev].pushBack(e);
361  else
362  ePrev = e;
363  }
364 }
365 
366 
367 //---------------------------------------------------------
368 // Methods for simple graphs
369 //---------------------------------------------------------
370 
371 
373 
377 inline bool isSimple(const Graph &G) {
378  return isLoopFree(G) && isParallelFree(G);
379 }
380 
381 
383 
386 inline void makeSimple(Graph &G) {
387  makeLoopFree(G);
388  makeParallelFree(G);
389 }
390 
391 
393 
398 inline bool isSimpleUndirected(const Graph &G) {
399  return isLoopFree(G) && isParallelFreeUndirected(G);
400 }
401 
402 
404 
407 inline void makeSimpleUndirected(Graph &G) {
408  makeLoopFree(G);
410 }
411 
412 
413 
414 //---------------------------------------------------------
415 // Methods for connectivity
416 //---------------------------------------------------------
417 
419 
423 OGDF_EXPORT bool isConnected(const Graph &G);
424 
425 
427 
431 OGDF_EXPORT void makeConnected(Graph &G, List<edge> &added);
432 
433 
435 
438 inline void makeConnected(Graph &G) {
439  List<edge> added;
440  makeConnected(G,added);
441 }
442 
443 
445 
453 OGDF_EXPORT int connectedComponents(const Graph &G, NodeArray<int> &component);
454 
455 
457 
468  const Graph &G,
469  List<node> &isolated,
470  NodeArray<int> &component);
471 
472 
474 
479 OGDF_EXPORT bool isBiconnected(const Graph &G, node &cutVertex);
480 
481 
483 
486 inline bool isBiconnected(const Graph &G) {
487  node cutVertex;
488  return isBiconnected(G,cutVertex);
489 }
490 
491 
493 
497 OGDF_EXPORT void makeBiconnected(Graph &G, List<edge> &added);
498 
499 
501 
504 inline void makeBiconnected(Graph &G) {
505  List<edge> added;
506  makeBiconnected(G,added);
507 }
508 
509 
511 
519 OGDF_EXPORT int biconnectedComponents(const Graph &G, EdgeArray<int> &component);
520 
521 
523 
534 OGDF_EXPORT bool isTriconnected(const Graph &G, node &s1, node &s2);
535 
536 
538 
542 inline bool isTriconnected(const Graph &G) {
543  node s1, s2;
544  return isTriconnected(G,s1,s2);
545 }
546 
547 
549 
563 OGDF_EXPORT bool isTriconnectedPrimitive(const Graph &G, node &s1, node &s2);
564 
565 
567 
574 inline bool isTriconnectedPrimitive(const Graph &G) {
575  node s1, s2;
576  return isTriconnectedPrimitive(G,s1,s2);
577 }
578 
579 
581 
589 void triangulate(Graph &G);
590 
591 
592 //---------------------------------------------------------
593 // Methods for directed graphs
594 //---------------------------------------------------------
595 
597 
602 OGDF_EXPORT bool isAcyclic(const Graph &G, List<edge> &backedges);
603 
604 
606 
610 inline bool isAcyclic(const Graph &G) {
611  List<edge> backedges;
612  return isAcyclic(G,backedges);
613 }
614 
615 
617 
622 OGDF_EXPORT bool isAcyclicUndirected(const Graph &G, List<edge> &backedges);
623 
624 
626 
630 inline bool isAcyclicUndirected(const Graph &G) {
631  List<edge> backedges;
632  return isAcyclicUndirected(G,backedges);
633 }
634 
635 
637 
642 OGDF_EXPORT void makeAcyclic(Graph &G);
643 
644 
646 
652 OGDF_EXPORT void makeAcyclicByReverse(Graph &G);
653 
654 
656 
661 OGDF_EXPORT bool hasSingleSource(const Graph &G, node &source);
662 
663 
665 
669 inline bool hasSingleSource(const Graph &G) {
670  node source;
671  return hasSingleSource(G,source);
672 }
673 
674 
676 
681 OGDF_EXPORT bool hasSingleSink(const Graph &G, node &sink);
682 
683 
685 
689 inline bool hasSingleSink(const Graph &G) {
690  node sink;
691  return hasSingleSink(G,sink);
692 }
693 
694 
696 
706 OGDF_EXPORT bool isStGraph(const Graph &G, node &s, node &t, edge &st);
707 
708 
710 
716 inline bool isStGraph(const Graph &G) {
717  node s, t;
718  edge st;
719  return isStGraph(G,s,t,st);
720 }
721 
722 
724 
730 OGDF_EXPORT void topologicalNumbering(const Graph &G, NodeArray<int> &num);
731 
732 
734 
741 OGDF_EXPORT int strongComponents(const Graph& G, NodeArray<int>& component);
742 
743 
744 
745 //---------------------------------------------------------
746 // Methods for trees and forests
747 //---------------------------------------------------------
748 
750 
754 OGDF_EXPORT bool isFreeForest(const Graph &G);
755 
756 
758 
763 OGDF_EXPORT bool isForest(const Graph& G, List<node> &roots);
764 
765 
767 
771 inline bool isForest(const Graph &G)
772 {
773  List<node> roots;
774  return isForest(G,roots);
775 }
776 
777 
779 
784 OGDF_EXPORT bool isTree (const Graph& G, node &root);
785 
786 
788 
792 inline bool isTree(const Graph &G) {
793  node root;
794  return isTree(G,root);
795 }
796 
797 
798 } // end namespace ogdf
799 
800 #endif