int _IsolateOuterplanarObstruction(graphP theGraph, int v, int R) { int RetVal; /* A subgraph homeomorphic to K_{2,3} or K_4 will be isolated by using the visited flags, set=keep edge/vertex and clear=omit. Here we initialize to omit all, then we subsequently set visited on all edges and vertices in the homeomorph. */ _ClearVisitedFlags(theGraph); /* Next we determineg which of the non-outerplanarity Minors was encountered and the principal bicomp on which the isolator will focus attention. */ if (_ChooseTypeOfNonOuterplanarityMinor(theGraph, v, R) != OK) return NOTOK; /* Find the path connecting the pertinent vertex w with the current vertex v */ if (theGraph->IC.minorType & MINORTYPE_B) { isolatorContextP IC = &theGraph->IC; int SubtreeRoot = gp_GetVertexLastPertinentRootChild(theGraph, IC->w); if (_FindUnembeddedEdgeToSubtree(theGraph, IC->v, SubtreeRoot, &IC->dw) != TRUE) return NOTOK; } else { isolatorContextP IC = &theGraph->IC; if (_FindUnembeddedEdgeToCurVertex(theGraph, IC->w, &IC->dw) != TRUE) return NOTOK; } /* For minor E, we need to find and mark an X-Y path */ if (theGraph->IC.minorType & MINORTYPE_E) { if (_MarkHighestXYPath(theGraph) != TRUE) return NOTOK; } /* Call the appropriate isolator */ if (theGraph->IC.minorType & MINORTYPE_A) RetVal = _IsolateOuterplanarityObstructionA(theGraph); else if (theGraph->IC.minorType & MINORTYPE_B) RetVal = _IsolateOuterplanarityObstructionB(theGraph); else if (theGraph->IC.minorType & MINORTYPE_E) RetVal = _IsolateOuterplanarityObstructionE(theGraph); else RetVal = NOTOK; /* Delete the unmarked edges and vertices, and return */ if (RetVal == OK) RetVal = _DeleteUnmarkedVerticesAndEdges(theGraph); return RetVal; }
int _IsolateOuterplanarityObstructionE3orE4(graphP theGraph) { isolatorContextP IC = &theGraph->IC; int u, d, XorY; /* Minor E3 */ if (FUTUREPERTINENT(theGraph, theGraph->IC.x, theGraph->IC.v) || FUTUREPERTINENT(theGraph, theGraph->IC.y, theGraph->IC.v)) { if (_MarkHighestXYPath(theGraph) != TRUE) return NOTOK; if (FUTUREPERTINENT(theGraph, theGraph->IC.x, theGraph->IC.v)) XorY = theGraph->IC.x; else XorY = theGraph->IC.y; /* The cases of X externally active and Y externally active are the same except for the bicomp external face marking (because parameter order is important) */ if (XorY == theGraph->IC.x) { if (_MarkPathAlongBicompExtFace(theGraph, IC->x, IC->w) != OK || _MarkPathAlongBicompExtFace(theGraph, IC->y, IC->r) != OK) return NOTOK; } else { if (_MarkPathAlongBicompExtFace(theGraph, IC->r, IC->x) != OK || _MarkPathAlongBicompExtFace(theGraph, IC->w, IC->y) != OK) return NOTOK; } if (_FindUnembeddedEdgeToCurVertex(theGraph, IC->w, &IC->dw) != TRUE) return NOTOK; if (_FindUnembeddedEdgeToAncestor(theGraph, XorY, &u, &d) != TRUE) return NOTOK; if (theGraph->functions.fpMarkDFSPath(theGraph, u, IC->v) != OK || theGraph->functions.fpMarkDFSPath(theGraph, XorY, d) != OK || theGraph->functions.fpMarkDFSPath(theGraph, IC->w, IC->dw) != OK || _JoinBicomps(theGraph) != OK || _AddAndMarkEdge(theGraph, u, d) != OK || _AddAndMarkEdge(theGraph, IC->v, IC->dw) != OK) return NOTOK; return OK; } /* Otherwise, isolate Minor E4 (reduce to minor A) */ if (_FindUnembeddedEdgeToAncestor(theGraph, IC->w, &u, &d) != TRUE) return NOTOK; IC->v = u; IC->dw = d; return _IsolateOuterplanarityObstructionA(theGraph); }
int _IsolateOuterplanarityObstructionE1orE2(graphP theGraph) { isolatorContextP IC = &theGraph->IC; int XPrevLink = 1; if (_MarkHighestXYPath(theGraph) != TRUE) return NOTOK; /* Isolate E1 */ if (theGraph->IC.px != theGraph->IC.x) { if (_MarkPathAlongBicompExtFace(theGraph, IC->r, IC->w) != OK || _MarkPathAlongBicompExtFace(theGraph, IC->py, IC->r) != OK) return NOTOK; } else if (theGraph->IC.py != theGraph->IC.y) { if (_MarkPathAlongBicompExtFace(theGraph, IC->r, IC->x) != OK || _MarkPathAlongBicompExtFace(theGraph, IC->w, IC->r) != OK) return NOTOK; } /* Isolate E2 */ else if (IC->w != _GetNextVertexOnExternalFace(theGraph, IC->x, &XPrevLink)) { if (_MarkPathAlongBicompExtFace(theGraph, IC->r, IC->y) != OK) return NOTOK; } else { if (_MarkPathAlongBicompExtFace(theGraph, IC->x, IC->r) != OK) return NOTOK; } /* Final bits are in common */ if (_FindUnembeddedEdgeToCurVertex(theGraph, IC->w, &IC->dw) != TRUE || theGraph->functions.fpMarkDFSPath(theGraph, IC->w, IC->dw) != OK || _JoinBicomps(theGraph) != OK || _AddAndMarkEdge(theGraph, IC->v, IC->dw) != OK) return NOTOK; return OK; }
int _InitializeIsolatorContext(graphP theGraph) { isolatorContextP IC = &theGraph->IC; /* Obtains the edges connecting X and Y to ancestors of the current vertex */ if (_FindUnembeddedEdgeToAncestor(theGraph, IC->x, &IC->ux, &IC->dx) != TRUE || _FindUnembeddedEdgeToAncestor(theGraph, IC->y, &IC->uy, &IC->dy) != TRUE) return NOTOK; /* For Minor B, we seek the last pertinent child biconnected component, which is also future pertinent, and obtain the DFS child in its root edge. This child is the subtree root containing vertices with connections to both the current vertex and an ancestor of the current vertex. */ if (theGraph->IC.minorType & MINORTYPE_B) { int SubtreeRoot = gp_GetVertexLastPertinentRootChild(theGraph, IC->w); IC->uz = gp_GetVertexLowpoint(theGraph, SubtreeRoot); if (_FindUnembeddedEdgeToSubtree(theGraph, IC->v, SubtreeRoot, &IC->dw) != TRUE || _FindUnembeddedEdgeToSubtree(theGraph, IC->uz, SubtreeRoot, &IC->dz) != TRUE) return NOTOK; } /* For all other minors, we obtain an unembedded connecting the current vertex to the pertinent vertex W, and for minor E we collect the additional unembedded ancestor connection for the future pertinent vertex Z. */ else { if (_FindUnembeddedEdgeToCurVertex(theGraph, IC->w, &IC->dw) != TRUE) return NOTOK; if (theGraph->IC.minorType & MINORTYPE_E) if (_FindUnembeddedEdgeToAncestor(theGraph, IC->z, &IC->uz, &IC->dz) != TRUE) return NOTOK; } return OK; }
int _InitializeIsolatorContext(graphP theGraph) { isolatorContextP IC = &theGraph->IC; /* Obtains the edges connecting X and Y to ancestors of the current vertex */ if (_FindUnembeddedEdgeToAncestor(theGraph, IC->x, &IC->ux, &IC->dx) != TRUE || _FindUnembeddedEdgeToAncestor(theGraph, IC->y, &IC->uy, &IC->dy) != TRUE) return NOTOK; /* For Minor B, we seek the last pertinent child biconnected component, which is externally active, and obtain the DFS child in its root edge. This child is the subtree root containing vertices with connections to both the current vertex and an ancestor of the current vertex. */ if (theGraph->IC.minorType & MINORTYPE_B) { int SubtreeRoot = LCGetPrev(theGraph->BicompLists, theGraph->V[IC->w].pertinentBicompList, NIL); IC->uz = theGraph->V[SubtreeRoot].Lowpoint; if (_FindUnembeddedEdgeToSubtree(theGraph, IC->v, SubtreeRoot, &IC->dw) != TRUE || _FindUnembeddedEdgeToSubtree(theGraph, IC->uz, SubtreeRoot, &IC->dz) != TRUE) return NOTOK; } /* For all other minors, we obtain */ else { if (_FindUnembeddedEdgeToCurVertex(theGraph, IC->w, &IC->dw) != TRUE) return NOTOK; if (theGraph->IC.minorType & MINORTYPE_E) if (_FindUnembeddedEdgeToAncestor(theGraph, IC->z, &IC->uz, &IC->dz) != TRUE) return NOTOK; } return OK; }
int _SearchForK23InBicomp(graphP theGraph, int I, int R) { isolatorContextP IC = &theGraph->IC; int X, Y, XPrevLink, YPrevLink; /* Begin by determining whether minor A, B or E is detected */ if (_ChooseTypeOfNonOuterplanarityMinor(theGraph, I, R) != OK) return NOTOK; /* Minors A and B result in the desired K_{2,3} homeomorph, so we isolate it and return NONEMBEDDABLE. */ if (theGraph->IC.minorType & (MINORTYPE_A|MINORTYPE_B)) { _FillVisitedFlags(theGraph, 0); if (theGraph->IC.minorType & MINORTYPE_A) { if (_FindUnembeddedEdgeToCurVertex(theGraph, IC->w, &IC->dw) != TRUE) return NOTOK; if (_IsolateOuterplanarityObstructionA(theGraph) != OK) return NOTOK; } else if (theGraph->IC.minorType & MINORTYPE_B) { int SubtreeRoot = LCGetPrev(theGraph->BicompLists, theGraph->V[IC->w].pertinentBicompList, NIL); if (_FindUnembeddedEdgeToSubtree(theGraph, IC->v, SubtreeRoot, &IC->dw) != TRUE) return NOTOK; if (_IsolateOuterplanarityObstructionB(theGraph) != OK) return NOTOK; } if (_DeleteUnmarkedVerticesAndEdges(theGraph) != OK) return NOTOK; return NONEMBEDDABLE; } /* For minor E (a K_4) , we run the additional tests to see if a K_{2,3} is entangled with the K_4. If not, then we return OK to indicate that the outerplanarity embedder should proceed as if the K_4 had not been found. */ /* If any vertices other than R, X, Y and W exist along the external face, then we can obtain a K_{2,3} by minor E1 or E2 */ X = IC->x; Y = IC->y; XPrevLink = 1; YPrevLink = 0; if (IC->w != _GetNextVertexOnExternalFace(theGraph, X, &XPrevLink) || IC->w != _GetNextVertexOnExternalFace(theGraph, Y, &YPrevLink)) { _FillVisitedFlags(theGraph, 0); if (_IsolateOuterplanarityObstructionE1orE2(theGraph) != OK) return NOTOK; if (_DeleteUnmarkedVerticesAndEdges(theGraph) != OK) return NOTOK; return NONEMBEDDABLE; } /* If X, Y or W make either a direct back edge connection or a connection through a separated child bicomp to an ancestor of the current vertex I, then we can obtain a K_{2,3} by minor E3 or E4. Note that this question is query on X, Y and W is equivalent to the planarity version of external activity. */ if (FUTUREPERTINENT(theGraph, X, I) || FUTUREPERTINENT(theGraph, Y, I) || FUTUREPERTINENT(theGraph, IC->w, I)) { _FillVisitedFlags(theGraph, 0); if (_IsolateOuterplanarityObstructionE3orE4(theGraph) != OK) return NOTOK; if (_DeleteUnmarkedVerticesAndEdges(theGraph) != OK) return NOTOK; return NONEMBEDDABLE; } /* The extra cases for finding a K_{2,3} failed, so the bicomp rooted by R is a separable subgraph of the input that is isomorphic to K_4. So, we restore the original vertex orientation of the bicomp (because it's polite, not because we really have to). Then, we return OK to tell the outerplanarity embedder that it can ignore this K_4 and keep processing. */ if (_OrientVerticesInBicomp(theGraph, R, 1) != OK) return NOTOK; return OK; }