Open
Graph Drawing
Framework

 v.2007.11
 

ClusterGraph.h

Go to the documentation of this file.
00001 /*
00002  * $Revision: 1.12 $
00003  * 
00004  * last checkin:
00005  *   $Author: klein $ 
00006  *   $Date: 2007-11-15 11:48:55 +0100 (Do, 15 Nov 2007) $ 
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                                           // Don't use a GraphList ! 
00089                                           // This messes with the adjacency 
00090                                           // list of the underlying graph
00091 
00092     #ifdef OGDF_DEBUG
00093     // we store the graph containing this node for debugging purposes
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     // Iteration over tree structures.
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 };// class ClusterElement
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 // iteration macros
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     //inserted mainly for use in gmlparser.
00400     void reInit(Graph& G) 
00401     {
00402         reinitGraph(G);
00403     }
00404 
00405     //---------------------------
00406     //tree queries / depth issues
00407 
00409     void setUpdateDepth(bool b) const 
00410     {
00411         m_updateDepth = b;
00412         //make sure that depth cant be used anymore
00413         //(even if it may still be valid a little while)
00414         if (!b) m_depthUpToDate = false;
00415     }
00416 
00418     void pullUpSubTree(cluster c);
00419 
00421     //maybe later we should provide a permanent depth member update
00422     int treeDepth() const
00423     {
00424         //initialize depth at first call
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     //should be called instead of direct c->depth call to assure
00441     //valid depth
00442     int& clusterDepth(cluster c) const 
00443     {
00444         //initialize depth at first call
00445         if (m_updateDepth && !m_depthUpToDate)
00446             computeSubTreeDepth(rootCluster());
00447         //if depth is requested but not updated
00448         if (!m_updateDepth) THROW(AlgorithmFailureException);
00449         //debug check
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         //end
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) //virtual?
00521     {
00522         //if (!c) return false; //Allows easy use in loops
00523         return (c->nCount() == 1) && (c->cCount() == 0);
00524     }
00525 
00527     inline bool emptyOnClusterDelete(cluster c) //virtual?
00528     {
00529         //if (!c) return false; //Allows easy use in loops
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             //because nodes can already be unassigned (they are always
00576             //unassigned if deleted), we have to check this
00577             /*
00578             if (m_nodeMap[w])
00579             {
00580                 cluster c = m_nodeMap[w];
00581                 c->m_entries.del(m_itMap[w]);
00582             }
00583             */
00584             //removeNodeAssignment(w);
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     //file output
00628 
00630     void writeGML(const char *fileName);
00631 
00633     void writeGML(ostream &os);
00634 
00636     // (for debugging purposes only)
00637     bool consistencyCheck();
00638 
00640     // (for debugging purposes only)
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     //int m_treeDepth; //should be implemented and updated in operations?
00665 
00666     mutable bool m_updateDepth; 
00667     mutable bool m_depthUpToDate; 
00668 
00670     //we assume that c is inserted via pushback in newparent->children
00671     void updatePostOrder(cluster c, cluster oldParent, cluster newParent);
00672 
00674     //0 if c==root 
00675     cluster postOrderPredecessor(cluster c) const;
00677     cluster leftMostCluster(cluster c) const;
00678 
00679     //---------------------------------------
00680     //functions inherited from GraphObserver:
00681     //define how to cope with graph changes
00682     
00684     virtual void nodeDeleted(node v) 
00685     { 
00686         bool cRemove = false;
00687         cluster c = clusterOf(v);
00688         if (!c) return;
00689         //never allow totally empty cluster
00690         //if ((emptyOnNodeDelete(c)) &&
00691         //  (c != rootCluster()) ) cRemove = true;
00692         unassignNode(v); 
00693         if (cRemove && !m_allowEmptyClusters) //parent exists
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 /* e */) {};
00715     virtual void edgeAdded(edge /* e */)   {};
00717     virtual void reInit()            {};
00719     virtual void cleared()           
00720     {
00721         //we don't want a complete clear, as the graph still exists
00722         //and can be updated from input stream
00723         semiClear();
00724     };//Graph cleared
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]) //iff == 0, itmap == 0 !!?
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 } // end namespace ogdf
00817 
00818 #endif


© 1999-2007 by oreas GmbH, © 2005-2007 by University Dortmund and University Cologne.

Generated on Thu Nov 22 19:40:01 2007 by doxygen 1.5.4.