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;
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
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);
		  }
     }
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 8
0
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;
}