Open
Graph Drawing
Framework

 v.2007.11
 

Graph_d.h

Go to the documentation of this file.
00001 /*
00002  * $Revision: 1.25 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2007-11-08 16:10:37 +0100 (Do, 08 Nov 2007) $ 
00007  ***************************************************************/
00008  
00054 #ifdef _MSC_VER
00055 #pragma once
00056 #endif
00057 
00058 #ifndef OGDF_GRAPH_D_H
00059 #define OGDF_GRAPH_D_H
00060 
00061 
00062 #include <ogdf/basic/List.h>
00063 
00064 
00065 namespace ogdf {
00066 
00067 //
00068 // in embedded graphs, adjacency lists are given in clockwise order.
00069 //
00070 
00071 
00072 class Graph;
00073 class NodeElement;
00074 class EdgeElement;
00075 class AdjElement;
00076 class FaceElement;
00077 class GraphListBase;
00078 class ClusterElement;
00079 
00080 
00082 
00087 class GraphElement {
00088     friend class Graph;
00089     friend class GraphListBase;
00090 
00091 protected:
00092     GraphElement *m_next; 
00093     GraphElement *m_prev; 
00094 
00095     OGDF_NEW_DELETE
00096 }; // class GraphElement
00097 
00098 
00100 class GraphListBase {
00101 protected:
00102     GraphElement *m_head; 
00103     GraphElement *m_tail; 
00104 
00105 public:
00107     GraphListBase() { m_head = m_tail = 0; }
00108     // destruction
00109     ~GraphListBase() { }
00110 
00112     void pushBack(GraphElement *pX) {
00113         pX->m_next = 0;
00114         pX->m_prev = m_tail;
00115         if (m_head)
00116             m_tail = m_tail->m_next = pX;
00117         else
00118             m_tail = m_head = pX;
00119     }
00120 
00122     void insertAfter(GraphElement *pX, GraphElement *pY) {
00123         pX->m_prev = pY;
00124         GraphElement *pYnext = pX->m_next = pY->m_next;
00125         pY->m_next = pX;
00126         if (pYnext) pYnext->m_prev = pX;
00127         else m_tail = pX;
00128     }
00129 
00131     void insertBefore(GraphElement *pX, GraphElement *pY) {
00132         pX->m_next = pY;
00133         GraphElement *pYprev = pX->m_prev = pY->m_prev;
00134         pY->m_prev = pX;
00135         if (pYprev) pYprev->m_next = pX;
00136         else m_head = pX;
00137     }
00138 
00140     void del(GraphElement *pX) {
00141         GraphElement *pxPrev = pX->m_prev, *pxNext = pX->m_next;
00142 
00143         if (pxPrev)
00144             pxPrev->m_next = pxNext;
00145         else
00146             m_head = pxNext;
00147         if (pxNext)
00148             pxNext->m_prev = pxPrev;
00149         else
00150             m_tail = pxPrev;
00151     }
00152 
00154     template<class LIST>
00155     void sort(const LIST &newOrder) {
00156         GraphElement *pPred = 0;
00157         typename LIST::const_iterator it = newOrder.begin();
00158         if (!it.valid()) return;
00159 
00160         m_head = *it;
00161         for(; it.valid(); ++it) {
00162             GraphElement *p = *it;
00163             if ((p->m_prev = pPred)) pPred->m_next = p;
00164             pPred = p;
00165         }
00166 
00167         (m_tail = pPred)->m_next = 0;
00168     }
00169 
00171     void reverse() {
00172         GraphElement *pX = m_head;
00173         m_head = m_tail;
00174         m_tail = pX;
00175         while(pX) {
00176             GraphElement *pY = pX->m_next;
00177             pX->m_next = pX->m_prev;
00178             pX = pX->m_prev = pY;
00179         }
00180     }
00181 
00183     void swap(GraphElement *pX, GraphElement *pY) {
00184         if (pX->m_next == pY) {
00185             pX->m_next = pY->m_next;
00186             pY->m_prev = pX->m_prev;
00187             pY->m_next = pX;
00188             pX->m_prev = pY;
00189 
00190         } else if(pY->m_next == pX) {
00191             pY->m_next = pX->m_next;
00192             pX->m_prev = pY->m_prev;
00193             pX->m_next = pY;
00194             pY->m_prev = pX;
00195 
00196         } else {
00197             ogdf::swap(pX->m_next,pY->m_next);
00198             ogdf::swap(pX->m_prev,pY->m_prev);
00199         }
00200 
00201         if(pX->m_prev)
00202             pX->m_prev->m_next = pX;
00203         else
00204             m_head = pX;
00205         if(pX->m_next)
00206             pX->m_next->m_prev = pX;
00207         else
00208             m_tail = pX;
00209 
00210         if(pY->m_prev)
00211             pY->m_prev->m_next = pY;
00212         else
00213             m_head = pY;
00214         if(pY->m_next)
00215             pY->m_next->m_prev = pY;
00216         else
00217             m_tail = pY;
00218 
00219         OGDF_ASSERT(consistencyCheck());
00220     }
00221 
00222 
00224     bool consistencyCheck() {
00225         if (m_head == 0) {
00226             return (m_tail == 0);
00227 
00228         } else if (m_tail == 0) {
00229             return false;
00230 
00231         } else {
00232             if (m_head->m_prev != 0)
00233                 return false;
00234             if (m_tail->m_next != 0)
00235                 return false;
00236 
00237             GraphElement *pX = m_head;
00238             for(; pX; pX = pX->m_next) {
00239                 if (pX->m_prev) {
00240                     if (pX->m_prev->m_next != pX)
00241                         return false;
00242                 } else if(pX != m_head)
00243                     return false;
00244 
00245                 if (pX->m_next) {
00246                     if (pX->m_next->m_prev != pX)
00247                         return false;
00248                 } else if (pX != m_tail)
00249                     return false;
00250             }
00251         }
00252 
00253         return true;
00254     }
00255 
00256     OGDF_NEW_DELETE
00257 }; // class GraphListBase
00258 
00259 
00261 
00264 template<class T> class GraphList : protected GraphListBase {
00265 public:
00267     GraphList() { }
00268     // destruction (deletes all elements)
00269     ~GraphList() {
00270         if (m_head) g_memory.deallocateList(m_head,m_tail,sizeof(T));
00271     }
00272 
00274     T *begin () const { return (T *)m_head; }
00276     T *rbegin() const { return (T *)m_tail; }
00277 
00279     bool empty() { return m_head; }
00280 
00282     void pushBack(T *pX) {
00283         GraphListBase::pushBack(pX);
00284     }
00285 
00287     void insertAfter(T *pX, T *pY) {
00288         GraphListBase::insertAfter(pX,pY);
00289     }
00290 
00292     void insertBefore(T *pX, T *pY) {
00293         GraphListBase::insertBefore(pX,pY);
00294     }
00295 
00297     void move(T *pX, GraphList<T> &L, T *pY, Direction dir) {
00298         GraphListBase::del(pX);
00299         if (dir == after)
00300             L.insertAfter(pX,pY);
00301         else
00302             L.insertBefore(pX,pY);
00303     }
00304 
00306     void move(T *pX, GraphList<T> &L) {
00307         GraphListBase::del(pX);
00308         L.pushBack(pX);
00309     }
00310 
00312     void moveAfter(T *pX, T *pY){
00313         GraphListBase::del(pX);
00314         insertAfter(pX,pY);
00315     }
00316 
00318     void moveBefore(T *pX, T *pY){
00319         GraphListBase::del(pX);
00320         insertBefore(pX,pY);
00321     }
00322 
00324     void del(T *pX) {
00325         GraphListBase::del(pX);
00326         delete pX;
00327     }
00328 
00330     void delPure(T *pX) {
00331         GraphListBase::del(pX);
00332     }
00333 
00335     void clear() {
00336         if (m_head) {
00337             g_memory.deallocateList(m_head,m_tail,sizeof(T));
00338             m_head = m_tail = 0;
00339         }
00340     }
00341 
00343     template<class T_LIST>
00344     void sort(const T_LIST &newOrder) {
00345         GraphListBase::sort(newOrder);
00346     }
00347 
00348 
00350     void reverse() {
00351         GraphListBase::reverse();
00352     }
00353 
00355     void swap(T *pX, T *pY) {
00356         GraphListBase::swap(pX,pY);
00357     }
00358 
00359 
00361     bool consistencyCheck() {
00362         return GraphListBase::consistencyCheck();
00363     }
00364     
00365     
00366     OGDF_NEW_DELETE
00367 }; // class GraphList<T>
00368 
00369 
00370 typedef NodeElement *node; 
00371 typedef EdgeElement *edge; 
00372 typedef AdjElement *adjEntry; 
00373 
00374 
00375 
00377 
00381 class AdjElement : private GraphElement {
00382     friend class Graph;
00383     friend class GraphListBase;
00384     friend class GraphList<AdjElement>;
00385 
00386     AdjElement *m_twin; 
00387     edge m_edge; 
00388     node m_node; 
00389     int m_id;    
00390 
00392     AdjElement(node v) : m_node(v) { }
00394     AdjElement(edge e, int id) : m_edge(e), m_id(id) { }
00395 
00396 public:
00398     edge theEdge() const { return m_edge; }
00400     operator edge() const { return m_edge; }
00402     node theNode() const { return m_node; }
00403 
00405     adjEntry twin() const { return m_twin; }
00406 
00408     node twinNode() const { return m_twin->m_node; }
00409 
00411     int index() const { return m_id; }
00412 
00413     // traversing faces in clockwise (resp. counter-clockwise) order
00414     // (if face is an interior face)
00415     
00417     adjEntry clockwiseFaceSucc() const { return m_twin->cyclicPred(); }
00419     adjEntry clockwiseFacePred() const { return cyclicSucc()->m_twin; }
00421     adjEntry counterClockwiseFaceSucc() const { return m_twin->cyclicSucc(); }
00423     adjEntry counterClockwiseFacePred() const { return cyclicPred()->m_twin; }
00424 
00425     // default is traversing faces in clockwise order
00427     adjEntry faceCycleSucc() const { return clockwiseFaceSucc(); }
00429     adjEntry faceCyclePred() const { return clockwiseFacePred(); }
00430 
00431 
00433     adjEntry succ() const { return (adjEntry)m_next; }
00435     adjEntry pred() const { return (adjEntry)m_prev; }
00436 
00438     adjEntry cyclicSucc() const;
00440     adjEntry cyclicPred() const;
00441 
00442 #ifdef OGDF_DEBUG
00443     const Graph *graphOf() const;
00444 #endif
00445 
00446     OGDF_NEW_DELETE
00447 }; // class AdjElement
00448 
00449 
00451 class NodeElement : private GraphElement {
00452     friend class Graph;
00453     friend class GraphList<NodeElement>;
00454 
00455     GraphList<AdjElement> m_adjEdges; 
00456     int m_indeg;  
00457     int m_outdeg; 
00458     int m_id;     
00459 
00460 #ifdef OGDF_DEBUG
00461     // we store the graph containing this node for debugging purposes
00462     const Graph *m_pGraph; 
00463 #endif
00464 
00465 
00466     // construction
00467 #ifdef OGDF_DEBUG
00469 
00474     NodeElement(const Graph *pGraph, int id) :
00475         m_indeg(0), m_outdeg(0), m_id(id), m_pGraph(pGraph) { }
00476 #else
00477     NodeElement(int id) : m_indeg(0), m_outdeg(0), m_id(id) { }
00478 #endif
00479 
00480 
00481 public:
00483     int index() const { return m_id; }
00484 
00486     int indeg() const { return m_indeg; }
00488     int outdeg() const { return m_outdeg; }
00490     int degree() const { return m_indeg + m_outdeg; }
00491 
00493     adjEntry firstAdj() const { return m_adjEdges.begin();  }
00495     adjEntry lastAdj () const { return m_adjEdges.rbegin(); }
00496 
00498     node succ() const { return (node)m_next; }
00500     node pred() const { return (node)m_prev; }
00501 
00502 #ifdef OGDF_DEBUG
00504     const Graph *graphOf() const { return m_pGraph; }
00505 #endif
00506 
00507     OGDF_NEW_DELETE
00508 }; // class NodeElement
00509 
00510 
00511 inline adjEntry AdjElement::cyclicSucc() const
00512 {
00513     return (m_next) ? (adjEntry)m_next : m_node->firstAdj();
00514 }
00515 
00516 inline adjEntry AdjElement::cyclicPred() const
00517 {
00518     return (m_prev) ? (adjEntry)m_prev : m_node->lastAdj();
00519 }
00520 
00521 inline bool test_forall_adj_edges(adjEntry &adj, edge &e)
00522 {
00523     if (adj) { e = adj->theEdge(); return true; }
00524     else return false;
00525 }
00526 
00527 
00528 
00530 class EdgeElement : private GraphElement {
00531     friend class Graph;
00532     friend class GraphList<EdgeElement>;
00533 
00534     node m_src; 
00535     node m_tgt; 
00536     AdjElement *m_adjSrc; 
00537     AdjElement *m_adjTgt; 
00538     int m_id; // The (unique) index of the node.
00539 
00541 
00548     EdgeElement(node src, node tgt, AdjElement *adjSrc, AdjElement *adjTgt, int id) :
00549         m_src(src), m_tgt(tgt), m_adjSrc(adjSrc), m_adjTgt(adjTgt), m_id(id) { }
00550         
00552 
00557     EdgeElement(node src, node tgt, int id) :
00558         m_src(src), m_tgt(tgt), m_id(id) { }
00559 
00560 public:
00562     int index() const { return m_id; }
00564     node source() const { return m_src; }
00566     node target() const { return m_tgt; }
00567 
00569     adjEntry adjSource() const { return m_adjSrc; }
00571     adjEntry adjTarget() const { return m_adjTgt; }
00572 
00574     node opposite(node v) const { return (v == m_src) ? m_tgt : m_src; }
00575     // Returns true iff the edge is a self-loop (source node = target node).
00576     bool isSelfLoop() const { return m_src == m_tgt; }
00577 
00579     edge succ() const { return (edge)m_next; }
00581     edge pred() const { return (edge)m_prev; }
00582 
00583 #ifdef OGDF_DEBUG
00585     const Graph *graphOf() const { return m_src->graphOf(); }
00586 #endif
00587 
00589     bool isIncident(node v) const { return v == m_src || v == m_tgt; }
00590     
00592     node commonNode(edge e) const { return (m_src==e->m_src || m_src==e->m_tgt) ? m_src : ((m_tgt==e->m_src || m_tgt==e->m_tgt) ? m_tgt: 0); }
00593 
00594     OGDF_NEW_DELETE
00595 }; // class EdgeElement
00596 
00597 
00598 #ifdef OGDF_DEBUG
00599 inline const Graph *AdjElement::graphOf() const {
00600     return m_node->graphOf();
00601 }
00602 #endif
00603 
00604 
00605 template<>inline bool doDestruction<node>(const node *) { return false; }
00606 template<>inline bool doDestruction<edge>(const edge *) { return false; }
00607 template<>inline bool doDestruction<adjEntry>(const adjEntry *) { return false; }
00608 
00609 class NodeArrayBase;
00610 class EdgeArrayBase;
00611 class AdjEntryArrayBase;
00612 template<class T>class NodeArray;
00613 template<class T>class EdgeArray;
00614 template<class T>class AdjEntryArray;
00615 class GraphObserver;
00616 
00617 
00618 //---------------------------------------------------------
00619 // iteration macros
00620 //---------------------------------------------------------
00621 
00623 #define forall_nodes(v,G) for((v)=(G).firstNode(); (v); (v)=(v)->succ())
00625 #define forall_rev_nodes(v,G) for((v)=(G).lastNode(); (v); (v)=(v)->pred())
00626 
00628 #define forall_edges(e,G) for((e)=(G).firstEdge(); (e); (e)=(e)->succ())
00630 #define forall_rev_edges(e,G) for((e)=(G).lastEdge(); (e); (e)=(e)->pred())
00631 
00633 #define forall_adj(adj,v) for((adj)=(v)->firstAdj(); (adj); (adj)=(adj)->succ())
00635 #define forall_rev_adj(adj,v) for((adj)=(v)->lastAdj(); (adj); (adj)=(adj)->pred())
00636 
00638 #define forall_adj_edges(e,v)\
00639 ogdf::adjEntry OGDF_VAR(__LINE__);\
00640 for(OGDF_VAR(__LINE__)=(v)->firstAdj();\
00641     ogdf::test_forall_adj_edges(OGDF_VAR(__LINE__),(e));\
00642 OGDF_VAR(__LINE__)=OGDF_VAR(__LINE__)->succ())
00643 
00644 
00646 
00697 class Graph
00698 {
00699     GraphList<NodeElement> m_nodes; 
00700     GraphList<EdgeElement> m_edges; 
00701     int m_nNodes; 
00702     int m_nEdges; 
00703 
00704     int m_nodeIdCount; 
00705     int m_edgeIdCount; 
00706 
00707     int m_nodeArrayTableSize; 
00708     int m_edgeArrayTableSize; 
00709 
00710     mutable ListPure<NodeArrayBase*> m_regNodeArrays; 
00711     mutable ListPure<EdgeArrayBase*> m_regEdgeArrays; 
00712     mutable ListPure<AdjEntryArrayBase*> m_regAdjArrays;  
00713     mutable ListPure<GraphObserver*> m_regStructures; 
00714 
00715     GraphList<EdgeElement> m_hiddenEdges; 
00716 
00717 public:
00718     //
00719     // enumerations
00720     //
00721 
00723     enum EdgeType {
00724         association = 0,
00725         generalization = 1,
00726         dependency = 2
00727     }; // should be more flexible, standard, dissect, expand
00728     
00730     enum NodeType {
00731         vertex,
00732         dummy,
00733         generalizationMerger,
00734         generalizationExpander,
00735         highDegreeExpander,
00736         lowDegreeExpander,
00737         associationClass
00738     };
00739 
00740 
00742     Graph();
00743     
00745 
00750     Graph(const Graph &G);
00751     
00752     // destruction
00753     virtual ~Graph();
00754 
00755 
00760 
00762     bool empty() const { return m_nNodes == 0; }
00763 
00765     int numberOfNodes() const { return m_nNodes; }
00766 
00768     int numberOfEdges() const { return m_nEdges; }
00769 
00771     int maxNodeIndex() const { return m_nodeIdCount-1; }
00773     int maxEdgeIndex() const { return m_edgeIdCount-1; }
00775     int maxAdjEntryIndex() const { return (m_edgeIdCount<<1)-1; }
00776 
00778     int nodeArrayTableSize() const { return m_nodeArrayTableSize; }
00780     int edgeArrayTableSize() const { return m_edgeArrayTableSize; }
00782     int adjEntryArrayTableSize() const { return m_edgeArrayTableSize << 1; }
00783 
00785     node firstNode() const { return m_nodes.begin (); }
00787     node lastNode () const { return m_nodes.rbegin(); }
00788     
00790     edge firstEdge() const { return m_edges.begin (); }
00792     edge lastEdge () const { return m_edges.rbegin(); }
00793 
00795     node chooseNode() const;
00797     edge chooseEdge() const;
00798 
00800     template<class NODELIST>
00801     void allNodes(NODELIST &nodes) const {
00802         nodes.clear();
00803         for (node v = m_nodes.begin(); v; v = v->succ())
00804             nodes.pushBack(v);
00805     }
00806 
00808     template<class EDGELIST>
00809     void allEdges(EDGELIST &edges) const {
00810         edges.clear();
00811         for (edge e = m_edges.begin(); e; e = e->succ())
00812             edges.pushBack(e);
00813     }
00814 
00816     template<class EDGELIST>
00817     void adjEdges(node v, EDGELIST &edges) const {
00818         edges.clear();
00819         edge e;
00820         forall_adj_edges(e,v)
00821             edges.pushBack(e);
00822     }
00823 
00825     template<class ADJLIST>
00826     void adjEntries(node v, ADJLIST &entries) const {
00827         entries.clear();
00828         adjEntry adj;
00829         forall_adj(adj,v)
00830             entries.pushBack(adj);
00831     }
00832 
00834     template<class EDGELIST>
00835     void inEdges(node v, EDGELIST &edges) const {
00836         edges.clear();
00837         edge e;
00838         forall_adj_edges(e,v)
00839             if (e->target() == v) edges.pushBack(e);
00840     }
00841 
00843     template<class EDGELIST>
00844     void outEdges(node v, EDGELIST &edges) const {
00845         edges.clear();
00846         edge e;
00847         forall_adj_edges(e,v)
00848             if (e->source() == v) edges.pushBack(e);
00849     }
00850 
00851 
00853 
00857 
00859     node newNode();
00860 
00862 
00869     node newNode(int index);
00870 
00872     edge newEdge(node v, node w);
00873 
00875 
00882     edge newEdge(node v, node w, int index);
00883 
00885 
00897     edge newEdge(adjEntry adjSrc, adjEntry adjTgt, Direction dir = ogdf::after);
00898     
00900 
00908     edge newEdge(node v, adjEntry adjTgt);
00909 
00911 
00919     edge newEdge(adjEntry adjSrc, node w);
00920 
00921 
00923 
00927 
00929     void delNode(node v);
00930 
00932     void delEdge(edge e);
00933 
00935     void clear();
00936 
00937     
00939 
00947 
00949 
00954     void hideEdge(edge e);
00955 
00957 
00960     void restoreEdge(edge e);
00961 
00963     void restoreAllEdges();
00964 
00969 
00970     
00972 
00978     virtual edge split(edge e);
00979 
00981 
00988     void unsplit(node u);
00989 
00991 
00999     virtual void unsplit(edge eIn, edge eOut);
01000 
01002 
01019     node splitNode(adjEntry adjStartLeft, adjEntry adjStartRight);
01020 
01022     node contract(edge e);
01023 
01024     // moves edge e to adjacency list of owner(adjSrc) inserting it before
01025     // or after adjSrc, and to owner(adjTgt) inserting it before or after
01026     // adjTgt; e is afterwards an edge from owner(adjSrc) to owner(adjTgt)
01027     void move(edge e, adjEntry adjSrc, Direction dirSrc,
01028         adjEntry adjTgt, Direction dirTgt);
01029 
01031 
01034     void moveTarget(edge e, node w);
01035 
01037 
01041     void moveTarget(edge e, adjEntry adjTgt, Direction dir);
01042 
01044 
01047     void moveSource(edge e, node w);
01048 
01050 
01054     void moveSource(edge e, adjEntry adjSrc, Direction dir);
01055     
01057     //  If no such edge exists, 0 is returned.
01058     edge searchEdge (node v, node w) const;
01059 
01061     void reverseEdge(edge e);
01062 
01064     void reverseAllEdges();
01065 
01067 
01070     template<class NODELIST>
01071     void collaps(NODELIST &nodes){
01072         node v = nodes.popFrontRet();
01073         while (!nodes.empty())
01074         {
01075             node w = nodes.popFrontRet();
01076             adjEntry adj = w->firstAdj();
01077             while (adj !=0)
01078             {
01079                 adjEntry succ = adj->succ();
01080                 edge e = adj->theEdge();
01081                 if (e->source() == v || e->target() == v)
01082                     delEdge(e);
01083                 else if (e->source() == w)
01084                     moveSource(e,v);
01085                 else
01086                     moveTarget(e,v);
01087                 adj = succ;
01088             }
01089             delNode(w);
01090         }
01091     }
01092 
01094 
01097     template<class ADJ_ENTRY_LIST>
01098     void sort(node v, const ADJ_ENTRY_LIST &newOrder) {
01099 #ifdef OGDF_DEBUG
01100         typename ADJ_ENTRY_LIST::const_iterator it;
01101         for(it = newOrder.begin(); it.valid() ; ++it) {
01102             OGDF_ASSERT((*it)->theNode() == v);
01103         }
01104 #endif
01105         v->m_adjEdges.sort(newOrder);
01106     }
01107 
01109     void reverseAdjEdges(node v) {
01110         v->m_adjEdges.reverse();
01111     }
01112 
01114 
01120     void moveAdj(adjEntry adjMove, Direction dir, adjEntry adjPos) {
01121         OGDF_ASSERT(adjMove->graphOf() == this && adjPos->graphOf() == this);
01122         OGDF_ASSERT(adjMove != 0 && adjPos != 0);
01123         GraphList<AdjElement> &adjList = adjMove->m_node->m_adjEdges;
01124         adjList.move(adjMove, adjList, adjPos, dir);
01125     }
01126 
01128 
01133     void moveAdjAfter(adjEntry adjMove, adjEntry adjAfter) {
01134         OGDF_ASSERT(adjMove->graphOf() == this && adjAfter->graphOf() == this);
01135         OGDF_ASSERT(adjMove != 0 && adjAfter != 0);
01136         adjMove->m_node->m_adjEdges.moveAfter(adjMove,adjAfter);
01137     }
01138 
01140 
01145     void moveAdjBefore(adjEntry adjMove, adjEntry adjBefore) {
01146         OGDF_ASSERT(adjMove->graphOf() == this && adjBefore->graphOf() == this);
01147         OGDF_ASSERT(adjMove != 0 && adjBefore != 0);
01148         adjMove->m_node->m_adjEdges.moveBefore(adjMove,adjBefore);
01149     }
01150 
01152     void reverseAdjEdges();
01153 
01155 
01158     void swapAdjEdges(adjEntry adj1, adjEntry adj2) {
01159         OGDF_ASSERT(adj1->theNode() == adj2->theNode());
01160         OGDF_ASSERT(adj1->graphOf() == this);
01161 
01162         adj1->theNode()->m_adjEdges.swap(adj1,adj2);
01163     }
01164 
01165 
01167 
01171 
01173     bool readGML(const char *fileName);
01174 
01176     bool readGML(istream &is);
01177 
01179     void writeGML(const char *fileName) const;
01180 
01182     void writeGML(ostream &os) const;
01183 
01185     bool readLEDAGraph(const char *fileName);
01186 
01188     bool readLEDAGraph(istream &is);
01189 
01190 
01192 
01196 
01198 
01206     int genus() const;
01207 
01209     bool representsCombEmbedding() const {
01210         return (genus() == 0);
01211     }
01212 
01214 
01217     bool consistencyCheck() const;
01218 
01219 
01221 
01227 
01229     ListIterator<NodeArrayBase*> registerArray(NodeArrayBase *pNodeArray) const;
01231     ListIterator<EdgeArrayBase*> registerArray(EdgeArrayBase *pEdgeArray) const;
01233     ListIterator<AdjEntryArrayBase*> registerArray(AdjEntryArrayBase *pAdjArray) const;
01235     ListIterator<GraphObserver*> registerStructure(GraphObserver *pStructure) const;
01236 
01238     void unregisterArray(ListIterator<NodeArrayBase*> it) const;
01240     void unregisterArray(ListIterator<EdgeArrayBase*> it) const;
01242     void unregisterArray(ListIterator<AdjEntryArrayBase*> it) const;
01244     void unregisterStructure(ListIterator<GraphObserver*> it) const;
01245 
01246 
01248 
01272     void resetEdgeIdCount(int maxId);
01273 
01274 
01276 
01280 
01281 
01286     Graph &operator=(const Graph &G);
01287 
01288     OGDF_NEW_DELETE
01289 
01291 
01292 
01294     static int nextPower2(int start, int idCount);
01295 
01296 
01297 protected:
01298     void construct(const Graph &G, NodeArray<node> &mapNode,
01299         EdgeArray<edge> &mapEdge);
01300 
01301     void assign(const Graph &G, NodeArray<node> &mapNode,
01302         EdgeArray<edge> &mapEdge);
01303 
01310     void constructInitByNodes(
01311         const Graph &G,
01312         const List<node> &nodes,
01313         NodeArray<node> &mapNode,
01314         EdgeArray<edge> &mapEdge);
01315 
01316     void constructInitByActiveNodes(
01317         const List<node> &nodes,
01318         const NodeArray<bool> &activeNodes,
01319         NodeArray<node> &mapNode,
01320         EdgeArray<edge> &mapEdge);
01321 
01322 private:
01323     void copy(const Graph &G, NodeArray<node> &mapNode,
01324         EdgeArray<edge> &mapEdge);
01325     void copy(const Graph &G);
01326 
01327     edge createEdgeElement(node v, node w, adjEntry adjSrc, adjEntry adjTgt);
01328     node pureNewNode();
01329 
01330     // moves adjacency entry to node w
01331     void moveAdj(adjEntry adj, node w);
01332 
01333     void reinitArrays();
01334     void reinitStructures();
01335     void resetAdjEntryIndex(int newIndex, int oldIndex);
01336 
01337     bool readToEndOfLine(istream &is);
01338 }; // class Graph
01339 
01340 
01341 
01343 class BucketSourceIndex : public BucketFunc<edge> {
01344 public:
01346     int getBucket(const edge &e) { return e->source()->index(); }
01347 };
01348 
01350 class BucketTargetIndex : public BucketFunc<edge> {
01351 public:
01353     int getBucket(const edge &e) { return e->target()->index(); }
01354 };
01355 
01356 
01357 } //namespace 
01358 
01359 #endif
01360 


© 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.