Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/graphs/planarity/graph.h
4079 views
1
#ifndef GRAPH_H
2
#define GRAPH_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
#ifdef __cplusplus
49
extern "C" {
50
#endif
51
52
#include "graphStructures.h"
53
54
/* Public functions for graphs */
55
56
#include "graphExtensions.h"
57
58
graphP gp_New(void);
59
60
int gp_InitGraph(graphP theGraph, int N);
61
void gp_ReinitializeGraph(graphP theGraph);
62
int gp_CopyGraph(graphP dstGraph, graphP srcGraph);
63
graphP gp_DupGraph(graphP theGraph);
64
65
int gp_CreateRandomGraph(graphP theGraph);
66
int gp_CreateRandomGraphEx(graphP theGraph, int numEdges);
67
68
void gp_Free(graphP *pGraph);
69
70
int gp_Read(graphP theGraph, char *FileName);
71
#define WRITE_ADJLIST 1
72
#define WRITE_ADJMATRIX 2
73
#define WRITE_DEBUGINFO 3
74
int gp_Write(graphP theGraph, char *FileName, int Mode);
75
76
#define EDGEFLAG_DIRECTION_INONLY 1
77
#define EDGEFLAG_DIRECTION_OUTONLY 2
78
#define gp_GetDirection(theGraph, e, edgeFlag_Direction) (theGraph->G[e].flags & edgeFlag_Direction)
79
void gp_SetDirection(graphP theGraph, int e, int edgeFlag_Direction);
80
81
// An edge is comprised of two arcs, each represented by a graphNode
82
// in the adjacency lists of the vertex endpoints of the edge.
83
// This macro returns the calculated twin arc of a given arc.
84
// If the arc location is even, then the successor is the twin.
85
// If the arc node is odd, then the predecessor is the twin.
86
#define gp_GetTwinArc(theGraph, Arc) (((Arc) & 1) ? (Arc)-1 : (Arc)+1)
87
88
// Definitions that enable iteration of arcs in adjacency lists
89
#define gp_GetFirstArc(theGraph, v) (theGraph->G[v].link[0])
90
#define gp_GetLastArc(theGraph, v) (theGraph->G[v].link[1])
91
#define gp_GetNextArc(theGraph, e) (theGraph->G[e].link[0])
92
#define gp_GetPrevArc(theGraph, e) (theGraph->G[e].link[1])
93
94
//#define CIRCULAR "Non-circular is faster due to simpler comparison"
95
96
#ifdef CIRCULAR
97
#define gp_IsArc(theGraph, e) ((e) >= theGraph->edgeOffset)
98
#else
99
#define gp_IsArc(theGraph, e) ((e) != NIL)
100
#endif
101
102
// Definitions that parameterize getting either a first or last arc in a vertex
103
// and getting either a next or prev arc in a given arc
104
#define gp_GetArc(theGraph, v, theLink) (theGraph->G[v].link[theLink])
105
#define gp_GetAdjacentArc(theGraph, e, theLink) (theGraph->G[e].link[theLink])
106
107
// Definitions that enable getting the next or previous arc
108
// as if the adjacency list were circular, i.e. that the
109
// first arc and last arc were linked
110
#define gp_GetNextArcCircular(theGraph, e) \
111
(gp_IsArc(theGraph, theGraph->G[e].link[0]) ? \
112
theGraph->G[e].link[0] : \
113
gp_GetFirstArc(theGraph, theGraph->G[gp_GetTwinArc(theGraph, e)].v))
114
115
#define gp_GetPrevArcCircular(theGraph, e) \
116
(gp_IsArc(theGraph, theGraph->G[e].link[1]) ? \
117
theGraph->G[e].link[1] : \
118
gp_GetLastArc(theGraph, theGraph->G[gp_GetTwinArc(theGraph, e)].v))
119
120
// This definition is used to mark the adjacency links in arcs that are the
121
// first and last arcs in an adjacency list
122
#ifdef CIRCULAR
123
#define gp_AdjacencyListEndMark(v) (v)
124
#else
125
#define gp_AdjacencyListEndMark(v) (NIL)
126
#endif
127
128
// Definitions for very low-level adjacency list manipulations
129
#define gp_SetFirstArc(theGraph, v, newFirstArc) (theGraph->G[v].link[0] = newFirstArc)
130
#define gp_SetLastArc(theGraph, v, newLastArc) (theGraph->G[v].link[1] = newLastArc)
131
#define gp_SetNextArc(theGraph, e, newNextArc) (theGraph->G[e].link[0] = newNextArc)
132
#define gp_SetPrevArc(theGraph, e, newPrevArc) (theGraph->G[e].link[1] = newPrevArc)
133
134
#define gp_SetArc(theGraph, v, theLink, newArc) (theGraph->G[v].link[theLink] = newArc)
135
#define gp_SetAdjacentArc(theGraph, e, theLink, newArc) (theGraph->G[e].link[theLink] = newArc)
136
137
// Definitions that make the cross-link binding between a vertex and an arc
138
// The old first or last arc should be bound to this arc by separate calls,
139
// e.g. see gp_AttachFirstArc() and gp_AttachLastArc()
140
#define gp_BindFirstArc(theGraph, v, arc) \
141
{ \
142
gp_SetPrevArc(theGraph, arc, gp_AdjacencyListEndMark(v)); \
143
gp_SetFirstArc(theGraph, v, arc); \
144
}
145
146
#define gp_BindLastArc(theGraph, v, arc) \
147
{ \
148
gp_SetNextArc(theGraph, arc, gp_AdjacencyListEndMark(v)); \
149
gp_SetLastArc(theGraph, v, arc); \
150
}
151
152
// Attaches an arc between the current binding between a vertex and its first arc
153
#define gp_AttachFirstArc(theGraph, v, arc) \
154
{ \
155
if (gp_IsArc(theGraph, gp_GetFirstArc(theGraph, v))) \
156
{ \
157
gp_SetNextArc(theGraph, arc, gp_GetFirstArc(theGraph, v)); \
158
gp_SetPrevArc(theGraph, gp_GetFirstArc(theGraph, v), arc); \
159
} \
160
else gp_BindLastArc(theGraph, v, arc); \
161
gp_BindFirstArc(theGraph, v, arc); \
162
}
163
164
// Attaches an arc between the current binding betwen a vertex and its last arc
165
#define gp_AttachLastArc(theGraph, v, arc) \
166
{ \
167
if (gp_IsArc(theGraph, gp_GetLastArc(theGraph, v))) \
168
{ \
169
gp_SetPrevArc(theGraph, arc, gp_GetLastArc(theGraph, v)); \
170
gp_SetNextArc(theGraph, gp_GetLastArc(theGraph, v), arc); \
171
} \
172
else gp_BindFirstArc(theGraph, v, arc); \
173
gp_BindLastArc(theGraph, v, arc); \
174
}
175
176
// Moves an arc that is in the adjacency list of v to the start of the adjacency list
177
#define gp_MoveArcToFirst(theGraph, v, arc) \
178
if (arc != gp_GetFirstArc(theGraph, v)) \
179
{ \
180
/* If the arc is last in the adjacency list of uparent,
181
then we delete it by adjacency list end management */ \
182
if (arc == gp_GetLastArc(theGraph, v)) \
183
{ \
184
gp_SetNextArc(theGraph, gp_GetPrevArc(theGraph, arc), gp_AdjacencyListEndMark(v)); \
185
gp_SetLastArc(theGraph, v, gp_GetPrevArc(theGraph, arc)); \
186
} \
187
/* Otherwise, we delete the arc from the middle of the list */ \
188
else \
189
{ \
190
gp_SetNextArc(theGraph, gp_GetPrevArc(theGraph, arc), gp_GetNextArc(theGraph, arc)); \
191
gp_SetPrevArc(theGraph, gp_GetNextArc(theGraph, arc), gp_GetPrevArc(theGraph, arc)); \
192
} \
193
\
194
/* Now add arc e as the new first arc of uparent.
195
Note that the adjacency list is non-empty at this time */ \
196
gp_SetNextArc(theGraph, arc, gp_GetFirstArc(theGraph, v)); \
197
gp_SetPrevArc(theGraph, gp_GetFirstArc(theGraph, v), arc); \
198
gp_BindFirstArc(theGraph, v, arc); \
199
}
200
201
// Moves an arc that is in the adjacency list of v to the end of the adjacency list
202
#define gp_MoveArcToLast(theGraph, v, arc) \
203
if (arc != gp_GetLastArc(theGraph, v)) \
204
{ \
205
/* If the arc is first in the adjacency list of vertex v,
206
then we delete it by adjacency list end management */ \
207
if (arc == gp_GetFirstArc(theGraph, v)) \
208
{ \
209
gp_SetPrevArc(theGraph, gp_GetNextArc(theGraph, arc), gp_AdjacencyListEndMark(v)); \
210
gp_SetFirstArc(theGraph, v, gp_GetNextArc(theGraph, arc)); \
211
} \
212
/* Otherwise, we delete the arc from the middle of the list */ \
213
else \
214
{ \
215
gp_SetNextArc(theGraph, gp_GetPrevArc(theGraph, arc), gp_GetNextArc(theGraph, arc)); \
216
gp_SetPrevArc(theGraph, gp_GetNextArc(theGraph, arc), gp_GetPrevArc(theGraph, arc)); \
217
} \
218
\
219
/* Now add the arc as the new last arc of v.
220
Note that the adjacency list is non-empty at this time */ \
221
gp_SetPrevArc(theGraph, arc, gp_GetLastArc(theGraph, v)); \
222
gp_SetNextArc(theGraph, gp_GetLastArc(theGraph, v), arc); \
223
gp_BindLastArc(theGraph, v, arc); \
224
}
225
226
// Methods for attaching an arc into the adjacency list or detaching an arc from it.
227
// The terms AddArc, InsertArc and DeleteArc are not used because the arcs are not
228
// inserted or added to or deleted from storage (only whole edges are inserted or deleted)
229
void gp_AttachArc(graphP theGraph, int v, int e, int link, int newArc);
230
void gp_DetachArc(graphP theGraph, int arc);
231
232
233
//////////////////////////////////////////////////////////////////////////////
234
// Definitions for higher-order operations at the vertex, edge and graph level
235
//////////////////////////////////////////////////////////////////////////////
236
int gp_IsNeighbor(graphP theGraph, int u, int v);
237
int gp_GetNeighborEdgeRecord(graphP theGraph, int u, int v);
238
int gp_GetVertexDegree(graphP theGraph, int v);
239
int gp_GetVertexInDegree(graphP theGraph, int v);
240
int gp_GetVertexOutDegree(graphP theGraph, int v);
241
242
int gp_GetArcCapacity(graphP theGraph);
243
int gp_EnsureArcCapacity(graphP theGraph, int requiredArcCapacity);
244
245
int gp_AddEdge(graphP theGraph, int u, int ulink, int v, int vlink);
246
int gp_InsertEdge(graphP theGraph, int u, int e_u, int e_ulink,
247
int v, int e_v, int e_vlink);
248
249
void gp_HideEdge(graphP theGraph, int e);
250
void gp_RestoreEdge(graphP theGraph, int e);
251
int gp_HideVertex(graphP theGraph, int vertex);
252
int gp_DeleteEdge(graphP theGraph, int e, int nextLink);
253
254
int gp_ContractEdge(graphP theGraph, int e);
255
int gp_IdentifyVertices(graphP theGraph, int u, int v, int eBefore);
256
int gp_RestoreVertices(graphP theGraph);
257
258
int gp_CreateDFSTree(graphP theGraph);
259
int gp_SortVertices(graphP theGraph);
260
int gp_LowpointAndLeastAncestor(graphP theGraph);
261
262
int gp_Embed(graphP theGraph, int embedFlags);
263
int gp_TestEmbedResultIntegrity(graphP theGraph, graphP origGraph, int embedResult);
264
265
/* If LOGGING is defined, then write to the log, otherwise no-op
266
By default, neither release nor DEBUG builds including LOGGING.
267
Logging is useful for seeing details of how various algorithms
268
handle a particular graph. */
269
270
//#define LOGGING
271
#ifdef LOGGING
272
273
#define gp_LogLine _LogLine
274
#define gp_Log _Log
275
276
void _LogLine(char *Line);
277
void _Log(char *Line);
278
279
#define gp_MakeLogStr1 _MakeLogStr1
280
#define gp_MakeLogStr2 _MakeLogStr2
281
#define gp_MakeLogStr3 _MakeLogStr3
282
#define gp_MakeLogStr4 _MakeLogStr4
283
#define gp_MakeLogStr5 _MakeLogStr5
284
285
char *_MakeLogStr1(char *format, int);
286
char *_MakeLogStr2(char *format, int, int);
287
char *_MakeLogStr3(char *format, int, int, int);
288
char *_MakeLogStr4(char *format, int, int, int, int);
289
char *_MakeLogStr5(char *format, int, int, int, int, int);
290
291
#else
292
#define gp_LogLine(Line)
293
#define gp_Log(Line)
294
#define gp_MakeLogStr1(format, one)
295
#define gp_MakeLogStr2(format, one, two)
296
#define gp_MakeLogStr3(format, one, two, three)
297
#define gp_MakeLogStr4(format, one, two, three, four)
298
#define gp_MakeLogStr5(format, one, two, three, four, five)
299
#endif
300
301
/* Possible Flags for gp_Embed. The planar and outerplanar settings are supported
302
natively. The rest require extension modules. */
303
304
#define EMBEDFLAGS_PLANAR 1
305
#define EMBEDFLAGS_OUTERPLANAR 2
306
307
#define EMBEDFLAGS_DRAWPLANAR (4|EMBEDFLAGS_PLANAR)
308
309
#define EMBEDFLAGS_SEARCHFORK23 (16|EMBEDFLAGS_OUTERPLANAR)
310
#define EMBEDFLAGS_SEARCHFORK4 (32|EMBEDFLAGS_OUTERPLANAR)
311
#define EMBEDFLAGS_SEARCHFORK33 (64|EMBEDFLAGS_PLANAR)
312
313
#define EMBEDFLAGS_SEARCHFORK5 (128|EMBEDFLAGS_PLANAR)
314
315
#define EMBEDFLAGS_MAXIMALPLANARSUBGRAPH 256
316
#define EMBEDFLAGS_PROJECTIVEPLANAR 512
317
#define EMBEDFLAGS_TOROIDAL 1024
318
319
#ifdef __cplusplus
320
}
321
#endif
322
323
#endif
324
325