Open
Graph Drawing
Framework

 v.2012.05
 

extended_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  
00042 #ifdef _MSC_VER
00043 #pragma once
00044 #endif
00045 
00046 #ifndef OGDF_EXTENDED_GRAPH_ALG_H
00047 #define OGDF_EXTENDED_GRAPH_ALG_H
00048 
00049 
00050 #include <ogdf/cluster/ClusterGraph.h>
00051 #include <ogdf/basic/BinaryHeap2.h>
00052 #include <limits>
00053 
00054 namespace ogdf {
00055 
00056 
00057 //---------------------------------------------------------
00058 // Methods for induced subgraphs
00059 //---------------------------------------------------------
00060 
00062 template<class LISTITERATOR>
00063 void inducedSubGraph(const Graph &G, LISTITERATOR start, Graph &subGraph)
00064 {
00065     NodeArray<node> nodeTableOrig2New;
00066     inducedSubGraph(G,start,subGraph,nodeTableOrig2New);
00067 }
00068 
00070 template<class LISTITERATOR>
00071 void inducedSubGraph(const Graph &G,
00072                      LISTITERATOR start,
00073                      Graph &subGraph,
00074                      NodeArray<node> &nodeTableOrig2New)
00075 {
00076     subGraph.clear();
00077     nodeTableOrig2New.init(G,0);
00078 
00079     EdgeArray<bool> mark(G,false);
00080 
00081     LISTITERATOR its;
00082     for (its = start; its.valid(); its++)
00083     {
00084         node w = (*its);
00085         OGDF_ASSERT(w != 0 && w->graphOf() == &G);
00086         nodeTableOrig2New[w] = subGraph.newNode();
00087 
00088         adjEntry adj = w->firstAdj();
00089         forall_adj(adj,w)
00090         {
00091             edge e = adj->theEdge();
00092             if (nodeTableOrig2New[e->source()] && nodeTableOrig2New[e->target()] && !mark[e])
00093             {
00094                 subGraph.newEdge(nodeTableOrig2New[e->source()],nodeTableOrig2New[e->target()]);
00095                 mark[e] = true;
00096             }
00097         }
00098     }
00099 }
00100                      
00101 
00103 template<class LISTITERATOR>
00104 void inducedSubGraph(const Graph &G,
00105                      LISTITERATOR start,
00106                      Graph &subGraph,
00107                      NodeArray<node> &nodeTableOrig2New,
00108                      EdgeArray<edge> &edgeTableOrig2New)
00109 {
00110     subGraph.clear();
00111     nodeTableOrig2New.init(G,0);
00112     edgeTableOrig2New.init(G,0);
00113 
00114     EdgeArray<bool> mark(G,false);
00115 
00116     LISTITERATOR its;
00117     for (its = start; its.valid(); its++)
00118     {
00119         node w = (*its);
00120         OGDF_ASSERT(w != 0 && w->graphOf() == &G);
00121         nodeTableOrig2New[w] = subGraph.newNode();
00122 
00123         adjEntry adj = w->firstAdj();
00124         forall_adj(adj,w)
00125         {
00126             edge e = adj->theEdge();
00127             if (nodeTableOrig2New[e->source()] && 
00128                 nodeTableOrig2New[e->target()] && 
00129                 !mark[e])
00130             {
00131                 edgeTableOrig2New[e] = 
00132                     subGraph.newEdge(
00133                         nodeTableOrig2New[e->source()],
00134                         nodeTableOrig2New[e->target()]);
00135                 mark[e] = true;
00136             }
00137         }
00138     }
00139 }
00140 
00141 
00142 template<class NODELISTITERATOR,class EDGELIST>
00143 void inducedSubgraph(Graph &G,NODELISTITERATOR &it,EDGELIST &E)
00144 {
00145     NODELISTITERATOR itBegin = it;
00146     NodeArray<bool>  mark(G,false);
00147 
00148     for (;it.valid();it++)
00149         mark[(*it)] = true;
00150     it = itBegin;
00151     for (;it.valid();it++)
00152     {
00153         node v = (*it);
00154         adjEntry adj;
00155         forall_adj(adj,v)
00156         {
00157             edge e = adj->theEdge();
00158             if (mark[e->source()] && mark[e->target()])
00159                 E.pushBack(e);
00160         }
00161     }
00162 }
00163 
00164 
00165 //---------------------------------------------------------
00166 // Methods for clustered graphs
00167 //---------------------------------------------------------
00168 
00169 
00170 // true <=> C is C-connected
00171 OGDF_EXPORT bool isCConnected(const ClusterGraph &C);
00172 
00173 //connect clusters to achieve c-connectivity (probably loosing planarity)
00174 //GG is underlying graph of C, returns inserted edges in addededges
00175 //simple: only connect underlying cluster subgraph without crossing check
00176 OGDF_EXPORT void makeCConnected(
00177     ClusterGraph& C,
00178     Graph& GG,
00179     List<edge>& addedEdges,
00180     bool simple = true);
00181 
00182 
00183 
00184 
00185 //---------------------------------------------------------
00186 // Methods for st-numbering
00187 //---------------------------------------------------------
00188 
00189 
00190 // Computes an st-Numbering.
00191 // Precondition: G must be biconnected and simple.
00192 // Exception: the Graph is allowed to have isolated nodes.
00193 // The st-numbers are stored in NodeArray. Return value is 
00194 // the number t. It is 0, if the computation was unsuccessful.
00195 // The nodes s and t may be specified. In this case 
00196 // s and t have to be adjacent.
00197 // If s and t are set 0 and parameter randomized is set to true,
00198 // the st edge is chosen to be a random edge in G.
00199 OGDF_EXPORT int stNumber(const Graph &G,
00200     NodeArray<int> &numbering,
00201     node s = 0,
00202     node t = 0,
00203     bool randomized = false);
00204 
00205 // Tests, whether a numbering is an st-numbering
00206 // Precondition: G must be biconnected and simple.
00207 // Exception: the Graph is allowed to have isolated nodes.
00208 OGDF_EXPORT bool testSTnumber(const Graph &G, NodeArray<int> &st_no,int max);
00209 
00210 
00211 //---------------------------------------------------------
00212 // Methods for minimum spanning tree computation
00213 //---------------------------------------------------------
00215 
00221 template<typename T>
00222 T computeMinST(const Graph &G, const EdgeArray<T> &weight, EdgeArray<bool> &isInTree){
00223     NodeArray<edge> pred(G, 0);
00224     return computeMinST(G.firstNode(), G, weight, pred, isInTree);
00225 }
00226 
00227 template<typename T>
00228 T computeMinST(const Graph &G, const EdgeArray<T> &weight, NodeArray<edge> &pred, EdgeArray<bool> &isInTree){
00229     return computeMinST(G.firstNode(), G, weight, pred, isInTree);
00230 }
00231 
00232 template<typename T>
00233 T computeMinST(node s, const Graph &G, const EdgeArray<T> &weight, NodeArray<edge> &pred, EdgeArray<bool> &isInTree)
00234 {
00235     //our priority queue storing the front vertices
00236     BinaryHeap2<T, node> pq;
00237 
00238     //initialize tree flag for edges
00239     edge e;
00240     forall_edges(e, G)
00241     {
00242         isInTree[e] = false;
00243     }
00244 
00245     //array to save the position information from pq
00246     int* pqpos = new int[G.numberOfNodes()];
00247 
00248     int i = 0;
00249     NodeArray<int> vIndex(G);
00250     //array that tells us if node is already processed
00251     NodeArray<bool> processed(G);
00252     //predecessor of node v is given by an edge (w,v)
00253 
00254     //insert nodes into pr
00255     node v = G.firstNode();
00256     T prio = std::numeric_limits<T>::max();;
00257     while (v != 0)
00258     {
00259         vIndex[v] = i;
00260         pq.insert(v, prio, &(pqpos[i++]));
00261         processed[v] = false;
00262         pred[v] = 0;
00263         v = v->succ();
00264     }//while all nodes
00265     // decrease start node
00266     pq.decreaseKey(pqpos[vIndex[s]], 0.0);
00267 
00268     //extract the nodes again along a minimum ST
00269     while (!pq.empty())
00270     {
00271         v = pq.extractMin();
00272         processed[v] = true;
00273         forall_adj_edges(e, v)
00274         {
00275             node w = e->opposite(v);
00276 
00277             int posofw = pqpos[vIndex[w]];
00278             if ((!processed[w]) && (weight[e] < pq.getPriority(posofw)))
00279             {
00280                 pq.decreaseKey(posofw, weight[e]);
00281                 pred[w] = e;
00282             }//if improvement
00283         }
00284     }//while pq
00285 
00286     //only for connected graphs
00287     int rootcount = 0;
00288     T treeWeight = 0.0;
00289     forall_nodes(v, G)
00290     {
00291         if (pred[v] == 0) rootcount++;
00292         else
00293         {
00294             isInTree[pred[v]] = true;
00295             treeWeight += weight[pred[v]];
00296         }
00297     }
00298     OGDF_ASSERT(rootcount == 1);
00299 
00300     delete[] pqpos;
00301     return treeWeight;
00302 }//computeMinST
00303 
00304 } // end namespace ogdf
00305 
00306 
00307 #endif