Ejemplo n.º 1
0
int  _IsolateMinorE2(graphP theGraph)
{
isolatorContextP IC = &theGraph->IC;

     _FillVisitedFlags(theGraph, 0);

     IC->v = IC->uz;
     IC->dw = IC->dz;
     IC->z = IC->uz = IC->dz = NIL;

     theGraph->IC.minorType ^= MINORTYPE_E;
     theGraph->IC.minorType |= (MINORTYPE_A|MINORTYPE_E2);
     return _IsolateMinorA(theGraph);
}
Ejemplo n.º 2
0
int  _IsolateKuratowskiSubgraph(graphP theGraph, int I, int R)
{
int  RetVal;

/* A subgraph homeomorphic to K_{3,3} or K_5 will be isolated by using the visited
   flags, 1=keep edge/vertex and 0=omit. Here we initialize to omit all, then we
   subsequently set visited to 1 on all edges and vertices in the homeomorph. */

	 _FillVisitedFlags(theGraph, 0);

/* Next, we determine which of the non-planarity Minors was encountered
        and the principal bicomp on which the isolator will focus attention. */

     if (_ChooseTypeOfNonplanarityMinor(theGraph, I, R) != OK)
         return NOTOK;

     if (_InitializeIsolatorContext(theGraph) != OK)
         return NOTOK;

/* Call the appropriate isolator */

     if (theGraph->IC.minorType & MINORTYPE_A)
         RetVal = _IsolateMinorA(theGraph);
     else if (theGraph->IC.minorType & MINORTYPE_B)
         RetVal = _IsolateMinorB(theGraph);
     else if (theGraph->IC.minorType & MINORTYPE_C)
         RetVal = _IsolateMinorC(theGraph);
     else if (theGraph->IC.minorType & MINORTYPE_D)
         RetVal = _IsolateMinorD(theGraph);
     else if (theGraph->IC.minorType & MINORTYPE_E)
         RetVal = _IsolateMinorE(theGraph);
     else
    	 RetVal = NOTOK;

/* Delete the unmarked edges and vertices, and return */

     if (RetVal == OK)
         RetVal = _DeleteUnmarkedVerticesAndEdges(theGraph);

     return RetVal;
}
Ejemplo n.º 3
0
int gp_ColorVertices(graphP theGraph)
{
    ColorVerticesContext *context = NULL;
    int v, deg;
    int u=0, w=0, contractible;

    // Attach the algorithm if it is not already attached
	if (gp_AttachColorVertices(theGraph) != OK)
		return NOTOK;

	// Ensure there is enough stack to perform this operation.
	// At a maximum, the graph reduction will push 7N+M integers.
	// One integer is pushed per edge that is hidden. Plus, whether
	// a vertex is hidden or identified with another vertex, 7 integers
	// are used to store enough information to restore it.
	if (sp_NonEmpty(theGraph->theStack))
		return NOTOK;

	if (sp_GetCapacity(theGraph->theStack) < 7*theGraph->N + theGraph->M)
	{
		stackP newStack = sp_New(7*theGraph->N + theGraph->M);
		if (newStack == NULL)
			return NOTOK;
		sp_Free(&theGraph->theStack);
		theGraph->theStack = newStack;
	}

	// Get the extension context and reinitialize it if necessary
    gp_FindExtension(theGraph, COLORVERTICES_ID, (void *)&context);

    if (context->color[0] > -1)
    	_ColorVertices_Reinitialize(context);

    // Initialize the degree lists, and provide a color for any trivial vertices
    for (v = 0; v < theGraph->N; v++)
    {
    	deg = gp_GetVertexDegree(theGraph, v);
    	_AddVertexToDegList(context, theGraph, v, deg);

    	if (deg == 0)
    		context->color[v] = 0;
    }

    // Initialize the visited flags so they can be used during reductions
    _FillVisitedFlags(theGraph, 0);

    // Reduce the graph using minimum degree selection
    while (context->numVerticesToReduce > 0)
    {
    	v = _GetVertexToReduce(context, theGraph);

    	// Find out if v is contractible and the neighbors to contract
    	contractible = _GetContractibleNeighbors(context, v, &u, &w);

    	// Remove the vertex from the graph. This calls the fpHideEdge
    	// overload, which performs the correct _RemoveVertexFromDegList()
    	// and _AddVertexToDegList() operations on v and its neighbors.
    	if (gp_HideVertex(theGraph, v) != OK)
    		return NOTOK;

    	// If v was contractibile, then identify u and w
    	if (contractible)
    	{
    		if (gp_IdentifyVertices(theGraph, u, w, NIL) != OK)
    			return NOTOK;
    	}
    }

    // Restore the graph one vertex at a time, coloring each vertex distinctly
    // from its neighbors as it is restored.
    context->colorDetector = (int *) calloc(theGraph->N, sizeof(int));
    if (context->colorDetector == NULL)
    	return NOTOK;

    if (gp_RestoreVertices(theGraph) != OK)
    	return NOTOK;

    free(context->colorDetector);
    context->colorDetector = NULL;

	return OK;
}
Ejemplo n.º 4
0
int _CheckVisibilityRepresentationIntegrity(DrawPlanarContext *context)
{
graphP theEmbedding = context->theGraph;
int I, e, J, JTwin, JPos, JIndex;

    if (sp_NonEmpty(context->theGraph->edgeHoles))
        return NOTOK;

    _FillVisitedFlags(theEmbedding, 0);

/* Test whether the vertex values make sense and
        whether the vertex positions are unique. */

    for (I = 0; I < theEmbedding->N; I++)
    {
    	if (theEmbedding->M > 0)
    	{
            if (context->G[I].pos < 0 ||
                context->G[I].pos >= theEmbedding->N ||
                context->G[I].start < 0 ||
                context->G[I].start > context->G[I].end ||
                context->G[I].end >= theEmbedding->M)
                return NOTOK;
    	}

        // Has the vertex position (context->G[I].pos) been used by a
        // vertex before vertex I?
        if (theEmbedding->G[context->G[I].pos].visited)
            return NOTOK;

        // Mark the vertex position as used by vertex I.
        // Note that this marking is made on some other vertex unrelated to I
        // We're just reusing the vertex visited array as cheap storage for a
        // detector of reusing vertex position integers.
        theEmbedding->G[context->G[I].pos].visited = 1;
    }

/* Test whether the edge values make sense and
        whether the edge positions are unique */

    for (e = 0; e < theEmbedding->M; e++)
    {
        /* Each edge has an index location J in the graph structure */
        J = theEmbedding->edgeOffset + 2*e;
        JTwin = gp_GetTwinArc(theEmbedding, J);

        if (context->G[J].pos != context->G[JTwin].pos ||
            context->G[J].start != context->G[JTwin].start ||
            context->G[J].end != context->G[JTwin].end ||
            context->G[J].pos < 0 ||
            context->G[J].pos >= theEmbedding->M ||
            context->G[J].start < 0 ||
            context->G[J].start > context->G[J].end ||
            context->G[J].end >= theEmbedding->N)
            return NOTOK;

        /* Get the recorded horizontal position of that edge,
            a number between 0 and M-1 */

        JPos = context->G[J].pos;

        /* Convert that to an index in the graph structure so we
            can use the visited flags in the graph's edges to
            tell us whether the positions are being reused. */

        JIndex = theEmbedding->edgeOffset + 2*JPos;
        JTwin = gp_GetTwinArc(theEmbedding, JIndex);

        if (theEmbedding->G[JIndex].visited || theEmbedding->G[JTwin].visited)
            return NOTOK;

        theEmbedding->G[JIndex].visited = theEmbedding->G[JTwin].visited = 1;
    }

/* Test whether any edge intersects any vertex position
    for a vertex that is not an endpoint of the edge. */

    for (e = 0; e < theEmbedding->M; e++)
    {
        J = theEmbedding->edgeOffset + 2*e;
        JTwin = gp_GetTwinArc(theEmbedding, J);

        for (I = 0; I < theEmbedding->N; I++)
        {
            /* If the vertex is an endpoint of the edge, then... */

            if (theEmbedding->G[J].v == I || theEmbedding->G[JTwin].v == I)
            {
                /* The vertical position of the vertex must be
                   at the top or bottom of the edge,  */
                if (context->G[J].start != context->G[I].pos &&
                    context->G[J].end != context->G[I].pos)
                    return NOTOK;

                /* The horizontal edge position must be in the range of the vertex */
                if (context->G[J].pos < context->G[I].start ||
                    context->G[J].pos > context->G[I].end)
                    return NOTOK;
            }

            /* If the vertex is not an endpoint of the edge... */

            else // if (theEmbedding->G[J].v != I && theEmbedding->G[JTwin].v != I)
            {
                /* If the vertical position of the vertex is in the
                    vertical range of the edge ... */

                if (context->G[J].start <= context->G[I].pos &&
                    context->G[J].end >= context->G[I].pos)
                {
                    /* And if the horizontal position of the edge is in the
                        horizontal range of the vertex, then return an error. */

                    if (context->G[I].start <= context->G[J].pos &&
                        context->G[I].end >= context->G[J].pos)
                        return NOTOK;
                }
            }
        }
    }

/* All tests passed */

    return OK;
}
Ejemplo n.º 5
0
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;
}