graph_boyer.h

Go to the documentation of this file.
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                          /*  */

Generated on Thu Oct 20 14:58:41 2005 for DominoParitySeparator by  doxygen 1.4.5