예제 #1
0
RefInstanceListNode *AllocateRefInstanceListNode()
{
   RefInstanceListNode *refInstanceListNode = malloc(sizeof(RefInstanceListNode));

   refInstanceListNode->instanceList = AllocateInstanceList();
   refInstanceListNode->refGraph = NULL;
   refInstanceListNode->next = NULL;

   return refInstanceListNode;
}
예제 #2
0
InstanceList *CollectRecursiveInstances(Instance **instanceMap,
                                        ULONG numInstances)
{
   InstanceList *recInstances;
   ULONG i, j;

   recInstances = AllocateInstanceList();
   for (i = 0; i < numInstances; i++)
      if (instanceMap[i] != NULL) 
      {
         InstanceListInsert(instanceMap[i], recInstances, FALSE);
         for (j = i + 1; j < numInstances; j++)
            if (instanceMap[j] == instanceMap[i])
               instanceMap[j] = NULL;
         instanceMap[i] = NULL;
      }
   return recInstances;
}
예제 #3
0
InstanceList *ExtendInstancesByEdge(InstanceList *instanceList,
                                    Graph *g1, Edge *edge1, Graph *g2,
                                    Parameters *parameters)
{
   InstanceList *newInstanceList;
   InstanceListNode *instanceListNode;
   Instance *instance;
   Instance *newInstance;
   ULONG v2;
   ULONG e2;
   Edge *edge2;
   Vertex *vertex2;

   newInstanceList = AllocateInstanceList();
   // extend each instance
   instanceListNode = instanceList->head;
   while (instanceListNode != NULL) 
   {
      instance = instanceListNode->instance;
      MarkInstanceEdges(instance, g2, TRUE);
      // consider extending from each vertex in instance
      for (v2 = 0; v2 < instance->numVertices; v2++) 
      {
         vertex2 = & g2->vertices[instance->vertices[v2]];
         for (e2 = 0; e2 < vertex2->numEdges; e2++) 
         {
            edge2 = & g2->edges[vertex2->edges[e2]];
            if ((! edge2->used) &&
                (EdgesMatch(g1, edge1, g2, edge2, parameters))) 
            {
               // add new instance to list
               newInstance =
                  CreateExtendedInstance(instance, instance->vertices[v2],
                                         vertex2->edges[e2], g2);
               InstanceListInsert(newInstance, newInstanceList, TRUE);
            }
         }
      }
      MarkInstanceEdges(instance, g2, FALSE);
      instanceListNode = instanceListNode->next;
   }
   FreeInstanceList(instanceList);
   return newInstanceList;
}
예제 #4
0
InstanceList *FilterInstances(Graph *subGraph, InstanceList *instanceList,
                              Graph *graph, Parameters *parameters)
{
   InstanceListNode *instanceListNode;
   Instance *instance;
   InstanceList *newInstanceList;
   Graph *instanceGraph;
   double thresholdLimit;
   double matchCost;

   newInstanceList = AllocateInstanceList();
   if (instanceList != NULL) 
   {
      instanceListNode = instanceList->head;
      while (instanceListNode != NULL) 
      {
         if (instanceListNode->instance != NULL) 
         {
            instance = instanceListNode->instance;
            if (parameters->allowInstanceOverlap ||
                (! InstanceListOverlap(instance, newInstanceList))) 
            {
               thresholdLimit = parameters->threshold *
                                (instance->numVertices + instance->numEdges);
               instanceGraph = InstanceToGraph(instance, graph);
               if (GraphMatch(subGraph, instanceGraph, parameters->labelList,
                              thresholdLimit, & matchCost, NULL)) 
               {
                  if (matchCost < instance->minMatchCost)
                     instance->minMatchCost = matchCost;
                  InstanceListInsert(instance, newInstanceList, FALSE);
               }
               FreeGraph(instanceGraph);
            }
         }
         instanceListNode = instanceListNode->next;
      }
   }
   FreeInstanceList(instanceList);
   return newInstanceList;
}
예제 #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;
}
예제 #6
0
InstanceList *ExtendInstances(InstanceList *instanceList, Graph *graph)
{
   InstanceList *newInstanceList;
   InstanceListNode *instanceListNode;
   Instance *instance;
   Instance *newInstance;
   ULONG v;
   ULONG e;
   Vertex *vertex;
   Edge *edge;

   newInstanceList = AllocateInstanceList();
   instanceListNode = instanceList->head;
   while (instanceListNode != NULL) 
   {
      instance = instanceListNode->instance;
      MarkInstanceEdges(instance, graph, TRUE);
      for (v = 0; v < instance->numVertices; v++) 
      {
         vertex = & graph->vertices[instance->vertices[v]];
         for (e = 0; e < vertex->numEdges; e++) 
         {
            edge = & graph->edges[vertex->edges[e]];
            if (! edge->used) 
            {
               // add new instance to list
               newInstance =
                  CreateExtendedInstance(instance, instance->vertices[v],
                                         vertex->edges[e], graph);
               InstanceListInsert(newInstance, newInstanceList, TRUE);
            }
         }
      }
      MarkInstanceEdges(instance, graph, FALSE);
      instanceListNode = instanceListNode->next;
   }
   return newInstanceList;
}
예제 #7
0
파일: discover.c 프로젝트: SeanToner/SUBDUE
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;
}
예제 #8
0
//---------------------------------------------------------------------------
//
// NAME: AddNegInstancesToSub
//
// INPUTS: (Substructure *sub) - substructure to collect instances
//         (Instance *subInstance) - instance of substructure
//         (InstanceList *instanceList) - instances to collect from in
//                                        negative graph
//         (Parameters *parameters)
//
// RETURN: (void)
//
// PURPOSE: Add instance from instanceList to sub's negative
// instances if the instance matches sub's definition.  If
// allowInstanceOverlap=FALSE, then instances added only if they do
// not overlap with existing instances.
//---------------------------------------------------------------------------
void AddNegInstancesToSub(Substructure *sub, Instance *subInstance,
                           InstanceList *instanceList, Parameters *parameters)
{
   InstanceListNode *instanceListNode;
   Instance *instance;
   Graph *instanceGraph;
   double thresholdLimit;
   double matchCost;

   // parameters used
   Graph *negGraph              = parameters->negGraph;
   LabelList *labelList         = parameters->labelList;
   BOOLEAN allowInstanceOverlap = parameters->allowInstanceOverlap;
   double threshold             = parameters->threshold;

   // collect negative instances of substructure
   if (instanceList != NULL) 
   {
      sub->negInstances = AllocateInstanceList();
      instanceListNode = instanceList->head;
      while (instanceListNode != NULL) 
      {
         if (instanceListNode->instance != NULL) 
         {
            instance = instanceListNode->instance;
            if (allowInstanceOverlap ||
                (! InstanceListOverlap(instance, sub->negInstances))) 
            {
               thresholdLimit = threshold *
                                (instance->numVertices + instance->numEdges);
               instanceGraph = InstanceToGraph(instance, negGraph);
               //
               // First, if the threshold is 0.0, see if we can match on
               // just the new edge that was added.
               //
               if (threshold == 0.0)
               {
                  // If instance has already been added to another substructure's
                  // list of instances, we can skip it
                  if (!instance->used)
                  {
                     if (NewEdgeMatch (sub->definition, subInstance, instanceGraph, 
                                       instance, parameters, thresholdLimit, 
                                       & matchCost))
                     {
                        if (matchCost < instance->minMatchCost)
                           instance->minMatchCost = matchCost;
                        instance->used = TRUE;
                        InstanceListInsert(instance, sub->negInstances, FALSE);
                        sub->numNegInstances++;
                     }
                  }
               } 
               else 
               {
                  if (GraphMatch(sub->definition, instanceGraph, labelList,
                                 thresholdLimit, & matchCost, NULL))
                  {
                     if (matchCost < instance->minMatchCost)
                        instance->minMatchCost = matchCost;
                     InstanceListInsert(instance, sub->negInstances, FALSE);
                     sub->numNegInstances++;
                  }
               }
               FreeGraph(instanceGraph);
            }
         }
         instanceListNode = instanceListNode->next;
      }
   }
}
예제 #9
0
//---------------------------------------------------------------------------
//
// NAME: AddPosInstancesToSub
//
// INPUTS: (Substructure *sub) - substructure to collect instances
//         (Instance *subInstance) - instance of substructure
//         (InstanceList *instanceList) - instances to collect from in
//                                        positive graph
//         (Parameters *parameters)
//         (ULONG index) - index of substructure into instance list
//
// RETURN: (void)
//
// PURPOSE: Add instance from instanceList to sub's positive
// instances if the instance matches sub's definition.  If
// allowInstanceOverlap=FALSE, then instances added only if they do
// not overlap with existing instances.
//---------------------------------------------------------------------------
void AddPosInstancesToSub(Substructure *sub, Instance *subInstance,
                           InstanceList *instanceList, Parameters *parameters,
                           ULONG index)
{
   InstanceListNode *instanceListNode;
   Instance *instance;
   Graph *instanceGraph;
   double thresholdLimit;
   double matchCost;
   ULONG counter = 0;

   // parameters used
   Graph *posGraph              = parameters->posGraph;
   LabelList *labelList         = parameters->labelList;
   BOOLEAN allowInstanceOverlap = parameters->allowInstanceOverlap;
   double threshold             = parameters->threshold;

   // collect positive instances of substructure
   if (instanceList != NULL) 
   {
      sub->instances = AllocateInstanceList();
      //
      // Go ahead an insert the subInstance onto the list of instances for the
      // substructure, as it is obviously an instance.
      //
      subInstance->used = TRUE;
      InstanceListInsert(subInstance, sub->instances, FALSE);
      sub->numInstances++;
      instanceListNode = instanceList->head;
      while (instanceListNode != NULL) 
      {
         if (instanceListNode->instance != NULL) 
         {
            instance = instanceListNode->instance;
            if (allowInstanceOverlap ||
               (! InstanceListOverlap(instance, sub->instances))) 
            {
               thresholdLimit = threshold *
                                (instance->numVertices + instance->numEdges);
               instanceGraph = InstanceToGraph(instance, posGraph);
               //
               // First, if the threshold is 0.0, see if we can match on
               // just the new edge that was added.
               //
               if (threshold == 0.0)
               {
                  //
                  // To avoid processing duplicates, skip all entries
                  // before this instance (because they have been checked
                  // before in a previous call), and skip itself (because
                  // there is no point in comparing it to itself).
                  //
                  // Also, skip processing this instance if it is already
                  // matched with another substructure.
                  //
                  if ((counter > index) && (!instance->used))
                  {
                     if (NewEdgeMatch (sub->definition, subInstance, instanceGraph, 
                                       instance, parameters, thresholdLimit, 
                                       & matchCost))
                     {
                        if (matchCost < instance->minMatchCost)
                           instance->minMatchCost = matchCost;
                        instance->used = TRUE;
                        InstanceListInsert(instance, sub->instances, FALSE);
                        sub->numInstances++;
                     }
                  }
               }
               else
               {
                  if (GraphMatch(sub->definition, instanceGraph, labelList,
                                 thresholdLimit, & matchCost, NULL))
                  {
                     if (matchCost < instance->minMatchCost)
                        instance->minMatchCost = matchCost;
                     InstanceListInsert(instance, sub->instances, FALSE);
                     sub->numInstances++;
                  }
               }
               FreeGraph(instanceGraph);
            }
            counter++;
         }
         instanceListNode = instanceListNode->next;
      }
   }
}