コード例 #1
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);
		  }
     }
}
コード例 #2
0
ファイル: listcoll.c プロジェクト: bdiri/planarity-1
int  LCPrepend(listCollectionP listColl, int theList, int theNode)
{
     /* If the append worked, then theNode is last, which in a circular
        list is the direct predecessor of the list head node, so we
        just back up one. For singletons, the result is unchanged. */

     return listColl->List[LCAppend(listColl, theList, theNode)].prev;
}
コード例 #3
0
ファイル: graphColorVertices.c プロジェクト: sageb0t/testsage
void _AddVertexToDegList(ColorVerticesContext *context, graphP theGraph, int v, int deg)
{
	if (deg > 0)
	{
		if (_IsConstantTimeContractible(context, v))
			context->degListHeads[deg] = LCPrepend(context->degLists, context->degListHeads[deg], v);
		else
			context->degListHeads[deg] = LCAppend(context->degLists, context->degListHeads[deg], v);

        context->numVerticesToReduce++;
	}
	context->degree[v] = deg;
}
コード例 #4
0
ファイル: graphDrawPlanar.c プロジェクト: sageb0t/testsage
int _ComputeEdgePositions(DrawPlanarContext *context)
{
graphP theEmbedding = context->theGraph;
int *vertexOrder = NULL;
listCollectionP edgeList = NULL;
int edgeListHead, edgeListInsertPoint;
int I, J, Jcur, e, v, vpos;
int eIndex, JTwin;

	gp_LogLine("\ngraphDrawPlanar.c/_ComputeEdgePositions() start");

    // Sort the vertices by vertical position (in linear time)

    if ((vertexOrder = (int *) malloc(theEmbedding->N * sizeof(int))) == NULL)
        return NOTOK;

    for (I = 0; I < theEmbedding->N; I++)
        vertexOrder[context->G[I].pos] = I;

    // Allocate the edge list of size M.
    //    This is an array of (prev, next) pointers.
    //    An edge at position X corresponds to the edge
    //    at position X in the graph structure, which is
    //    represented by a pair of adjacent graph nodes
    //    starting at index 2N + 2X.

    if (theEmbedding->M > 0 && (edgeList = LCNew(theEmbedding->M)) == NULL)
    {
        free(vertexOrder);
        return NOTOK;
    }

    edgeListHead = NIL;

    // Each vertex starts out with a NIL generator edge.

    for (I=0; I < theEmbedding->N; I++)
        theEmbedding->G[I].visited = NIL;

    // Perform the vertical sweep of the combinatorial embedding, using
    // the vertex ordering to guide the sweep.
    // For each vertex, each edge leading to a vertex with a higher number in
    // the vertex order is recorded as the "generator edge", or the edge of
    // first discovery of that higher numbered vertex, unless the vertex already has
    // a recorded generator edge
    for (vpos=0; vpos < theEmbedding->N; vpos++)
    {
        // Get the vertex associated with the position
        v = vertexOrder[vpos];
        gp_LogLine(gp_MakeLogStr3("Processing vertex %d with DFI=%d at position=%d",
    				 theEmbedding->G[v].v, v, vpos));

        // The DFS tree root of a connected component is always the least
        // number vertex in the vertex ordering.  We have to give it a
        // false generator edge so that it is still "visited" and then
        // all of its edges are generators for its neighbor vertices because
        // they all have greater numbers in the vertex order.
        if (theEmbedding->V[v].DFSParent == NIL)
        {
            // False generator edge, so the vertex is distinguishable from
            // a vertex with no generator edge when its neighbors are visited
            // This way, an edge from a neighbor won't get recorded as the
            // generator edge of the DFS tree root.
            theEmbedding->G[v].visited = 1;

            // Now we traverse the adjacency list of the DFS tree root and
            // record each edge as the generator edge of the neighbors
            J = gp_GetFirstArc(theEmbedding, v);
            while (gp_IsArc(theGraph, J))
            {
                e = (J - theEmbedding->edgeOffset) / 2;

                edgeListHead = LCAppend(edgeList, edgeListHead, e);
                gp_LogLine(gp_MakeLogStr2("Append generator edge (%d, %d) to edgeList",
                		theEmbedding->G[v].v, theEmbedding->G[theEmbedding->G[J].v].v));

                // Set the generator edge for the root's neighbor
                theEmbedding->G[theEmbedding->G[J].v].visited = J;

                // Go to the next node of the root's adj list
                J = gp_GetNextArc(theEmbedding, J);
            }
        }

        // Else, if we are not on a DFS tree root...
        else
        {
            // Get the generator edge of the vertex
            if ((JTwin = theEmbedding->G[v].visited) == NIL)
                return NOTOK;
            J = gp_GetTwinArc(theEmbedding, JTwin);

            // Traverse the edges of the vertex, starting
            // from the generator edge and going counterclockwise...

            e = (J - theEmbedding->edgeOffset) / 2;
            edgeListInsertPoint = e;

            Jcur = gp_GetNextArcCircular(theEmbedding, J);

            while (Jcur != J)
            {
                // If the neighboring vertex's position is greater
                // than the current vertex (meaning it is lower in the
                // diagram), then add that edge to the edge order.

                if (context->G[theEmbedding->G[Jcur].v].pos > vpos)
                {
                    e = (Jcur - theEmbedding->edgeOffset) / 2;
                    LCInsertAfter(edgeList, edgeListInsertPoint, e);

                    gp_LogLine(gp_MakeLogStr4("Insert (%d, %d) after (%d, %d)",
                    		theEmbedding->G[v].v,
                    		theEmbedding->G[theEmbedding->G[Jcur].v].v,
                    		theEmbedding->G[theEmbedding->G[gp_GetTwinArc(theEmbedding, J)].v].v,
                    		theEmbedding->G[theEmbedding->G[J].v].v));

                    edgeListInsertPoint = e;

                    // If the vertex does not yet have a generator edge, then set it.
                    if (theEmbedding->G[theEmbedding->G[Jcur].v].visited == NIL)
                    {
                        theEmbedding->G[theEmbedding->G[Jcur].v].visited = Jcur;
                        gp_LogLine(gp_MakeLogStr2("Generator edge (%d, %d)",
                        		theEmbedding->G[theEmbedding->G[gp_GetTwinArc(theEmbedding, J)].v].v,
                        		theEmbedding->G[theEmbedding->G[Jcur].v].v));
                    }
                }

                // Go to the next node in v's adjacency list
                Jcur = gp_GetNextArcCircular(theEmbedding, Jcur);
            }
        }

#ifdef LOGGING
        _LogEdgeList(theEmbedding, edgeList, edgeListHead);
#endif
    }

    // Now iterate through the edgeList and assign positions to the edges.
    eIndex = 0;
    e = edgeListHead;
    while (e != NIL)
    {
        J = theEmbedding->edgeOffset + 2*e;
        JTwin = gp_GetTwinArc(theEmbedding, J);

        context->G[J].pos = context->G[JTwin].pos = eIndex;

        eIndex++;

        e = LCGetNext(edgeList, edgeListHead, e);
    }

    // Clean up and return
    LCFree(&edgeList);
    free(vertexOrder);

	gp_LogLine("graphDrawPlanar.c/_ComputeEdgePositions() end\n");

    return OK;
}
コード例 #5
0
ファイル: graphDrawPlanar.c プロジェクト: sageb0t/testsage
int _ComputeVertexPositionsInComponent(DrawPlanarContext *context, int root, int *pIndex)
{
graphP theEmbedding = context->theGraph;
listCollectionP theOrder = LCNew(theEmbedding->N);
int W, P, C, V, J;

    if (theOrder == NULL)
        return NOTOK;

    // Determine the vertex order using a depth first search with
    // pre-order visitation.

    sp_ClearStack(theEmbedding->theStack);
    sp_Push(theEmbedding->theStack, root);
    while (!sp_IsEmpty(theEmbedding->theStack))
    {
        sp_Pop(theEmbedding->theStack, W);

        P = theEmbedding->V[W].DFSParent;
        V = context->V[W].ancestor;
        C = context->V[W].ancestorChild;

        // For the special case that we just popped the DFS tree root,
        // we simply add the root to its own position.
        if (P == NIL)
        {
            // Put the DFS root in the list by itself
            LCAppend(theOrder, NIL, W);
            // The children of the DFS root have the root as their
            // ancestorChild and 'beyond' as the drawingFlag, so this
            // causes the root's children to be placed below the root
            context->V[W].drawingFlag = DRAWINGFLAG_BELOW;
        }

        // Determine vertex W position relative to P
        else
        {
            // An unresolved tie is an error
            if (context->V[W].drawingFlag == DRAWINGFLAG_TIE)
                return NOTOK;

            // If C below V, then P below V, so interpret W between
            // P and V as W above P, and interpret W beyond P relative
            // to V as W below P.
            if (context->V[C].drawingFlag == DRAWINGFLAG_BELOW)
            {
                if (context->V[W].drawingFlag == DRAWINGFLAG_BETWEEN)
                    context->V[W].drawingFlag = DRAWINGFLAG_ABOVE;
                else
                    context->V[W].drawingFlag = DRAWINGFLAG_BELOW;
            }

            // If C above V, then P above V, so interpret W between
            // P and V as W below P, and interpret W beyond P relative
            // to V as W above P.
            else
            {
                if (context->V[W].drawingFlag == DRAWINGFLAG_BETWEEN)
                    context->V[W].drawingFlag = DRAWINGFLAG_BELOW;
                else
                    context->V[W].drawingFlag = DRAWINGFLAG_ABOVE;
            }

            if (context->V[W].drawingFlag == DRAWINGFLAG_BELOW)
                LCInsertAfter(theOrder, P, W);
            else
                LCInsertBefore(theOrder, P, W);
        }

        // Push DFS children
        J = gp_GetFirstArc(theEmbedding, W);
        while (gp_IsArc(theEmbedding, J))
        {
            if (theEmbedding->G[J].type == EDGE_DFSCHILD)
                sp_Push(theEmbedding->theStack, theEmbedding->G[J].v);

            J = gp_GetNextArc(theEmbedding, J);
        }
    }

    // Use the order to assign vertical positions
    V = root;
    while (V != NIL)
    {
        context->G[V].pos = *pIndex;
        (*pIndex)++;
        V = LCGetNext(theOrder, root, V);
    }

    // Clean up and return

    LCFree(&theOrder);
    return OK;
}