00001 /* Copyright (c) 2005 by John M. Boyer, All Rights Reserved. Please see 00002 * License.txt for use and redistribution license. */ 00003 #ifndef GRAPH_H 00004 #define GRAPH_H 00005 00006 /* Copyright (c) 1997-2003 by John M. Boyer, All Rights Reserved. 00007 This code may not be reproduced or disseminated in whole or in part 00008 without the written permission of the author. */ 00009 00010 #include <stdio.h> 00011 #include <stdlib.h> 00012 #include "appconst.h" 00013 #include "listcoll.h" 00014 #include "stack.h" 00015 00016 #ifdef __cplusplus 00017 extern "C" 00018 { 00019 00020 #endif /* */ 00021 00022 /* The EDGELIMIT expresses the maximum number of edges allowed as a constant 00023 factor of N, the number of vertices. We allow 3N edges, but this 00024 number can be safely set to a larger integer value. */ 00025 00026 #define EDGE_LIMIT 6 00027 00028 /* Simple integer selection macros */ 00029 00030 #define MIN(x, y) ((x) < (y) ? (x) : (y)) 00031 #define MAX(x, y) ((x) > (y) ? (x) : (y)) 00032 00033 #define MIN3(x, y, z) MIN(MIN((x), (y)), MIN((y), (z))) 00034 #define MAX3(x, y, z) MAX(MAX((x), (y)), MAX((y), (z))) 00035 00036 /* Vertex activity categories */ 00037 00038 #define VAS_INACTIVE 0 00039 #define VAS_INTERNAL 1 00040 #define VAS_EXTERNAL 2 00041 00042 /* Types: 00043 00044 TYPE_UNKNOWN - initial assignment 00045 00046 Edge types: (assigned by depth first search; used throughout algorithms) 00047 00048 EDGE_DFSCHILD - the arc is an edge to a DFS child; these are embedded first 00049 as singleton bicomps. 00050 EDGE_FORWARD - back edge directed from DFS ancestor to descendant 00051 EDGE_BACK - DFS tree edge _or_ back edge directed from descendant to 00052 ancestor. Embedder ignores these because the ancestors of a 00053 vertex are only embedded after the vertex. 00054 EDGE_DFSPARENT - If the arc (u,v) is of type EDGE_DFSCHILD, then the 00055 twin arc (v,u) is marked with EDGE_DFSPARENT 00056 00057 Vertex types: (used when searching paths of interest in a non-planar graph) 00058 00059 VERTEX_HIGH_RXW - On the external face path between vertices R and X 00060 VERTEX_LOW_RXW - X or on the external face path between vertices X and W 00061 VERTEX_HIGH_RYW - On the external face path between vertices R and Y 00062 VERTEX_LOW_RYW - Y or on the external face path between vertices Y and W 00063 */ 00064 00065 #define TYPE_UNKNOWN 0 00066 00067 #define EDGE_DFSCHILD 1 00068 #define EDGE_FORWARD 2 00069 #define EDGE_BACK 3 00070 #define EDGE_DFSPARENT 4 00071 00072 #define VERTEX_HIGH_RXW 6 00073 #define VERTEX_LOW_RXW 7 00074 #define VERTEX_HIGH_RYW 8 00075 #define VERTEX_LOW_RYW 9 00076 00077 /* Data members needed by vertices and edges 00078 00079 Vertices 00080 v: Carries original vertex number (same as array index) 00081 DFSNumber then uses it to store DFI. 00082 SortVertices then restores original vertex numbers when vertices 00083 are put in DFI order (i.e. not same as array index) 00084 visited: helps detect vertex visitation during various algorithms 00085 such as Walkup 00086 link: array indices that 'point' to the start and end of the edge list 00087 00088 type: Used by Kuratowski subgraph isolator to classify vertices when 00089 searching for certain paths in a biconnected component. 00090 sign: Unused 00091 00092 Edges 00093 v: The edge record for (u,v) will be in u's list and store the index of 00094 the neighbour v. Starts out being original vertex number, but 00095 SortVertices renumbers to DFI so we get constant time access. 00096 visited: helps detect edge visitation, e.g. during the initial depth 00097 first search, during a face reading, and during 00098 Kuratowski subgraph isolation 00099 link: Linkages to other edges in an adjacency list. 00100 type: Used by DFSNumber to classify edges as DFSCHILD, DFSPARENT, 00101 FORWARD, BACK or SHORTCIRCUIT. See macro definitions above. 00102 sign: Initialized to 1, may become -1 during embedding. 00103 For planar embedder, set to -1 on the DFSCHILD edge record of 00104 the root edge of a bicomp that is flipped. Used to recover 00105 consistent vertex orientation in each bicomp. 00106 */ 00107 typedef struct 00108 { 00109 int v; 00110 int visited; 00111 int link[2]; 00112 int type; 00113 int sign; 00114 int id; 00115 } 00116 graphNode; 00117 typedef graphNode *graphNodeP; 00118 00119 /* Additional data members needed only by vertices 00120 DFSParent: The DFI of the DFS tree parent of this vertex 00121 leastAncestor: min(DFI of neighbors connected by backedge) 00122 Lowpoint: min(leastAncestor, min(Lowpoint of DFS Children)) 00123 adjacentTo: Used by the embedder; during walk-up, each vertex that is 00124 directly adjacent via a back edge to the vertex currently 00125 being embedded will have the forward edge's index stored in 00126 this field. During walkdown, each vertex whose AdjacentTo 00127 field is set will cause a back edge to be embedded. 00128 pertinentBicompList: used by Walkup to store a list of child bicomps of 00129 a vertex descendant of the current vertex that are pertinent 00130 and must be merged by the Walkdown in order to embed the cycle 00131 edges of the current vertex. In this implementation, 00132 externally active pertinent child bicomps are placed at the end 00133 of the list as an easy way to make sure all internally active 00134 bicomps are processed first. 00135 separatedDFSChildList: contains list DFS children of this vertex in 00136 non-descending order by Lowpoint (sorted in linear time). 00137 When merging bicomp rooted by edge (r, c) into vertex v (i.e. 00138 merging root copy r with parent copy v), the vertex c is 00139 removed from the separatedDFSChildList of v. 00140 A vertex's status-- inactive, internally active, externally 00141 active-- is determined by the lesser of its leastAncestor and 00142 the least lowpoint from among only those DFS children that 00143 aren't in the same bicomp with the vertex. 00144 fwdArcList: at the start of embedding, the back edges from a vertex 00145 to its DFS descendants are separated from the main adjacency 00146 list and placed in a circular list until they are embedded. 00147 This member indicates a node in that list. 00148 */ 00149 typedef struct 00150 { 00151 int DFSParent, 00152 leastAncestor, 00153 Lowpoint, 00154 adjacentTo; 00155 int pertinentBicompList, 00156 separatedDFSChildList, 00157 fwdArcList; 00158 } 00159 vertexRec; 00160 typedef vertexRec *vertexRecP; 00161 00162 /* This structure defines a pair of links used by each vertex and root copy 00163 to more efficiently traverse the external face. 00164 These also help in the creation of a planarity tester that does not need 00165 to embed the edges, which would be more efficient when one only needs to 00166 know whether any of a give set of graphs is planar without justifying 00167 the result. */ 00168 typedef struct 00169 { 00170 int link[2]; 00171 int inversionFlag; 00172 } 00173 extFaceLinkRec; 00174 typedef extFaceLinkRec *extFaceLinkRecP; 00175 00176 /* Flags for graph: 00177 FLAGS_DFSNUMBERED is set if DFSNumber() has succeeded for the graph 00178 FLAGS_SORTEDBYDFI records whether the graph is in original vertex 00179 order or sorted by depth first index. Successive calls to 00180 SortVertices() toggle this bit. 00181 */ 00182 00183 #define FLAGS_DFSNUMBERED 1 00184 #define FLAGS_SORTEDBYDFI 2 00185 00186 /* Variables needed in embedding by Kuratowski subgraph isolator: 00187 minorType: the type of planarity obstruction found. 00188 v: the current vertex I 00189 r: the root of the bicomp on which the Walkdown failed 00190 x,y: stopping vertices on bicomp rooted by r 00191 w: pertinent vertex on ext. face path below x and y 00192 px, py: attachment points of x-y path, 00193 z: Unused except in minors D and E (not needed in A, B, C). 00194 00195 ux,dx: endpoints of unembedded edge that helps connext x with 00196 ancestor of v 00197 uy,dy: endpoints of unembedded edge that helps connext y with 00198 ancestor of v 00199 dw: descendant endpoint in unembedded edge to v 00200 uz,dz: endpoints of unembedded edge that helps connext z with 00201 ancestor of v (for minors B and E, not A, C, D). 00202 */ 00203 typedef struct 00204 { 00205 int minorType; 00206 int v, 00207 r, 00208 x, 00209 y, 00210 w, 00211 px, 00212 py, 00213 z; 00214 int ux, 00215 dx, 00216 uy, 00217 dy, 00218 dw, 00219 uz, 00220 dz; 00221 } 00222 isolatorContext; 00223 typedef isolatorContext *isolatorContextP; 00224 00225 #define FLAGS_MINOR_A 1 00226 #define FLAGS_MINOR_B 2 00227 #define FLAGS_MINOR_C 4 00228 #define FLAGS_MINOR_D 8 00229 #define FLAGS_MINOR_E 16 00230 #define FLAGS_MINOR_E1 32 00231 #define FLAGS_MINOR_E2 64 00232 #define FLAGS_MINOR_E3 128 00233 #define FLAGS_MINOR_E4 256 00234 00235 #define FLAGS_MINOR_E5 512 00236 #define FLAGS_MINOR_E6 1024 00237 #define FLAGS_MINOR_E7 2048 00238 00239 /* Container for graph functions 00240 G: Vertices stored at 0 to n-1, second vertex buffer at n to 2n-1, 00241 edges at 2n and above 00242 V: Additional information about vertices 00243 N: Number of vertices 00244 M: Number of edges 00245 internalFlags: Additional state information about the graph 00246 embedFlags: controls type of embedding (e.g. planar) 00247 IC: contains additional useful variables for Kuratowski subgraph isolation. 00248 BicompLists: storage space for pertinent bicomp lists that develop 00249 during embedding 00250 DFSChildLists: storage space for separated DFS child lists that 00251 develop during embedding 00252 theStack: Used by various routines needing a stack, including 00253 depth first search, lowpoint, Walkdown, OrientVerticesInBicomp, 00254 and MarkHighestXYPath in the Kuratowski subgraph isolator 00255 buckets: Used to help bucket sort the separatedDFSChildList elements 00256 of all vertices (see _CreateSortedSeparatedDFSChildLists()) 00257 bin: Used to help bucket sort the separatedDFSChildList elements 00258 of all vertices (see _CreateSortedSeparatedDFSChildLists()) 00259 */ 00260 typedef struct 00261 { 00262 graphNodeP G; 00263 vertexRecP V; 00264 int N, 00265 M, 00266 internalFlags, 00267 embedFlags; 00268 isolatorContext IC; 00269 listCollectionP BicompLists, 00270 DFSChildLists; 00271 stackP theStack; 00272 int *buckets; 00273 listCollectionP bin; 00274 extFaceLinkRecP extFace; 00275 } 00276 BM_graph; 00277 typedef BM_graph *graphP; 00278 00279 /* Public functions for graphs */ 00280 graphP gp_New (void); 00281 int gp_InitGraph (graphP theGraph, 00282 int N); 00283 void gp_ReinitializeGraph (graphP theGraph); 00284 int gp_CopyGraph (graphP dstGraph, 00285 graphP srcGraph); 00286 graphP gp_DupGraph (graphP theGraph); 00287 int gp_CreateRandomGraph (graphP theGraph); 00288 int gp_CreateRandomGraphEx (graphP theGraph, 00289 int numEdges); 00290 void gp_Free (graphP * pGraph); 00291 int gp_Read (graphP theGraph, 00292 char *FileName); 00293 int gp_Write (graphP theGraph, 00294 char *FileName, 00295 int Mode); 00296 int gp_IsNeighbor (graphP theGraph, 00297 int u, 00298 int v); 00299 int gp_GetVertexDegree (graphP theGraph, 00300 int v); 00301 int gp_AddEdge (graphP theGraph, 00302 int u, 00303 int ulink, 00304 int v, 00305 int vlink); 00306 void gp_HideEdge (graphP theGraph, 00307 int arcPos); 00308 void gp_RestoreEdge (graphP theGraph, 00309 int arcPos); 00310 int gp_DeleteEdge (graphP theGraph, 00311 int J, 00312 int nextLink); 00313 int gp_CreateDFSTree (graphP theGraph); 00314 int gp_SortVertices (graphP theGraph); 00315 void gp_LowpointAndLeastAncestor (graphP theGraph); 00316 int gp_Embed (graphP theGraph, 00317 int embedFlags); 00318 int gp_CheckEmbeddingIntegrity (graphP theGraph); 00319 int gp_CheckKuratowskiSubgraphIntegrity (graphP theGraph); 00320 00321 /******************************************************************** 00322 int gp_GetTwinArc(graphP theGraph, int Arc); 00323 This macro function returns the calculated twin arc of a given arc. 00324 If the arc location is even, then the successor is the twin. 00325 If the arc node is odd, then the predecessor is the twin. 00326 00327 Logically, we return (Arc & 1) ? Arc-1 : Arc+1 00328 ********************************************************************/ 00329 00330 // The original, first definition appears to be the faster one 00331 #define gp_GetTwinArc(theGraph, Arc) ((Arc) & 1) ? Arc-1 : Arc+1 00332 //#define gp_GetTwinArc(theGraph, Arc) ((Arc)+1-(((Arc)&1)<<1)) 00333 00334 /* Possible Mode parameter of gp_Write */ 00335 00336 #define WRITE_ADJLIST 1 00337 #define WRITE_ADJMATRIX 2 00338 #define WRITE_DEBUGINFO 3 00339 00340 /* Possible Flags for gp_Embed */ 00341 00342 #define EMBEDFLAGS_PLANAR 1 00343 00344 /* Private functions shared by modules in this implementation */ 00345 00346 /******************************************************************** 00347 _VertexActiveStatus() 00348 Tells whether a vertex is externally active, internally active 00349 or inactive. 00350 ********************************************************************/ 00351 00352 #define _VertexActiveStatus(theGraph, theVertex, I) (EXTERNALLYACTIVE (theGraph, theVertex, I) ? VAS_EXTERNAL : PERTINENT (theGraph, theVertex, I) ? VAS_INTERNAL : VAS_INACTIVE) 00353 /******************************************************************** 00354 _PERTINENT() 00355 Tells whether a vertex is still pertinent to the processing of edges 00356 from I to its descendants. A vertex can become non-pertinent during 00357 step I as edges are embedded. 00358 ********************************************************************/ 00359 00360 #define PERTINENT(theGraph, theVertex, I) (theGraph->V[theVertex].adjacentTo != NIL || theGraph->V[theVertex].pertinentBicompList != NIL ? 1 : 0) 00361 /******************************************************************** 00362 _EXTERNALLYACTIVE() 00363 Tells whether a vertex is still externally active in step I. 00364 A vertex can become inactive during step I as edges are embedded. 00365 ********************************************************************/ 00366 00367 #define EXTERNALLYACTIVE(theGraph, theVertex, I) (theGraph->V[theVertex].leastAncestor < I ? 1 : theGraph->V[theVertex].separatedDFSChildList != NIL && theGraph->V[theGraph->V[theVertex].separatedDFSChildList].Lowpoint < I ? 1 : 0) 00368 #ifdef __cplusplus 00369 } 00370 00371 #endif /* */ 00372 00373 #endif /* */