00001
00002
00003
00004
00005
00006
00007
00008
00043 #ifdef _MSC_VER
00044 #pragma once
00045 #endif
00046
00047
00048 #ifndef OGDF_CLUSTER_GRAPH_H
00049 #define OGDF_CLUSTER_GRAPH_H
00050
00051 #include <ogdf/basic/NodeArray.h>
00052 #include <ogdf/basic/Stack.h>
00053 #include <ogdf/basic/GraphObserver.h>
00054
00055
00056 namespace ogdf {
00057
00058 class OGDF_EXPORT ClusterGraph;
00059 class OGDF_EXPORT ClusterGraphObserver;
00060
00062
00065 class OGDF_EXPORT ClusterElement : private GraphElement {
00066
00067 friend class OGDF_EXPORT ClusterGraph;
00068 friend class GraphList<ClusterElement>;
00069
00070 int m_id;
00071 int m_depth;
00072 List<node> m_entries;
00073 List<ClusterElement*> m_children;
00074 ClusterElement *m_parent;
00075 ClusterElement *m_pPrev;
00076 ClusterElement *m_pNext;
00077 ListIterator<ClusterElement*> m_it;
00078
00079 List<adjEntry> m_adjEntries;
00080
00081
00082
00083
00084 #ifdef OGDF_DEBUG
00085
00086 const ClusterGraph *m_pClusterGraph;
00087 #endif
00088
00089
00090 void init(List<node> &nodes) {
00091 while (!nodes.empty())
00092 m_entries.pushBack(nodes.popFrontRet());
00093 }
00094
00095 List<ClusterElement*> &getChildren(){
00096 return m_children;
00097 }
00098
00099 List<node> &getNodes(){
00100 return m_entries;
00101 }
00102
00104
00107 void getClusterInducedNodes(List<node> &clusterNodes);
00108 void getClusterInducedNodes(NodeArray<bool> &clusterNode, int& num);
00109
00110
00111 public:
00112
00114 #ifdef OGDF_DEBUG
00115 ClusterElement(const ClusterGraph *pClusterGraph,int id):
00116 m_id(id),m_depth(0),m_parent(0),m_pPrev(0),m_pNext(0),m_it(0),
00117 m_pClusterGraph(pClusterGraph) {};
00118 #else
00119 ClusterElement(int id):
00120 m_id(id), m_depth(0),m_parent(0),m_pPrev(0),m_pNext(0),m_it(0) {};
00121 #endif
00122
00123
00124 #ifdef OGDF_DEBUG
00125 const ClusterGraph *graphOf() const { return m_pClusterGraph; }
00126 #endif
00127
00128
00130 int index() const { return m_id; }
00132 int depth() const { return m_depth; }
00133 int& depth() { return m_depth; }
00135 ClusterElement* succ() const { return (ClusterElement*)m_next; }
00137 ClusterElement* pred() const { return (ClusterElement*)m_prev; }
00138
00140 ClusterElement* pSucc() const { return m_pNext; }
00142 ClusterElement* pPred() const { return m_pPrev; }
00143
00144
00145
00147 ListConstIterator<ClusterElement*> cBegin() const{ return m_children.begin();}
00149 ListConstIterator<ClusterElement*> crBegin() const{ return m_children.rbegin();}
00151 int cCount(){ return m_children.size();}
00153 ListIterator<node> nBegin(){ return m_entries.begin();}
00155 ListConstIterator<node> nBegin() const{ return m_entries.begin();}
00157 int nCount(){ return m_entries.size();}
00158
00160 ClusterElement* parent(){return m_parent;}
00161
00162
00164 ListConstIterator<adjEntry> firstAdj() const { return m_adjEntries.begin(); }
00166 ListIterator<adjEntry> firstAdj() { return m_adjEntries.begin(); }
00168 ListConstIterator<adjEntry> lastAdj () const { return m_adjEntries.rbegin(); }
00170 ListIterator<adjEntry> lastAdj () { return m_adjEntries.rbegin(); }
00171
00173
00176 void getClusterNodes(List<node> &clusterNodes);
00183 int getClusterNodes(NodeArray<bool> &clusterNode);
00184
00185 OGDF_NEW_DELETE
00186
00187 };
00188
00189
00190
00191
00192 typedef ClusterElement *cluster;
00193
00194
00195 #define forall_cluster_adj(adj,c)\
00196 for(ogdf::ListIterator<adjEntry> ogdf_loop_var=(c)->firstAdj();\
00197 ogdf::test_forall_adj_entries_of_cluster(ogdf_loop_var,(adj));\
00198 ogdf_loop_var=ogdf_loop_var.succ())
00199
00200 #define forall_cluster_rev_adj(adj,c)\
00201 for(ogdf::ListIterator<adjEntry> ogdf_loop_var=(c)->lastAdj();\
00202 ogdf::test_forall_adj_entries_of_cluster(ogdf_loop_var,(adj));\
00203 ogdf_loop_var=ogdf_loop_var.pred())
00204
00205 #define forall_cluster_adj_edges(e,c)\
00206 for(ogdf::ListIterator<adjEntry> ogdf_loop_var=(c)->firstAdj();\
00207 ogdf::test_forall_adj_edges_of_cluster(ogdf_loop_var,(e));\
00208 ogdf_loop_var=ogdf_loop_var.succ())
00209
00210
00211
00212 inline bool test_forall_adj_entries_of_cluster(ListIterator<adjEntry> &it, adjEntry &adj)
00213 {
00214 if (it.valid()) { adj = (*it);return true; }
00215 else return false;
00216 }
00217
00218 inline bool test_forall_adj_edges_of_cluster(ListIterator<adjEntry> &it, edge &e)
00219 {
00220 adjEntry adj = (*it);
00221 if (adj) { e = adj->theEdge(); return true; }
00222 else return false;
00223 }
00224
00225 inline bool test_forall_adj_edges_of_cluster(adjEntry &adj, edge &e)
00226 {
00227 if (adj) { e = adj->theEdge(); return true; }
00228 else return false;
00229 }
00230
00231
00232 class ClusterArrayBase;
00233 template<class T>class ClusterArray;
00234
00235
00236
00237
00238
00240 #define forall_clusters(c,C) for((c)=(C).firstCluster(); (c); (c)=(c)->succ())
00241
00242 #define forall_postOrderClusters(c,C)\
00243 for((c)=(C).firstPostOrderCluster(); (c); (c)=(c)->pSucc())
00244
00245
00246
00247
00249
00253 class OGDF_EXPORT ClusterGraph : public GraphObserver
00254 {
00255 GraphList<ClusterElement> m_clusters;
00256
00257 const Graph *m_pGraph;
00258
00259 int m_nClusters;
00260 int m_clusterIdCount;
00261 int m_clusterArrayTableSize;
00262
00263 mutable cluster m_postOrderStart;
00264 cluster m_rootCluster;
00265
00266 bool m_adjAvailable;
00267 bool m_allowEmptyClusters;
00268
00269 NodeArray<cluster> m_nodeMap;
00270
00271 NodeArray<ListIterator<node> > m_itMap;
00272
00273 mutable ListPure<ClusterArrayBase*> m_regClusterArrays;
00274 mutable ListPure<ClusterGraphObserver*> m_regObservers;
00275
00276 public:
00277
00279 ClusterGraph();
00280
00282
00285 ClusterGraph(const Graph &G);
00286
00288 ClusterGraph(const ClusterGraph &C);
00289
00291
00294 ClusterGraph(const ClusterGraph &C,Graph &G);
00295
00297
00302 ClusterGraph(
00303 const ClusterGraph &C,
00304 Graph &G,
00305 ClusterArray<cluster> &originalClusterTable,
00306 NodeArray<node> &originalNodeTable);
00307
00309
00314 ClusterGraph(
00315 const ClusterGraph &C,
00316 Graph &G,
00317 ClusterArray<cluster> &originalClusterTable,
00318 NodeArray<node> &originalNodeTable,
00319 EdgeArray<edge> &edgeCopy);
00320
00321 virtual ~ClusterGraph();
00322
00324 int maxClusterIndex() const { return m_clusterIdCount-1; }
00325
00327 void clear();
00328
00330 void semiClear();
00331
00333 void init(const Graph &G);
00334
00336 operator const Graph &() const { return *m_pGraph; }
00337
00339 ClusterGraph &operator=(const ClusterGraph &C);
00340
00342 void clearClusterTree(cluster C);
00343
00345
00346 const Graph & getGraph() const {return *m_pGraph;}
00347
00349 cluster newCluster(cluster parent, int id = -1);
00350
00352 cluster createEmptyCluster(const cluster parent = 0, int clusterId = -1);
00353
00355
00363 cluster createCluster(SList<node>& nodes, const cluster parent = 0);
00364
00366
00370 void delCluster(cluster c);
00371
00373 cluster rootCluster() const {return m_rootCluster;};
00374
00376 inline cluster clusterOf(node v) const{
00377 OGDF_ASSERT(v->graphOf() == m_pGraph)
00378 return m_nodeMap[v];
00379 }
00380
00382 int numberOfClusters() const { return m_nClusters; }
00384 int clusterIdCount() const { return m_clusterIdCount;}
00385
00387 int clusterArrayTableSize() const { return m_clusterArrayTableSize; }
00388
00390 void moveCluster(cluster c, cluster newParent);
00391
00392
00394 void reassignNode(node v, cluster c);
00395
00397
00398 void reInit(Graph& G)
00399 {
00400 reinitGraph(G);
00401 }
00402
00403
00404
00405
00407 void setUpdateDepth(bool b) const
00408 {
00409 m_updateDepth = b;
00410
00411
00412 if (!b) m_depthUpToDate = false;
00413 }
00414
00416 void pullUpSubTree(cluster c);
00417
00419
00420 int treeDepth() const
00421 {
00422
00423 if (m_updateDepth && !m_depthUpToDate)
00424 computeSubTreeDepth(rootCluster());
00425 if (!m_updateDepth) OGDF_THROW(AlgorithmFailureException);
00426 int l_depth = 1;
00427 cluster c;
00428 forall_clusters(c, *this)
00429 {
00430 if (c->depth() > l_depth) l_depth = c->depth();
00431 }
00432
00433 return l_depth;
00434 }
00436 void computeSubTreeDepth(cluster c) const;
00438
00439
00440 int& clusterDepth(cluster c) const
00441 {
00442
00443 OGDF_ASSERT(m_updateDepth);
00444
00445
00446 if (!m_depthUpToDate)
00447 computeSubTreeDepth(rootCluster());
00448 OGDF_ASSERT(c->depth() != 0)
00449 return c->depth();
00450 }
00451
00453 cluster commonCluster(SList<node>& nodes);
00454
00456
00459 cluster commonCluster(node v, node w) const;
00460
00462 cluster commonClusterLastAncestors(
00463 node v,
00464 node w,
00465 cluster& c1,
00466 cluster& c2) const;
00468
00469 cluster commonClusterPath(
00470 node v,
00471 node w,
00472 List<cluster>& eL) const;
00473
00475 cluster commonClusterAncestorsPath(
00476 node v,
00477 node w,
00478 cluster& c1,
00479 cluster& c2,
00480 List<cluster>& eL) const;
00481
00483 ListIterator<ClusterArrayBase*> registerArray(ClusterArrayBase *pClusterArray) const;
00484
00486 void unregisterArray(ListIterator<ClusterArrayBase*> it) const;
00487
00489 ListIterator<ClusterGraphObserver*> registerObserver(ClusterGraphObserver *pObserver) const;
00490
00492 void unregisterObserver(ListIterator<ClusterGraphObserver*> it) const;
00493
00495
00502 void emptyClusters(SList<cluster>& emptyCluster, SList<cluster>* checkCluster = 0);
00503
00505 inline bool emptyOnNodeDelete(cluster c)
00506 {
00507
00508 return (c->nCount() == 1) && (c->cCount() == 0);
00509 }
00510
00512 inline bool emptyOnClusterDelete(cluster c)
00513 {
00514
00515 return (c->nCount() == 0) && (c->cCount() == 1);
00516 }
00517
00519 cluster firstCluster() const { return m_clusters.begin (); }
00521 cluster lastCluster () const { return m_clusters.rbegin(); }
00523 cluster firstPostOrderCluster() const {
00524 if (!m_postOrderStart) postOrder();
00525 return m_postOrderStart;
00526 }
00527
00529 template<class CLUSTERLIST>
00530 void allClusters(CLUSTERLIST &clusters) const {
00531 clusters.clear();
00532 for (cluster c = m_clusters.begin(); c; c = c->succ())
00533 clusters.pushBack(c);
00534 }
00535
00537 template<class NODELIST>
00538 void collaps(NODELIST &nodes,Graph &G){
00539 OGDF_ASSERT(&G == m_pGraph);
00540 m_adjAvailable = false;
00541
00542 m_postOrderStart = 0;
00543 node v = nodes.popFrontRet();
00544 while (!nodes.empty())
00545 {
00546 node w = nodes.popFrontRet();
00547 adjEntry adj = w->firstAdj();
00548 while (adj !=0)
00549 {
00550 adjEntry succ = adj->succ();
00551 edge e = adj->theEdge();
00552 if (e->source() == v || e->target() == v)
00553 G.delEdge(e);
00554 else if (e->source() == w)
00555 G.moveSource(e,v);
00556 else
00557 G.moveTarget(e,v);
00558 adj = succ;
00559 }
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 G.delNode(w);
00571 }
00572 }
00573
00575 template<class EDGELIST>
00576 void adjEdges(cluster c, EDGELIST &edges) const {
00577 edges.clear();
00578 edge e;
00579 if (m_adjAvailable)
00580 {
00581 forall_cluster_adj_edges(e,c)
00582 edges.pushBack(e);
00583 }
00584 }
00585
00587 template<class ADJLIST>
00588 void adjEntries(cluster c, ADJLIST &entries) const {
00589 entries.clear();
00590 adjEntry adj;
00591 if (m_adjAvailable)
00592 {
00593 forall_cluster_adj(adj,c)
00594 entries.pushBack(adj);
00595 }
00596 }
00597
00599 template<class LISTITERATOR>
00600 void makeAdjEntries(cluster c,LISTITERATOR start){
00601 adjEntry adj;
00602 c->m_adjEntries.clear();
00603 LISTITERATOR its;
00604 for (its = start; its.valid(); its++)
00605 {
00606 adj = (*its);
00607 c->m_adjEntries.pushBack(adj);
00608 }
00609 }
00610
00611
00612
00613
00615 void writeGML(const char *fileName);
00616
00618 void writeGML(ostream &os);
00619
00620
00621
00622
00624 bool readClusterGML(const char* fileName, Graph& G);
00626 bool readClusterGML(istream& is, Graph& G);
00627
00628
00629
00630
00632
00633 bool consistencyCheck();
00634
00636
00637 bool representsCombEmbedding();
00638
00640 void adjAvailable(bool val){ m_adjAvailable = val;};
00641
00642 protected:
00645 cluster doCreateCluster(SList<node>& nodes,
00646 const cluster parent, int clusterId = -1);
00649 cluster doCreateCluster(SList<node>& nodes,
00650 SList<cluster>& emptyCluster,
00651 const cluster parent, int clusterId = -1);
00652
00653 mutable ClusterArray<int>* m_lcaSearch;
00654 mutable int m_lcaNumber;
00655 mutable ClusterArray<cluster>* m_vAncestor;
00656 mutable ClusterArray<cluster>* m_wAncestor;
00657
00659 void copyLCA(const ClusterGraph &C, ClusterArray<cluster>* clusterCopy=0);
00660
00661
00662 mutable bool m_updateDepth;
00663 mutable bool m_depthUpToDate;
00664
00666
00667 void updatePostOrder(cluster c, cluster oldParent, cluster newParent);
00668
00670
00671 cluster postOrderPredecessor(cluster c) const;
00673 cluster leftMostCluster(cluster c) const;
00674
00675
00676
00677
00678
00680 virtual void nodeDeleted(node v)
00681 {
00682 bool cRemove = false;
00683 cluster c = clusterOf(v);
00684 if (!c) return;
00685
00686
00687
00688 unassignNode(v);
00689 if (cRemove && !m_allowEmptyClusters)
00690 {
00691 cluster nonEmpty = c->parent();
00692 cluster cRun = nonEmpty;
00693 delCluster(c);
00694 while ((cRun != rootCluster()) && (cRun->nCount() + cRun->cCount() == 0))
00695 {
00696 nonEmpty = cRun->parent();
00697 delCluster(cRun);
00698 cRun = nonEmpty;
00699 }
00700
00701 }
00702 }
00704 virtual void nodeAdded(node v)
00705 {
00706 assignNode(v, rootCluster());
00707 };
00709 virtual void edgeDeleted(edge ) {};
00711 virtual void edgeAdded(edge ) {};
00713 virtual void reInit() {};
00715 virtual void cleared()
00716 {
00717
00718
00719 semiClear();
00720 };
00721
00722 private:
00724 void assignNode(node v, cluster C);
00725
00727 void unassignNode(node v);
00728
00731 void removeNodeAssignment(node v)
00732 {
00733 if (m_nodeMap[v])
00734 {
00735 cluster C2 = m_nodeMap[v];
00736 C2->m_entries.del(m_itMap[v]);
00737 m_nodeMap[v] = 0;
00738 m_itMap[v] = 0;
00739 }
00740 }
00741
00744 void shallowCopy(const ClusterGraph &C);
00745
00748 void deepCopy(const ClusterGraph &C,Graph &G);
00751 void deepCopy(const ClusterGraph &C,Graph &G,
00752 ClusterArray<cluster> &originalClusterTable,
00753 NodeArray<node> &originalNodeTable);
00757 void deepCopy(const ClusterGraph &C,Graph &G,
00758 ClusterArray<cluster> &originalClusterTable,
00759 NodeArray<node> &originalNodeTable,
00760 EdgeArray<edge> &edgeCopy);
00761
00762
00763 void clearClusterTree(cluster c,List<node> &attached);
00764
00765 void initGraph(const Graph &G);
00766
00768 void reinitGraph(const Graph &G);
00769
00771 cluster newCluster(int id);
00773 cluster newCluster();
00774
00776 void postOrder() const;
00778 void checkPostOrder() const;
00779
00780 void postOrder(cluster c,SListPure<cluster> &S) const;
00781
00782 void reinitArrays();
00783
00784
00786 void writeCluster(ostream &os,
00787 NodeArray<int> &nId,
00788 ClusterArray<int> & cId,
00789 int &nextId,
00790 cluster c,
00791 String ttt);
00792
00794 void writeGraphWinCluster(ostream &os,
00795 NodeArray<int> &nId,
00796 NodeArray<String> &nStr,
00797 ClusterArray<int> &cId,
00798 ClusterArray<String> &cStr,
00799 int &nextId,
00800 cluster c,
00801 String ttt);
00802
00803 };
00804
00805
00806
00807
00808
00809 ostream &operator<<(ostream &os, ogdf::cluster c);
00810
00811
00812 }
00813
00814 #endif