/******************************************************************** _ColorVertices_CreateStructures() Create uninitialized structures for the vertex and graph node levels, and initialized structures for the graph level ********************************************************************/ int _ColorVertices_CreateStructures(ColorVerticesContext *context) { int I, N = context->theGraph->N; //int Gsize = ((graphP) theGraph)->edgeOffset + ((graphP) theGraph)->arcCapacity; if (N <= 0) return NOTOK; if ((context->degLists = LCNew(N)) == NULL || (context->degListHeads = (int *) malloc(N*sizeof(int))) == NULL || (context->degree = (int *) malloc(N*sizeof(int))) == NULL || (context->color = (int *) malloc(N*sizeof(int))) == NULL ) { return NOTOK; } for (I=0; I<N; I++) { context->degListHeads[I] = NIL; context->degree[I] = 0; context->color[I] = 0; } context->numVerticesToReduce = 0; context->highestColorUsed = -1; context->colorDetector = NULL; return OK; }
/******************************************************************** _K33Search_CreateStructures() Create uninitialized structures for the vertex and edge levels, and initialized structures for the graph level ********************************************************************/ int _K33Search_CreateStructures(K33SearchContext *context) { int VIsize = gp_PrimaryVertexIndexBound(context->theGraph); int Esize = gp_EdgeIndexBound(context->theGraph); if (context->theGraph->N <= 0) return NOTOK; if ((context->E = (K33Search_EdgeRecP) malloc(Esize*sizeof(K33Search_EdgeRec))) == NULL || (context->VI = (K33Search_VertexInfoP) malloc(VIsize*sizeof(K33Search_VertexInfo))) == NULL || (context->separatedDFSChildLists = LCNew(VIsize)) == NULL || (context->buckets = (int *) malloc(VIsize * sizeof(int))) == NULL || (context->bin = LCNew(VIsize)) == NULL ) { return NOTOK; } return OK; }
/******************************************************************** _K33Search_CreateStructures() Create uninitialized structures for the vertex and graph node levels, and initialized structures for the graph level ********************************************************************/ int _K33Search_CreateStructures(K33SearchContext *context) { int N = context->theGraph->N; int Gsize = context->theGraph->edgeOffset + context->theGraph->arcCapacity; if (N <= 0) return NOTOK; if ((context->sortedDFSChildLists = LCNew(context->theGraph->N)) == NULL || (context->G = (K33Search_GraphNodeP) malloc(Gsize*sizeof(K33Search_GraphNode))) == NULL || (context->V = (K33Search_VertexRecP) malloc(N*sizeof(K33Search_VertexRec))) == NULL ) { return NOTOK; } return OK; }
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; }
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; }