Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/graphs/planarity/graphStructures.h
4057 views
1
#ifndef GRAPHSTRUCTURE_H
2
#define GRAPHSTRUCTURE_H
3
4
/*
5
Planarity-Related Graph Algorithms Project
6
Copyright (c) 1997-2010, John M. Boyer
7
All rights reserved. Includes a reference implementation of the following:
8
9
* John M. Boyer. "Simplified O(n) Algorithms for Planar Graph Embedding,
10
Kuratowski Subgraph Isolation, and Related Problems". Ph.D. Dissertation,
11
University of Victoria, 2001.
12
13
* John M. Boyer and Wendy J. Myrvold. "On the Cutting Edge: Simplified O(n)
14
Planarity by Edge Addition". Journal of Graph Algorithms and Applications,
15
Vol. 8, No. 3, pp. 241-273, 2004.
16
17
* John M. Boyer. "A New Method for Efficiently Generating Planar Graph
18
Visibility Representations". In P. Eades and P. Healy, editors,
19
Proceedings of the 13th International Conference on Graph Drawing 2005,
20
Lecture Notes Comput. Sci., Volume 3843, pp. 508-511, Springer-Verlag, 2006.
21
22
Redistribution and use in source and binary forms, with or without modification,
23
are permitted provided that the following conditions are met:
24
25
* Redistributions of source code must retain the above copyright notice, this
26
list of conditions and the following disclaimer.
27
28
* Redistributions in binary form must reproduce the above copyright notice, this
29
list of conditions and the following disclaimer in the documentation and/or
30
other materials provided with the distribution.
31
32
* Neither the name of the Planarity-Related Graph Algorithms Project nor the names
33
of its contributors may be used to endorse or promote products derived from this
34
software without specific prior written permission.
35
36
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
37
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
40
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
41
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
43
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46
*/
47
48
#include <stdio.h>
49
#include "appconst.h"
50
#include "listcoll.h"
51
#include "stack.h"
52
53
#include "graphFunctionTable.h"
54
#include "graphExtensions.private.h"
55
56
#ifdef __cplusplus
57
extern "C" {
58
#endif
59
60
/* The DEFAULT_EDGE_LIMIT expresses the initial setting for the arcCapacity
61
* as a constant factor of N, the number of vertices. We allow 3N edges, but
62
* this number can be safely set to a larger integer value.
63
*/
64
65
#define DEFAULT_EDGE_LIMIT 3
66
67
/* Simple integer selection macros */
68
69
#define MIN(x, y) ((x) < (y) ? (x) : (y))
70
#define MAX(x, y) ((x) > (y) ? (x) : (y))
71
72
#define MIN3(x, y, z) MIN(MIN((x), (y)), MIN((y), (z)))
73
#define MAX3(x, y, z) MAX(MAX((x), (y)), MAX((y), (z)))
74
75
/* Vertex activity categories */
76
77
#define VAS_INACTIVE 0
78
#define VAS_INTERNAL 1
79
#define VAS_EXTERNAL 2
80
81
/* Types:
82
83
TYPE_UNKNOWN - initial assignment
84
85
Edge types: (assigned by depth first search; used throughout algorithms)
86
87
EDGE_DFSCHILD - the arc is an edge to a DFS child; these are embedded first
88
as singleton bicomps.
89
EDGE_FORWARD - back edge directed from DFS ancestor to descendant
90
EDGE_BACK - DFS tree edge _or_ back edge directed from descendant to
91
ancestor. Embedder ignores these because the ancestors of a
92
vertex are only embedded after the vertex.
93
EDGE_DFSPARENT - If the arc (u,v) is of type EDGE_DFSCHILD, then the
94
twin arc (v,u) is marked with EDGE_DFSPARENT
95
96
Vertex types: (used when searching paths of interest in a non-planar graph)
97
98
VERTEX_HIGH_RXW - On the external face path between vertices R and X
99
VERTEX_LOW_RXW - X or on the external face path between vertices X and W
100
VERTEX_HIGH_RYW - On the external face path between vertices R and Y
101
VERTEX_LOW_RYW - Y or on the external face path between vertices Y and W
102
*/
103
104
#define TYPE_UNKNOWN 0
105
106
#define TYPE_VERTEX_VISITED 1
107
108
#define EDGE_DFSCHILD 1
109
#define EDGE_FORWARD 2
110
#define EDGE_BACK 3
111
#define EDGE_DFSPARENT 4
112
113
#define VERTEX_HIGH_RXW 6
114
#define VERTEX_LOW_RXW 7
115
#define VERTEX_HIGH_RYW 8
116
#define VERTEX_LOW_RYW 9
117
118
/* Data members needed by vertices and edges
119
120
Vertices
121
v: Carries original vertex number (same as array index)
122
DFSNumber then uses it to store DFI.
123
SortVertices then restores original vertex numbers when vertices
124
are put in DFI order (i.e. not same as array index)
125
visited: helps detect vertex visitation during various algorithms
126
such as Walkup
127
link: array indices that 'point' to the start and end arcs of the adjacency list
128
type: Used by Kuratowski subgraph isolator to classify vertices when
129
searching for certain paths in a biconnected component.
130
flags: Lowest 16 bits a reserved for future expansion of the library.
131
Next higher 16 bits can be safely used by consuming applications.
132
Currently, no flag bits are used for vertices.
133
134
Edges
135
v: The edge record for (u,v) will be in u's list and store the index of
136
the neighbour v. Starts out being original vertex number, but
137
SortVertices renumbers to DFI so we get constant time access.
138
visited: helps detect edge visitation, e.g. during the initial depth
139
first search, during a face reading, and during
140
Kuratowski subgraph isolation
141
link: Linkages to other edges in an adjacency list.
142
type: Used by DFSNumber to classify edges as DFSCHILD, DFSPARENT,
143
FORWARD, BACK. See macro definitions above.
144
flags: Lowest 16 bits a reserved for future expansion of the library.
145
Next higher 16 bits can be safely used by consuming applications.
146
The library uses bits 0 and 1 to indicate the INONLY and OUTONLY
147
arcs of a directed edge.
148
The planar embedder uses bit 2 on a DFSCHILD edge record of the
149
root edge of a bicomp to indicate inverted orientation.
150
*/
151
152
typedef struct
153
{
154
int v;
155
int visited;
156
int link[2];
157
int type;
158
int flags;
159
} graphNode;
160
161
typedef graphNode * graphNodeP;
162
163
#define EDGEFLAG_INVERTED 4
164
#define GET_EDGEFLAG_INVERTED(theGraph, e) (theGraph->G[e].flags & EDGEFLAG_INVERTED)
165
#define SET_EDGEFLAG_INVERTED(theGraph, e) (theGraph->G[e].flags |= EDGEFLAG_INVERTED)
166
#define CLEAR_EDGEFLAG_INVERTED(theGraph, e) (theGraph->G[e].flags &= (~EDGEFLAG_INVERTED))
167
168
/* Data members needed by vertices
169
DFSParent: The DFI of the DFS tree parent of this vertex
170
leastAncestor: min(DFI of neighbors connected by backedge)
171
Lowpoint: min(leastAncestor, min(Lowpoint of DFS Children))
172
adjacentTo: Used by the embedder; during walk-up, each vertex that is
173
directly adjacent via a back edge to the vertex currently
174
being embedded will have the forward edge's index stored in
175
this field. During walkdown, each vertex whose AdjacentTo
176
field is set will cause a back edge to be embedded.
177
pertinentBicompList: used by Walkup to store a list of child bicomps of
178
a vertex descendant of the current vertex that are pertinent
179
and must be merged by the Walkdown in order to embed the cycle
180
edges of the current vertex. In this implementation,
181
externally active pertinent child bicomps are placed at the end
182
of the list as an easy way to make sure all internally active
183
bicomps are processed first.
184
separatedDFSChildList: contains list DFS children of this vertex in
185
non-descending order by Lowpoint (sorted in linear time).
186
When merging bicomp rooted by edge (r, c) into vertex v (i.e.
187
merging root copy r with parent copy v), the vertex c is
188
removed from the separatedDFSChildList of v.
189
A vertex's status-- inactive, internally active, externally
190
active-- is determined by the lesser of its leastAncestor and
191
the least lowpoint from among only those DFS children that
192
aren't in the same bicomp with the vertex.
193
fwdArcList: at the start of embedding, the back edges from a vertex
194
to its DFS descendants are separated from the main adjacency
195
list and placed in a circular list until they are embedded.
196
This member indicates a node in that list.
197
*/
198
199
typedef struct
200
{
201
int DFSParent, leastAncestor, Lowpoint, adjacentTo;
202
int pertinentBicompList, separatedDFSChildList, fwdArcList;
203
} vertexRec;
204
205
typedef vertexRec * vertexRecP;
206
207
/* This structure defines a pair of links used by each vertex and root copy
208
to more efficiently traverse the external face.
209
These also help in the creation of a planarity tester that does not need
210
to embed the edges, which would be more efficient when one only needs to
211
know whether any of a give set of graphs is planar without justifying
212
the result with a combinatorial embedding. */
213
214
typedef struct
215
{
216
int vertex[2];
217
int inversionFlag;
218
} extFaceLinkRec;
219
220
typedef extFaceLinkRec * extFaceLinkRecP;
221
222
/* Flags for graph:
223
FLAGS_DFSNUMBERED is set if DFSNumber() has succeeded for the graph
224
FLAGS_SORTEDBYDFI records whether the graph is in original vertex
225
order or sorted by depth first index. Successive calls to
226
SortVertices() toggle this bit.
227
FLAGS_OBSTRUCTIONFOUND is set by gp_Embed() if an embedding obstruction
228
was isolated in the graph returned. It is cleared by gp_Embed()
229
if an obstruction was not found. The flag is used by
230
gp_TestEmbedResultIntegrity() to decide what integrity tests to run.
231
*/
232
233
#define FLAGS_DFSNUMBERED 1
234
#define FLAGS_SORTEDBYDFI 2
235
#define FLAGS_OBSTRUCTIONFOUND 4
236
237
/* Variables needed in embedding by Kuratowski subgraph isolator:
238
minorType: the type of planarity obstruction found.
239
v: the current vertex I
240
r: the root of the bicomp on which the Walkdown failed
241
x,y: stopping vertices on bicomp rooted by r
242
w: pertinent vertex on ext. face path below x and y
243
px, py: attachment points of x-y path,
244
z: Unused except in minors D and E (not needed in A, B, C).
245
246
ux,dx: endpoints of unembedded edge that helps connext x with
247
ancestor of v
248
uy,dy: endpoints of unembedded edge that helps connext y with
249
ancestor of v
250
dw: descendant endpoint in unembedded edge to v
251
uz,dz: endpoints of unembedded edge that helps connext z with
252
ancestor of v (for minors B and E, not A, C, D).
253
*/
254
255
typedef struct
256
{
257
int minorType;
258
int v, r, x, y, w, px, py, z;
259
int ux, dx, uy, dy, dw, uz, dz;
260
} isolatorContext;
261
262
typedef isolatorContext * isolatorContextP;
263
264
#define MINORTYPE_A 1
265
#define MINORTYPE_B 2
266
#define MINORTYPE_C 4
267
#define MINORTYPE_D 8
268
#define MINORTYPE_E 16
269
#define MINORTYPE_E1 32
270
#define MINORTYPE_E2 64
271
#define MINORTYPE_E3 128
272
#define MINORTYPE_E4 256
273
274
#define MINORTYPE_E5 512
275
#define MINORTYPE_E6 1024
276
#define MINORTYPE_E7 2048
277
278
/* Container for graph functions
279
G: Vertices stored at 0 to n-1, second vertex buffer at n to 2n-1,
280
edges at 2n and above
281
V: Additional information about vertices
282
N: Number of vertices
283
M: Number of edges
284
edgeOffset: always 2*N; location of the start of edge records in G
285
arcCapacity: the maximum number of edge records allowed in G
286
edgeHoles: free locations where edges have been deleted
287
theStack: Used by various graph routines needing a stack
288
internalFlags: Additional state information about the graph
289
embedFlags: controls type of embedding (e.g. planar)
290
291
IC: contains additional useful variables for Kuratowski subgraph isolation.
292
BicompLists: storage space for pertinent bicomp lists that develop
293
during embedding
294
DFSChildLists: storage space for separated DFS child lists that
295
develop during embedding
296
buckets: Used to help bucket sort the separatedDFSChildList elements
297
of all vertices (see _CreateSortedSeparatedDFSChildLists())
298
bin: Used to help bucket sort the separatedDFSChildList elements
299
of all vertices (see _CreateSortedSeparatedDFSChildLists())
300
301
extensions: a list of extension data structures
302
functions: a table of function pointers that can be overloaded to provide
303
extension behaviors to the graph
304
*/
305
306
typedef struct
307
{
308
graphNodeP G;
309
vertexRecP V;
310
int N, M, edgeOffset, arcCapacity;
311
stackP edgeHoles;
312
stackP theStack;
313
int internalFlags, embedFlags;
314
315
isolatorContext IC;
316
listCollectionP BicompLists, DFSChildLists;
317
int *buckets;
318
listCollectionP bin;
319
extFaceLinkRecP extFace;
320
321
graphExtensionP extensions;
322
graphFunctionTable functions;
323
324
} baseGraphStructure;
325
326
typedef baseGraphStructure * graphP;
327
328
/********************************************************************
329
_VertexActiveStatus()
330
Tells whether a vertex is externally active, internally active
331
or inactive.
332
********************************************************************/
333
334
#define _VertexActiveStatus(theGraph, theVertex, I) \
335
(EXTERNALLYACTIVE(theGraph, theVertex, I) \
336
? VAS_EXTERNAL \
337
: PERTINENT(theGraph, theVertex) \
338
? VAS_INTERNAL \
339
: VAS_INACTIVE)
340
341
/********************************************************************
342
PERTINENT()
343
A vertex is pertinent in a partially processed graph if there is an
344
unprocessed back edge between the vertex I whose edges are currently
345
being processed and either the vertex or a DFS descendant D of the
346
vertex not in the same bicomp as the vertex.
347
348
The vertex is either directly adjacent to I by an unembedded back edge
349
or there is an unembedded back edge (I, D) and the vertex is a cut
350
vertex in the partially processed graph along the DFS tree path from
351
D to I.
352
353
Pertinence is a dynamic property that can change for a vertex after
354
each edge addition. In other words, a vertex can become non-pertinent
355
during step I as more back edges to I are embedded.
356
********************************************************************/
357
358
#define PERTINENT(theGraph, theVertex) \
359
(theGraph->V[theVertex].adjacentTo != NIL || \
360
theGraph->V[theVertex].pertinentBicompList != NIL)
361
362
/********************************************************************
363
FUTUREPERTINENT()
364
A vertex is future-pertinent in a partially processed graph if
365
there is an unprocessed back edge between a DFS ancestor A of the
366
vertex I whose edges are currently being processed and either the
367
vertex or a DFS descendant D of the vertex not in the same bicomp
368
as the vertex.
369
370
The vertex is either directly adjacent to A by an unembedded back edge
371
or there is an unembedded back edge (A, D) and the vertex is a cut
372
vertex in the partially processed graph along the DFS tree path from
373
D to A.
374
375
If no more edges are added to the partially processed graph prior to
376
processing the edges of A, then the vertex would be pertinent.
377
The addition of edges to the partially processed graph can alter
378
both the pertinence and future pertinence of a vertex. For example,
379
if the vertex is pertinent due to an unprocessed back edge (I, D1) and
380
future pertinent due to an unprocessed back edge (A, D2), then the
381
vertex may lose both its pertinence and future pertinence when edge
382
(I, D1) is added if D2 is equal to or an ancestor of D1.
383
384
Generally, pertinence and future pertinence are dynamic properties
385
that can change for a vertex after each edge addition.
386
********************************************************************/
387
388
#define FUTUREPERTINENT(theGraph, theVertex, I) \
389
( theGraph->V[theVertex].leastAncestor < I || \
390
(theGraph->V[theVertex].separatedDFSChildList != NIL && \
391
theGraph->V[theGraph->V[theVertex].separatedDFSChildList].Lowpoint < I) )
392
393
/********************************************************************
394
EXTERNALLYACTIVE()
395
Tells whether a vertex is still externally active in step I.
396
A vertex can become inactive during step I as edges are embedded.
397
398
In planarity-related algorithms, external activity is the same as
399
future pertinence. A vertex must be kept on the external face of
400
the partial embedding until its pertinence and future pertinence
401
are resolved through edge additions.
402
403
For outerplanarity-related algorithms, all vertices are always
404
externally active, since they must always remain on the external face.
405
********************************************************************/
406
407
#define EXTERNALLYACTIVE(theGraph, theVertex, I) \
408
( ( theGraph->embedFlags & EMBEDFLAGS_OUTERPLANAR) || \
409
FUTUREPERTINENT(theGraph, theVertex, I) )
410
411
#ifdef __cplusplus
412
}
413
#endif
414
415
#endif
416
417
418