Open
Graph Drawing
Framework

 v.2012.05
 

ExtendedNestingGraph.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  
00044 #ifdef _MSC_VER
00045 #pragma once
00046 #endif
00047 
00048 #ifndef OGDF_EXTENDED_NESTING_GRAPH_H
00049 #define OGDF_EXTENDED_NESTING_GRAPH_H
00050 
00051 
00052 
00053 #include <ogdf/cluster/ClusterGraph.h>
00054 #include <ogdf/basic/EdgeArray.h>
00055 #include <ogdf/cluster/ClusterArray.h>
00056 #include <limits.h>
00057 
00058 
00059 namespace ogdf {
00060 
00061 
00062 //---------------------------------------------------------
00063 // RCCrossings
00064 //---------------------------------------------------------
00065 struct OGDF_EXPORT RCCrossings
00066 {
00067     RCCrossings() {
00068         m_cnClusters = 0;
00069         m_cnEdges    = 0;
00070     }
00071 
00072     RCCrossings(int cnClusters, int cnEdges) {
00073         m_cnClusters = cnClusters;
00074         m_cnEdges    = cnEdges;
00075     }
00076 
00077     void incEdges(int cn) {
00078         m_cnEdges += cn;
00079     }
00080 
00081     void incClusters() {
00082         ++m_cnClusters;
00083     }
00084 
00085     RCCrossings &operator+=(const RCCrossings &cr) {
00086         m_cnClusters += cr.m_cnClusters;
00087         m_cnEdges    += cr.m_cnEdges;
00088         return *this;
00089     }
00090 
00091     RCCrossings operator+(const RCCrossings &cr) const {
00092         return RCCrossings(m_cnClusters+cr.m_cnClusters, m_cnEdges+cr.m_cnEdges);
00093     }
00094 
00095     RCCrossings operator-(const RCCrossings &cr) const {
00096         return RCCrossings(m_cnClusters-cr.m_cnClusters, m_cnEdges-cr.m_cnEdges);
00097     }
00098 
00099     bool operator<=(const RCCrossings &cr) const {
00100         if(m_cnClusters == cr.m_cnClusters)
00101             return (m_cnEdges <= cr.m_cnEdges);
00102         else
00103             return (m_cnClusters <= cr.m_cnClusters);
00104     }
00105 
00106     bool operator<(const RCCrossings &cr) const {
00107         if(m_cnClusters == cr.m_cnClusters)
00108             return (m_cnEdges < cr.m_cnEdges);
00109         else
00110             return (m_cnClusters < cr.m_cnClusters);
00111     }
00112 
00113     bool isZero() const {
00114         return m_cnClusters == 0 && m_cnEdges == 0;
00115     }
00116 
00117     RCCrossings &setInfinity() {
00118         m_cnClusters = m_cnEdges = INT_MAX;
00119         return *this;
00120     }
00121 
00122     static int compare(const RCCrossings &x, const RCCrossings &y)
00123     {
00124         int dc = y.m_cnClusters - x.m_cnClusters;
00125         if(dc != 0)
00126             return dc;
00127         return y.m_cnEdges - x.m_cnEdges;
00128     }
00129 
00130     int m_cnClusters;
00131     int m_cnEdges;
00132 };
00133 
00134 OGDF_EXPORT ostream& operator<<(ostream &os, const RCCrossings &cr);
00135 
00136 
00137 //---------------------------------------------------------
00138 // LHTreeNode
00139 //---------------------------------------------------------
00140 class OGDF_EXPORT LHTreeNode
00141 {
00142 public:
00143     enum Type { Compound, Node, AuxNode };
00144 
00145     struct Adjacency
00146     {
00147         Adjacency() { m_u = 0; m_v = 0; m_weight = 0; }
00148         Adjacency(node u, LHTreeNode *vNode, int weight = 1) {
00149             m_u      = u;
00150             m_v      = vNode;
00151             m_weight = weight;
00152         }
00153 
00154         node          m_u;
00155         LHTreeNode   *m_v;
00156         int           m_weight;
00157 
00158         OGDF_NEW_DELETE
00159     };
00160 
00161     struct ClusterCrossing
00162     {
00163         ClusterCrossing() { m_uc = 0; m_u = 0; m_cNode = 0; m_uNode = 0; }
00164         ClusterCrossing(node uc, LHTreeNode *cNode, node u, LHTreeNode *uNode, edge e) {
00165             m_uc = uc;
00166             m_u  = u;
00167             m_cNode = cNode;
00168             m_uNode = uNode;
00169 
00170             m_edge = e;
00171         }
00172 
00173         node m_uc;
00174         node m_u;
00175         LHTreeNode *m_cNode;
00176         LHTreeNode *m_uNode;
00177 
00178         edge m_edge;
00179     };
00180 
00181     // Construction
00182     LHTreeNode(cluster c, LHTreeNode *up) {
00183         m_parent      = 0; 
00184         m_origCluster = c;
00185         m_node        = 0;
00186         m_type        = Compound;
00187         m_down        = 0;
00188 
00189         m_up = up;
00190         if(up)
00191             up->m_down = this;
00192     }
00193 
00194     LHTreeNode(LHTreeNode *parent, node v, Type t = Node) {
00195         m_parent      = parent; 
00196         m_origCluster = 0;
00197         m_node        = v;
00198         m_type        = t;
00199         m_up          = 0;
00200         m_down        = 0;
00201     }
00202 
00203     // Access functions
00204     bool isCompound() const { return m_type == Compound; }
00205 
00206     int numberOfChildren() const { return m_child.size(); }
00207 
00208     const LHTreeNode *parent() const { return m_parent; }
00209     const LHTreeNode *child(int i) const { return m_child[i]; }
00210 
00211     cluster originalCluster() const { return m_origCluster; }
00212     node    getNode()         const { return m_node; }
00213     
00214     const LHTreeNode *up  () const { return m_up; }
00215     const LHTreeNode *down() const { return m_down; }
00216 
00217     int pos() const { return m_pos; }
00218 
00219 
00220     // Modification functions
00221     LHTreeNode *parent() { return m_parent; }
00222     void setParent(LHTreeNode *p) { m_parent = p; }
00223 
00224     LHTreeNode *child(int i) { return m_child[i]; }
00225     void initChild(int n) { m_child.init(n); }
00226     void setChild(int i, LHTreeNode *p) { m_child[i] = p; }
00227 
00228     void setPos();
00229 
00230     void store() { m_storedChild = m_child; }
00231     void restore() { m_child = m_storedChild; }
00232     void permute() { m_child.permute(); }
00233 
00234     void removeAuxChildren();
00235 
00236     List<Adjacency> m_upperAdj;
00237     List<Adjacency> m_lowerAdj;
00238     List<ClusterCrossing> m_upperClusterCrossing;
00239     List<ClusterCrossing> m_lowerClusterCrossing;
00240 
00241 private:
00242     LHTreeNode        *m_parent;
00243 
00244     cluster            m_origCluster;
00245     node               m_node;
00246     Type               m_type;
00247 
00248     Array<LHTreeNode*> m_child;
00249     Array<LHTreeNode*> m_storedChild;
00250 
00251     LHTreeNode        *m_up;
00252     LHTreeNode        *m_down;
00253     int                m_pos;
00254 
00255     OGDF_NEW_DELETE
00256 };
00257 
00258 
00259 //---------------------------------------------------------
00260 // ENGLayer
00261 //---------------------------------------------------------
00262 class OGDF_EXPORT ENGLayer
00263 {
00264 public:
00265     ENGLayer() { m_root = 0; }
00266     ~ENGLayer();
00267     
00268     const LHTreeNode *root() const { return m_root; }
00269     LHTreeNode *root() { return m_root; }
00270 
00271     void setRoot(LHTreeNode *r) { m_root = r; }
00272 
00273     void store();
00274     void restore();
00275     void permute();
00276 
00277     void simplifyAdjacencies();
00278     void removeAuxNodes();
00279 
00280 private:
00281     void simplifyAdjacencies(List<LHTreeNode::Adjacency> &adjs);
00282 
00283     LHTreeNode *m_root;
00284 };
00285 
00286 
00287 //---------------------------------------------------------
00288 // ClusterGraphCopy
00289 //---------------------------------------------------------
00290 class OGDF_EXPORT ExtendedNestingGraph;
00291 
00292 class OGDF_EXPORT ClusterGraphCopy : public ClusterGraph
00293 {
00294 public:
00295 
00296     ClusterGraphCopy();
00297     ClusterGraphCopy(const ExtendedNestingGraph &H, const ClusterGraph &CG);
00298 
00299     void init(const ExtendedNestingGraph &H, const ClusterGraph &CG);
00300 
00301     const ClusterGraph &getOriginalClusterGraph() const { return *m_pCG; }
00302 
00303     cluster copy(cluster cOrig) const { return m_copy[cOrig]; }
00304     cluster original(cluster cCopy) const { return m_original[cCopy]; }
00305 
00306     void setParent(node v, cluster c);
00307 
00308 private:
00309     void createClusterTree(cluster cOrig);
00310 
00311     const ClusterGraph         *m_pCG;
00312     const ExtendedNestingGraph *m_pH;
00313 
00314     ClusterArray<cluster> m_copy;
00315     ClusterArray<cluster> m_original;
00316 };
00317 
00318 
00319 //---------------------------------------------------------
00320 // ExtendedNestingGraph
00321 //---------------------------------------------------------
00322 class OGDF_EXPORT ExtendedNestingGraph : public Graph
00323 {
00324 public:
00325     // the type of a node in this copy
00326     enum NodeType { ntNode, ntClusterTop, ntClusterBottom, ntDummy, ntClusterTopBottom };
00327 
00328     ExtendedNestingGraph(const ClusterGraph &CG);
00329 
00330     const ClusterGraphCopy &getClusterGraph() const { return m_CGC; }
00331     const ClusterGraph &getOriginalClusterGraph() const { return m_CGC.getOriginalClusterGraph(); }
00332 
00333     node copy  (node v)    const { return m_copy[v]; }
00334     node top   (cluster cOrig) const { return m_topNode[cOrig]; }
00335     node bottom(cluster cOrig) const { return m_bottomNode[cOrig]; }
00336 
00337     int topRank   (cluster c) const { return m_topRank[c]; }
00338     int bottomRank(cluster c) const { return m_bottomRank[c]; }
00339 
00340 
00341     NodeType type(node v) const { return m_type[v]; }
00342     node    origNode   (node v) const { return m_origNode[v]; }
00343     edge    origEdge   (edge e) const { return m_origEdge[e]; }
00344     
00345     cluster originalCluster(node v) const { return m_CGC.original(m_CGC.clusterOf(v)); }
00346     cluster parent(node v) const { return m_CGC.clusterOf(v); }
00347     cluster parent(cluster c) const { return c->parent(); }
00348     bool isVirtual(cluster c) const { return m_CGC.original(c) == 0; }
00349 
00350     const List<edge> &chain(edge e) const { return m_copyEdge[e]; }
00351 
00352     // is edge e reversed ?
00353     bool isReversed (edge e) const {
00354         return e->source() != origNode(chain(e).front()->source());
00355     }
00356 
00357     bool isLongEdgeDummy(node v) const {
00358         return (type(v) == ntDummy && v->outdeg() == 1);
00359     }
00360 
00361     bool verticalSegment(edge e) const { return m_vertical[e]; }
00362 
00363     int numberOfLayers() const { return m_numLayers; }
00364     int rank(node v) const { return m_rank[v]; }
00365     int pos(node v) const { return m_pos[v]; }
00366     const LHTreeNode *layerHierarchyTree(int i) const { return m_layer[i].root(); }
00367     const ENGLayer &layer(int i) const { return m_layer[i]; }
00368 
00369     RCCrossings reduceCrossings(int i, bool dirTopDown);
00370     void storeCurrentPos();
00371     void restorePos();
00372     void permute();
00373 
00374     void removeTopBottomEdges();
00375 
00376     int aeLevel(node v) const { return m_aeLevel[v]; }
00377 
00378 protected:
00379     cluster lca(node u, node v) const;
00380     LHTreeNode *lca(
00381         LHTreeNode *uNode,
00382         LHTreeNode *vNode,
00383         LHTreeNode **uChild,
00384         LHTreeNode **vChild) const;
00385 
00386     edge addEdge(node u, node v, bool addAlways = false);
00387     void assignAeLevel(cluster c, int &count);
00388     bool reachable(node v, node u, SListPure<node> &successors);
00389     void moveDown(node v, const SListPure<node> &successors, NodeArray<int> &level);
00390     bool tryEdge(node u, node v, Graph &G, NodeArray<int> &level);
00391 
00392     RCCrossings reduceCrossings(LHTreeNode *cNode, bool dirTopDown);
00393     void assignPos(const LHTreeNode *vNode, int &count);
00394 
00395 private:
00396     void computeRanking();
00397     void createDummyNodes();
00398     void createVirtualClusters();
00399     void createVirtualClusters(
00400         cluster c,
00401         NodeArray<node> &vCopy,
00402         ClusterArray<node> &cCopy);
00403     void buildLayers();
00404     void removeAuxNodes();
00405 
00406     // original graph
00407     //const ClusterGraph &m_CG;
00408     ClusterGraphCopy m_CGC;
00409 
00410     // mapping: nodes in CG <-> nodes in this copy
00411     NodeArray<node>    m_copy;
00412     NodeArray<node>    m_origNode;
00413 
00414     // mapping: clusters in CG <-> nodes in this copy
00415     ClusterArray<node> m_topNode;     // the node representing top-most part of cluster (min. rank)
00416     ClusterArray<node> m_bottomNode;  // the node representing bottom-most part of cluster (max. rank)
00417     ClusterArray<int> m_topRank;
00418     ClusterArray<int> m_bottomRank;
00419 
00420     // the type of a node in this copy
00421     NodeArray<NodeType> m_type;
00422 
00423     // mapping: edges in CG <-> edges in this copy
00424     EdgeArray<List<edge> > m_copyEdge;
00425     EdgeArray<edge>        m_origEdge;
00426 
00427     // level of each node
00428     NodeArray<int>     m_rank;
00429     int                m_numLayers;
00430 
00431     // the layers
00432     Array<ENGLayer> m_layer;
00433     // positions within a layer
00434     NodeArray<int>  m_pos;
00435 
00436     // can an edge segment be drawn vertically?
00437     EdgeArray<bool> m_vertical;
00438 
00439     // temporary data for "addEdge()"
00440     NodeArray<int>  m_aeLevel;
00441     NodeArray<bool> m_aeVisited;
00442     NodeArray<int>  m_auxDeg;
00443 
00444     // temporary data for "lca()"
00445     mutable ClusterArray<cluster> m_mark;
00446     mutable SListPure<cluster>    m_markedClusters;
00447     mutable cluster               m_secondPath;
00448     mutable node                  m_secondPathTo;
00449     mutable SListPure<cluster>    m_markedClustersTree;
00450     mutable ClusterArray<LHTreeNode*> m_markTree;
00451 };
00452 
00453 
00454 } // end namespace ogdf
00455 
00456 
00457 #endif