コード例 #1
0
void SaveAsciiGraph(graphP theGraph, char *filename)
{
    int  e, EsizeOccupied, vertexLabelFix;
    FILE *outfile = fopen(filename, "wt");
    fprintf(outfile, "%s\n", filename);

    // This edge list file format uses 1-based vertex numbering, and the current code
    // internally uses 1-based indexing by default, so this vertex label 'fix' adds zero
    // But earlier code used 0-based indexing and added one on output, so we replicate
    // that behavior in case the current code has been compiled with zero-based indexing.
    vertexLabelFix = 1 - gp_GetFirstVertex(theGraph);

    // Iterate over the edges of the graph
    EsizeOccupied = gp_EdgeInUseIndexBound(theGraph);
    for (e = gp_GetFirstEdge(theGraph); e < EsizeOccupied; e+=2)
    {
        // Only output edges that haven't been deleted (i.e. skip the edge holes)
        if (gp_EdgeInUse(theGraph, e))
        {
            fprintf(outfile, "%d %d\n",
                    gp_GetNeighbor(theGraph, e) + vertexLabelFix,
                    gp_GetNeighbor(theGraph, e+1) + vertexLabelFix);
        }
    }

    // Since vertex numbers are at least 1, this indicates the end of the edge list
    fprintf(outfile, "0 0\n");

    fclose(outfile);
}
コード例 #2
0
int  _CheckEmbeddingFacialIntegrity(graphP theGraph)
{
stackP theStack = theGraph->theStack;
int EsizeOccupied, v, e, eTwin, eStart, eNext, NumFaces, connectedComponents;

     if (theGraph == NULL)
         return NOTOK;

/* The stack need only contain 2M entries, one for each edge record. With
        max M at 3N, this amounts to 6N integers of space.  The embedding
        structure already contains this stack, so we just make sure it
        starts out empty. */

     sp_ClearStack(theStack);

/* Push all arcs and set them to unvisited */

	 EsizeOccupied = gp_EdgeInUseIndexBound(theGraph);
     for (e = gp_GetFirstEdge(theGraph); e < EsizeOccupied; e+=2)
     {
    	  // Except skip edge holes
          if (gp_EdgeInUse(theGraph, e))
          {
			  sp_Push(theStack, e);
			  gp_ClearEdgeVisited(theGraph, e);
			  eTwin = gp_GetTwinArc(theGraph, e);
			  sp_Push(theStack, eTwin);
			  gp_ClearEdgeVisited(theGraph, eTwin);
          }
     }

     // There are M edges, so we better have pushed 2M arcs just now
     // i.e. testing that the continue above skipped only edge holes
     if (sp_GetCurrentSize(theStack) != 2*theGraph->M)
    	 return NOTOK;


/* Read faces until every arc is used */

     NumFaces = 0;
     while (sp_NonEmpty(theStack))
     {
            /* Get an arc; if it has already been used by a face, then
                don't use it to traverse a new face */
            sp_Pop(theStack, eStart);
            if (gp_GetEdgeVisited(theGraph, eStart)) continue;

            e = eStart;
            do {
                eNext = gp_GetNextArcCircular(theGraph, gp_GetTwinArc(theGraph, e));
                if (gp_GetEdgeVisited(theGraph, eNext))
                    return NOTOK;
                gp_SetEdgeVisited(theGraph, eNext);
                e = eNext;
            } while (e != eStart);
            NumFaces++;
     }

/* Count the external face once rather than once per connected component;
    each connected component is detected by the fact that it has no
    DFS parent, except in the case of isolated vertices, no face was counted
    so we do not subtract one. */

     connectedComponents = 0;
     for (v = gp_GetFirstVertex(theGraph); gp_VertexInRange(theGraph, v); v++)
     {
          if (gp_IsDFSTreeRoot(theGraph, v))
          {
              if (gp_GetVertexDegree(theGraph, v) > 0)
                  NumFaces--;
              connectedComponents++;
          }
     }

     NumFaces++;

/* Test number of faces using the extended Euler's formula.
     For connected components, Euler's formula is f=m-n+2, but
     for disconnected graphs it is extended to f=m-n+1+c where
     c is the number of connected components.*/

     return NumFaces == theGraph->M - theGraph->N + 1 + connectedComponents
            ? OK : NOTOK;
}