void FreeSub(Substructure *sub) { if (sub != NULL) { FreeGraph(sub->definition); FreeInstanceList(sub->instances); FreeInstanceList(sub->negInstances); free(sub); } }
SubList *ExtendSub(Substructure *sub, Parameters *parameters) { InstanceList *negInstanceList; InstanceList *newInstanceList; InstanceListNode *newInstanceListNode; Instance *newInstance; Substructure *newSub; SubList *extendedSubs; SubListNode *newSubListNode = NULL; ULONG newInstanceListIndex = 0; // parameters used Graph *posGraph = parameters->posGraph; Graph *negGraph = parameters->negGraph; LabelList *labelList = parameters->labelList; extendedSubs = AllocateSubList(); newInstanceList = ExtendInstances(sub->instances, posGraph); negInstanceList = NULL; if (negGraph != NULL) negInstanceList = ExtendInstances(sub->negInstances, negGraph); newInstanceListNode = newInstanceList->head; while (newInstanceListNode != NULL) { newInstance = newInstanceListNode->instance; if (newInstance->minMatchCost != 0.0) { // minMatchCost=0.0 means the instance is an exact match to a // previously-generated sub, so a sub created from this instance // would be a duplicate of one already on the extendedSubs list newSub = CreateSubFromInstance(newInstance, posGraph); if (! MemberOfSubList(newSub, extendedSubs, labelList)) { AddPosInstancesToSub(newSub, newInstance, newInstanceList, parameters,newInstanceListIndex); if (negInstanceList != NULL) AddNegInstancesToSub(newSub, newInstance, negInstanceList, parameters); // add newSub to head of extendedSubs list newSubListNode = AllocateSubListNode(newSub); newSubListNode->next = extendedSubs->head; extendedSubs->head = newSubListNode; } else FreeSub(newSub); } newInstanceListNode = newInstanceListNode->next; newInstanceListIndex++; } FreeInstanceList(negInstanceList); FreeInstanceList(newInstanceList); return extendedSubs; }
BOOLEAN PositiveExample(Graph *graph, Graph **subGraphs, ULONG numSubGraphs, Parameters *parameters) { ULONG i = 0; BOOLEAN found = FALSE; InstanceList *instanceList = NULL; while ((i < numSubGraphs) && (! found)) { instanceList = FindInstances(subGraphs[i], graph, parameters); if (instanceList->head != NULL) found = TRUE; FreeInstanceList(instanceList); i++; } return found; }
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; }
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; }
void FreeRefInstanceListNode(RefInstanceListNode *refInstanceListNode) { FreeInstanceList(refInstanceListNode->instanceList); FreeReferenceGraph(refInstanceListNode->refGraph); free(refInstanceListNode); }
int main(int argc, char **argv) { Parameters *parameters; ULONG numLabels; Graph *g1; Graph *g2; Graph *g2compressed; InstanceList *instanceList; ULONG numInstances; ULONG subSize, graphSize, compressedSize; double subDL, graphDL, compressedDL; double value; Label label; parameters = GetParameters(argc, argv); g1 = ReadGraph(argv[argc - 2], parameters->labelList, parameters->directed); g2 = ReadGraph(argv[argc - 1], parameters->labelList, parameters->directed); instanceList = FindInstances(g1, g2, parameters); numInstances = CountInstances(instanceList); printf("Found %lu instances.\n\n", numInstances); g2compressed = CompressGraph(g2, instanceList, parameters); // Compute and print compression-based measures subSize = GraphSize(g1); graphSize = GraphSize(g2); compressedSize = GraphSize(g2compressed); value = ((double) graphSize) / (((double) subSize) + ((double) compressedSize)); printf("Size of graph = %lu\n", graphSize); printf("Size of substructure = %lu\n", subSize); printf("Size of compressed graph = %lu\n", compressedSize); printf("Value = %f\n\n", value); // Compute and print MDL based measures numLabels = parameters->labelList->numLabels; subDL = MDL(g1, numLabels, parameters); graphDL = MDL(g2, numLabels, parameters); numLabels++; // add one for new "SUB" vertex label if ((parameters->allowInstanceOverlap) && (InstancesOverlap(instanceList))) numLabels++; // add one for new "OVERLAP" edge label compressedDL = MDL(g2compressed, numLabels, parameters); // add extra bits to describe where external edges connect to instances compressedDL += ExternalEdgeBits(g2compressed, g1, numInstances); value = graphDL / (subDL + compressedDL); printf("DL of graph = %f\n", graphDL); printf("DL of substructure = %f\n", subDL); printf("DL of compressed graph = %f\n", compressedDL); printf("Value = %f\n\n", value); if (parameters->outputToFile) { // first, actually add "SUB" and "OVERLAP" labels label.labelType = STRING_LABEL; label.labelValue.stringLabel = SUB_LABEL_STRING; StoreLabel(& label, parameters->labelList); label.labelValue.stringLabel = OVERLAP_LABEL_STRING; StoreLabel(& label, parameters->labelList); parameters->posGraph = g2compressed; WriteGraphToDotFile(parameters->outFileName, parameters); printf("Compressed graph written to dot file %s\n", parameters->outFileName); } FreeGraph(g2compressed); FreeInstanceList(instanceList); FreeGraph(g1); FreeGraph(g2); FreeParameters(parameters); return 0; }