void FreeSubListNode(SubListNode *subListNode) { if (subListNode != NULL) { FreeSub(subListNode->sub); free(subListNode); } }
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; }
void FreeSubList(SubList *subList) { SubListNode *subListNode1 = NULL; SubListNode *subListNode2 = NULL; if (subList != NULL) { subListNode1 = subList->head; while (subListNode1 != NULL) { subListNode2 = subListNode1; subListNode1 = subListNode1->next; FreeSub(subListNode2->sub); free(subListNode2); } free(subList); } }
SubList *DiscoverSubs(Parameters *parameters) { SubList *parentSubList; SubList *childSubList; SubList *extendedSubList; SubList *discoveredSubList; SubListNode *parentSubListNode; SubListNode *extendedSubListNode; Substructure *parentSub; Substructure *extendedSub; Substructure *recursiveSub = NULL; // parameters used ULONG limit = parameters->limit; ULONG numBestSubs = parameters->numBestSubs; ULONG beamWidth = parameters->beamWidth; BOOLEAN valueBased = parameters->valueBased; LabelList *labelList = parameters->labelList; BOOLEAN prune = parameters->prune; ULONG maxVertices = parameters->maxVertices; ULONG minVertices = parameters->minVertices; ULONG outputLevel = parameters->outputLevel; BOOLEAN recursion = parameters->recursion; ULONG evalMethod = parameters->evalMethod; // get initial one-vertex substructures parentSubList = GetInitialSubs(parameters); discoveredSubList = AllocateSubList(); while ((limit > 0) && (parentSubList->head != NULL)) { parentSubListNode = parentSubList->head; childSubList = AllocateSubList(); // extend each substructure in parent list while (parentSubListNode != NULL) { parentSub = parentSubListNode->sub; parentSubListNode->sub = NULL; if (outputLevel > 4) { parameters->outputLevel = 1; // turn off instance printing printf("\nConsidering "); PrintSub(parentSub, parameters); printf("\n"); parameters->outputLevel = outputLevel; } if ((((parentSub->numInstances > 1) && (evalMethod != EVAL_SETCOVER)) || (parentSub->numNegInstances > 0)) && (limit > 0)) { limit--; if (outputLevel > 3) printf("%lu substructures left to be considered\n", limit); fflush(stdout); extendedSubList = ExtendSub(parentSub, parameters); extendedSubListNode = extendedSubList->head; while (extendedSubListNode != NULL) { extendedSub = extendedSubListNode->sub; extendedSubListNode->sub = NULL; if (extendedSub->definition->numVertices <= maxVertices) { // evaluate each extension and add to child list EvaluateSub(extendedSub, parameters); if (prune && (extendedSub->value < parentSub->value)) { FreeSub(extendedSub); } else { SubListInsert(extendedSub, childSubList, beamWidth, valueBased, labelList); } } else { FreeSub(extendedSub); } extendedSubListNode = extendedSubListNode->next; } FreeSubList(extendedSubList); } // add parent substructure to final discovered list if (parentSub->definition->numVertices >= minVertices) { if (! SinglePreviousSub(parentSub, parameters)) { // consider recursive substructure, if requested if (recursion) recursiveSub = RecursifySub(parentSub, parameters); if (outputLevel > 3) PrintNewBestSub(parentSub, discoveredSubList, parameters); SubListInsert(parentSub, discoveredSubList, numBestSubs, FALSE, labelList); if (recursion && (recursiveSub != NULL)) { if (outputLevel > 4) { parameters->outputLevel = 1; // turn off instance printing printf("\nConsidering Recursive "); PrintSub(recursiveSub, parameters); printf ("\n"); parameters->outputLevel = outputLevel; } if (outputLevel > 3) PrintNewBestSub(recursiveSub, discoveredSubList, parameters); SubListInsert(recursiveSub, discoveredSubList, numBestSubs, FALSE, labelList); } } } else { FreeSub (parentSub); } parentSubListNode = parentSubListNode->next; } FreeSubList(parentSubList); parentSubList = childSubList; } if ((limit > 0) && (outputLevel > 2)) printf ("\nSubstructure queue empty.\n"); // try to insert any remaining subs in parent list on to discovered list parentSubListNode = parentSubList->head; while (parentSubListNode != NULL) { parentSub = parentSubListNode->sub; parentSubListNode->sub = NULL; if (parentSub->definition->numVertices >= minVertices) { if (! SinglePreviousSub(parentSub, parameters)) { if (outputLevel > 3) PrintNewBestSub(parentSub, discoveredSubList, parameters); SubListInsert(parentSub, discoveredSubList, numBestSubs, FALSE, labelList); } } else { FreeSub(parentSub); } parentSubListNode = parentSubListNode->next; } FreeSubList(parentSubList); return discoveredSubList; }
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; }
Substructure *RecursifySub(Substructure *sub, Parameters *parameters) { ULONG i; Substructure *recursiveSub = NULL; Substructure *bestRecursiveSub = NULL; InstanceListNode *instanceListNode1; InstanceListNode *instanceListNode2; Instance *instance1; Instance *instance2; Vertex *vertex1; ULONG v1; ULONG v2Index; ULONG e; Edge *edge; BOOLEAN foundPair; // parameters used Graph *graph = parameters->posGraph; LabelList *labelList = parameters->labelList; // reset labels' used flag for (i = 0; i < labelList->numLabels; i++) labelList->labels[i].used = FALSE; // mark all instance edges instanceListNode1 = sub->instances->head; while (instanceListNode1 != NULL) { instance1 = instanceListNode1->instance; MarkInstanceEdges(instance1, graph, TRUE); instanceListNode1 = instanceListNode1->next; } // search instance list for a connected pair instanceListNode1 = sub->instances->head; while (instanceListNode1 != NULL) { instance1 = instanceListNode1->instance; for (v1 = 0; v1 < instance1->numVertices; v1++) { vertex1 = & graph->vertices[instance1->vertices[v1]]; for (e = 0; e < vertex1->numEdges; e++) { edge = & graph->edges[vertex1->edges[e]]; if ((! edge->used) && (! labelList->labels[edge->label].used)) { // search instance list for another instance involving edge v2Index = edge->vertex2; if (edge->vertex2 == instance1->vertices[v1]) v2Index = edge->vertex1; foundPair = FALSE; instanceListNode2 = instanceListNode1->next; while ((instanceListNode2 != NULL) && (! foundPair)) { instance2 = instanceListNode2->instance; if ((instance2 != instance1) && (InstanceContainsVertex(instance2, v2Index))) foundPair = TRUE; instanceListNode2 = instanceListNode2->next; } if (foundPair) { // connected pair of instances found; make recursive sub labelList->labels[edge->label].used = TRUE; recursiveSub = MakeRecursiveSub(sub, edge->label, parameters); if (bestRecursiveSub == NULL) bestRecursiveSub = recursiveSub; else if (recursiveSub->value > bestRecursiveSub->value) { FreeSub(bestRecursiveSub); bestRecursiveSub = recursiveSub; } else FreeSub(recursiveSub); } } } } instanceListNode1 = instanceListNode1->next; } // unmark all instance edges instanceListNode1 = sub->instances->head; while (instanceListNode1 != NULL) { instance1 = instanceListNode1->instance; MarkInstanceEdges(instance1, graph, FALSE); instanceListNode1 = instanceListNode1->next; } return bestRecursiveSub; }
int Disintegrate(ITEM *i) { SUB *s; if(!Duped(i)) return(-1); Place(i,NULL); while((s=i->it_Properties)!=NULL) { switch(s->pr_Key) { case KEY_ROOM: UnRoom(i); break; case KEY_OBJECT: UnObject(i); break; case KEY_PLAYER: UnPlayer(i); break; case KEY_GENEXIT: UnGenExit(i); break; case KEY_MSGEXIT: UnMsgExit(i,(MSGEXIT *)s); break; case KEY_CHAIN: RemoveChain(i,((CHAIN *)(s))->ch_Chained); break; case KEY_USERFLAG: case KEY_USERFLAG2: UnUserFlag(i); break; case KEY_CONDEXIT: UnCondExit(i,(CONDEXIT *)s); break; case KEY_CONTAINER: UnContainer(i); break; case KEY_INHERIT: UnInherit(i); break; case KEY_SNOOP:; case KEY_SNOOPBACK: StopAllSnoops(i); StopSnoopsOn(i); break; case KEY_DUPED: UnlockItem(((DUP *)(s))->du_Master); FreeSub(i,s); break; case KEY_USERTEXT: UnUserText(i); break; case KEY_INOUTHERE: KillIOH(i); break; default:fprintf(stderr,"SUBID=%d\n",s->pr_Key); Error("Disintegrate: Prop Problem"); } } KillEventQueue(i); if(FreeItem(i)<0) { i->it_Perception=-1; /* Queue deletion */ return(-1); } if(i==Me()) SetMe(NULL); if(i==Item1) Item1=NULL; if(i==Item2) Item2=NULL; return(0); }