コード例 #1
0
ファイル: graphIsolator.c プロジェクト: nvcleemp/planarity
/****************************************************************************
 _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;
}
コード例 #2
0
ファイル: graphIsolator.c プロジェクト: nvcleemp/planarity
int  _FindUnembeddedEdgeToSubtree(graphP theGraph, int ancestor,
                                  int SubtreeRoot, int *pDescendant)
{
    int  e, Z, ZNew;

    *pDescendant = NIL;

    /* If SubtreeRoot is a root copy, then we change to the DFS child in the
            DFS tree root edge of the bicomp rooted by SubtreeRoot. */

    SubtreeRoot = gp_IsVirtualVertex(theGraph, SubtreeRoot)
                  ? gp_GetDFSChildFromRoot(theGraph, SubtreeRoot)
                  : SubtreeRoot;

    /* Find the least descendant of the cut vertex incident to the ancestor. */

    e = gp_GetVertexFwdArcList(theGraph, ancestor);
    while (gp_IsArc(e))
    {
        if (gp_GetNeighbor(theGraph, e) >= SubtreeRoot)
        {
            if (gp_IsNotVertex(*pDescendant) || *pDescendant > gp_GetNeighbor(theGraph, e))
                *pDescendant = gp_GetNeighbor(theGraph, e);
        }

        e = gp_GetNextArc(theGraph, e);
        if (e == gp_GetVertexFwdArcList(theGraph, ancestor))
            e = NIL;
    }

    if (gp_IsNotVertex(*pDescendant))
        return FALSE;

    /* Make sure the identified descendant actually descends from the cut vertex */

    Z = *pDescendant;
    while (Z != SubtreeRoot)
    {
        ZNew = gp_GetVertexParent(theGraph, Z);
        if (gp_IsNotVertex(ZNew) || ZNew == Z)
            return FALSE;
        Z = ZNew;
    }

    /* Return successfully */

    return TRUE;
}
コード例 #3
0
int  _TestSubgraph(graphP theSubgraph, graphP theGraph)
{
int v, e, degreeCount;
int Result = TRUE;
int invokeSortOnGraph = FALSE;
int invokeSortOnSubgraph = FALSE;

    // If the graph is not sorted by DFI, but the alleged subgraph is,
    // then "unsort" the alleged subgraph so both have the same vertex order
    if (!(theGraph->internalFlags & FLAGS_SORTEDBYDFI) &&
         (theSubgraph->internalFlags & FLAGS_SORTEDBYDFI))
    {
        invokeSortOnSubgraph = TRUE;
        gp_SortVertices(theSubgraph);
    }

    // If the graph is not sorted by DFI, but the alleged subgraph is,
    // then "unsort" the alleged subgraph so both have the same vertex order
    if (!(theSubgraph->internalFlags & FLAGS_SORTEDBYDFI) &&
         (theGraph->internalFlags & FLAGS_SORTEDBYDFI))
    {
        invokeSortOnGraph = TRUE;
        gp_SortVertices(theGraph);
    }

/* We clear all visitation flags */

     _ClearVertexVisitedFlags(theGraph, FALSE);

/* For each vertex... */
     for (v = gp_GetFirstVertex(theSubgraph), degreeCount = 0; gp_VertexInRange(theSubgraph, v); v++)
     {
          /* For each neighbor w in the adjacency list of vertex v in the
                subgraph, set the visited flag in w in the graph */

          e = gp_GetFirstArc(theSubgraph, v);
          while (gp_IsArc(e))
          {
        	  if (gp_IsNotVertex(gp_GetNeighbor(theSubgraph, e)))
        	  {
        		  Result = FALSE;
        		  break;
        	  }
        	  degreeCount++;
        	  gp_SetVertexVisited(theGraph, gp_GetNeighbor(theSubgraph, e));
              e = gp_GetNextArc(theSubgraph, e);
          }

          if (Result != TRUE)
        	  break;

          /* For each neighbor w in the adjacency list of vertex v in the graph,
                clear the visited flag in w in the graph */

          e = gp_GetFirstArc(theGraph, v);
          while (gp_IsArc(e))
          {
        	  if (gp_IsNotVertex(gp_GetNeighbor(theGraph, e)))
        	  {
        		  Result = FALSE;
        		  break;
        	  }
        	  gp_ClearVertexVisited(theGraph, gp_GetNeighbor(theGraph, e));
              e = gp_GetNextArc(theGraph, e);
          }

          if (Result != TRUE)
        	  break;

          /* For each neighbor w in the adjacency list of vertex v in the subgraph,
             ensure that the visited flag in w was cleared (otherwise, the "subgraph"
             would incorrectly contain an adjacency not contained in the ("super") graph) */

          e = gp_GetFirstArc(theSubgraph, v);
          while (gp_IsArc(e))
          {
              if (gp_GetVertexVisited(theGraph, gp_GetNeighbor(theSubgraph, e)))
              {
            	  Result = FALSE;
            	  break;
              }
              e = gp_GetNextArc(theSubgraph, e);
          }

          if (Result != TRUE)
        	  break;
     }

    // Restore the DFI sort order of either graph if it had to be reordered at the start
    if (invokeSortOnSubgraph)
        gp_SortVertices(theSubgraph);
    if (invokeSortOnGraph)
        gp_SortVertices(theGraph);

    // Assuming theSubgraph is a subgraph, we also do an extra integrity check to ensure
    // proper edge array utilization
    if (Result == TRUE)
    {
    	// If the edge count is wrong, we fail the subgraph test in a way that invokes
    	// the name NOTOK so that in debug mode there is more trace on the failure.
    	if (degreeCount != 2*theSubgraph->M)
    		Result = NOTOK == FALSE ? NOTOK : FALSE;
    }

     return Result;
}