Beispiel #1
0
int  _MarkPathAlongBicompExtFace(graphP theGraph, int startVert, int endVert)
{
    int  Z, ZPrevLink, ZPrevArc;

    /* Mark the start vertex (and if it is a root copy, mark the parent copy too. */

    gp_SetVertexVisited(theGraph, startVert);

    /* For each vertex visited after the start vertex, mark the vertex and the
            edge used to get there.  Stop after marking the ending vertex. */

    Z = startVert;
    ZPrevLink = 1;
    do {
        Z = _GetNeighborOnExtFace(theGraph, Z, &ZPrevLink);

        ZPrevArc = gp_GetArc(theGraph, Z, ZPrevLink);

        gp_SetEdgeVisited(theGraph, ZPrevArc);
        gp_SetEdgeVisited(theGraph, gp_GetTwinArc(theGraph, ZPrevArc));
        gp_SetVertexVisited(theGraph, Z);

    } while (Z != endVert);

    return OK;
}
Beispiel #2
0
/****************************************************************************
 _MarkDFSPath()

 Sets visited flags of vertices and edges from descendant to ancestor,
 including root copy vertices, and including the step of hopping from
 a root copy to its parent copy.

 At each vertex, the edge record is obtained whose type indicates that it
 leads to the DFS parent.  An earlier implementation just used the DFS parent
 member of the vertex, but then had to find the edge to mark anyway.
 This method is more generalized because some extension algorithms reduce
 DFS paths to single DFS tree edges, in which case the edge record with type
 EDGE_TYPE_PARENT may indicate the DFS paent or an ancestor.
 ****************************************************************************/
int  _MarkDFSPath(graphP theGraph, int ancestor, int descendant)
{
    int  e, parent;

    // If we are marking from a root (virtual) vertex upward, then go up to the parent
    // copy before starting the loop
    if (gp_IsVirtualVertex(theGraph, descendant))
        descendant = gp_GetPrimaryVertexFromRoot(theGraph, descendant);

    // Mark the lowest vertex (the one with the highest number).
    gp_SetVertexVisited(theGraph, descendant);

    // Mark all ancestors of the lowest vertex, and the edges used to reach
    // them, up to the given ancestor vertex.
    while (descendant != ancestor)
    {
        if (gp_IsNotVertex(descendant))
            return NOTOK;

        // If we are at a bicomp root, then ascend to its parent copy and
        // mark it as visited.
        if (gp_IsVirtualVertex(theGraph, descendant))
        {
            parent = gp_GetPrimaryVertexFromRoot(theGraph, descendant);
        }

        // If we are on a regular, non-virtual vertex then get the edge to the parent,
        // mark the edge, then fall through to the code that marks the parent vertex.
        else
        {
            // Scan the edges for the one marked as the DFS parent
            parent = NIL;
            e = gp_GetFirstArc(theGraph, descendant);
            while (gp_IsArc(e))
            {
                if (gp_GetEdgeType(theGraph, e) == EDGE_TYPE_PARENT)
                {
                    parent = gp_GetNeighbor(theGraph, e);
                    break;
                }
                e = gp_GetNextArc(theGraph, e);
            }

            // Sanity check on the data structure integrity
            if (gp_IsNotVertex(parent))
                return NOTOK;

            // Mark the edge
            gp_SetEdgeVisited(theGraph, e);
            gp_SetEdgeVisited(theGraph, gp_GetTwinArc(theGraph, e));
        }

        // Mark the parent, then hop to the parent and reiterate
        gp_SetVertexVisited(theGraph, parent);
        descendant = parent;
    }

    return OK;
}
Beispiel #3
0
int _AddAndMarkEdge(graphP theGraph, int ancestor, int descendant)
{
    _AddBackEdge(theGraph, ancestor, descendant);

    /* Mark the edge so it is not deleted */

    gp_SetVertexVisited(theGraph, ancestor);
    gp_SetEdgeVisited(theGraph, gp_GetFirstArc(theGraph, ancestor));
    gp_SetEdgeVisited(theGraph, gp_GetFirstArc(theGraph, descendant));
    gp_SetVertexVisited(theGraph, descendant);

    return OK;
}
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;
}