6 * $Date: 2012-07-02 20:59:27 +0200 (Mon, 02 Jul 2012) $
7 ***************************************************************/
10 * \brief Declaration of ExtendedNestingGraph
12 * Manages access on copy of an attributed graph.
14 * \author Carsten Gutwenger
17 * This file is part of the Open Graph Drawing Framework (OGDF).
21 * See README.txt in the root directory of the OGDF installation for details.
24 * This program is free software; you can redistribute it and/or
25 * modify it under the terms of the GNU General Public License
26 * Version 2 or 3 as published by the Free Software Foundation;
27 * see the file LICENSE.txt included in the packaging of this file
31 * This program is distributed in the hope that it will be useful,
32 * but WITHOUT ANY WARRANTY; without even the implied warranty of
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34 * GNU General Public License for more details.
37 * You should have received a copy of the GNU General Public
38 * License along with this program; if not, write to the Free
39 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
40 * Boston, MA 02110-1301, USA.
42 * \see http://www.gnu.org/copyleft/gpl.html
43 ***************************************************************/
49 #ifndef OGDF_EXTENDED_NESTING_GRAPH_H
50 #define OGDF_EXTENDED_NESTING_GRAPH_H
54 #include <ogdf/cluster/ClusterGraph.h>
55 #include <ogdf/basic/EdgeArray.h>
56 #include <ogdf/cluster/ClusterArray.h>
63 //---------------------------------------------------------
65 //---------------------------------------------------------
66 struct OGDF_EXPORT RCCrossings
73 RCCrossings(int cnClusters
, int cnEdges
) {
74 m_cnClusters
= cnClusters
;
78 void incEdges(int cn
) {
86 RCCrossings
&operator+=(const RCCrossings
&cr
) {
87 m_cnClusters
+= cr
.m_cnClusters
;
88 m_cnEdges
+= cr
.m_cnEdges
;
92 RCCrossings
operator+(const RCCrossings
&cr
) const {
93 return RCCrossings(m_cnClusters
+cr
.m_cnClusters
, m_cnEdges
+cr
.m_cnEdges
);
96 RCCrossings
operator-(const RCCrossings
&cr
) const {
97 return RCCrossings(m_cnClusters
-cr
.m_cnClusters
, m_cnEdges
-cr
.m_cnEdges
);
100 bool operator<=(const RCCrossings
&cr
) const {
101 if(m_cnClusters
== cr
.m_cnClusters
)
102 return (m_cnEdges
<= cr
.m_cnEdges
);
104 return (m_cnClusters
<= cr
.m_cnClusters
);
107 bool operator<(const RCCrossings
&cr
) const {
108 if(m_cnClusters
== cr
.m_cnClusters
)
109 return (m_cnEdges
< cr
.m_cnEdges
);
111 return (m_cnClusters
< cr
.m_cnClusters
);
114 bool isZero() const {
115 return m_cnClusters
== 0 && m_cnEdges
== 0;
118 RCCrossings
&setInfinity() {
119 m_cnClusters
= m_cnEdges
= INT_MAX
;
123 static int compare(const RCCrossings
&x
, const RCCrossings
&y
)
125 int dc
= y
.m_cnClusters
- x
.m_cnClusters
;
128 return y
.m_cnEdges
- x
.m_cnEdges
;
135 OGDF_EXPORT ostream
& operator<<(ostream
&os
, const RCCrossings
&cr
);
138 //---------------------------------------------------------
140 //---------------------------------------------------------
141 class OGDF_EXPORT LHTreeNode
144 enum Type
{ Compound
, Node
, AuxNode
};
148 Adjacency() { m_u
= 0; m_v
= 0; m_weight
= 0; }
149 Adjacency(node u
, LHTreeNode
*vNode
, int weight
= 1) {
162 struct ClusterCrossing
164 ClusterCrossing() { m_uc
= 0; m_u
= 0; m_cNode
= 0; m_uNode
= 0; }
165 ClusterCrossing(node uc
, LHTreeNode
*cNode
, node u
, LHTreeNode
*uNode
, edge e
) {
183 LHTreeNode(cluster c
, LHTreeNode
*up
) {
195 LHTreeNode(LHTreeNode
*parent
, node v
, Type t
= Node
) {
205 bool isCompound() const { return m_type
== Compound
; }
207 int numberOfChildren() const { return m_child
.size(); }
209 const LHTreeNode
*parent() const { return m_parent
; }
210 const LHTreeNode
*child(int i
) const { return m_child
[i
]; }
212 cluster
originalCluster() const { return m_origCluster
; }
213 node
getNode() const { return m_node
; }
215 const LHTreeNode
*up () const { return m_up
; }
216 const LHTreeNode
*down() const { return m_down
; }
218 int pos() const { return m_pos
; }
221 // Modification functions
222 LHTreeNode
*parent() { return m_parent
; }
223 void setParent(LHTreeNode
*p
) { m_parent
= p
; }
225 LHTreeNode
*child(int i
) { return m_child
[i
]; }
226 void initChild(int n
) { m_child
.init(n
); }
227 void setChild(int i
, LHTreeNode
*p
) { m_child
[i
] = p
; }
231 void store() { m_storedChild
= m_child
; }
232 void restore() { m_child
= m_storedChild
; }
233 void permute() { m_child
.permute(); }
235 void removeAuxChildren();
237 List
<Adjacency
> m_upperAdj
;
238 List
<Adjacency
> m_lowerAdj
;
239 List
<ClusterCrossing
> m_upperClusterCrossing
;
240 List
<ClusterCrossing
> m_lowerClusterCrossing
;
243 LHTreeNode
*m_parent
;
245 cluster m_origCluster
;
249 Array
<LHTreeNode
*> m_child
;
250 Array
<LHTreeNode
*> m_storedChild
;
260 //---------------------------------------------------------
262 //---------------------------------------------------------
263 class OGDF_EXPORT ENGLayer
266 ENGLayer() { m_root
= 0; }
269 const LHTreeNode
*root() const { return m_root
; }
270 LHTreeNode
*root() { return m_root
; }
272 void setRoot(LHTreeNode
*r
) { m_root
= r
; }
278 void simplifyAdjacencies();
279 void removeAuxNodes();
282 void simplifyAdjacencies(List
<LHTreeNode::Adjacency
> &adjs
);
288 //---------------------------------------------------------
290 //---------------------------------------------------------
291 class OGDF_EXPORT ExtendedNestingGraph
;
293 class OGDF_EXPORT ClusterGraphCopy
: public ClusterGraph
298 ClusterGraphCopy(const ExtendedNestingGraph
&H
, const ClusterGraph
&CG
);
300 void init(const ExtendedNestingGraph
&H
, const ClusterGraph
&CG
);
302 const ClusterGraph
&getOriginalClusterGraph() const { return *m_pCG
; }
304 cluster
copy(cluster cOrig
) const { return m_copy
[cOrig
]; }
305 cluster
original(cluster cCopy
) const { return m_original
[cCopy
]; }
307 void setParent(node v
, cluster c
);
310 void createClusterTree(cluster cOrig
);
312 const ClusterGraph
*m_pCG
;
313 const ExtendedNestingGraph
*m_pH
;
315 ClusterArray
<cluster
> m_copy
;
316 ClusterArray
<cluster
> m_original
;
320 //---------------------------------------------------------
321 // ExtendedNestingGraph
322 //---------------------------------------------------------
323 class OGDF_EXPORT ExtendedNestingGraph
: public Graph
326 // the type of a node in this copy
327 enum NodeType
{ ntNode
, ntClusterTop
, ntClusterBottom
, ntDummy
, ntClusterTopBottom
};
329 ExtendedNestingGraph(const ClusterGraph
&CG
);
331 const ClusterGraphCopy
&getClusterGraph() const { return m_CGC
; }
332 const ClusterGraph
&getOriginalClusterGraph() const { return m_CGC
.getOriginalClusterGraph(); }
334 node
copy (node v
) const { return m_copy
[v
]; }
335 node
top (cluster cOrig
) const { return m_topNode
[cOrig
]; }
336 node
bottom(cluster cOrig
) const { return m_bottomNode
[cOrig
]; }
338 int topRank (cluster c
) const { return m_topRank
[c
]; }
339 int bottomRank(cluster c
) const { return m_bottomRank
[c
]; }
342 NodeType
type(node v
) const { return m_type
[v
]; }
343 node
origNode (node v
) const { return m_origNode
[v
]; }
344 edge
origEdge (edge e
) const { return m_origEdge
[e
]; }
346 cluster
originalCluster(node v
) const { return m_CGC
.original(m_CGC
.clusterOf(v
)); }
347 cluster
parent(node v
) const { return m_CGC
.clusterOf(v
); }
348 cluster
parent(cluster c
) const { return c
->parent(); }
349 bool isVirtual(cluster c
) const { return m_CGC
.original(c
) == 0; }
351 const List
<edge
> &chain(edge e
) const { return m_copyEdge
[e
]; }
353 // is edge e reversed ?
354 bool isReversed (edge e
) const {
355 return e
->source() != origNode(chain(e
).front()->source());
358 bool isLongEdgeDummy(node v
) const {
359 return (type(v
) == ntDummy
&& v
->outdeg() == 1);
362 bool verticalSegment(edge e
) const { return m_vertical
[e
]; }
364 int numberOfLayers() const { return m_numLayers
; }
365 int rank(node v
) const { return m_rank
[v
]; }
366 int pos(node v
) const { return m_pos
[v
]; }
367 const LHTreeNode
*layerHierarchyTree(int i
) const { return m_layer
[i
].root(); }
368 const ENGLayer
&layer(int i
) const { return m_layer
[i
]; }
370 RCCrossings
reduceCrossings(int i
, bool dirTopDown
);
371 void storeCurrentPos();
375 void removeTopBottomEdges();
377 int aeLevel(node v
) const { return m_aeLevel
[v
]; }
380 cluster
lca(node u
, node v
) const;
385 LHTreeNode
**vChild
) const;
387 edge
addEdge(node u
, node v
, bool addAlways
= false);
388 void assignAeLevel(cluster c
, int &count
);
389 bool reachable(node v
, node u
, SListPure
<node
> &successors
);
390 void moveDown(node v
, const SListPure
<node
> &successors
, NodeArray
<int> &level
);
391 bool tryEdge(node u
, node v
, Graph
&G
, NodeArray
<int> &level
);
393 RCCrossings
reduceCrossings(LHTreeNode
*cNode
, bool dirTopDown
);
394 void assignPos(const LHTreeNode
*vNode
, int &count
);
397 void computeRanking();
398 void createDummyNodes();
399 void createVirtualClusters();
400 void createVirtualClusters(
402 NodeArray
<node
> &vCopy
,
403 ClusterArray
<node
> &cCopy
);
405 void removeAuxNodes();
408 //const ClusterGraph &m_CG;
409 ClusterGraphCopy m_CGC
;
411 // mapping: nodes in CG <-> nodes in this copy
412 NodeArray
<node
> m_copy
;
413 NodeArray
<node
> m_origNode
;
415 // mapping: clusters in CG <-> nodes in this copy
416 ClusterArray
<node
> m_topNode
; // the node representing top-most part of cluster (min. rank)
417 ClusterArray
<node
> m_bottomNode
; // the node representing bottom-most part of cluster (max. rank)
418 ClusterArray
<int> m_topRank
;
419 ClusterArray
<int> m_bottomRank
;
421 // the type of a node in this copy
422 NodeArray
<NodeType
> m_type
;
424 // mapping: edges in CG <-> edges in this copy
425 EdgeArray
<List
<edge
> > m_copyEdge
;
426 EdgeArray
<edge
> m_origEdge
;
428 // level of each node
429 NodeArray
<int> m_rank
;
433 Array
<ENGLayer
> m_layer
;
434 // positions within a layer
435 NodeArray
<int> m_pos
;
437 // can an edge segment be drawn vertically?
438 EdgeArray
<bool> m_vertical
;
440 // temporary data for "addEdge()"
441 NodeArray
<int> m_aeLevel
;
442 NodeArray
<bool> m_aeVisited
;
443 NodeArray
<int> m_auxDeg
;
445 // temporary data for "lca()"
446 mutable ClusterArray
<cluster
> m_mark
;
447 mutable SListPure
<cluster
> m_markedClusters
;
448 mutable cluster m_secondPath
;
449 mutable node m_secondPathTo
;
450 mutable SListPure
<cluster
> m_markedClustersTree
;
451 mutable ClusterArray
<LHTreeNode
*> m_markTree
;
455 } // end namespace ogdf