Open
Graph Drawing
Framework

 v.2012.05
 

simple_graph_alg.h
Go to the documentation of this file.
00001 /*
00002  * $Revision: 2299 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2012-05-07 15:57:08 +0200 (Mon, 07 May 2012) $ 
00007  ***************************************************************/
00008  
00043 #ifdef _MSC_VER
00044 #pragma once
00045 #endif
00046 
00047 #ifndef OGDF_SIMPLE_GRAPH_ALG_H
00048 #define OGDF_SIMPLE_GRAPH_ALG_H
00049 
00050 
00051 #include <ogdf/basic/EdgeArray.h>
00052 #include <ogdf/basic/SList.h>
00053 #include <ogdf/basic/BoundedStack.h>
00054 
00055 namespace ogdf {
00056 
00057 
00058 //---------------------------------------------------------
00059 // Methods for loops
00060 //---------------------------------------------------------
00061 
00063 OGDF_EXPORT bool isLoopFree(const Graph &G);
00064 
00066 template<class NODELIST>
00067 void makeLoopFree(Graph &G, NODELIST &L)
00068 {
00069     L.clear();
00070 
00071     edge e, eNext;
00072     for (e = G.firstEdge(); e; e = eNext) {
00073         eNext = e->succ();
00074         if (e->isSelfLoop()) {
00075             L.pushBack(e->source());
00076             G.delEdge(e);
00077         }
00078     }
00079 }
00080 
00082 OGDF_EXPORT void makeLoopFree(Graph &G);
00083 
00084 
00085 //---------------------------------------------------------
00086 // Methods for parallel edges
00087 //---------------------------------------------------------
00088 
00089 OGDF_EXPORT void parallelFreeSort(const Graph &G, SListPure<edge> &edges);
00090 
00092 OGDF_EXPORT bool isParallelFree(const Graph &G);
00093 
00095 OGDF_EXPORT int numParallelEdges(const Graph &G);
00096 
00097 
00099 
00104 template <class EDGELIST>
00105 void makeParallelFree(Graph &G, EDGELIST &parallelEdges)
00106 {
00107     parallelEdges.clear();
00108     if (G.numberOfEdges() <= 1) return;
00109 
00110     SListPure<edge> edges;
00111     parallelFreeSort(G,edges);
00112 
00113     SListConstIterator<edge> it = edges.begin();
00114     edge ePrev = *it++, e;
00115     bool bAppend = true;
00116     while(it.valid()) {
00117         e = *it++;
00118         if (ePrev->source() == e->source() && ePrev->target() == e->target()) {
00119             G.delEdge(e);
00120             if (bAppend) { parallelEdges.pushBack(ePrev); bAppend = false; }
00121         } else {
00122             ePrev = e; bAppend = true;
00123         }
00124     }
00125 }
00126 
00127 
00129 inline void makeParallelFree(Graph &G) {
00130     List<edge> parallelEdges;
00131     makeParallelFree(G,parallelEdges);
00132 }
00133 
00134 
00135 
00136 OGDF_EXPORT void parallelFreeSortUndirected(const Graph &G, SListPure<edge> &edges,
00137     EdgeArray<int> &minIndex, EdgeArray<int> &maxIndex);
00138 
00140 OGDF_EXPORT bool isParallelFreeUndirected(const Graph &G);
00141 
00143 OGDF_EXPORT int numParallelEdgesUndirected(const Graph &G);
00144 
00145 
00147 
00153 template <class EDGELIST>
00154 void makeParallelFreeUndirected(Graph &G, EDGELIST &parallelEdges)
00155 {
00156     parallelEdges.clear();
00157     if (G.numberOfEdges() <= 1) return;
00158 
00159     SListPure<edge> edges;
00160     EdgeArray<int> minIndex(G), maxIndex(G);
00161     parallelFreeSortUndirected(G,edges,minIndex,maxIndex);
00162 
00163     SListConstIterator<edge> it = edges.begin();
00164     edge ePrev = *it++, e;
00165     bool bAppend = true;
00166     while(it.valid()) {
00167         e = *it++;
00168         if (minIndex[ePrev] == minIndex[e] && maxIndex[ePrev] == maxIndex[e]) {
00169             G.delEdge(e);
00170             if (bAppend) { parallelEdges.pushBack(ePrev); bAppend = false; }
00171         } else {
00172             ePrev = e; bAppend = true;
00173         }
00174     }
00175 }
00176 
00177 
00179 
00182 inline void makeParallelFreeUndirected(Graph &G) {
00183     List<edge> parallelEdges;
00184     makeParallelFreeUndirected(G,parallelEdges);
00185 }
00186 
00187 
00188 // removes all but one of each bundle of undirected parallel edges
00189 // ((v,w) and (w,v) are considered as the same edge); returns the
00190 // list of remaining edges with parallel edges in the original graph
00191 // including the number of the removed edges that have been parallel 
00192 // to an edge in parallelEdges.
00193 
00195 
00205 template <class EDGELIST>
00206 void makeParallelFreeUndirected(Graph &G, 
00207                                 EDGELIST &parallelEdges, 
00208                                 EdgeArray<int> &cardPositive,
00209                                 EdgeArray<int> &cardNegative)
00210 {
00211     parallelEdges.clear();
00212     cardPositive.fill(0);
00213     cardNegative.fill(0);
00214     if (G.numberOfEdges() <= 1) return;
00215 
00216     SListPure<edge> edges;
00217     EdgeArray<int> minIndex(G), maxIndex(G);
00218     parallelFreeSortUndirected(G,edges,minIndex,maxIndex);
00219 
00220     SListConstIterator<edge> it = edges.begin();
00221     edge ePrev = *it++, e;
00222     bool bAppend = true;
00223     int  counter = 0;
00224     while(it.valid()) 
00225     {
00226         e = *it++;
00227         if (minIndex[ePrev] == minIndex[e] && maxIndex[ePrev] == maxIndex[e]) 
00228         {
00229             if (ePrev->source() == e->source() && ePrev->target() == e->target()) 
00230                 cardPositive[ePrev]++;
00231             else if (ePrev->source() == e->target() && ePrev->target() == e->source()) 
00232                 cardNegative[ePrev]++;
00233             G.delEdge(e);
00234             if (bAppend) 
00235             { 
00236                 parallelEdges.pushBack(ePrev); 
00237                 bAppend = false; 
00238             }
00239         } 
00240         else 
00241         {
00242             ePrev = e; bAppend = true;
00243         }
00244     }
00245 }
00246 
00248 
00253 template <class EDGELIST>
00254 void getParallelFreeUndirected(const Graph &G, EdgeArray<EDGELIST> &parallelEdges)
00255 {
00256     if (G.numberOfEdges() <= 1) return;
00257 
00258     SListPure<edge> edges;
00259     EdgeArray<int> minIndex(G), maxIndex(G);
00260     parallelFreeSortUndirected(G,edges,minIndex,maxIndex);
00261 
00262     SListConstIterator<edge> it = edges.begin();
00263     edge ePrev = *it++, e;
00264     while(it.valid()) 
00265     {
00266         e = *it++;
00267         if (minIndex[ePrev] == minIndex[e] && maxIndex[ePrev] == maxIndex[e]) 
00268             parallelEdges[ePrev].pushBack(e);
00269         else 
00270             ePrev = e;
00271     }
00272 }
00273 
00274 //---------------------------------------------------------
00275 // Methods for simple graphs
00276 //---------------------------------------------------------
00277 
00278 
00280 inline bool isSimple(const Graph &G) {
00281     return isLoopFree(G) && isParallelFree(G);
00282 }
00283 
00285 inline void makeSimple(Graph &G) {
00286     makeLoopFree(G);
00287     makeParallelFree(G);
00288 }
00289 
00290 
00291 
00293 inline bool isSimpleUndirected(const Graph &G) {
00294     return isLoopFree(G) && isParallelFreeUndirected(G);
00295 }
00296 
00298 inline void makeSimpleUndirected(Graph &G) {
00299     makeLoopFree(G);
00300     makeParallelFreeUndirected(G);
00301 }
00302 
00303 
00304 
00305 //---------------------------------------------------------
00306 // Methods for connectivity
00307 //---------------------------------------------------------
00308 
00310 OGDF_EXPORT bool isConnected(const Graph &G);
00311 
00313 
00317 OGDF_EXPORT void makeConnected(Graph &G, List<edge> &added);
00318 
00320 inline void makeConnected(Graph &G) {
00321     List<edge> added;
00322     makeConnected(G,added);
00323 }
00324 
00326 
00333 OGDF_EXPORT int connectedComponents(const Graph &G, NodeArray<int> &component);
00334 
00335 //the same as connnectedComponents, but returns the isolated nodes 
00337 
00346 OGDF_EXPORT int connectedIsolatedComponents(const Graph &G, List<node> &isolated, 
00347                                 NodeArray<int> &component);
00348 
00350 
00354 OGDF_EXPORT bool isBiconnected(const Graph &G, node &cutVertex);
00355 
00357 inline bool isBiconnected(const Graph &G) {
00358     node cutVertex;
00359     return isBiconnected(G,cutVertex);
00360 }
00361 
00363 
00367 OGDF_EXPORT void makeBiconnected(Graph &G, List<edge> &added);
00368 
00370 inline void makeBiconnected(Graph &G) {
00371     List<edge> added;
00372     makeBiconnected(G,added);
00373 }
00374 
00376 
00381 OGDF_EXPORT int biconnectedComponents(const Graph &G, EdgeArray<int> &component);
00382 
00383 
00385 
00391 OGDF_EXPORT bool isTriconnected(const Graph &G, node &s1, node &s2);
00392 
00394 inline bool isTriconnected(const Graph &G) {
00395     node s1, s2;
00396     return isTriconnected(G,s1,s2);
00397 }
00398 
00399 
00401 
00410 OGDF_EXPORT bool isTriconnectedPrimitive(const Graph &G, node &s1, node &s2);
00411 
00413 
00417 inline bool isTriconnectedPrimitive(const Graph &G) {
00418     node s1, s2;
00419     return isTriconnectedPrimitive(G,s1,s2);
00420 }
00421 
00429 void triangulate(Graph &G);
00430 
00431 //---------------------------------------------------------
00432 // Methods for directed graphs
00433 //---------------------------------------------------------
00434 
00436 
00440 OGDF_EXPORT bool isAcyclic(const Graph &G, List<edge> &backedges);
00441 
00443 inline bool isAcyclic(const Graph &G) {
00444     List<edge> backedges;
00445     return isAcyclic(G,backedges);
00446 }
00447 
00449 
00453 OGDF_EXPORT bool isAcyclicUndirected(const Graph &G, List<edge> &backedges);
00454 
00456 inline bool isAcyclicUndirected(const Graph &G) {
00457     List<edge> backedges;
00458     return isAcyclicUndirected(G,backedges);
00459 }
00460 
00462 
00465 OGDF_EXPORT void makeAcyclic(Graph &G);
00466 
00468 
00472 OGDF_EXPORT void makeAcyclicByReverse(Graph &G);
00473 
00474 
00476 
00480 OGDF_EXPORT bool hasSingleSource(const Graph &G, node &source);
00481 
00483 inline bool hasSingleSource(const Graph &G) {
00484     node source;
00485     return hasSingleSource(G,source);
00486 }
00487 
00489 
00493 OGDF_EXPORT bool hasSingleSink(const Graph &G, node &sink);
00494 
00495 // Returns true iff \a G contains exactly one sink node (or is empty).
00496 inline bool hasSingleSink(const Graph &G) {
00497     node sink;
00498     return hasSingleSink(G,sink);
00499 }
00500 
00501 
00503 
00511 OGDF_EXPORT bool isStGraph(const Graph &G, node &s, node &t, edge &st);
00512 
00514 inline bool isStGraph(const Graph &G) {
00515     node s, t;
00516     edge st;
00517     return isStGraph(G,s,t,st);
00518 }
00519 
00521 
00526 OGDF_EXPORT void topologicalNumbering(const Graph &G, NodeArray<int> &num);
00527 
00529 
00533 OGDF_EXPORT int strongComponents(const Graph& G, NodeArray<int>& component);
00534 
00536 
00547 void dfsStrongComponents(const Graph& G,
00548                         node w,
00549                         BoundedStack<node>& S,
00550                         NodeArray<int>& pre,
00551                         NodeArray<int>& low,
00552                         int& cnt,
00553                         int& scnt,
00554                         NodeArray<int>& component);
00555 
00556 //---------------------------------------------------------
00557 // Methods for trees and forests
00558 //---------------------------------------------------------
00559 
00561 OGDF_EXPORT bool isFreeForest(const Graph &G);
00562 
00563 
00564 //---------------------------------------------------------
00565 // Methods for trees and forests
00566 //---------------------------------------------------------
00567 
00569 
00573 OGDF_EXPORT bool isForest(const Graph& G, List<node> &roots);
00574 
00576 inline bool isForest(const Graph &G)
00577 {
00578     List<node> roots;
00579     return isForest(G,roots);
00580 }
00581 
00583 
00587 OGDF_EXPORT bool isTree (const Graph& G, node &root);
00588 
00590 inline bool isTree(const Graph &G) {
00591     node root;
00592     return isTree(G,root);
00593 }
00594 
00595 
00596 } // end namespace ogdf
00597 
00598 #endif