Path: blob/master/sage/graphs/planarity/graphStructures.h
4057 views
#ifndef GRAPHSTRUCTURE_H1#define GRAPHSTRUCTURE_H23/*4Planarity-Related Graph Algorithms Project5Copyright (c) 1997-2010, John M. Boyer6All rights reserved. Includes a reference implementation of the following:78* John M. Boyer. "Simplified O(n) Algorithms for Planar Graph Embedding,9Kuratowski Subgraph Isolation, and Related Problems". Ph.D. Dissertation,10University of Victoria, 2001.1112* John M. Boyer and Wendy J. Myrvold. "On the Cutting Edge: Simplified O(n)13Planarity by Edge Addition". Journal of Graph Algorithms and Applications,14Vol. 8, No. 3, pp. 241-273, 2004.1516* John M. Boyer. "A New Method for Efficiently Generating Planar Graph17Visibility Representations". In P. Eades and P. Healy, editors,18Proceedings of the 13th International Conference on Graph Drawing 2005,19Lecture Notes Comput. Sci., Volume 3843, pp. 508-511, Springer-Verlag, 2006.2021Redistribution and use in source and binary forms, with or without modification,22are permitted provided that the following conditions are met:2324* Redistributions of source code must retain the above copyright notice, this25list of conditions and the following disclaimer.2627* Redistributions in binary form must reproduce the above copyright notice, this28list of conditions and the following disclaimer in the documentation and/or29other materials provided with the distribution.3031* Neither the name of the Planarity-Related Graph Algorithms Project nor the names32of its contributors may be used to endorse or promote products derived from this33software without specific prior written permission.3435THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"36AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE37IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE38DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR39ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES40(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;41LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON42ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT43(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS44SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.45*/4647#include <stdio.h>48#include "appconst.h"49#include "listcoll.h"50#include "stack.h"5152#include "graphFunctionTable.h"53#include "graphExtensions.private.h"5455#ifdef __cplusplus56extern "C" {57#endif5859/* The DEFAULT_EDGE_LIMIT expresses the initial setting for the arcCapacity60* as a constant factor of N, the number of vertices. We allow 3N edges, but61* this number can be safely set to a larger integer value.62*/6364#define DEFAULT_EDGE_LIMIT 36566/* Simple integer selection macros */6768#define MIN(x, y) ((x) < (y) ? (x) : (y))69#define MAX(x, y) ((x) > (y) ? (x) : (y))7071#define MIN3(x, y, z) MIN(MIN((x), (y)), MIN((y), (z)))72#define MAX3(x, y, z) MAX(MAX((x), (y)), MAX((y), (z)))7374/* Vertex activity categories */7576#define VAS_INACTIVE 077#define VAS_INTERNAL 178#define VAS_EXTERNAL 27980/* Types:8182TYPE_UNKNOWN - initial assignment8384Edge types: (assigned by depth first search; used throughout algorithms)8586EDGE_DFSCHILD - the arc is an edge to a DFS child; these are embedded first87as singleton bicomps.88EDGE_FORWARD - back edge directed from DFS ancestor to descendant89EDGE_BACK - DFS tree edge _or_ back edge directed from descendant to90ancestor. Embedder ignores these because the ancestors of a91vertex are only embedded after the vertex.92EDGE_DFSPARENT - If the arc (u,v) is of type EDGE_DFSCHILD, then the93twin arc (v,u) is marked with EDGE_DFSPARENT9495Vertex types: (used when searching paths of interest in a non-planar graph)9697VERTEX_HIGH_RXW - On the external face path between vertices R and X98VERTEX_LOW_RXW - X or on the external face path between vertices X and W99VERTEX_HIGH_RYW - On the external face path between vertices R and Y100VERTEX_LOW_RYW - Y or on the external face path between vertices Y and W101*/102103#define TYPE_UNKNOWN 0104105#define TYPE_VERTEX_VISITED 1106107#define EDGE_DFSCHILD 1108#define EDGE_FORWARD 2109#define EDGE_BACK 3110#define EDGE_DFSPARENT 4111112#define VERTEX_HIGH_RXW 6113#define VERTEX_LOW_RXW 7114#define VERTEX_HIGH_RYW 8115#define VERTEX_LOW_RYW 9116117/* Data members needed by vertices and edges118119Vertices120v: Carries original vertex number (same as array index)121DFSNumber then uses it to store DFI.122SortVertices then restores original vertex numbers when vertices123are put in DFI order (i.e. not same as array index)124visited: helps detect vertex visitation during various algorithms125such as Walkup126link: array indices that 'point' to the start and end arcs of the adjacency list127type: Used by Kuratowski subgraph isolator to classify vertices when128searching for certain paths in a biconnected component.129flags: Lowest 16 bits a reserved for future expansion of the library.130Next higher 16 bits can be safely used by consuming applications.131Currently, no flag bits are used for vertices.132133Edges134v: The edge record for (u,v) will be in u's list and store the index of135the neighbour v. Starts out being original vertex number, but136SortVertices renumbers to DFI so we get constant time access.137visited: helps detect edge visitation, e.g. during the initial depth138first search, during a face reading, and during139Kuratowski subgraph isolation140link: Linkages to other edges in an adjacency list.141type: Used by DFSNumber to classify edges as DFSCHILD, DFSPARENT,142FORWARD, BACK. See macro definitions above.143flags: Lowest 16 bits a reserved for future expansion of the library.144Next higher 16 bits can be safely used by consuming applications.145The library uses bits 0 and 1 to indicate the INONLY and OUTONLY146arcs of a directed edge.147The planar embedder uses bit 2 on a DFSCHILD edge record of the148root edge of a bicomp to indicate inverted orientation.149*/150151typedef struct152{153int v;154int visited;155int link[2];156int type;157int flags;158} graphNode;159160typedef graphNode * graphNodeP;161162#define EDGEFLAG_INVERTED 4163#define GET_EDGEFLAG_INVERTED(theGraph, e) (theGraph->G[e].flags & EDGEFLAG_INVERTED)164#define SET_EDGEFLAG_INVERTED(theGraph, e) (theGraph->G[e].flags |= EDGEFLAG_INVERTED)165#define CLEAR_EDGEFLAG_INVERTED(theGraph, e) (theGraph->G[e].flags &= (~EDGEFLAG_INVERTED))166167/* Data members needed by vertices168DFSParent: The DFI of the DFS tree parent of this vertex169leastAncestor: min(DFI of neighbors connected by backedge)170Lowpoint: min(leastAncestor, min(Lowpoint of DFS Children))171adjacentTo: Used by the embedder; during walk-up, each vertex that is172directly adjacent via a back edge to the vertex currently173being embedded will have the forward edge's index stored in174this field. During walkdown, each vertex whose AdjacentTo175field is set will cause a back edge to be embedded.176pertinentBicompList: used by Walkup to store a list of child bicomps of177a vertex descendant of the current vertex that are pertinent178and must be merged by the Walkdown in order to embed the cycle179edges of the current vertex. In this implementation,180externally active pertinent child bicomps are placed at the end181of the list as an easy way to make sure all internally active182bicomps are processed first.183separatedDFSChildList: contains list DFS children of this vertex in184non-descending order by Lowpoint (sorted in linear time).185When merging bicomp rooted by edge (r, c) into vertex v (i.e.186merging root copy r with parent copy v), the vertex c is187removed from the separatedDFSChildList of v.188A vertex's status-- inactive, internally active, externally189active-- is determined by the lesser of its leastAncestor and190the least lowpoint from among only those DFS children that191aren't in the same bicomp with the vertex.192fwdArcList: at the start of embedding, the back edges from a vertex193to its DFS descendants are separated from the main adjacency194list and placed in a circular list until they are embedded.195This member indicates a node in that list.196*/197198typedef struct199{200int DFSParent, leastAncestor, Lowpoint, adjacentTo;201int pertinentBicompList, separatedDFSChildList, fwdArcList;202} vertexRec;203204typedef vertexRec * vertexRecP;205206/* This structure defines a pair of links used by each vertex and root copy207to more efficiently traverse the external face.208These also help in the creation of a planarity tester that does not need209to embed the edges, which would be more efficient when one only needs to210know whether any of a give set of graphs is planar without justifying211the result with a combinatorial embedding. */212213typedef struct214{215int vertex[2];216int inversionFlag;217} extFaceLinkRec;218219typedef extFaceLinkRec * extFaceLinkRecP;220221/* Flags for graph:222FLAGS_DFSNUMBERED is set if DFSNumber() has succeeded for the graph223FLAGS_SORTEDBYDFI records whether the graph is in original vertex224order or sorted by depth first index. Successive calls to225SortVertices() toggle this bit.226FLAGS_OBSTRUCTIONFOUND is set by gp_Embed() if an embedding obstruction227was isolated in the graph returned. It is cleared by gp_Embed()228if an obstruction was not found. The flag is used by229gp_TestEmbedResultIntegrity() to decide what integrity tests to run.230*/231232#define FLAGS_DFSNUMBERED 1233#define FLAGS_SORTEDBYDFI 2234#define FLAGS_OBSTRUCTIONFOUND 4235236/* Variables needed in embedding by Kuratowski subgraph isolator:237minorType: the type of planarity obstruction found.238v: the current vertex I239r: the root of the bicomp on which the Walkdown failed240x,y: stopping vertices on bicomp rooted by r241w: pertinent vertex on ext. face path below x and y242px, py: attachment points of x-y path,243z: Unused except in minors D and E (not needed in A, B, C).244245ux,dx: endpoints of unembedded edge that helps connext x with246ancestor of v247uy,dy: endpoints of unembedded edge that helps connext y with248ancestor of v249dw: descendant endpoint in unembedded edge to v250uz,dz: endpoints of unembedded edge that helps connext z with251ancestor of v (for minors B and E, not A, C, D).252*/253254typedef struct255{256int minorType;257int v, r, x, y, w, px, py, z;258int ux, dx, uy, dy, dw, uz, dz;259} isolatorContext;260261typedef isolatorContext * isolatorContextP;262263#define MINORTYPE_A 1264#define MINORTYPE_B 2265#define MINORTYPE_C 4266#define MINORTYPE_D 8267#define MINORTYPE_E 16268#define MINORTYPE_E1 32269#define MINORTYPE_E2 64270#define MINORTYPE_E3 128271#define MINORTYPE_E4 256272273#define MINORTYPE_E5 512274#define MINORTYPE_E6 1024275#define MINORTYPE_E7 2048276277/* Container for graph functions278G: Vertices stored at 0 to n-1, second vertex buffer at n to 2n-1,279edges at 2n and above280V: Additional information about vertices281N: Number of vertices282M: Number of edges283edgeOffset: always 2*N; location of the start of edge records in G284arcCapacity: the maximum number of edge records allowed in G285edgeHoles: free locations where edges have been deleted286theStack: Used by various graph routines needing a stack287internalFlags: Additional state information about the graph288embedFlags: controls type of embedding (e.g. planar)289290IC: contains additional useful variables for Kuratowski subgraph isolation.291BicompLists: storage space for pertinent bicomp lists that develop292during embedding293DFSChildLists: storage space for separated DFS child lists that294develop during embedding295buckets: Used to help bucket sort the separatedDFSChildList elements296of all vertices (see _CreateSortedSeparatedDFSChildLists())297bin: Used to help bucket sort the separatedDFSChildList elements298of all vertices (see _CreateSortedSeparatedDFSChildLists())299300extensions: a list of extension data structures301functions: a table of function pointers that can be overloaded to provide302extension behaviors to the graph303*/304305typedef struct306{307graphNodeP G;308vertexRecP V;309int N, M, edgeOffset, arcCapacity;310stackP edgeHoles;311stackP theStack;312int internalFlags, embedFlags;313314isolatorContext IC;315listCollectionP BicompLists, DFSChildLists;316int *buckets;317listCollectionP bin;318extFaceLinkRecP extFace;319320graphExtensionP extensions;321graphFunctionTable functions;322323} baseGraphStructure;324325typedef baseGraphStructure * graphP;326327/********************************************************************328_VertexActiveStatus()329Tells whether a vertex is externally active, internally active330or inactive.331********************************************************************/332333#define _VertexActiveStatus(theGraph, theVertex, I) \334(EXTERNALLYACTIVE(theGraph, theVertex, I) \335? VAS_EXTERNAL \336: PERTINENT(theGraph, theVertex) \337? VAS_INTERNAL \338: VAS_INACTIVE)339340/********************************************************************341PERTINENT()342A vertex is pertinent in a partially processed graph if there is an343unprocessed back edge between the vertex I whose edges are currently344being processed and either the vertex or a DFS descendant D of the345vertex not in the same bicomp as the vertex.346347The vertex is either directly adjacent to I by an unembedded back edge348or there is an unembedded back edge (I, D) and the vertex is a cut349vertex in the partially processed graph along the DFS tree path from350D to I.351352Pertinence is a dynamic property that can change for a vertex after353each edge addition. In other words, a vertex can become non-pertinent354during step I as more back edges to I are embedded.355********************************************************************/356357#define PERTINENT(theGraph, theVertex) \358(theGraph->V[theVertex].adjacentTo != NIL || \359theGraph->V[theVertex].pertinentBicompList != NIL)360361/********************************************************************362FUTUREPERTINENT()363A vertex is future-pertinent in a partially processed graph if364there is an unprocessed back edge between a DFS ancestor A of the365vertex I whose edges are currently being processed and either the366vertex or a DFS descendant D of the vertex not in the same bicomp367as the vertex.368369The vertex is either directly adjacent to A by an unembedded back edge370or there is an unembedded back edge (A, D) and the vertex is a cut371vertex in the partially processed graph along the DFS tree path from372D to A.373374If no more edges are added to the partially processed graph prior to375processing the edges of A, then the vertex would be pertinent.376The addition of edges to the partially processed graph can alter377both the pertinence and future pertinence of a vertex. For example,378if the vertex is pertinent due to an unprocessed back edge (I, D1) and379future pertinent due to an unprocessed back edge (A, D2), then the380vertex may lose both its pertinence and future pertinence when edge381(I, D1) is added if D2 is equal to or an ancestor of D1.382383Generally, pertinence and future pertinence are dynamic properties384that can change for a vertex after each edge addition.385********************************************************************/386387#define FUTUREPERTINENT(theGraph, theVertex, I) \388( theGraph->V[theVertex].leastAncestor < I || \389(theGraph->V[theVertex].separatedDFSChildList != NIL && \390theGraph->V[theGraph->V[theVertex].separatedDFSChildList].Lowpoint < I) )391392/********************************************************************393EXTERNALLYACTIVE()394Tells whether a vertex is still externally active in step I.395A vertex can become inactive during step I as edges are embedded.396397In planarity-related algorithms, external activity is the same as398future pertinence. A vertex must be kept on the external face of399the partial embedding until its pertinence and future pertinence400are resolved through edge additions.401402For outerplanarity-related algorithms, all vertices are always403externally active, since they must always remain on the external face.404********************************************************************/405406#define EXTERNALLYACTIVE(theGraph, theVertex, I) \407( ( theGraph->embedFlags & EMBEDFLAGS_OUTERPLANAR) || \408FUTUREPERTINENT(theGraph, theVertex, I) )409410#ifdef __cplusplus411}412#endif413414#endif415416417418