Go to the documentation of this file.00001
00002
00003
00004
00005
00006
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
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
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
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
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
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
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
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
00321
00322 class OGDF_EXPORT ExtendedNestingGraph : public Graph
00323 {
00324 public:
00325
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
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
00407
00408 ClusterGraphCopy m_CGC;
00409
00410
00411 NodeArray<node> m_copy;
00412 NodeArray<node> m_origNode;
00413
00414
00415 ClusterArray<node> m_topNode;
00416 ClusterArray<node> m_bottomNode;
00417 ClusterArray<int> m_topRank;
00418 ClusterArray<int> m_bottomRank;
00419
00420
00421 NodeArray<NodeType> m_type;
00422
00423
00424 EdgeArray<List<edge> > m_copyEdge;
00425 EdgeArray<edge> m_origEdge;
00426
00427
00428 NodeArray<int> m_rank;
00429 int m_numLayers;
00430
00431
00432 Array<ENGLayer> m_layer;
00433
00434 NodeArray<int> m_pos;
00435
00436
00437 EdgeArray<bool> m_vertical;
00438
00439
00440 NodeArray<int> m_aeLevel;
00441 NodeArray<bool> m_aeVisited;
00442 NodeArray<int> m_auxDeg;
00443
00444
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 }
00455
00456
00457 #endif