int _ChooseTypeOfNonOuterplanarityMinor(graphP theGraph, int v, int R) { int X, Y, W; // Create the initial non-outerplanarity obstruction isolator state. if (_InitializeNonplanarityContext(theGraph, v, R) != OK) return NOTOK; R = theGraph->IC.r; X = theGraph->IC.x; Y = theGraph->IC.y; W = theGraph->IC.w; // If the root copy is not a root copy of the current vertex v, // then the Walkdown terminated on a descendant bicomp, which is Minor A. if (gp_GetPrimaryVertexFromRoot(theGraph, R) != v) { theGraph->IC.minorType |= MINORTYPE_A; return OK; } // If W has a pertinent child bicomp, then we've found Minor B. // Notice this is different from planarity, in which minor B is indicated // only if the pertinent child bicomp is also future pertinent. if (gp_IsVertex(gp_GetVertexPertinentRootsList(theGraph, W))) { theGraph->IC.minorType |= MINORTYPE_B; return OK; } // The only other result is minor E (we will search for the X-Y path later) theGraph->IC.minorType |= MINORTYPE_E; return OK; }
int _FindUnembeddedEdgeToAncestor(graphP theGraph, int cutVertex, int *pAncestor, int *pDescendant) { int child, foundChild; int ancestor = gp_GetVertexLeastAncestor(theGraph, cutVertex); child = gp_GetVertexFuturePertinentChild(theGraph, cutVertex); foundChild = NIL; while (gp_IsVertex(child)) { if (gp_IsSeparatedDFSChild(theGraph, child) && ancestor > gp_GetVertexLowpoint(theGraph, child)) { ancestor = gp_GetVertexLowpoint(theGraph, child); foundChild = child; } child = gp_GetVertexNextDFSChild(theGraph, cutVertex, child); } *pAncestor = ancestor; // If the least ancestor connection was direct, then return the cutVertex as the descendant if (ancestor == gp_GetVertexLeastAncestor(theGraph, cutVertex)) { *pDescendant = cutVertex; return TRUE; } // Otherwise find the descendant based on the separated child with least lowpoint return _FindUnembeddedEdgeToSubtree(theGraph, *pAncestor, foundChild, pDescendant); }
void _CreateSeparatedDFSChildLists(graphP theGraph, K33SearchContext *context) { int *buckets; listCollectionP bin; int v, L, DFSParent, theList; buckets = context->buckets; bin = context->bin; // Initialize the bin and all the buckets to be empty LCReset(bin); for (L = gp_GetFirstVertex(theGraph); gp_VertexInRange(theGraph, L); L++) buckets[L] = NIL; // For each vertex, add it to the bucket whose index is equal to the lowpoint of the vertex. for (v = gp_GetFirstVertex(theGraph); gp_VertexInRange(theGraph, v); v++) { L = gp_GetVertexLowpoint(theGraph, v); buckets[L] = LCAppend(bin, buckets[L], v); } // For each bucket, add each vertex in the bucket to the separatedDFSChildList of its DFSParent. // Since lower numbered buckets are processed before higher numbered buckets, vertices with lower // lowpoint values are added before those with higher lowpoint values, so the separatedDFSChildList // of each vertex is sorted by lowpoint for (L = gp_GetFirstVertex(theGraph); gp_VertexInRange(theGraph, L); L++) { v = buckets[L]; // Loop through all the vertices with lowpoint L, putting each in the list of its parent while (gp_IsVertex(v)) { DFSParent = gp_GetVertexParent(theGraph, v); if (gp_IsVertex(DFSParent) && DFSParent != v) { theList = context->VI[DFSParent].separatedDFSChildList; theList = LCAppend(context->separatedDFSChildLists, theList, v); context->VI[DFSParent].separatedDFSChildList = theList; } v = LCGetNext(bin, buckets[L], v); } } }
int _AddAndMarkUnembeddedEdges(graphP theGraph) { isolatorContextP IC = &theGraph->IC; if (_AddAndMarkEdge(theGraph, IC->ux, IC->dx) != OK || _AddAndMarkEdge(theGraph, IC->uy, IC->dy) != OK) return NOTOK; if (gp_IsVertex(IC->dw)) if (_AddAndMarkEdge(theGraph, IC->v, IC->dw) != OK) return NOTOK; if (gp_IsVertex(IC->dz)) if (_AddAndMarkEdge(theGraph, IC->uz, IC->dz) != OK) return NOTOK; return OK; }
int _MarkDFSPathsToDescendants(graphP theGraph) { isolatorContextP IC = &theGraph->IC; if (theGraph->functions.fpMarkDFSPath(theGraph, IC->x, IC->dx) != OK || theGraph->functions.fpMarkDFSPath(theGraph, IC->y, IC->dy) != OK) return NOTOK; if (gp_IsVertex(IC->dw)) if (theGraph->functions.fpMarkDFSPath(theGraph, IC->w, IC->dw) != OK) return NOTOK; if (gp_IsVertex(IC->dz)) if (theGraph->functions.fpMarkDFSPath(theGraph, IC->w, IC->dz) != OK) return NOTOK; return OK; }
int _K33Search_MergeBicomps(graphP theGraph, int v, int RootVertex, int W, int WPrevLink) { K33SearchContext *context = NULL; gp_FindExtension(theGraph, K33SEARCH_ID, (void *)&context); if (context != NULL) { /* If the merge is blocked, then a K_{3,3} homeomorph is isolated, and NONEMBEDDABLE is returned so that the Walkdown terminates */ if (theGraph->embedFlags == EMBEDFLAGS_SEARCHFORK33) { int mergeBlocker; // We want to test all merge points on the stack // as well as W, since the connection will go // from W. So we push W as a 'degenerate' merge point. sp_Push2(theGraph->theStack, W, WPrevLink); sp_Push2(theGraph->theStack, NIL, NIL); if (_SearchForMergeBlocker(theGraph, context, v, &mergeBlocker) != OK) return NOTOK; if (gp_IsVertex(mergeBlocker)) { if (_FindK33WithMergeBlocker(theGraph, context, v, mergeBlocker) != OK) return NOTOK; return NONEMBEDDABLE; } // If no merge blocker was found, then remove W from the stack. sp_Pop2(theGraph->theStack, W, WPrevLink); sp_Pop2(theGraph->theStack, W, WPrevLink); } // If the merge was not blocked, then we perform the merge // When not doing a K3,3 search, then the merge is not // blocked as far as the K3,3 search method is concerned // Another algorithms could overload MergeBicomps and block // merges under certain conditions, but those would be based // on data maintained by the extension that implements the // other algorithm-- if *that* algorithm is the one being run return context->functions.fpMergeBicomps(theGraph, v, RootVertex, W, WPrevLink); } return NOTOK; }
int _GetVertexToReduce(ColorVerticesContext *context, graphP theGraph) { int v = NIL, deg; for (deg = 1; deg < theGraph->N; deg++) { if (gp_IsVertex(context->degListHeads[deg])) { // Get the first vertex in the list v = context->degListHeads[deg]; break; } } return v; }
int _GetLeastAncestorConnection(graphP theGraph, int cutVertex) { int child; int ancestor = gp_GetVertexLeastAncestor(theGraph, cutVertex); child = gp_GetVertexFuturePertinentChild(theGraph, cutVertex); while (gp_IsVertex(child)) { if (gp_IsSeparatedDFSChild(theGraph, child) && ancestor > gp_GetVertexLowpoint(theGraph, child)) ancestor = gp_GetVertexLowpoint(theGraph, child); child = gp_GetVertexNextDFSChild(theGraph, cutVertex, child); } return ancestor; }