00001
00002
00003
00004
00005
00006
00007
00008
00051 #ifdef _MSC_VER
00052 #pragma once
00053 #endif
00054
00055
00056 #ifndef OGDF_CLUSTER_GRAPH_H
00057 #define OGDF_CLUSTER_GRAPH_H
00058
00059 #include <ogdf/basic/NodeArray.h>
00060 #include <ogdf/basic/Stack.h>
00061 #include <ogdf/basic/GraphObserver.h>
00062
00063
00064 namespace ogdf {
00065
00066 class ClusterGraph;
00067 class ClusterGraphObserver;
00068
00070
00073 class ClusterElement : private GraphElement {
00074
00075 friend class ClusterGraph;
00076 friend class GraphList<ClusterElement>;
00077
00078 int m_id;
00079 int m_depth;
00080 List<node> m_entries;
00081 List<ClusterElement*> m_children;
00082 ClusterElement *m_parent;
00083 ClusterElement *m_pPrev;
00084 ClusterElement *m_pNext;
00085 ListIterator<ClusterElement*> m_it;
00086
00087 List<adjEntry> m_adjEntries;
00088
00089
00090
00091
00092 #ifdef OGDF_DEBUG
00093
00094 const ClusterGraph *m_pClusterGraph;
00095 #endif
00096
00097
00098 void init(List<node> &nodes) {
00099 while (!nodes.empty())
00100 m_entries.pushBack(nodes.popFrontRet());
00101 }
00102
00103 List<ClusterElement*> &getChildren(){
00104 return m_children;
00105 }
00106
00107 List<node> &getNodes(){
00108 return m_entries;
00109 }
00110
00112
00115 void getClusterInducedNodes(List<node> &clusterNodes);
00116
00117
00118 public:
00119
00121 #ifdef OGDF_DEBUG
00122 ClusterElement(const ClusterGraph *pClusterGraph,int id):
00123 m_id(id),m_depth(0),m_parent(0),m_pPrev(0),m_pNext(0),m_it(0),
00124 m_pClusterGraph(pClusterGraph) {};
00125 #else
00126 ClusterElement(int id):
00127 m_id(id), m_depth(0),m_parent(0),m_pPrev(0),m_pNext(0),m_it(0) {};
00128 #endif
00129
00130
00131 #ifdef OGDF_DEBUG
00132 const ClusterGraph *graphOf() const { return m_pClusterGraph; }
00133 #endif
00134
00135
00137 int index() const { return m_id; }
00139 int depth() const { return m_depth; }
00140 int& depth() { return m_depth; }
00142 ClusterElement* succ() const { return (ClusterElement*)m_next; }
00144 ClusterElement* pred() const { return (ClusterElement*)m_prev; }
00145
00147 ClusterElement* pSucc() const { return m_pNext; }
00149 ClusterElement* pPred() const { return m_pPrev; }
00150
00151
00152
00154 ListConstIterator<ClusterElement*> cBegin() const{ return m_children.begin();}
00156 ListConstIterator<ClusterElement*> crBegin() const{ return m_children.rbegin();}
00158 int cCount(){ return m_children.size();}
00160 ListIterator<node> nBegin(){ return m_entries.begin();}
00162 ListConstIterator<node> nBegin() const{ return m_entries.begin();}
00164 int nCount(){ return m_entries.size();}
00165
00167 ClusterElement* parent(){return m_parent;}
00168
00169
00171 ListConstIterator<adjEntry> firstAdj() const { return m_adjEntries.begin(); }
00173 ListIterator<adjEntry> firstAdj() { return m_adjEntries.begin(); }
00175 ListConstIterator<adjEntry> lastAdj () const { return m_adjEntries.rbegin(); }
00177 ListIterator<adjEntry> lastAdj () { return m_adjEntries.rbegin(); }
00178
00180
00183 void getClusterNodes(List<node> &clusterNodes);
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 ogdf::ListIterator<adjEntry> OGDF_VAR(__LINE__);\
00197 for(OGDF_VAR(__LINE__)=(c)->firstAdj();\
00198 ogdf::test_forall_adj_entries_of_cluster(OGDF_VAR(__LINE__),(adj));\
00199 OGDF_VAR(__LINE__)=OGDF_VAR(__LINE__).succ())
00200
00201 #define forall_cluster_rev_adj(adj,c)\
00202 ogdf::ListIterator<adjEntry> OGDF_VAR(__LINE__);\
00203 for(OGDF_VAR(__LINE__)=(c)->lastAdj();\
00204 ogdf::test_forall_adj_entries_of_cluster(OGDF_VAR(__LINE__),(adj));\
00205 OGDF_VAR(__LINE__)=OGDF_VAR(__LINE__).pred())
00206
00207 #define forall_cluster_adj_edges(e,c)\
00208 ogdf::ListIterator<adjEntry> OGDF_VAR(__LINE__);\
00209 for(OGDF_VAR(__LINE__)=(c)->firstAdj();\
00210 ogdf::test_forall_adj_edges_of_cluster(OGDF_VAR(__LINE__),(e));\
00211 OGDF_VAR(__LINE__)=OGDF_VAR(__LINE__).succ())
00212
00213
00214
00215 inline bool test_forall_adj_entries_of_cluster(ListIterator<adjEntry> &it, adjEntry &adj)
00216 {
00217 if (it.valid()) { adj = (*it);return true; }
00218 else return false;
00219 }
00220
00221 inline bool test_forall_adj_edges_of_cluster(ListIterator<adjEntry> &it, edge &e)
00222 {
00223 adjEntry adj = (*it);
00224 if (adj) { e = adj->theEdge(); return true; }
00225 else return false;
00226 }
00227
00228 inline bool test_forall_adj_edges_of_cluster(adjEntry &adj, edge &e)
00229 {
00230 if (adj) { e = adj->theEdge(); return true; }
00231 else return false;
00232 }
00233
00234
00235 class ClusterArrayBase;
00236 template<class T>class ClusterArray;
00237
00238
00239
00240
00241
00243 #define forall_clusters(c,C) for((c)=(C).firstCluster(); (c); (c)=(c)->succ())
00245 #define forall_postOrderClusters(c,C)\
00246 for((c)=(C).firstPostOrderCluster(); (c); (c)=(c)->pSucc())
00247
00248
00249
00250
00252
00256 class ClusterGraph : public GraphObserver
00257 {
00258 GraphList<ClusterElement> m_clusters;
00259
00260 const Graph *m_pGraph;
00261
00262 int m_nClusters;
00263 int m_clusterIdCount;
00264 int m_clusterArrayTableSize;
00265
00266 mutable cluster m_postOrderStart;
00267 cluster m_rootCluster;
00268
00269 bool m_adjAvailable;
00270 bool m_allowEmptyClusters;
00271
00272 NodeArray<cluster> m_nodeMap;
00273
00274 NodeArray<ListIterator<node> > m_itMap;
00275
00276 mutable ListPure<ClusterArrayBase*> m_regClusterArrays;
00277 mutable ListPure<ClusterGraphObserver*> m_regObservers;
00278
00279 public:
00280
00282 ClusterGraph();
00283
00285
00288 ClusterGraph(const Graph &G);
00289
00291 ClusterGraph(const ClusterGraph &C);
00292
00294
00297 ClusterGraph(const ClusterGraph &C,Graph &G);
00298
00300
00305 ClusterGraph(
00306 const ClusterGraph &C,
00307 Graph &G,
00308 ClusterArray<cluster> &originalClusterTable,
00309 NodeArray<node> &originalNodeTable);
00310
00312
00317 ClusterGraph(
00318 const ClusterGraph &C,
00319 Graph &G,
00320 ClusterArray<cluster> &originalClusterTable,
00321 NodeArray<node> &originalNodeTable,
00322 EdgeArray<edge> &edgeCopy);
00323
00324 virtual ~ClusterGraph();
00325
00327 int maxClusterIndex() const { return m_clusterIdCount-1; }
00328
00330 void clear();
00331
00333 void semiClear();
00334
00336 void init(const Graph &G);
00337
00339 operator const Graph &() const { return *m_pGraph; }
00340
00342 ClusterGraph &operator=(const ClusterGraph &C);
00343
00345 void clearClusterTree(cluster C);
00346
00348 const Graph & getGraph() const {return *m_pGraph;}
00349
00351 cluster newCluster(cluster parent, int id = -1);
00352
00354 cluster createEmptyCluster(const cluster parent = 0, int clusterId = -1);
00355
00357
00365 cluster createCluster(SList<node>& nodes, const cluster parent = 0);
00366
00368
00372 void delCluster(cluster c);
00373
00375 cluster rootCluster() const {return m_rootCluster;};
00376
00378 inline cluster clusterOf(node v) const{
00379 OGDF_ASSERT(v->graphOf() == m_pGraph)
00380 return m_nodeMap[v];
00381 }
00382
00384 int numberOfClusters() const { return m_nClusters; }
00386 int clusterIdCount() const { return m_clusterIdCount;}
00387
00389 int clusterArrayTableSize() const { return m_clusterArrayTableSize; }
00390
00392 void moveCluster(cluster c, cluster newParent);
00393
00394
00396 void reassignNode(node v, cluster c);
00397
00399
00400 void reInit(Graph& G)
00401 {
00402 reinitGraph(G);
00403 }
00404
00405
00406
00407
00409 void setUpdateDepth(bool b) const
00410 {
00411 m_updateDepth = b;
00412
00413
00414 if (!b) m_depthUpToDate = false;
00415 }
00416
00418 void pullUpSubTree(cluster c);
00419
00421
00422 int treeDepth() const
00423 {
00424
00425 if (m_updateDepth && !m_depthUpToDate)
00426 computeSubTreeDepth(rootCluster());
00427 if (!m_updateDepth) THROW(AlgorithmFailureException);
00428 int l_depth = 1;
00429 cluster c;
00430 forall_clusters(c, *this)
00431 {
00432 if (c->depth() > l_depth) l_depth = c->depth();
00433 }
00434
00435 return l_depth;
00436 }
00438 void computeSubTreeDepth(cluster c) const;
00440
00441
00442 int& clusterDepth(cluster c) const
00443 {
00444
00445 if (m_updateDepth && !m_depthUpToDate)
00446 computeSubTreeDepth(rootCluster());
00447
00448 if (!m_updateDepth) THROW(AlgorithmFailureException);
00449
00450 #ifdef OGDF_DEBUG
00451 cluster cp = c->parent();
00452 int lastDepth = c->depth();
00453 while (cp != 0)
00454 {
00455 bool b = (lastDepth == cp->depth()+1);
00456 OGDF_ASSERT(b)
00457 lastDepth = cp->depth();
00458 cp = cp->parent();
00459 }
00460 OGDF_ASSERT(lastDepth == 1);
00461 #endif
00462
00463 OGDF_ASSERT(c->depth() != 0)
00464 return c->depth();
00465 }
00466
00468 cluster commonCluster(SList<node>& nodes);
00469
00471
00474 cluster commonCluster(node v, node w) const;
00475
00477 cluster commonClusterLastAncestors(
00478 node v,
00479 node w,
00480 cluster& c1,
00481 cluster& c2) const;
00483
00484 cluster commonClusterPath(
00485 node v,
00486 node w,
00487 List<cluster>& eL) const;
00488
00490 cluster commonClusterAncestorsPath(
00491 node v,
00492 node w,
00493 cluster& c1,
00494 cluster& c2,
00495 List<cluster>& eL) const;
00496
00498 ListIterator<ClusterArrayBase*> registerArray(ClusterArrayBase *pClusterArray) const;
00499
00501 void unregisterArray(ListIterator<ClusterArrayBase*> it) const;
00502
00504 ListIterator<ClusterGraphObserver*> registerObserver(ClusterGraphObserver *pObserver) const;
00505
00507 void unregisterObserver(ListIterator<ClusterGraphObserver*> it) const;
00508
00510
00517 void emptyClusters(SList<cluster>& emptyCluster, SList<cluster>* checkCluster = 0);
00518
00520 inline bool emptyOnNodeDelete(cluster c)
00521 {
00522
00523 return (c->nCount() == 1) && (c->cCount() == 0);
00524 }
00525
00527 inline bool emptyOnClusterDelete(cluster c)
00528 {
00529
00530 return (c->nCount() == 0) && (c->cCount() == 1);
00531 }
00532
00534 cluster firstCluster() const { return m_clusters.begin (); }
00536 cluster lastCluster () const { return m_clusters.rbegin(); }
00538 cluster firstPostOrderCluster() const {
00539 if (!m_postOrderStart) postOrder();
00540 return m_postOrderStart;
00541 }
00542
00544 template<class CLUSTERLIST>
00545 void allNodes(CLUSTERLIST &clusters) const {
00546 clusters.clear();
00547 for (cluster c = m_clusters.begin(); c; c = c->succ())
00548 clusters.pushBack(c);
00549 }
00550
00552 template<class NODELIST>
00553 void collaps(NODELIST &nodes,Graph &G){
00554 OGDF_ASSERT(&G == m_pGraph);
00555 m_adjAvailable = false;
00556
00557 m_postOrderStart = 0;
00558 node v = nodes.popFrontRet();
00559 while (!nodes.empty())
00560 {
00561 node w = nodes.popFrontRet();
00562 adjEntry adj = w->firstAdj();
00563 while (adj !=0)
00564 {
00565 adjEntry succ = adj->succ();
00566 edge e = adj->theEdge();
00567 if (e->source() == v || e->target() == v)
00568 G.delEdge(e);
00569 else if (e->source() == w)
00570 G.moveSource(e,v);
00571 else
00572 G.moveTarget(e,v);
00573 adj = succ;
00574 }
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585 G.delNode(w);
00586 }
00587 }
00588
00590 template<class EDGELIST>
00591 void adjEdges(cluster c, EDGELIST &edges) const {
00592 edges.clear();
00593 edge e;
00594 if (m_adjAvailable)
00595 {
00596 forall_cluster_adj_edges(e,c)
00597 edges.pushBack(e);
00598 }
00599 }
00600
00602 template<class ADJLIST>
00603 void adjEntries(cluster c, ADJLIST &entries) const {
00604 entries.clear();
00605 adjEntry adj;
00606 if (m_adjAvailable)
00607 {
00608 forall_cluster_adj(adj,c)
00609 entries.pushBack(adj);
00610 }
00611 }
00612
00614 template<class LISTITERATOR>
00615 void makeAdjEntries(cluster c,LISTITERATOR start){
00616 adjEntry adj;
00617 c->m_adjEntries.clear();
00618 LISTITERATOR its;
00619 for (its = start; its.valid(); its++)
00620 {
00621 adj = (*its);
00622 c->m_adjEntries.pushBack(adj);
00623 }
00624 }
00625
00626
00627
00628
00630 void writeGML(const char *fileName);
00631
00633 void writeGML(ostream &os);
00634
00636
00637 bool consistencyCheck();
00638
00640
00641 bool representsCombEmbedding();
00642
00644 void adjAvailable(bool val){ m_adjAvailable = val;};
00645
00646 protected:
00649 cluster doCreateCluster(SList<node>& nodes,
00650 const cluster parent, int clusterId = -1);
00653 cluster doCreateCluster(SList<node>& nodes,
00654 SList<cluster>& emptyCluster,
00655 const cluster parent, int clusterId = -1);
00656
00657 mutable ClusterArray<int>* m_lcaSearch;
00658 mutable int m_lcaNumber;
00659 mutable ClusterArray<cluster>* m_vAncestor;
00660 mutable ClusterArray<cluster>* m_wAncestor;
00661
00663 void copyLCA(const ClusterGraph &C, ClusterArray<cluster>* clusterCopy=0);
00664
00665
00666 mutable bool m_updateDepth;
00667 mutable bool m_depthUpToDate;
00668
00670
00671 void updatePostOrder(cluster c, cluster oldParent, cluster newParent);
00672
00674
00675 cluster postOrderPredecessor(cluster c) const;
00677 cluster leftMostCluster(cluster c) const;
00678
00679
00680
00681
00682
00684 virtual void nodeDeleted(node v)
00685 {
00686 bool cRemove = false;
00687 cluster c = clusterOf(v);
00688 if (!c) return;
00689
00690
00691
00692 unassignNode(v);
00693 if (cRemove && !m_allowEmptyClusters)
00694 {
00695 cluster nonEmpty = c->parent();
00696 cluster cRun = nonEmpty;
00697 delCluster(c);
00698 while ((cRun != rootCluster()) && (cRun->nCount() + cRun->cCount() == 0))
00699 {
00700 nonEmpty = cRun->parent();
00701 delCluster(cRun);
00702 cRun = nonEmpty;
00703 }
00704
00705 }
00706 }
00708 virtual void nodeAdded(node v)
00709 {
00710 assignNode(v, rootCluster());
00711 };
00713 virtual void edgeDeleted(edge ) {};
00715 virtual void edgeAdded(edge ) {};
00717 virtual void reInit() {};
00719 virtual void cleared()
00720 {
00721
00722
00723 semiClear();
00724 };
00725
00726 private:
00728 void assignNode(node v, cluster C);
00729
00731 void unassignNode(node v);
00732
00735 void removeNodeAssignment(node v)
00736 {
00737 if (m_nodeMap[v])
00738 {
00739 cluster C2 = m_nodeMap[v];
00740 C2->m_entries.del(m_itMap[v]);
00741 m_nodeMap[v] = 0;
00742 m_itMap[v] = 0;
00743 }
00744 }
00745
00748 void shallowCopy(const ClusterGraph &C);
00749
00752 void deepCopy(const ClusterGraph &C,Graph &G);
00755 void deepCopy(const ClusterGraph &C,Graph &G,
00756 ClusterArray<cluster> &originalClusterTable,
00757 NodeArray<node> &originalNodeTable);
00761 void deepCopy(const ClusterGraph &C,Graph &G,
00762 ClusterArray<cluster> &originalClusterTable,
00763 NodeArray<node> &originalNodeTable,
00764 EdgeArray<edge> &edgeCopy);
00765
00766
00767 void clearClusterTree(cluster c,List<node> &attached);
00768
00769 void initGraph(const Graph &G);
00770
00772 void reinitGraph(const Graph &G);
00773
00775 cluster newCluster(int id);
00777 cluster newCluster();
00778
00780 void postOrder() const;
00782 void checkPostOrder() const;
00783
00784 void postOrder(cluster c,SListPure<cluster> &S) const;
00785
00786 void reinitArrays();
00787
00788
00790 void writeCluster(ostream &os,
00791 NodeArray<int> &nId,
00792 ClusterArray<int> & cId,
00793 int &nextId,
00794 cluster c,
00795 String ttt);
00796
00798 void writeGraphWinCluster(ostream &os,
00799 NodeArray<int> &nId,
00800 NodeArray<String> &nStr,
00801 ClusterArray<int> &cId,
00802 ClusterArray<String> &cStr,
00803 int &nextId,
00804 cluster c,
00805 String ttt);
00806
00807 };
00808
00809
00810
00811
00812
00813 ostream &operator<<(ostream &os, ogdf::cluster c);
00814
00815
00816 }
00817
00818 #endif