void AddEdgeToInstance(ULONG edgeIndex, Edge *edge, Instance *instance2)
{
   Instance *instance1;

   // convert edge to instance
   if (edge->vertex1 == edge->vertex2) 
   { // self-edge
      instance1 = AllocateInstance(1, 1);
      instance1->vertices[0] = edge->vertex1;
   } 
   else 
   {
      instance1 = AllocateInstance(2, 1);
      if (edge->vertex1 < edge->vertex2) 
      {
         instance1->vertices[0] = edge->vertex1;
         instance1->vertices[1] = edge->vertex2;
      } 
      else 
      {
         instance1->vertices[0] = edge->vertex2;
         instance1->vertices[1] = edge->vertex1;
      }
   }
   instance1->edges[0] = edgeIndex;
   AddInstanceToInstance(instance1, instance2);
   FreeInstance(instance1);
}
Exemple #2
0
Instance *CreateGraphRefInstance(Instance *instance1, ReferenceGraph *refGraph) 
{
   int i;
   Instance *instance2 =
      AllocateInstance(instance1->numVertices, instance1->numEdges);

   for(i=0;i<instance1->numVertices;i++)
   {
      // assign the vertices to the full graph
      instance2->vertices[i] = refGraph->vertices[instance1->vertices[i]].map;
   }

   // reorder indices based on the vertices in the full graph
   SortIndices(instance2->vertices, 0, instance2->numVertices-1);

   for(i=0;i<instance1->numEdges;i++)
   {
      // assign the vertices to the full graph
      instance2->edges[i] = refGraph->edges[instance1->edges[i]].map;
   }

   // reorder indices based on the vertices in the full graph
   SortIndices(instance2->edges, 0, instance2->numEdges-1);

   return instance2;
}
Exemple #3
0
Instance *CopyInstance(Instance *instance)
{
   Instance *newInstance;
   ULONG i;

   newInstance = AllocateInstance(instance->numVertices, instance->numEdges);
   for (i = 0; i < instance->numVertices; i++)
      newInstance->vertices[i] = instance->vertices[i];
   for (i = 0; i < instance->numEdges; i++)
      newInstance->edges[i] = instance->edges[i];

   return newInstance;	
}
void AddRecursiveInstancePair(ULONG i1, ULONG i2,
                              Instance *instance1, Instance *instance2,
                              ULONG edgeIndex, Edge *edge,
                              ULONG numInstances, Instance **instanceMap)
{
   Instance *tmpInstance = NULL;
   ULONG i;

   if ((instanceMap[i1] == instance1) && (instanceMap[i2] == instance2)) 
   {
      // instances not yet linked to a new recursive instance
      tmpInstance = AllocateInstance(0, 0);
      AddInstanceToInstance(instance1, tmpInstance);
      AddInstanceToInstance(instance2, tmpInstance);
      AddEdgeToInstance(edgeIndex, edge, tmpInstance);
      instanceMap[i1] = tmpInstance;
      instanceMap[i2] = tmpInstance;
   } 
   else if (instanceMap[i1] == instance1) 
   {
      // instance1 to be linked to new instance at instanceMap[i2]
      AddInstanceToInstance(instance1, instanceMap[i2]);
      AddEdgeToInstance(edgeIndex, edge, instanceMap[i2]);
      instanceMap[i1] = instanceMap[i2];
   } 
   else if (instanceMap[i2] == instance2) 
   {
      // instance2 to be linked to new instance at instanceMap[i1]
      AddInstanceToInstance(instance2, instanceMap[i1]);
      AddEdgeToInstance(edgeIndex, edge, instanceMap[i1]);
      instanceMap[i2] = instanceMap[i1];
   } 
   else if (instanceMap[i1] != instanceMap[i2]) 
   {
      // both instances already belong to new different recursive instances
      AddInstanceToInstance(instanceMap[i2], instanceMap[i1]);
      AddEdgeToInstance(edgeIndex, edge, instanceMap[i1]);
      tmpInstance = instanceMap[i2];
      for (i = 0; i < numInstances; i++)
         if (instanceMap[i] == tmpInstance)
      instanceMap[i] = instanceMap[i1];
      FreeInstance(tmpInstance);
   } 
   else 
   {
      // both instances already in same new recursive instance
      AddEdgeToInstance(edgeIndex, edge, instanceMap[i1]);
   }
}
Exemple #5
0
InstanceList *FindSingleVertexInstances(Graph *graph, Vertex *vertex,
                                        Parameters *parameters)
{
   ULONG v;
   InstanceList *instanceList;
   Instance *instance;

   instanceList = AllocateInstanceList();
   for (v = 0; v < graph->numVertices; v++) 
   {
      if (graph->vertices[v].label == vertex->label) 
      {
         // ***** do inexact label matches here? (instance->minMatchCost too)
         instance = AllocateInstance(1, 0);
         instance->vertices[0] = v;
         instance->minMatchCost = 0.0;
         InstanceListInsert(instance, instanceList, FALSE);
      }
   }
   return instanceList;
}
Exemple #6
0
SubList *GetInitialSubs(Parameters *parameters)
{
   SubList *initialSubs;
   ULONG i, j;
   ULONG vertexLabelIndex;
   ULONG numInitialSubs;
   Graph *g;
   Substructure *sub;
   Instance *instance;

   // parameters used
   Graph *posGraph      = parameters->posGraph;
   Graph *negGraph      = parameters->negGraph;
   LabelList *labelList = parameters->labelList;
   ULONG outputLevel    = parameters->outputLevel;
   ULONG currentIncrement = 0;
   ULONG startVertexIndex;

   if (parameters->incremental)
   {
      currentIncrement = GetCurrentIncrementNum(parameters);
      // Index for first vertex in increment
      // Begin with the index for the first vertex in this increment and
      // move up through all remaining vertices.  Relies on the fact that
      // each new increment is placed on the end of the vertex array and that
      // we are only interested in the current (last) increment
      startVertexIndex = GetStartVertexIndex(currentIncrement, parameters, POS);
      if (parameters->outputLevel > 2)
         printf("Start vertex index = %lu\n", startVertexIndex);
   }
   else 
      startVertexIndex = 0;

   // reset labels' used flag
   for (i = 0; i < labelList->numLabels; i++)
      labelList->labels[i].used = FALSE;
  
   numInitialSubs = 0;
   initialSubs = AllocateSubList();
   for (i = startVertexIndex; i < posGraph->numVertices; i++)
   {
	  posGraph->vertices[i].TimesAddedToInstanceList = 0;
      vertexLabelIndex = posGraph->vertices[i].label;
      if (labelList->labels[vertexLabelIndex].used == FALSE) 
      {
         labelList->labels[vertexLabelIndex].used = TRUE;

         // create one-vertex substructure definition
         g = AllocateGraph(1, 0);
         g->vertices[0].label = vertexLabelIndex;
         g->vertices[0].numEdges = 0;
         g->vertices[0].edges = NULL;
		  g->vertices[0].TimesAddedToInstanceList = 0;
         // allocate substructure
         sub = AllocateSub();
         sub->definition = g;
         sub->instances = AllocateInstanceList();
         // collect instances in positive graph
         j = posGraph->numVertices;
         do 
         {
            j--;
            if (posGraph->vertices[j].label == vertexLabelIndex) 
            {
               // ***** do inexact label matches here? (instance->minMatchCost
               // ***** too)
               instance = AllocateInstance(1, 0);
               instance->vertices[0] = j;
               instance->mapping[0].v1 = 0;
               instance->mapping[0].v2 = j;
               instance->minMatchCost = 0.0;
               InstanceListInsert(instance, sub->instances, FALSE);
               sub->numInstances++;
            }
         } while (j > i);

         // only keep substructure if more than one positive instance
         if (sub->numInstances > 1) 
         {
            if (negGraph != NULL) 
            {
               // collect instances in negative graph
               sub->negInstances = AllocateInstanceList();
               j = negGraph->numVertices;
               if (parameters->incremental)
                  startVertexIndex =
                     GetStartVertexIndex(currentIncrement, parameters, POS);
               else 
                  startVertexIndex = 0;
               do 
               {
                  j--;
                  if (negGraph->vertices[j].label == vertexLabelIndex) 
                  {
                     // ***** do inexact label matches here? 
                     // ***** (instance->minMatchCost too)
                     instance = AllocateInstance(1, 0);
                     instance->vertices[0] = j;
                     instance->mapping[0].v1 = 0;
                     instance->mapping[0].v2 = j;
                     instance->minMatchCost = 0.0;
                     InstanceListInsert(instance, sub->negInstances, FALSE);
                     sub->numNegInstances++;
                  }
                              // We need to try all negative graph labels
               } while (j > startVertexIndex);
            }
            EvaluateSub(sub, parameters);
            // add to initialSubs
            SubListInsert(sub, initialSubs, 0, FALSE, labelList);
            numInitialSubs++;
         } 
         else 
         { // prune single-instance substructure
            FreeSub(sub);
         }
      }
   }
   if (outputLevel > 1)
      printf("%lu initial substructures\n", numInitialSubs);

   return initialSubs;
}
Instance *CreateExtendedInstance(Instance *instance, ULONG v, ULONG e,
                                 Graph *graph)
{
   Instance *newInstance;
   ULONG v2;
   BOOLEAN found = FALSE;
   ULONG i;

   // get edge's other vertex
   if (graph->edges[e].vertex1 == v)
      v2 = graph->edges[e].vertex2;
   else 
      v2 = graph->edges[e].vertex1;

   // check if edge's other vertex is already in instance
   for (i = 0; ((i < instance->numVertices) && (! found)); i++)
      if (instance->vertices[i] == v2)
         found = TRUE;

   // allocate memory for new instance
   if (! found)
      newInstance = AllocateInstance(instance->numVertices + 1,
                                     instance->numEdges + 1);
   else 
      newInstance = AllocateInstance(instance->numVertices,
                                     instance->numEdges + 1);

   // save pointer to what the instance was before this
   // extension (to be used as the "parent mapping")
   newInstance->parentInstance = instance;

   // set vertices and mappings of new instance
   for (i = 0; i < instance->numVertices; i++)
   {
      // copy vertices
      newInstance->vertices[i] = instance->vertices[i];

      // copy mapping
      newInstance->mapping[i].v1 = instance->mapping[i].v1;
      newInstance->mapping[i].v2 = instance->mapping[i].v2;

      // set indices to indicate indices to source and target vertices
      if (newInstance->mapping[i].v2 == graph->edges[e].vertex2)
         newInstance->mappingIndex2 = i;
      if (newInstance->mapping[i].v2 == graph->edges[e].vertex1)
         newInstance->mappingIndex1 = i;
   }

   newInstance->newVertex = VERTEX_UNMAPPED;
   if (! found) 
   {
      i = instance->numVertices;
      while ((i > 0) && (v2 < newInstance->vertices[i-1])) 
      {
         newInstance->vertices[i] = newInstance->vertices[i-1];
         newInstance->mapping[i].v1 = i;
         newInstance->mapping[i].v2 = newInstance->mapping[i-1].v2;
         // if indices moved, move mapping indices
         if (newInstance->mapping[i].v2 == graph->edges[e].vertex2)
            newInstance->mappingIndex2 = i;
         if (newInstance->mapping[i].v2 == graph->edges[e].vertex1)
            newInstance->mappingIndex1 = i;
         i--;
      }
      newInstance->vertices[i] = v2;
      newInstance->newVertex = i;
      newInstance->mapping[i].v1 = i;
      newInstance->mapping[i].v2 = v2;
      // Since this is a new vertex, need to update the index
      if (newInstance->mapping[i].v2 == graph->edges[e].vertex2)
         newInstance->mappingIndex2 = i;
      if (newInstance->mapping[i].v2 == graph->edges[e].vertex1)
         newInstance->mappingIndex1 = i;
   }

   // set edges of new instance, kept in increasing order
   for (i = 0; i < instance->numEdges; i++)
      newInstance->edges[i] = instance->edges[i];
   i = instance->numEdges;
   while ((i > 0) && (e < newInstance->edges[i-1])) 
   {
      newInstance->edges[i] = newInstance->edges[i-1];
      i--;
   }
   newInstance->edges[i] = e;
   newInstance->newEdge = i;

   return newInstance;
}