/******************************************************************************** ** *A planar.c Planarity testing ** ** ** Copyright (C) 2018 - J. D. Mitchell ** ** This file is free software, see the digraphs/LICENSE. **
********************************************************************************/
#include"planar.h"
// C headers #include <limits.h> // for INT_MAX #include <stdbool.h> // for true and false
// Digraphs package headers #include"digraphs-config.h"// for DIGRAPHS_WITH_INCLUDED_PLANARITY #include"digraphs-debug.h"// for DIGRAPHS_ASSERT #include"digraphs.h"// for DigraphNrVertices, DigraphNrEdges, . . . #include"gap-includes.h"// for Fail, False, True
if (CALL_1ARGS(IsDigraph, digraph) != True) {
ErrorQuit("Digraphs: boyers_planarity_check (C): the 1st argument must be " "a digraph, not %s",
(Int) TNAM_OBJ(digraph),
0L);
} if (CALL_1ARGS(IsMultiDigraph, digraph) == True) {
ErrorQuit("expected a digraph without multiple edges!", 0L, 0L);
}
Int V = DigraphNrVertices(digraph); if (V == 0) { return trivial_planarity_output(0, krtwsk);
}
Int E = DigraphNrAdjacenciesWithoutLoops(digraph); if (E == 0) { return trivial_planarity_output(V, krtwsk);
} if (V > INT_MAX) { // Cannot currently test this, it might always be true, depending on the // definition of Int.
ErrorQuit("Digraphs: boyers_planarity_check (C): the maximum number of " "nodes is %d, found %d",
INT_MAX,
V); return 0L;
} elseif (2 * E > INT_MAX) { // Cannot currently test this
ErrorQuit("Digraphs: boyers_planarity_check (C): the maximum number of " "edges is %d, found %d",
INT_MAX / 2,
E); return 0L;
}
graphP theGraph = gp_New();
if (gp_InitGraph(theGraph, V) != OK) {
gp_Free(&theGraph);
ErrorQuit("Digraphs: boyers_planarity_check (C): invalid number of nodes!",
0L,
0L); return 0L;
} elseif (gp_EnsureArcCapacity(theGraph, 2 * E) != OK) {
gp_Free(&theGraph);
ErrorQuit("Digraphs: boyers_planarity_check (C): invalid number of edges!",
0L,
0L); return 0L;
}
switch (flags) { case EMBEDFLAGS_SEARCHFORK33:
gp_AttachK33Search(theGraph); break; case EMBEDFLAGS_SEARCHFORK23:
gp_AttachK23Search(theGraph); break; case EMBEDFLAGS_SEARCHFORK4:
gp_AttachK4Search(theGraph); break; default: break;
}
int status;
Obj const out = FuncOutNeighbours(0L, digraph);
// Construct the antisymmetric digraph with no loops for (Int v = 1; v <= LEN_LIST(out); ++v) {
DIGRAPHS_ASSERT(gp_VertexInRange(theGraph, v));
gp_SetVertexIndex(theGraph, v, v);
Obj const out_v = ELM_LIST(out, v); for (Int w = 1; w <= LEN_LIST(out_v); ++w) {
DIGRAPHS_ASSERT(gp_VertexInRange(theGraph, w)); Int u = INT_INTOBJ(ELM_LIST(out_v, w)); if (v < u
|| CALL_3ARGS(IsDigraphEdge, digraph, INTOBJ_INT(u), INTOBJ_INT(v))
== False) {
status = gp_AddEdge(theGraph, v, 0, u, 0); if (status != OK) { // Cannot currently test this, i.e. it shouldn't happen (and // currently there is no example where it does happen)
gp_Free(&theGraph);
ErrorQuit("Digraphs: boyers_planarity_check (C): internal error, " "can't add edge from %d to %d",
(Int) v,
(Int) u); return 0L;
}
}
}
}
status = gp_Embed(theGraph, flags); if (status == NOTOK) { // Cannot currently test this, i.e. it shouldn't happen (and // currently there is no example where it does happen)
gp_Free(&theGraph);
ErrorQuit("Digraphs: boyers_planarity_check (C): status is not ok", 0L, 0L);
}
// Construct the return value
Obj res; if (krtwsk) { // Kuratowski subgraph isolator
gp_SortVertices(theGraph);
Obj subgraph = NEW_PLIST_IMM(T_PLIST, theGraph->N);
SET_LEN_PLIST(subgraph, theGraph->N); for (int i = 1; i <= theGraph->N; ++i) { int nr = 0;
Obj list = NEW_PLIST(T_PLIST, 0); int j = theGraph->V[i].link[1]; while (j) { if (CALL_3ARGS(IsDigraphEdge,
digraph,
INTOBJ_INT((Int) i),
INTOBJ_INT((Int) theGraph->E[j].neighbor))
== True) {
AssPlist(list, ++nr, INTOBJ_INT(theGraph->E[j].neighbor));
}
j = theGraph->E[j].link[1];
} if (nr == 0) {
SET_LEN_PLIST(list, 0);
}
MakeImmutable(list);
SET_ELM_PLIST(subgraph, i, list);
CHANGED_BAG(subgraph);
}
res = NEW_PLIST_IMM(T_PLIST, 2);
SET_LEN_PLIST(res, 2);
SET_ELM_PLIST(res, 1, (status == NONEMBEDDABLE ? False : True));
SET_ELM_PLIST(res, 2, subgraph);
CHANGED_BAG(res);
} elseif (status == NONEMBEDDABLE) {
res = False;
} else {
res = True;
}
gp_Free(&theGraph); return res;
}
¤ Dauer der Verarbeitung: 0.26 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.