6 * $Date: 2012-07-02 20:59:27 +0200 (Mon, 02 Jul 2012) $
7 ***************************************************************/
10 * \brief Implementation of Graph class
12 * \author Carsten Gutwenger
15 * This file is part of the Open Graph Drawing Framework (OGDF).
19 * See README.txt in the root directory of the OGDF installation for details.
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * Version 2 or 3 as published by the Free Software Foundation;
25 * see the file LICENSE.txt included in the packaging of this file
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
35 * You should have received a copy of the GNU General Public
36 * License along with this program; if not, write to the Free
37 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
38 * Boston, MA 02110-1301, USA.
40 * \see http://www.gnu.org/copyleft/gpl.html
41 ***************************************************************/
43 #include <ogdf/basic/Array.h>
44 #include <ogdf/basic/AdjEntryArray.h>
45 #include <ogdf/fileformats/GmlParser.h>
46 #include <ogdf/basic/simple_graph_alg.h>
47 #include <ogdf/basic/GraphObserver.h>
50 #define MIN_NODE_TABLE_SIZE (1 << 4)
51 #define MIN_EDGE_TABLE_SIZE (1 << 4)
58 m_nNodes
= m_nEdges
= m_nodeIdCount
= m_edgeIdCount
= 0;
59 m_nodeArrayTableSize
= MIN_NODE_TABLE_SIZE
;
60 m_edgeArrayTableSize
= MIN_EDGE_TABLE_SIZE
;
64 Graph::Graph(const Graph
&G
)
66 m_nNodes
= m_nEdges
= m_nodeIdCount
= m_edgeIdCount
= 0;
68 m_nodeArrayTableSize
= nextPower2(MIN_NODE_TABLE_SIZE
,m_nodeIdCount
);
69 m_edgeArrayTableSize
= nextPower2(MIN_EDGE_TABLE_SIZE
,m_edgeIdCount
);
75 ListIterator
<NodeArrayBase
*> itVNext
;
76 for(ListIterator
<NodeArrayBase
*> itV
= m_regNodeArrays
.begin();
77 itV
.valid(); itV
= itVNext
)
83 ListIterator
<EdgeArrayBase
*> itENext
;
84 for(ListIterator
<EdgeArrayBase
*> itE
= m_regEdgeArrays
.begin();
85 itE
.valid(); itE
= itENext
)
91 ListIterator
<AdjEntryArrayBase
*> itAdjNext
;
92 for(ListIterator
<AdjEntryArrayBase
*> itAdj
= m_regAdjArrays
.begin();
93 itAdj
.valid(); itAdj
= itAdjNext
)
95 itAdjNext
= itAdj
.succ();
96 (*itAdj
)->disconnect();
99 for (node v
= m_nodes
.begin(); v
; v
= v
->succ()) {
100 v
->m_adjEdges
.~GraphList
<AdjElement
>();
105 Graph
&Graph::operator=(const Graph
&G
)
108 m_nodeArrayTableSize
= nextPower2(MIN_NODE_TABLE_SIZE
,m_nodeIdCount
);
109 m_edgeArrayTableSize
= nextPower2(MIN_EDGE_TABLE_SIZE
,m_edgeIdCount
);
112 OGDF_ASSERT_IF(dlConsistencyChecks
, consistencyCheck());
118 void Graph::assign(const Graph
&G
, NodeArray
<node
> &mapNode
,
119 EdgeArray
<edge
> &mapEdge
)
122 copy(G
,mapNode
,mapEdge
);
123 m_nodeArrayTableSize
= nextPower2(MIN_NODE_TABLE_SIZE
,m_nodeIdCount
);
124 m_edgeArrayTableSize
= nextPower2(MIN_EDGE_TABLE_SIZE
,m_edgeIdCount
);
129 void Graph::construct(const Graph
&G
, NodeArray
<node
> &mapNode
,
130 EdgeArray
<edge
> &mapEdge
)
132 copy(G
,mapNode
,mapEdge
);
133 m_nodeArrayTableSize
= nextPower2(MIN_NODE_TABLE_SIZE
,m_nodeIdCount
);
134 m_edgeArrayTableSize
= nextPower2(MIN_EDGE_TABLE_SIZE
,m_edgeIdCount
);
138 void Graph::copy(const Graph
&G
, NodeArray
<node
> &mapNode
,
139 EdgeArray
<edge
> &mapEdge
)
141 if (G
.m_nNodes
== 0) return;
147 node v
= mapNode
[vG
] = pureNewNode();
148 v
->m_indeg
= vG
->m_indeg
;
149 v
->m_outdeg
= vG
->m_outdeg
;
152 if (G
.m_nEdges
== 0) return;
158 m_edges
.pushBack(eC
= mapEdge
[e
] =
159 OGDF_NEW
EdgeElement(
160 mapNode
[e
->source()],mapNode
[e
->target()],m_edgeIdCount
));
162 eC
->m_adjSrc
= OGDF_NEW
AdjElement(eC
,m_edgeIdCount
<<1);
163 (eC
->m_adjTgt
= OGDF_NEW
AdjElement(eC
,(m_edgeIdCount
<<1)|1))
164 ->m_twin
= eC
->m_adjSrc
;
165 eC
->m_adjSrc
->m_twin
= eC
->m_adjTgt
;
168 m_nEdges
= G
.m_nEdges
;
170 EdgeArray
<bool> mark(G
,false);
173 node v
= mapNode
[vG
];
174 GraphList
<AdjElement
> &adjEdges
= vG
->m_adjEdges
;
175 for (AdjElement
*adjG
= adjEdges
.begin(); adjG
; adjG
= adjG
->succ()) {
176 int id
= adjG
->m_edge
->index();
177 edge eC
= mapEdge
[id
];
180 if (eC
->isSelfLoop()) {
188 adj
= (v
== eC
->m_src
) ? eC
->m_adjSrc
: eC
->m_adjTgt
;
190 v
->m_adjEdges
.pushBack(adj
);
197 void Graph::copy(const Graph
&G
)
199 NodeArray
<node
> mapNode
;
200 EdgeArray
<edge
> mapEdge
;
201 copy(G
,mapNode
,mapEdge
);
203 OGDF_ASSERT_IF(dlConsistencyChecks
, consistencyCheck());
207 void Graph::constructInitByNodes(
209 const List
<node
> &nodes
,
210 NodeArray
<node
> &mapNode
,
211 EdgeArray
<edge
> &mapEdge
)
214 for (node v
= m_nodes
.begin(); v
; v
= v
->succ()) {
215 v
->m_adjEdges
.~GraphList
<AdjElement
>();
221 m_nNodes
= m_nEdges
= m_nodeIdCount
= m_edgeIdCount
= 0;
222 m_nodeArrayTableSize
= MIN_NODE_TABLE_SIZE
;
225 // list of edges adjacent to nodes in nodes
226 SListPure
<edge
> edges
;
228 // create nodes and assemble list of edges
229 ListConstIterator
<node
> itG
;
230 for(itG
= nodes
.begin(); itG
.valid(); ++itG
) {
232 node v
= mapNode
[vG
] = pureNewNode();
234 v
->m_indeg
= vG
->m_indeg
;
235 v
->m_outdeg
= vG
->m_outdeg
;
238 forall_adj(adjG
,vG
) {
239 // corresponding adjacency entries differ by index modulo 2
240 // the following conditions makes sure that each edge is
241 // added only once to edges
242 if ((adjG
->m_id
& 1) == 0)
243 edges
.pushBack(adjG
->m_edge
);
248 SListConstIterator
<edge
> it
;
249 for(it
= edges
.begin(); it
.valid(); ++it
)
252 node v
= mapNode
[eG
->source()];
253 node w
= mapNode
[eG
->target()];
255 edge eC
= mapEdge
[eG
] = OGDF_NEW
EdgeElement(v
, w
, m_edgeIdCount
);
256 m_edges
.pushBack(eC
);
258 eC
->m_adjSrc
= OGDF_NEW
AdjElement(eC
, m_edgeIdCount
<<1);
259 (eC
->m_adjTgt
= OGDF_NEW
AdjElement(eC
, (m_edgeIdCount
<<1)|1))
260 ->m_twin
= eC
->m_adjSrc
;
261 eC
->m_adjSrc
->m_twin
= eC
->m_adjTgt
;
266 EdgeArray
<bool> mark(G
,false);
267 for(itG
= nodes
.begin(); itG
.valid(); ++itG
) {
269 node v
= mapNode
[vG
];
271 GraphList
<AdjElement
> &adjEdges
= vG
->m_adjEdges
;
272 for (AdjElement
*adjG
= adjEdges
.begin(); adjG
; adjG
= adjG
->succ()) {
273 int id
= adjG
->m_edge
->index();
274 edge eC
= mapEdge
[id
];
277 if (eC
->isSelfLoop()) {
285 adj
= (v
== eC
->m_src
) ? eC
->m_adjSrc
: eC
->m_adjTgt
;
287 v
->m_adjEdges
.pushBack(adj
);
293 AdjElement *adjSrc = OGDF_NEW AdjElement(v);
295 v->m_adjEdges.pushBack(adjSrc);
298 AdjElement *adjTgt = OGDF_NEW AdjElement(w);
300 w->m_adjEdges.pushBack(adjTgt);
303 adjSrc->m_twin = adjTgt;
304 adjTgt->m_twin = adjSrc;
306 adjTgt->m_id = (adjSrc->m_id = m_edgeIdCount << 1) | 1;
307 edge e = OGDF_NEW EdgeElement(v,w,adjSrc,adjTgt,m_edgeIdCount++);
312 mapEdge[eG] = adjSrc->m_edge = adjTgt->m_edge = e;
315 // set size of associated arrays and reinitialize all (we have now a
316 // completely new graph)
317 m_nodeArrayTableSize
= nextPower2(MIN_NODE_TABLE_SIZE
,m_nodeIdCount
);
318 m_edgeArrayTableSize
= nextPower2(MIN_EDGE_TABLE_SIZE
,m_edgeIdCount
);
321 OGDF_ASSERT_IF(dlConsistencyChecks
, consistencyCheck());
326 //mainly a copy of the above code, remerge this again
327 void Graph::constructInitByActiveNodes(
328 const List
<node
> &nodes
,
329 const NodeArray
<bool> &activeNodes
,
330 NodeArray
<node
> &mapNode
,
331 EdgeArray
<edge
> &mapEdge
)
334 for (node v
= m_nodes
.begin(); v
; v
= v
->succ()) {
335 v
->m_adjEdges
.~GraphList
<AdjElement
>();
341 m_nNodes
= m_nEdges
= m_nodeIdCount
= m_edgeIdCount
= 0;
342 m_nodeArrayTableSize
= MIN_NODE_TABLE_SIZE
;
345 // list of edges adjacent to nodes in nodes
346 SListPure
<edge
> edges
;
348 // create nodes and assemble list of edges
349 //NOTE: nodes is a list of ACTIVE nodes
350 ListConstIterator
<node
> itG
;
351 for(itG
= nodes
.begin(); itG
.valid(); ++itG
) {
353 node v
= mapNode
[vG
] = pureNewNode();
355 //we cannot assign the original degree, as there
356 //may be edges to non-active nodes
357 //v->m_indeg = vG->m_indeg;
358 //v->m_outdeg = vG->m_outdeg;
365 // coresponding adjacency entries differ by index modulo 2
366 // the following conditions makes sure that each edge is
367 // added only once to edges
368 if (activeNodes
[adjG
->m_edge
->opposite(vG
)])
370 if ((adjG
->m_id
& 1) == 0)
372 edges
.pushBack(adjG
->m_edge
);
374 if (adjG
->m_edge
->source() == vG
) outCount
++;
376 }//if opposite active
378 v
->m_indeg
= inCount
;
379 v
->m_outdeg
= outCount
;
383 SListConstIterator
<edge
> it
;
384 for(it
= edges
.begin(); it
.valid(); ++it
)
387 node v
= mapNode
[eG
->source()];
388 node w
= mapNode
[eG
->target()];
390 AdjElement
*adjSrc
= OGDF_NEW
AdjElement(v
);
392 v
->m_adjEdges
.pushBack(adjSrc
);
395 AdjElement
*adjTgt
= OGDF_NEW
AdjElement(w
);
397 w
->m_adjEdges
.pushBack(adjTgt
);
400 adjSrc
->m_twin
= adjTgt
;
401 adjTgt
->m_twin
= adjSrc
;
403 adjTgt
->m_id
= (adjSrc
->m_id
= m_edgeIdCount
<< 1) | 1;
404 edge e
= OGDF_NEW
EdgeElement(v
,w
,adjSrc
,adjTgt
,m_edgeIdCount
++);
409 mapEdge
[eG
] = adjSrc
->m_edge
= adjTgt
->m_edge
= e
;
412 // set size of associated arrays and reinitialize all (we have now a
413 // completely new graph)
414 m_nodeArrayTableSize
= nextPower2(MIN_NODE_TABLE_SIZE
,m_nodeIdCount
);
415 m_edgeArrayTableSize
= nextPower2(MIN_EDGE_TABLE_SIZE
,m_edgeIdCount
);
418 OGDF_ASSERT_IF(dlConsistencyChecks
, consistencyCheck());
419 }//constructinitbyactivenodes
425 node
Graph::newNode()
428 if (m_nodeIdCount
== m_nodeArrayTableSize
) {
429 m_nodeArrayTableSize
<<= 1;
430 for(ListIterator
<NodeArrayBase
*> it
= m_regNodeArrays
.begin();
433 (*it
)->enlargeTable(m_nodeArrayTableSize
);
438 node v
= OGDF_NEW
NodeElement(this,m_nodeIdCount
++);
440 node v
= OGDF_NEW
NodeElement(m_nodeIdCount
++);
444 // notify all registered observers
445 for(ListIterator
<GraphObserver
*> it
= m_regStructures
.begin();
446 it
.valid(); ++it
) (*it
)->nodeAdded(v
);
452 //what about negative index numbers?
453 node
Graph::newNode(int index
)
457 if(index
>= m_nodeIdCount
) {
458 m_nodeIdCount
= index
+1;
460 if(index
>= m_nodeArrayTableSize
) {
461 m_nodeArrayTableSize
= nextPower2(m_nodeArrayTableSize
,index
);
462 for(ListIterator
<NodeArrayBase
*> it
= m_regNodeArrays
.begin();
465 (*it
)->enlargeTable(m_nodeArrayTableSize
);
471 node v
= OGDF_NEW
NodeElement(this,index
);
473 node v
= OGDF_NEW
NodeElement(index
);
477 // notify all registered observers
478 for(ListIterator
<GraphObserver
*> it
= m_regStructures
.begin();
479 it
.valid(); ++it
) (*it
)->nodeAdded(v
);
484 node
Graph::pureNewNode()
489 node v
= OGDF_NEW
NodeElement(this,m_nodeIdCount
++);
491 node v
= OGDF_NEW
NodeElement(m_nodeIdCount
++);
495 // notify all registered observers
496 for(ListIterator
<GraphObserver
*> it
= m_regStructures
.begin();
497 it
.valid(); ++it
) (*it
)->nodeAdded(v
);
503 // The indices of the two adjacency entries pointing to an edge differ
504 // only in the last bit (adjSrc/2 == adjTgt/2)
506 // This can be useful sometimes in order to avoid visiting an edge twice.
507 edge
Graph::createEdgeElement(node v
, node w
, adjEntry adjSrc
, adjEntry adjTgt
)
509 if (m_edgeIdCount
== m_edgeArrayTableSize
) {
510 m_edgeArrayTableSize
<<= 1;
512 for(ListIterator
<EdgeArrayBase
*> it
= m_regEdgeArrays
.begin();
515 (*it
)->enlargeTable(m_edgeArrayTableSize
);
518 for(ListIterator
<AdjEntryArrayBase
*> itAdj
= m_regAdjArrays
.begin();
519 itAdj
.valid(); ++itAdj
)
521 (*itAdj
)->enlargeTable(m_edgeArrayTableSize
<< 1);
525 adjTgt
->m_id
= (adjSrc
->m_id
= m_edgeIdCount
<< 1) | 1;
526 edge e
= OGDF_NEW
EdgeElement(v
,w
,adjSrc
,adjTgt
,m_edgeIdCount
++);
528 // notify all registered observers
529 for(ListIterator
<GraphObserver
*> it
= m_regStructures
.begin();
530 it
.valid(); ++it
) (*it
)->edgeAdded(e
);
535 edge
Graph::newEdge(node v
, node w
, int index
)
537 OGDF_ASSERT(v
!= 0 && w
!= 0);
538 OGDF_ASSERT(v
->graphOf() == this && w
->graphOf() == this);
542 AdjElement
*adjSrc
= OGDF_NEW
AdjElement(v
);
544 v
->m_adjEdges
.pushBack(adjSrc
);
547 AdjElement
*adjTgt
= OGDF_NEW
AdjElement(w
);
549 w
->m_adjEdges
.pushBack(adjTgt
);
552 adjSrc
->m_twin
= adjTgt
;
553 adjTgt
->m_twin
= adjSrc
;
555 if(index
>= m_edgeIdCount
) {
556 m_edgeIdCount
= index
+1;
558 if(index
>= m_edgeArrayTableSize
) {
559 m_edgeArrayTableSize
= nextPower2(m_edgeArrayTableSize
,index
);
561 for(ListIterator
<EdgeArrayBase
*> it
= m_regEdgeArrays
.begin();
564 (*it
)->enlargeTable(m_edgeArrayTableSize
);
567 for(ListIterator
<AdjEntryArrayBase
*> itAdj
= m_regAdjArrays
.begin();
568 itAdj
.valid(); ++itAdj
)
570 (*itAdj
)->enlargeTable(m_edgeArrayTableSize
<< 1);
575 adjTgt
->m_id
= (adjSrc
->m_id
= index
/*m_edgeIdCount*/ << 1) | 1;
576 edge e
= OGDF_NEW
EdgeElement(v
,w
,adjSrc
,adjTgt
,index
);
578 // notify all registered observers
579 for(ListIterator
<GraphObserver
*> it
= m_regStructures
.begin();
580 it
.valid(); ++it
) (*it
)->edgeAdded(e
);
581 return adjSrc
->m_edge
= adjTgt
->m_edge
= e
;
585 edge
Graph::newEdge(node v
, node w
)
587 OGDF_ASSERT(v
!= 0 && w
!= 0);
588 OGDF_ASSERT(v
->graphOf() == this && w
->graphOf() == this);
592 AdjElement
*adjSrc
= OGDF_NEW
AdjElement(v
);
594 v
->m_adjEdges
.pushBack(adjSrc
);
597 AdjElement
*adjTgt
= OGDF_NEW
AdjElement(w
);
599 w
->m_adjEdges
.pushBack(adjTgt
);
602 adjSrc
->m_twin
= adjTgt
;
603 adjTgt
->m_twin
= adjSrc
;
605 edge e
= createEdgeElement(v
,w
,adjSrc
,adjTgt
);
607 return adjSrc
->m_edge
= adjTgt
->m_edge
= e
;
611 edge
Graph::newEdge(adjEntry adjStart
, adjEntry adjEnd
, Direction dir
)
613 OGDF_ASSERT(adjStart
!= 0 && adjEnd
!= 0)
614 OGDF_ASSERT(adjStart
->graphOf() == this && adjEnd
->graphOf() == this);
618 node v
= adjStart
->theNode(), w
= adjEnd
->theNode();
620 AdjElement
*adjTgt
= OGDF_NEW
AdjElement(w
);
621 AdjElement
*adjSrc
= OGDF_NEW
AdjElement(v
);
623 if(dir
== ogdf::after
) {
624 w
->m_adjEdges
.insertAfter(adjTgt
,adjEnd
);
625 v
->m_adjEdges
.insertAfter(adjSrc
,adjStart
);
627 w
->m_adjEdges
.insertBefore(adjTgt
,adjEnd
);
628 v
->m_adjEdges
.insertBefore(adjSrc
,adjStart
);
634 adjSrc
->m_twin
= adjTgt
;
635 adjTgt
->m_twin
= adjSrc
;
637 edge e
= createEdgeElement(v
,w
,adjSrc
,adjTgt
);
639 return adjSrc
->m_edge
= adjTgt
->m_edge
= e
;
642 edge
Graph::newEdge(node v
, adjEntry adjEnd
)
644 OGDF_ASSERT(v
!= 0 && adjEnd
!= 0)
645 OGDF_ASSERT(v
->graphOf() == this && adjEnd
->graphOf() == this);
649 node w
= adjEnd
->theNode();
651 AdjElement
*adjTgt
= OGDF_NEW
AdjElement(w
);
653 w
->m_adjEdges
.insertAfter(adjTgt
,adjEnd
);
656 AdjElement
*adjSrc
= OGDF_NEW
AdjElement(v
);
658 v
->m_adjEdges
.pushBack(adjSrc
);
661 adjSrc
->m_twin
= adjTgt
;
662 adjTgt
->m_twin
= adjSrc
;
664 edge e
= createEdgeElement(v
,w
,adjSrc
,adjTgt
);
666 return adjSrc
->m_edge
= adjTgt
->m_edge
= e
;
668 //copy of above function with edge ending at v
669 edge
Graph::newEdge(adjEntry adjStart
, node v
)
671 OGDF_ASSERT(v
!= 0 && adjStart
!= 0)
672 OGDF_ASSERT(v
->graphOf() == this && adjStart
->graphOf() == this);
676 node w
= adjStart
->theNode();
678 AdjElement
*adjSrc
= OGDF_NEW
AdjElement(w
);
680 w
->m_adjEdges
.insertAfter(adjSrc
, adjStart
);
683 AdjElement
*adjTgt
= OGDF_NEW
AdjElement(v
);
685 v
->m_adjEdges
.pushBack(adjTgt
);
688 adjSrc
->m_twin
= adjTgt
;
689 adjTgt
->m_twin
= adjSrc
;
691 edge e
= createEdgeElement(w
,v
,adjSrc
,adjTgt
);
693 return adjSrc
->m_edge
= adjTgt
->m_edge
= e
;
697 void Graph::move(edge e
,
703 OGDF_ASSERT(e
->graphOf() == this);
704 OGDF_ASSERT(adjSrc
->graphOf() == this && adjTgt
->graphOf() == this);
705 OGDF_ASSERT(adjSrc
!= e
->m_adjSrc
&& adjSrc
!= e
->m_adjTgt
);
706 OGDF_ASSERT(adjTgt
!= e
->m_adjSrc
&& adjTgt
!= e
->m_adjTgt
);
708 node v
= adjSrc
->m_node
, w
= adjTgt
->m_node
;
709 adjEntry adj1
= e
->m_adjSrc
, adj2
= e
->m_adjTgt
;
710 e
->m_src
->m_adjEdges
.move(adj1
,v
->m_adjEdges
,adjSrc
,dirSrc
);
711 e
->m_tgt
->m_adjEdges
.move(adj2
,w
->m_adjEdges
,adjTgt
,dirTgt
);
713 e
->m_src
->m_outdeg
--;
716 adj1
->m_node
= e
->m_src
= v
;
717 adj2
->m_node
= e
->m_tgt
= w
;
724 void Graph::moveTarget(edge e
, node v
)
726 OGDF_ASSERT(e
->graphOf() == this);
727 OGDF_ASSERT(v
->graphOf() == this);
729 adjEntry adj
= e
->m_adjTgt
;
730 e
->m_tgt
->m_adjEdges
.move(adj
,v
->m_adjEdges
);
733 adj
->m_node
= e
->m_tgt
= v
;
737 void Graph::moveTarget(edge e
, adjEntry adjTgt
, Direction dir
)
739 node v
= adjTgt
->theNode();
741 OGDF_ASSERT(e
->graphOf() == this);
742 OGDF_ASSERT(v
->graphOf() == this);
744 adjEntry adj
= e
->m_adjTgt
;
745 e
->m_tgt
->m_adjEdges
.move(adj
,v
->m_adjEdges
, adjTgt
, dir
);
748 adj
->m_node
= e
->m_tgt
= v
;
753 void Graph::moveSource(edge e
, node v
)
755 OGDF_ASSERT(e
->graphOf() == this);
756 OGDF_ASSERT(v
->graphOf() == this);
758 adjEntry adj
= e
->m_adjSrc
;
759 e
->m_src
->m_adjEdges
.move(adj
,v
->m_adjEdges
);
761 e
->m_src
->m_outdeg
--;
762 adj
->m_node
= e
->m_src
= v
;
766 void Graph::moveSource(edge e
, adjEntry adjSrc
, Direction dir
)
768 node v
= adjSrc
->theNode();
770 OGDF_ASSERT(e
->graphOf() == this);
771 OGDF_ASSERT(v
->graphOf() == this);
773 adjEntry adj
= e
->m_adjSrc
;
774 e
->m_src
->m_adjEdges
.move(adj
,v
->m_adjEdges
, adjSrc
, dir
);
776 e
->m_src
->m_outdeg
--;
777 adj
->m_node
= e
->m_src
= v
;
781 edge
Graph::split(edge e
)
783 OGDF_ASSERT(e
!= 0 && e
->graphOf() == this);
788 u
->m_indeg
= u
->m_outdeg
= 1;
790 adjEntry adjTgt
= OGDF_NEW
AdjElement(u
);
792 adjTgt
->m_twin
= e
->m_adjSrc
;
793 e
->m_adjSrc
->m_twin
= adjTgt
;
795 // adapt adjacency entry index to hold invariant
796 adjTgt
->m_id
= e
->m_adjTgt
->m_id
;
798 u
->m_adjEdges
.pushBack(adjTgt
);
800 adjEntry adjSrc
= OGDF_NEW
AdjElement(u
);
801 adjSrc
->m_twin
= e
->m_adjTgt
;
802 u
->m_adjEdges
.pushBack(adjSrc
);
804 int oldId
= e
->m_adjTgt
->m_id
;
805 edge e2
= createEdgeElement(u
,e
->m_tgt
,adjSrc
,e
->m_adjTgt
);
806 resetAdjEntryIndex(e
->m_adjTgt
->m_id
,oldId
);
808 e2
->m_adjTgt
->m_twin
= adjSrc
;
809 e
->m_adjTgt
->m_edge
= adjSrc
->m_edge
= e2
;
812 e
->m_adjTgt
= adjTgt
;
817 void Graph::unsplit(node u
)
819 edge eIn
= u
->firstAdj()->theEdge();
820 edge eOut
= u
->lastAdj()->theEdge();
822 if (eIn
->target() != u
)
830 void Graph::unsplit(edge eIn
, edge eOut
)
832 node u
= eIn
->target();
834 // u must be a node with exactly one incoming edge eIn and one outgoing
836 OGDF_ASSERT(u
->graphOf() == this && u
->indeg() == 1 &&
837 u
->outdeg() == 1 && eOut
->source() == u
);
839 // none of them is a self-loop!
840 OGDF_ASSERT(eIn
->isSelfLoop() == false && eOut
->isSelfLoop() == false);
842 // we reuse these adjacency entries
843 adjEntry adjSrc
= eIn
->m_adjSrc
;
844 adjEntry adjTgt
= eOut
->m_adjTgt
;
846 eIn
->m_tgt
= eOut
->m_tgt
;
848 // adapt adjacency entry index to hold invariant
849 resetAdjEntryIndex(eIn
->m_adjTgt
->m_id
,adjTgt
->m_id
);
850 adjTgt
->m_id
= eIn
->m_adjTgt
->m_id
; // correct id of adjacency entry!
852 eIn
->m_adjTgt
= adjTgt
;
854 adjSrc
->m_twin
= adjTgt
;
855 adjTgt
->m_twin
= adjSrc
;
857 adjTgt
->m_edge
= eIn
;
859 // notify all registered observers
860 for(ListIterator
<GraphObserver
*> it
= m_regStructures
.begin();
861 it
.valid(); ++it
) (*it
)->edgeDeleted(eOut
);
862 // notify all registered observers
863 for(ListIterator
<GraphObserver
*> it
= m_regStructures
.begin();
864 it
.valid(); ++it
) (*it
)->nodeDeleted(u
);
865 // remove structures that are no longer used
874 void Graph::delNode(node v
)
876 OGDF_ASSERT(v
!= 0 && v
->graphOf() == this)
878 for(ListIterator
<GraphObserver
*> it
= m_regStructures
.begin();
879 it
.valid(); ++it
) (*it
)->nodeDeleted(v
);
883 GraphList
<AdjElement
> &adjEdges
= v
->m_adjEdges
;
885 while((adj
= adjEdges
.begin()) != 0)
886 delEdge(adj
->m_edge
);
892 void Graph::delEdge(edge e
)
894 OGDF_ASSERT(e
!= 0 && e
->graphOf() == this)
896 // notify all registered observers
897 for(ListIterator
<GraphObserver
*> it
= m_regStructures
.begin();
898 it
.valid(); ++it
) (*it
)->edgeDeleted(e
);
902 node src
= e
->m_src
, tgt
= e
->m_tgt
;
904 src
->m_adjEdges
.del(e
->m_adjSrc
);
906 tgt
->m_adjEdges
.del(e
->m_adjTgt
);
915 //tell all structures to clear their graph-initialized data
916 for(ListIterator
<GraphObserver
*> it
= m_regStructures
.begin();
921 for (node v
= m_nodes
.begin(); v
; v
= v
->succ()) {
922 v
->m_adjEdges
.~GraphList
<AdjElement
>();
928 m_nNodes
= m_nEdges
= m_nodeIdCount
= m_edgeIdCount
= 0;
929 m_nodeArrayTableSize
= MIN_NODE_TABLE_SIZE
;
932 OGDF_ASSERT_IF(dlConsistencyChecks
, consistencyCheck());
936 void Graph::reverseEdge(edge e
)
938 OGDF_ASSERT(e
!= 0 && e
->graphOf() == this)
939 node
&src
= e
->m_src
, &tgt
= e
->m_tgt
;
942 swap(e
->m_adjSrc
,e
->m_adjTgt
);
943 src
->m_outdeg
++; src
->m_indeg
--;
944 tgt
->m_outdeg
--; tgt
->m_indeg
++;
948 void Graph::reverseAllEdges()
950 for (edge e
= m_edges
.begin(); e
; e
= e
->succ())
953 OGDF_ASSERT_IF(dlConsistencyChecks
, consistencyCheck());
957 void Graph::reverseAdjEdges()
960 forall_nodes(v
,*this)
965 node
Graph::chooseNode() const
967 if (m_nNodes
== 0) return 0;
968 int k
= ogdf::randomNumber(0,m_nNodes
-1);
969 node v
= firstNode();
970 while(k
--) v
= v
->succ();
975 edge
Graph::chooseEdge() const
977 if (m_nEdges
== 0) return 0;
978 int k
= ogdf::randomNumber(0,m_nEdges
-1);
979 edge e
= firstEdge();
980 while(k
--) e
= e
->succ();
985 edge
Graph::searchEdge(node v
, node w
) const
987 OGDF_ASSERT(v
!= 0 && v
->graphOf() == this)
988 OGDF_ASSERT(w
!= 0 && w
->graphOf() == this)
991 if(adj
->twinNode() == w
) return adj
->twin()->theEdge();
997 void Graph::hideEdge(edge e
)
999 OGDF_ASSERT(e
!= 0 && e
->graphOf() == this)
1002 node src
= e
->m_src
, tgt
= e
->m_tgt
;
1004 src
->m_adjEdges
.delPure(e
->m_adjSrc
);
1006 tgt
->m_adjEdges
.delPure(e
->m_adjTgt
);
1009 m_edges
.move(e
, m_hiddenEdges
);
1013 void Graph::restoreEdge(edge e
)
1018 v
->m_adjEdges
.pushBack(e
->m_adjSrc
);
1022 w
->m_adjEdges
.pushBack(e
->m_adjTgt
);
1025 m_hiddenEdges
.move(e
, m_edges
);
1029 void Graph::restoreAllEdges()
1032 for(e
= m_hiddenEdges
.rbegin(); e
!= 0; e
= ePrev
) {
1039 int Graph::genus() const
1041 if (m_nNodes
== 0) return 0;
1045 forall_nodes(v
,*this)
1046 if (v
->degree() == 0) ++nIsolated
;
1048 NodeArray
<int> component(*this);
1049 int nCC
= connectedComponents(*this,component
);
1051 AdjEntryArray
<bool> visited(*this,false);
1052 int nFaceCycles
= 0;
1054 forall_nodes(v
,*this) {
1056 forall_adj(adj1
,v
) {
1057 if (visited
[adj1
]) continue;
1059 adjEntry adj
= adj1
;
1061 visited
[adj
] = true;
1062 adj
= adj
->faceCycleSucc();
1063 } while (adj
!= adj1
);
1069 return (m_nEdges
- m_nNodes
- nIsolated
- nFaceCycles
+ 2*nCC
) / 2;
1073 ListIterator
<NodeArrayBase
*> Graph::registerArray(
1074 NodeArrayBase
*pNodeArray
) const
1076 return m_regNodeArrays
.pushBack(pNodeArray
);
1080 ListIterator
<EdgeArrayBase
*> Graph::registerArray(
1081 EdgeArrayBase
*pEdgeArray
) const
1083 return m_regEdgeArrays
.pushBack(pEdgeArray
);
1087 ListIterator
<AdjEntryArrayBase
*> Graph::registerArray(
1088 AdjEntryArrayBase
*pAdjArray
) const
1090 return m_regAdjArrays
.pushBack(pAdjArray
);
1093 ListIterator
<GraphObserver
*> Graph::registerStructure(
1094 GraphObserver
*pStructure
) const
1096 return m_regStructures
.pushBack(pStructure
);
1097 }//registerstructure
1100 void Graph::unregisterArray(ListIterator
<NodeArrayBase
*> it
) const
1102 m_regNodeArrays
.del(it
);
1106 void Graph::unregisterArray(ListIterator
<EdgeArrayBase
*> it
) const
1108 m_regEdgeArrays
.del(it
);
1112 void Graph::unregisterArray(ListIterator
<AdjEntryArrayBase
*> it
) const
1114 m_regAdjArrays
.del(it
);
1117 void Graph::unregisterStructure(ListIterator
<GraphObserver
*> it
) const
1119 m_regStructures
.del(it
);
1122 void Graph::reinitArrays()
1124 ListIterator
<NodeArrayBase
*> itNode
= m_regNodeArrays
.begin();
1125 for(; itNode
.valid(); ++itNode
)
1126 (*itNode
)->reinit(m_nodeArrayTableSize
);
1128 ListIterator
<EdgeArrayBase
*> itEdge
= m_regEdgeArrays
.begin();
1129 for(; itEdge
.valid(); ++itEdge
)
1130 (*itEdge
)->reinit(m_edgeArrayTableSize
);
1132 ListIterator
<AdjEntryArrayBase
*> itAdj
= m_regAdjArrays
.begin();
1133 for(; itAdj
.valid(); ++itAdj
)
1134 (*itAdj
)->reinit(m_edgeArrayTableSize
<< 1);
1137 void Graph::reinitStructures()
1139 //is there a challenge?
1140 ListIterator
<GraphObserver
*> itGS
= m_regStructures
.begin();
1141 for (;itGS
.valid(); ++itGS
)
1146 void Graph::resetAdjEntryIndex(int newIndex
, int oldIndex
)
1148 ListIterator
<AdjEntryArrayBase
*> itAdj
= m_regAdjArrays
.begin();
1149 for(; itAdj
.valid(); ++itAdj
)
1150 (*itAdj
)->resetIndex(newIndex
,oldIndex
);
1154 int Graph::nextPower2(int start
, int idCount
)
1156 while (start
<= idCount
)
1163 bool Graph::readGML(const char *fileName
)
1165 ifstream
is(fileName
);
1170 bool Graph::readGML(istream
&is
)
1173 if (gml
.error()) return false;
1174 bool result
= gml
.read(*this);
1176 OGDF_ASSERT_IF(dlConsistencyChecks
, consistencyCheck());
1182 void Graph::writeGML(const char *fileName
) const
1184 ofstream
os(fileName
);
1189 void Graph::writeGML(ostream
&os
) const
1191 NodeArray
<int> id(*this);
1194 os
<< "Creator \"ogdf::Graph::writeGML\"\n";
1196 os
<< " directed 1\n";
1199 forall_nodes(v
,*this) {
1201 os
<< " id " << (id
[v
] = nextId
++) << "\n";
1202 os
<< " ]\n"; // node
1206 forall_edges(e
,*this) {
1208 os
<< " source " << id
[e
->source()] << "\n";
1209 os
<< " target " << id
[e
->target()] << "\n";
1210 os
<< " ]\n"; // edge
1213 os
<< "]\n"; // graph
1217 // read graph in LEDA format from file fileName
1218 bool Graph::readLEDAGraph(const char *fileName
)
1220 ifstream
is(fileName
);
1221 return readLEDAGraph(is
);
1225 bool Graph::readToEndOfLine(istream
&is
)
1229 if (is
.eof()) return false;
1236 // read graph in LEDA format from input stream is
1237 bool Graph::readLEDAGraph(istream
&is
)
1241 // the first three strings in the LEDA format describe the type of the
1242 // format, of nodes and of edges. We simply ignore the additional node/
1244 String formatType
, nodeType
, edgeType
;
1250 if (formatType
!= "LEDA.GRAPH")
1258 // create n nodes and ignore n lines
1259 Array
<node
> nodes(1,n
);
1261 for(i
= 1; i
<= n
; ++i
) {
1262 if (readToEndOfLine(is
) == false)
1264 nodes
[i
] = newNode();
1271 for(i
= 1; i
<= m
; ++i
) {
1272 // read index of source and target node
1277 if (src
< 1 || n
< src
|| tgt
< 1 || n
< tgt
)
1280 newEdge(nodes
[src
],nodes
[tgt
]);
1282 // ignore rest of line
1283 if (readToEndOfLine(is
) == false)
1287 OGDF_ASSERT_IF(dlConsistencyChecks
, consistencyCheck());
1293 bool Graph::consistencyCheck() const
1297 forall_nodes(v
,*this) {
1299 if (v
->graphOf() != this)
1304 int in
= 0, out
= 0;
1308 edge e
= adj
->m_edge
;
1309 if (adj
->m_twin
->m_edge
!= e
)
1312 if (e
->m_adjSrc
== adj
)
1314 else if (e
->m_adjTgt
== adj
)
1319 if (adj
->m_node
!= v
)
1323 if (adj
->graphOf() != this)
1328 if (v
->m_indeg
!= in
)
1331 if (v
->m_outdeg
!= out
)
1340 forall_edges(e
,*this) {
1342 if (e
->graphOf() != this)
1347 if (e
->m_adjSrc
== e
->m_adjTgt
)
1350 if (e
->m_adjSrc
->m_edge
!= e
)
1353 if (e
->m_adjTgt
->m_edge
!= e
)
1356 if (e
->m_adjSrc
->m_node
!= e
->m_src
)
1359 if (e
->m_adjTgt
->m_node
!= e
->m_tgt
)
1370 void Graph::resetEdgeIdCount(int maxId
)
1372 m_edgeIdCount
= maxId
+1;
1375 if (ogdf::debugLevel
>= int(ogdf::dlConsistencyChecks
)) {
1377 forall_edges(e
,*this)
1379 // if there is an edge with higer index than maxId, we cannot
1380 // set the edge id count to maxId+1
1381 if (e
->index() > maxId
)
1389 node
Graph::splitNode(adjEntry adjStartLeft
, adjEntry adjStartRight
)
1391 OGDF_ASSERT(adjStartLeft
!= 0 && adjStartRight
!= 0);
1392 OGDF_ASSERT(adjStartLeft
->graphOf() == this && adjStartRight
->graphOf() == this);
1393 OGDF_ASSERT(adjStartLeft
->theNode() == adjStartRight
->theNode());
1397 adjEntry adj
, adjSucc
;
1398 for(adj
= adjStartRight
; adj
!= adjStartLeft
; adj
= adjSucc
) {
1399 adjSucc
= adj
->cyclicSucc();
1403 newEdge(adjStartLeft
, adjStartRight
, ogdf::before
);
1409 node
Graph::contract(edge e
)
1411 adjEntry adjSrc
= e
->adjSource();
1412 adjEntry adjTgt
= e
->adjTarget();
1413 node v
= e
->source();
1414 node w
= e
->target();
1417 for(adjEntry adj
= adjTgt
->cyclicSucc(); adj
!= adjTgt
; adj
= adjNext
)
1419 adjNext
= adj
->cyclicSucc();
1421 edge eAdj
= adj
->theEdge();
1422 if(w
== eAdj
->source())
1423 moveSource(eAdj
, adjSrc
, before
);
1425 moveTarget(eAdj
, adjSrc
, before
);
1428 delNode(adjTgt
->theNode());
1434 void Graph::moveAdj(adjEntry adj
, node w
)
1436 node v
= adj
->m_node
;
1438 v
->m_adjEdges
.move(adj
,w
->m_adjEdges
);
1441 edge e
= adj
->m_edge
;
1454 ostream
&operator<<(ostream
&os
, ogdf::node v
)
1456 if (v
) os
<< v
->index(); else os
<< "nil";
1460 ostream
&operator<<(ostream
&os
, ogdf::edge e
)
1462 if (e
) os
<< "(" << e
->source() << "," << e
->target() << ")";
1467 ostream
&operator<<(ostream
&os
, ogdf::adjEntry adj
)
1470 ogdf::edge e
= adj
->theEdge();
1471 if (adj
== e
->adjSource())
1472 os
<< e
->source() << "->" << e
->target();
1474 os
<< e
->target() << "->" << e
->source();
1480 } // end namespace ogdf