void _K33Search_EmbedBackEdgeToDescendant(graphP theGraph, int RootSide, int RootVertex, int W, int WPrevLink)
{
    K33SearchContext *context = NULL;
    gp_FindExtension(theGraph, K33SEARCH_ID, (void *)&context);

    if (context != NULL)
    {
        // K33 search may have been attached, but not enabled
        if (theGraph->embedFlags == EMBEDFLAGS_SEARCHFORK33)
        {
        	// Get the fwdArc from the adjacentTo field, and use it to get the backArc
            int backArc = gp_GetTwinArc(theGraph, gp_GetVertexPertinentEdge(theGraph, W));

            // Remove the backArc from the backArcList
            if (context->VI[W].backArcList == backArc)
            {
                if (gp_GetNextArc(theGraph, backArc) == backArc)
                     context->VI[W].backArcList = NIL;
                else context->VI[W].backArcList = gp_GetNextArc(theGraph, backArc);
            }

            gp_SetNextArc(theGraph, gp_GetPrevArc(theGraph, backArc), gp_GetNextArc(theGraph, backArc));
            gp_SetPrevArc(theGraph, gp_GetNextArc(theGraph, backArc), gp_GetPrevArc(theGraph, backArc));
        }

        // Invoke the superclass version of the function
        context->functions.fpEmbedBackEdgeToDescendant(theGraph, RootSide, RootVertex, W, WPrevLink);
    }
}
Example #2
0
void _AddBackEdge(graphP theGraph, int ancestor, int descendant)
{
int fwdArc, backArc;

    /* We get the two edge records of the back edge to embed. */

     fwdArc = theGraph->V[ancestor].fwdArcList;
     while (gp_IsArc(theGraph, fwdArc))
     {
          if (theGraph->G[fwdArc].v == descendant)
              break;

          fwdArc = gp_GetNextArc(theGraph, fwdArc);
          if (fwdArc == theGraph->V[ancestor].fwdArcList)
              fwdArc = NIL;
     }

     if (fwdArc == NIL)
         return;

    backArc = gp_GetTwinArc(theGraph, fwdArc);

    /* The forward arc is removed from the fwdArcList of the ancestor. */
    if (theGraph->V[ancestor].fwdArcList == fwdArc)
    {
        if (gp_GetNextArc(theGraph, fwdArc) == fwdArc)
             theGraph->V[ancestor].fwdArcList = NIL;
        else theGraph->V[ancestor].fwdArcList = gp_GetNextArc(theGraph, fwdArc);
    }

    gp_SetNextArc(theGraph, gp_GetPrevArc(theGraph, fwdArc), gp_GetNextArc(theGraph, fwdArc));
    gp_SetPrevArc(theGraph, gp_GetNextArc(theGraph, fwdArc), gp_GetPrevArc(theGraph, fwdArc));

    /* The forward arc is added to the adjacency list of the ancestor. */
    gp_SetPrevArc(theGraph, fwdArc, gp_AdjacencyListEndMark(ancestor));
    gp_SetNextArc(theGraph, fwdArc, gp_GetFirstArc(theGraph, ancestor));
    gp_SetPrevArc(theGraph, gp_GetFirstArc(theGraph, ancestor), fwdArc);
    gp_SetFirstArc(theGraph, ancestor, fwdArc);

    /* The back arc is added to the adjacency list of the descendant. */
    gp_SetPrevArc(theGraph, backArc, gp_AdjacencyListEndMark(descendant));
    gp_SetNextArc(theGraph, backArc, gp_GetFirstArc(theGraph, descendant));
    gp_SetPrevArc(theGraph, gp_GetFirstArc(theGraph, descendant), backArc);
    gp_SetFirstArc(theGraph, descendant, backArc);

    theGraph->G[backArc].v = ancestor;
}
Example #3
0
void _AddBackEdge(graphP theGraph, int ancestor, int descendant)
{
    int fwdArc, backArc;

    /* We get the two edge records of the back edge to embed. */

    fwdArc = gp_GetVertexFwdArcList(theGraph, ancestor);
    while (gp_IsArc(fwdArc))
    {
        if (gp_GetNeighbor(theGraph, fwdArc) == descendant)
            break;

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

    if (gp_IsNotArc(fwdArc))
        return;

    backArc = gp_GetTwinArc(theGraph, fwdArc);

    /* The forward arc is removed from the fwdArcList of the ancestor. */
    if (gp_GetVertexFwdArcList(theGraph, ancestor) == fwdArc)
    {
        if (gp_GetNextArc(theGraph, fwdArc) == fwdArc)
            gp_SetVertexFwdArcList(theGraph, ancestor, NIL);
        else gp_SetVertexFwdArcList(theGraph, ancestor, gp_GetNextArc(theGraph, fwdArc));
    }

    gp_SetNextArc(theGraph, gp_GetPrevArc(theGraph, fwdArc), gp_GetNextArc(theGraph, fwdArc));
    gp_SetPrevArc(theGraph, gp_GetNextArc(theGraph, fwdArc), gp_GetPrevArc(theGraph, fwdArc));

    /* The forward arc is added to the adjacency list of the ancestor. */
    gp_SetPrevArc(theGraph, fwdArc, NIL);
    gp_SetNextArc(theGraph, fwdArc, gp_GetFirstArc(theGraph, ancestor));
    gp_SetPrevArc(theGraph, gp_GetFirstArc(theGraph, ancestor), fwdArc);
    gp_SetFirstArc(theGraph, ancestor, fwdArc);

    /* The back arc is added to the adjacency list of the descendant. */
    gp_SetPrevArc(theGraph, backArc, NIL);
    gp_SetNextArc(theGraph, backArc, gp_GetFirstArc(theGraph, descendant));
    gp_SetPrevArc(theGraph, gp_GetFirstArc(theGraph, descendant), backArc);
    gp_SetFirstArc(theGraph, descendant, backArc);

    gp_SetNeighbor(theGraph, backArc, ancestor);
}
/********************************************************************
 _CreateBackArcLists()
 ********************************************************************/
void _CreateBackArcLists(graphP theGraph, K33SearchContext *context)
{
	int v, e, eTwin, ancestor;

	for (v = gp_GetFirstVertex(theGraph); gp_VertexInRange(theGraph, v); v++)
    {
    	e = gp_GetVertexFwdArcList(theGraph, v);
        while (gp_IsArc(e))
        {
        	// Get the ancestor endpoint and the associated back arc
        	ancestor = gp_GetNeighbor(theGraph, e);
        	eTwin = gp_GetTwinArc(theGraph, e);

        	// Put it into the back arc list of the ancestor
            if (gp_IsNotArc(context->VI[ancestor].backArcList))
            {
                context->VI[ancestor].backArcList = eTwin;
                gp_SetPrevArc(theGraph, eTwin, eTwin);
                gp_SetNextArc(theGraph, eTwin, eTwin);
            }
            else
            {
            	int eHead = context->VI[ancestor].backArcList;
            	int eTail = gp_GetPrevArc(theGraph, eHead);
        		gp_SetPrevArc(theGraph, eTwin, eTail);
        		gp_SetNextArc(theGraph, eTwin, eHead);
        		gp_SetPrevArc(theGraph, eHead, eTwin);
        		gp_SetNextArc(theGraph, eTail, eTwin);
            }

        	// Advance to the next forward edge
			e = gp_GetNextArc(theGraph, e);
			if (e == gp_GetVertexFwdArcList(theGraph, v))
				e = NIL;
        }
    }
}
Example #5
0
int  _ReadAdjList(graphP theGraph, FILE *Infile)
{
int N, I, W, ErrorCode, adjList, J;

     if (Infile == NULL) return NOTOK;
     fgetc(Infile);                             /* Skip the N= */
     fgetc(Infile);
     fscanf(Infile, " %d ", &N);                /* Read N */
     if (gp_InitGraph(theGraph, N) != OK)
     {
    	  printf("Failed to init graph");
          return NOTOK;
     }

     // Clear the visited members of the vertices so they can be used
     // during the adjacency list read operation
     for (I=0; I < N; I++)
          theGraph->G[I].visited = 0;

     // Do the adjacency list read operation for each vertex in order
     for (I = 0, ErrorCode = OK; I < N && ErrorCode==OK; I++)
     {
          // Read the vertex number
          fscanf(Infile, "%d", &theGraph->G[I].v);

          // The vertices are expected to be in numeric ascending order
          if (theGraph->G[I].v != I)
        	  return NOTOK;

          // Skip the colon after the vertex number
          fgetc(Infile);

          // If the vertex already has a non-empty adjacency list, then it is
          // the result of adding edges during processing of preceding vertices.
          // The list is removed from the current vertex I and saved for use
          // during the read operation for I.  Adjacencies to preceding vertices
          // are pulled from this list, if present, or added as directed edges
          // if not.  Adjacencies to succeeding vertices are added as undirected
          // edges, and will be corrected later if the succeeding vertex does not
          // have the matching adjacency using the following mechanism.  After the
          // read operation for a vertex I, any adjacency nodes left in the saved
          // list are converted to directed edges from the preceding vertex to I.
          adjList = gp_GetFirstArc(theGraph, I);
          if (gp_IsArc(theGraph, adjList))
          {
        	  // Store the adjacency node location in the visited member of each
        	  // of the preceding vertices to which I is adjacent so that we can
        	  // efficiently detect the adjacency during the read operation and
        	  // efficiently find the adjacency node.
        	  J = gp_GetFirstArc(theGraph, I);
			  while (gp_IsArc(theGraph, J))
			  {
				  theGraph->G[theGraph->G[J].v].visited = J;
				  J = gp_GetNextArc(theGraph, J);
			  }

        	  // Make the adjacency list circular, for later ease of processing
			  gp_SetPrevArc(theGraph, adjList, gp_GetLastArc(theGraph, I));
			  gp_SetNextArc(theGraph, gp_GetLastArc(theGraph, I), adjList);

        	  // Remove the list from the vertex
			  gp_SetFirstArc(theGraph, I, gp_AdjacencyListEndMark(I));
			  gp_SetLastArc(theGraph, I, gp_AdjacencyListEndMark(I));
          }

          // Read the adjacency list.
          while (1)
          {
        	 // Read the next adjacent vertex, with NIL indicating the list end
             fscanf(Infile, " %d ", &W);
             if (W < 0) break;

             // Vertex numbers must be less than N
             if (W >= N)
                  ErrorCode = NOTOK;

             // Loop edges are not supported, but no reason to throw an error if they occur
             // If a loop occurs, we just do like the ostrich and ignore it
             else if (W == I)
            	 ErrorCode = OK;

             // If the adjacency is to a succeeding, higher numbered vertex,
             // then we'll add an undirected edge for now
             else if (I < W)
             {
             	 ErrorCode = gp_AddEdge(theGraph, I, 0, W, 0);
             }

             // If the adjacency is to a preceding, lower numbered vertex, then
             // we have to pull the adjacency node from the preexisting adjList,
             // if it is there, and if not then we have to add a directed edge.
             else
             {
            	 // If the adjacency node (arc) already exists, then we add it
            	 // as the new first arc of the vertex and delete it from adjList
            	 if (theGraph->G[W].visited)
            	 {
            		 J = theGraph->G[W].visited;

            		 // Remove the arc J from the adjList construct
            		 theGraph->G[W].visited = 0;
            		 if (adjList == J)
            		 {
            			 if ((adjList = gp_GetNextArc(theGraph, J)) == J)
            				 adjList = NIL;
            		 }
            		 gp_SetPrevArc(theGraph, gp_GetNextArc(theGraph, J), gp_GetPrevArc(theGraph, J));
            		 gp_SetNextArc(theGraph, gp_GetPrevArc(theGraph, J), gp_GetNextArc(theGraph, J));

            		 gp_AttachFirstArc(theGraph, I, J);
            	 }

            	 // If an adjacency node to the lower numbered vertex W does not
            	 // already exist, then we make a new directed arc from the current
            	 // vertex I to W.
            	 else
            	 {
            		 // It is added as the new first arc in both vertices
                	 ErrorCode = gp_AddEdge(theGraph, I, 0, W, 0);
                	 if (ErrorCode == OK)
                		 // Note that this call also sets OUTONLY on the twin arc
                		 gp_SetDirection(theGraph, gp_GetFirstArc(theGraph, W), EDGEFLAG_DIRECTION_INONLY);
            	 }
             }

             if (ErrorCode != OK) break;
          }

          // If there are still adjList entries after the read operation
          // then those entries are not representative of full undirected edges.
          // Rather, they represent incoming directed arcs from other vertices
          // into vertex I. They need to be added back into I's adjacency list but
          // marked as "INONLY", while the twin is marked "OUTONLY" (by the same function).
          while (gp_IsArc(theGraph, adjList))
          {
        	  J = adjList;

			  theGraph->G[theGraph->G[J].v].visited = 0;

 			  if ((adjList = gp_GetNextArc(theGraph, J)) == J)
 				  adjList = NIL;

     		  gp_SetPrevArc(theGraph, gp_GetNextArc(theGraph, J), gp_GetPrevArc(theGraph, J));
     		  gp_SetNextArc(theGraph, gp_GetPrevArc(theGraph, J), gp_GetNextArc(theGraph, J));

     		  gp_AttachFirstArc(theGraph, I, J);
     		  gp_SetDirection(theGraph, J, EDGEFLAG_DIRECTION_INONLY);
          }
     }

     return ErrorCode;
}
int _K33Search_CreateFwdArcLists(graphP theGraph)
{
    K33SearchContext *context = NULL;

    gp_FindExtension(theGraph, K33SEARCH_ID, (void *)&context);
    if (context == NULL)
        return NOTOK;

    // For isolating a K_{3,3} homeomorph, we need the forward edges
    // of each vertex to be in sorted order by DFI of descendants.
    // Otherwise we just drop through to the normal processing...

    if (theGraph->embedFlags == EMBEDFLAGS_SEARCHFORK33)
    {
    int I, Jcur, Jnext, ancestor;

        // for each vertex v in order, we follow each of its back edges
        // to the twin forward edge in an ancestor u, then we move
        // the forward edge to the fwdArcList of u.  Since this loop
        // processes vertices in order, the fwdArcList of each vertex
        // will be in order by the neighbor indicated by the forward edges.

        for (I=0; I < theGraph->N; I++)
        {
        	// Skip this vertex if it has no edges
        	Jnext = gp_GetLastArc(theGraph, I);
        	if (!gp_IsArc(theGraph, Jnext))
        		continue;

            // Skip the forward edges, which are in succession at the
        	// end of the arc list (last and its predecessors)
            while (theGraph->G[Jnext].type == EDGE_FORWARD)
                Jnext = gp_GetPrevArc(theGraph, Jnext);

            // Now we want to put all the back arcs in a backArcList, too.
            // Since we've already skipped past the forward arcs, we continue
            // with the predecessor arcs until we either run out of arcs or
            // we find a DFS child arc (the DFS child arcs are in succession
            // at the beginning of the arc list, so when a child arc is
            // encountered in the predecessor direction, then there won't be
            // any more back arcs.
            while (gp_IsArc(theGraph, Jnext) &&
                   theGraph->G[Jnext].type != EDGE_DFSCHILD)
            {
                Jcur = Jnext;
                Jnext = gp_GetPrevArc(theGraph, Jnext);

                if (theGraph->G[Jcur].type == EDGE_BACK)
                {
                    // Remove the back arc from I's adjacency list
                	gp_DetachArc(theGraph, Jcur);

                    // Put the back arc in the backArcList
                    if (context->V[I].backArcList == NIL)
                    {
                        context->V[I].backArcList = Jcur;
                        gp_SetPrevArc(theGraph, Jcur, Jcur);
                        gp_SetNextArc(theGraph, Jcur, Jcur);
                    }
                    else
                    {
                    	gp_AttachArc(theGraph, NIL, context->V[I].backArcList, 1, Jcur);
                    }

                    // Determine the ancestor of vertex I to which Jcur connects
                    ancestor = theGraph->G[Jcur].v;

                    // Go to the forward arc in the ancestor
                    Jcur = gp_GetTwinArc(theGraph, Jcur);

                    // Remove the forward arc from the ancestor's adjacency list
                	gp_DetachArc(theGraph, Jcur);

                    // Add the forward arc to the end of the fwdArcList.
                    if (theGraph->V[ancestor].fwdArcList == NIL)
                    {
                        theGraph->V[ancestor].fwdArcList = Jcur;
                        gp_SetPrevArc(theGraph, Jcur, Jcur);
                        gp_SetNextArc(theGraph, Jcur, Jcur);
                    }
                    else
                    {
                    	gp_AttachArc(theGraph, NIL, theGraph->V[ancestor].fwdArcList, 1, Jcur);
                    }
                }
            }
        }

        // Since the fwdArcLists have been created, we do not fall through
        // to run the superclass implementation
        return OK;
    }

    // If we're not actually running a K3,3 search, then we just run the
    // superclass implementation
    return context->functions.fpCreateFwdArcLists(theGraph);
}