1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645
|
/*
* $Revision: 2583 $
*
* last checkin:
* $Author: gutwenger $
* $Date: 2012-07-12 01:02:21 +0200 (Do, 12. Jul 2012) $
***************************************************************/
/** \file
* \brief Declaration of graph copy classes.
*
* \author Carsten Gutwenger
*
* \par License:
* This file is part of the Open Graph Drawing Framework (OGDF).
*
* \par
* Copyright (C)<br>
* See README.txt in the root directory of the OGDF installation for details.
*
* \par
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* Version 2 or 3 as published by the Free Software Foundation;
* see the file LICENSE.txt included in the packaging of this file
* for details.
*
* \par
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* \par
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
* \see http://www.gnu.org/copyleft/gpl.html
***************************************************************/
#ifdef _MSC_VER
#pragma once
#endif
#ifndef OGDF_GRAPH_COPY_H
#define OGDF_GRAPH_COPY_H
#include "NodeArray.h"
#include "EdgeArray.h"
#include "SList.h"
#include "CombinatorialEmbedding.h"
namespace ogdf {
class FaceSetPure;
//---------------------------------------------------------
// GraphCopySimple
// simple graph copies (no support for edge splitting)
//---------------------------------------------------------
/**
* \brief Copies of graphs with mapping between nodes and edges
*
* The class GraphCopySimple represents a copy of a graph and
* maintains a mapping between the nodes and edges of the original
* graph to the copy and vice versa.
*
* New nodes and edges can be added to the copy; the counterpart
* of those nodes and edges is 0 indicating that there is no counterpart.
* This class <b>does not</b> support splitting of edges in such a way
* that both edges resulting from the split are mapped to the same
* original edge; this feature is provided by GraphCopy.
*/
class OGDF_EXPORT GraphCopySimple : public Graph
{
const Graph *m_pGraph; //!< The original graph.
NodeArray<node> m_vOrig; //!< The corresponding node in the original graph.
NodeArray<node> m_vCopy; //!< The corresponding node in the graph copy.
EdgeArray<edge> m_eOrig; //!< The corresponding edge in the original graph.
EdgeArray<edge> m_eCopy; //!< The corresponding edge in the graph copy.
public:
// construction
//! Constructs a copy of graph \a G.
GraphCopySimple(const Graph &G);
//! Copy constructor.
GraphCopySimple(const GraphCopySimple &GC);
virtual ~GraphCopySimple() { }
//! Returns a reference to the original graph.
const Graph &original() const { return *m_pGraph; }
/**
* \brief Returns the node in the original graph corresponding to \a v.
* @param v is a node in the graph copy.
* \return the corresponding node in the original graph, or 0 if no
* such node exists.
*/
node original(node v) const { return m_vOrig[v]; }
/**
* \brief Returns the edge in the original graph corresponding to \a e.
* @param e is an edge in the graph copy.
* \return the corresponding edge in the original graph, or 0 if no
* such edge exists.
*/
edge original(edge e) const { return m_eOrig[e]; }
/**
* \brief Returns the node in the graph copy corresponding to \a v.
* @param v is a node in the original graph.
* \return the corresponding node in the graph copy.
*/
node copy(node v) const { return m_vCopy[v]; }
/**
* \brief Returns the edge in the graph copy corresponding to \a e.
* @param e is an edge in the original graph.
* \return the corresponding edge in the graph copy.
*/
edge copy(edge e) const { return m_eCopy[e]; }
/**
* \brief Returns true iff \a v has no corresponding node in the original graph.
* @param v is a node in the graph copy.
*/
bool isDummy(node v) const { return (m_vOrig[v] == 0); }
/**
* \brief Returns true iff \a e has no corresponding edge in the original graph.
* @param e is an edge in the graph copy.
*/
bool isDummy(edge e) const { return (m_eOrig[e] == 0); }
//! Assignment operator.
GraphCopySimple &operator=(const GraphCopySimple &GC);
//! Creates a new node in the graph copy.
node newNode() {
return Graph::newNode();
}
/**
* \brief Creates a new node in the graph copy with original node \a vOrig.
* \warning You have to make sure that the original node makes sense, in
* particular that \a vOrig is not the original node of another node in the copy.
*/
node newNode(node vOrig) {
OGDF_ASSERT(vOrig != 0 && vOrig->graphOf() == m_pGraph);
node v = Graph::newNode();
m_vCopy[m_vOrig[v] = vOrig] = v;
return v;
}
//! Creates a new edge from \a v to \a w in the graph copy.
edge newEdge(node v, node w) {
return Graph::newEdge(v,w);
}
/**
* \brief Creates a new edge in the graph copy with original edge \a eOrig.
* \warning You have to make sure that the original edge makes sense, in
* particular that \a eOrig is not the original edge of another edge in the copy.
*/
edge newEdge(edge eOrig) {
OGDF_ASSERT(eOrig != 0 && eOrig->graphOf() == m_pGraph);
edge e = Graph::newEdge(m_vCopy[eOrig->source()], m_vCopy[eOrig->target()]);
m_eCopy[m_eOrig[e] = eOrig] = e;
return e;
}
private:
void initGC(const GraphCopySimple &GC, NodeArray<node> &vCopy,
EdgeArray<edge> &eCopy);
}; // class GraphCopySimple
//---------------------------------------------------------
// GraphCopy
// graph copies (support for edge splitting)
//---------------------------------------------------------
/**
* \brief Copies of graphs supporting edge splitting
*
* The class GraphCopy represents a copy of a graph and
* maintains a mapping between the nodes and edges of the original
* graph to the copy and vice versa.
*
* New nodes and edges can be added to the copy; the counterpart
* of those nodes and edges is 0 indicating that there is no counterpart.
* GraphCopy also support splitting of edges in such a way
* that both edges resulting from the split are mapped to the same
* original edge, and each edge of the original graph is mapped to a list
* of edges. Furthermore, it is allowed to reverse edges in the graph copy.
*
* <h3>Do's and Dont's</h3>
* Here is a short summary, what can be done with GraphCopy, and what should not
* be done. The following operations are safely supported:
* - Splitting of edges such that an original edge is represented by a path
* in the copy (split(), unsplit()).
* - Reversing edges in the copy (Graph::reverseEdge(), Graph::reverseAllEdges()).
* - Reinsertion of original edges such that they are represented by a path
* in the copy (insertEdgePath(), insertEdgePathEmbedded(), removeEdgePath(),
* removeEdgePathEmbedded()).
* - Inserting and removing dummy edges in the copy which are not associated
* with edges in the original graph.
*
* The following operations are <b>not supported</b> and are thus dangerous:
* - Any modifications on the original graph, since the copy will not be
* notified.
* - Moving the source or target node of an edge in the copy to a different node.
* - Removing edges in the graph copy that belong to a path representing an
* original edge.
* - ... (better think first!)
*/
class OGDF_EXPORT GraphCopy : public Graph {
protected:
const Graph *m_pGraph; //!< The original graph.
NodeArray<node> m_vOrig; //!< The corresponding node in the original graph.
EdgeArray<edge> m_eOrig; //!< The corresponding edge in the original graph.
EdgeArray<ListIterator<edge> > m_eIterator; //!< The position of copy edge in the list.
NodeArray<node> m_vCopy; //!< The corresponding node in the graph copy.
EdgeArray<List<edge> > m_eCopy; //!< The corresponding list of edges in the graph copy.
public:
//! Creates a graph copy of \a G.
/**
* The constructor assures that the adjacency lists of nodes in the
* constructed copy are in the same order as the adjacency lists in \a G.
* This is in particular important when dealing with embedded graphs.
*/
GraphCopy(const Graph &G);
//! Default constructor (does nothing!).
GraphCopy() : Graph() { }
//! Copy constructor.
/**
* Creates a graph copy that is a copy of \a GC and represents a graph
* copy of the original graph of \a GC.
*/
GraphCopy(const GraphCopy &GC);
virtual ~GraphCopy() { }
/**
* @name Mapping between original graph and copy
*/
//@{
//! Returns a reference to the original graph.
const Graph &original() const { return *m_pGraph; }
/**
* \brief Returns the node in the original graph corresponding to \a v.
* @param v is a node in the graph copy.
* \return the corresponding node in the original graph, or 0 if no
* such node exists.
*/
node original(node v) const { return m_vOrig[v]; }
/**
* \brief Returns the edge in the original graph corresponding to \a e.
* @param e is an edge in the graph copy.
* \return the corresponding edge in the original graph, or 0 if no
* such edge exists.
*/
edge original(edge e) const { return m_eOrig[e]; }
/**
* \brief Returns the node in the graph copy corresponding to \a v.
* @param v is a node in the original graph.
* \return the corresponding node in the graph copy.
*/
node copy(node v) const { return m_vCopy[v]; }
/**
* \brief Returns the list of edges coresponding to edge \a e.
* \param e is an edge in the original graph.
* \return the corresponding list of edges in the graph copy.
*/
const List<edge> &chain(edge e) const { return m_eCopy[e]; }
// returns first edge in chain(e)
/**
* \brief Returns the first edge in the list of edges coresponding to edge \a e.
* @param e is an edge in the original graph.
* \return the first edge in the corresponding list of edges in
* the graph copy.
*/
edge copy(edge e) const { return m_eCopy[e].front(); }
/**
* \brief Returns true iff \a v has no corresponding node in the original graph.
* @param v is a node in the graph copy.
*/
bool isDummy(node v) const { return (m_vOrig[v] == 0); }
/**
* \brief Returns true iff \a e has no corresponding edge in the original graph.
* @param e is an edge in the graph copy.
*/
bool isDummy(edge e) const { return (m_eOrig[e] == 0); }
/**
* \brief Returns true iff edge \a e has been reversed.
* @param e is an edge in the original graph.
*/
bool isReversed (edge e) const {
return e->source() != original(copy(e)->source());
}
/**
* @name Creation and deletion of nodes and edges
*/
//@{
//! Creates a new node in the graph copy.
node newNode() {
return Graph::newNode();
}
/**
* \brief Creates a new node in the graph copy with original node \a vOrig.
* \warning You have to make sure that the original node makes sense, in
* particular that \a vOrig is not the original node of another node in the copy.
*/
node newNode(node vOrig) {
OGDF_ASSERT(vOrig != 0 && vOrig->graphOf() == m_pGraph);
node v = Graph::newNode();
m_vCopy[m_vOrig[v] = vOrig] = v;
return v;
}
/**
* \brief Removes node \a v and all its adjacent edges cleaning-up their corresponding lists of original edges.
*
* \pre The corresponding lists oforiginal edges contain each only one edge.
* \param v is a node in the graph copy.
*/
void delCopy(node v);
/**
* \brief Removes edge e and clears the list of edges corresponding to \a e's original edge.
*
* \pre The list of edges corresponding to \a e's original edge contains only \a e.
* \param e is an edge in the graph copy.
*/
void delCopy(edge e);
/**
* \brief Splits edge \a e.
* @param e is an edge in the graph copy.
*/
virtual edge split(edge e);
/**
* \brief Undoes a previous split operation.
* The two edges \a eIn and \a eOut are merged to a single edge \a eIn.
* \pre The vertex \a u that was created by the previous split operation has
* exactly one incoming edge \a eIn and one outgoing edge \a eOut.
* @param eIn is an edge (*,\a u) in the graph copy.
* @param eOut is an edge (\a u,*) in the graph copy.
*/
void unsplit(edge eIn, edge eOut);
//! Creates a new edge (\a v,\a w) with original edge \a eOrig.
edge newEdge(edge eOrig);
//! Creates a new edge with original edge \a eOrig at predefined positions in the adjacency lists.
/**
* Let \a v be the node whose adjacency list contains \a adjSrc. Then,
* the created edge is (\a v,\a w).
* @param eOrig is the original edge.
* @param adjSrc is the adjacency entry after which the new edge is inserted
* in the adjacency list of \a v.
* @param w is the source node of the new edge; the edge is added at the end
* of the adjacency list of \a w.
* @return the created edge.
*/
edge newEdge(edge eOrig, adjEntry adjSrc, node w);
//! Creates a new edge with original edge \a eOrig at predefined positions in the adjacency lists.
/**
* Let \a w be the node whose adjacency list contains \a adjTgt. Then,
* the created edge is (\a v,\a w).
* @param eOrig is the original edge.
* @param v is the source node of the new edge; the edge is added at the end
* of the adjacency list of \a v.
* @param adjTgt is the adjacency entry after which the new edge is inserted
* in the adjacency list of \a w.
* @return the created edge.
*/
edge newEdge(edge eOrig, node v, adjEntry adjTgt);
edge newEdge(node v, node w) { return Graph::newEdge(v, w); }
edge newEdge(adjEntry adjSrc, adjEntry adjTgt) { return Graph::newEdge(adjSrc, adjTgt); }
edge newEdge(node v, adjEntry adjTgt) { return Graph::newEdge(v, adjTgt); }
edge newEdge(adjEntry adjSrc, node w) { return Graph::newEdge(adjSrc, w); }
//! sets eOrig to be the corresponding original edge of eCopy and vice versa
/**
* @param eOrig is the original edge
* @param eCopy is the edge copy
*/
void setEdge(edge eOrig, edge eCopy);
//! Re-inserts edge \a eOrig by "crossing" the edges in \a crossedEdges.
/**
* Let \a v and \a w be the copies of the source and target nodes of \a eOrig.
* Each edge in \a crossedEdges is split creating a sequence
* \f$u_1,\ldots,u_k\f$ of new nodes, and additional edges are inserted creating
* a path \f$v,u_1,\ldots,u_k,w\f$.
* @param eOrig is an edge in the original graph and becomes the original edge of
* all edges in the path \f$v,u_1,\ldots,u_k,w\f$.
* @param crossedEdges are edges in the graph copy.
*/
void insertEdgePath(edge eOrig, const SList<adjEntry> &crossedEdges);
//for FixedEmbeddingUpwardEdgeInserter only
void insertEdgePath(node srcOrig, node tgtOrig, const SList<adjEntry> &crossedEdges);
//! Removes the complete edge path for edge \a eOrig.
/**
* \@param eOrig is an edge in the original graph.
*/
void removeEdgePath(edge eOrig);
//! Inserts crossings between two copy edges.
/**
* This method is used in TopologyModule.
*
* Let \a crossingEdge = (\a a, \a b) and \a crossedEdge = (\a v, \a w).
* Then \a crossedEdge is split creating two edges \a crossedEdge = (\a v, \a u)
* and (\a u, \a w), \a crossingEdge is removed and replaced by two new edges
* \a e1 = (\a a, \a u) and \a e1 = (\a u, \a b).
* Finally it sets \a crossingEdge to \a e2 and returns (\a u, \a w).
*
* @param crossingEdge is the edge that gets split.
* @param crossedEdge is the edge that is replaced by two new edges.
* @param topDown is used as follows: If set to true, \a crossingEdge will cross
* \a crossedEdge from right to left, otherwise from left to right.
*/
edge insertCrossing(
edge& crossingEdge,
edge crossedEdge,
bool topDown);
/**
* @name Combinatorial Embeddings
*/
//@{
//! Creates a new edge with original edge \a eOrig in an embedding \a E.
/**
* Let \a w be the node whose adjacency list contains \a adjTgt. The original
* edge \a eOrig must connect the original nodes of \a v and \a w. If \a eOrig =
* (original(\a v),original(\a w)), then the created edge is (\a v,\a w), otherwise
* it is (\a w,\a v). The new edge \a e must split a face in \a E, such that \a e
* comes after \a adj in the adjacency list of \a v and at the end of the adjacency
* list of \a v.
*
* @param v is a node in the graph copy.
* @param adj is an adjacency entry in the graph copy.
* @param eOrig is an edge in the original graph.
* @param E is an embedding of the graph copy.
* @return the created edge.
*/
edge newEdge(node v, adjEntry adj, edge eOrig, CombinatorialEmbedding &E);
/**
* \brief Sets the embedding of the graph copy to the embedding of the original graph.
* \pre The graph copy has not been changed after construction, i.e., no new nodes
* or edges have been added and no edges have been split.
*/
void setOriginalEmbedding();
//! Re-inserts edge \a eOrig by "crossing" the edges in \a crossedEdges in embedding \a E.
/**
* Let \a v and \a w be the copies of the source and target nodes of \a eOrig,
* and let \f$e_0,e_1,\ldots,e_k,e_{k+1}\f$ be the sequence of edges corresponding
* to the adjacency entries in \a crossedEdges. The first edge needs to be incident
* to \a v and the last to \a w; the edges \f$e_1,\ldots,e_k\f$ are each split
* creating a sequence \f$u_1,\ldots,u_k\f$ of new nodes, and additional edges
* are inserted creating a path \f$v,u_1,\ldots,u_k,w\f$.
*
* The following figure illustrates, which adjacency entries need to be in the list
* \a crossedEdges. It inserts an edge connecting \a v and \a w by passing through
* the faces \f$f_0,f_1,f_2\f$; in this case, the list \a crossedEdges must contain
* the adjacency entries \f$adj_0,\ldots,adj_3\f$ (in this order).
* \image html insertEdgePathEmbedded.png
*
* @param eOrig is an edge in the original graph and becomes the original edge of
* all edges in the path \f$v,u_1,\ldots,u_k,w\f$.
* @param E is an embedding of the graph copy.
* @param crossedEdges are a list of adjacency entries in the graph copy.
*/
void insertEdgePathEmbedded(
edge eOrig,
CombinatorialEmbedding &E,
const SList<adjEntry> &crossedEdges);
/**
* Removes the complete edge path for edge \a eOrig while preserving the embedding.
* @param E is an embedding of the graph copy.
* @param eOrig is an edge in the original graph.
* @param newFaces is assigned the set of new faces resulting from joining faces
* when removing edges.
*/
void removeEdgePathEmbedded(
CombinatorialEmbedding &E,
edge eOrig,
FaceSetPure &newFaces);
//@}
/**
* @name Miscellaneous
*/
//@{
//! Checks the consistency of the data structure (for debugging only).
bool consistencyCheck() const;
//! Associates the graph copy with \a G, but does not create any nodes or edges.
/**
* This method is used for a special creation of the graph copy.
* The graph copy needs to be constructed with the default constructor,
* gets associated with \a G using this method, and then is initialized
* using either initByNodes() or initByActiveNodes().
*
* The following code snippet shows a typical application of this functionality:
* \code
* GraphCopy GC;
* GC.createEmpty(G);
*
* // compute connected components of G
* NodeArray<int> component(G);
* int numCC = connectedComponents(G,component);
*
* // intialize the array of lists of nodes contained in a CC
* Array<List<node> > nodesInCC(numCC);
*
* node v;
* forall_nodes(v,G)
* nodesInCC[component[v]].pushBack(v);
*
* EdgeArray<edge> auxCopy(G);
* Array<DPoint> boundingBox(numCC);
*
* for(int i = 0; i < numCC; ++i) {
* GC.initByNodes(nodesInCC[i],auxCopy);
* ...
* }
* \endcode
* @param G is the graph of which this graph copy shall be a copy.
*/
void createEmpty(const Graph &G);
//! Initializes the graph copy for the nodes in a component.
/**
* Creates copies of all nodes in \a nodes and their incident edges.
* Any nodes and edges allocated before are removed.
*
* The order of entries in the adjacency lists is preserved, i.e., if
* the original graph is embedded, its embedding induces the embedding
* of the created copy.
*
* It is important that \a nodes is the complete list of nodes in
* a connected component. If you wish to initialize the graph copy for an
* arbitrary set of nodes, use the method initByActiveNodes().
* \see createEmpty() for an example.
* @param nodes is the list of nodes in the original graph for which
* copies are created in the graph copy.
* @param eCopy is assigned the copy of each original edge.
*/
void initByNodes(const List<node> &nodes, EdgeArray<edge> &eCopy);
//! Initializes the graph copy for the nodes in \a nodes.
/**
* Creates copies of all nodes in \a nodes and edges between two nodes
* which are both contained in \a nodes.
* Any nodes and edges allocated before are destroyed.
*
* \see createEmpty()
* @param nodes is the list of nodes in the original graph for which
* copies are created in the graph copy.
* @param activeNodes must be true for every node in \a nodes, false
* otherwise.
* @param eCopy is assigned the copy of each original edge.
*/
void initByActiveNodes(const List<node> &nodes,
const NodeArray<bool> &activeNodes, EdgeArray<edge> &eCopy);
//@}
/**
* @name Operators
*/
//@{
//! Assignment operator.
/**
* Creates a graph copy that is a copy of \a GC and represents a graph
* copy of the original graph of \a GC.
*
* The constructor assures that the adjacency lists of nodes in the
* constructed graph are in the same order as the adjacency lists in \a G.
* This is in particular important when dealing with embedded graphs.
*/
GraphCopy &operator=(const GraphCopy &GC);
//@}
private:
void initGC(const GraphCopy &GC,
NodeArray<node> &vCopy, EdgeArray<edge> &eCopy);
}; // class GraphCopy
} // end namespace ogdf
#endif
|