def dfsMatch(self, subgraph, graph, result): # print ("in dfsMatch() result %s: " %result) if not isinstance(result, dict): print( "Class Vf dfsMatch() arguments type error! result expected dict!" ) curMap = Map(result) if len(result) == len(nx.nodes(subgraph)): return result subMNeighbor = curMap.neighbor(subgraph, 0) gMNeighbor = curMap.neighbor(graph, 1) if not subMNeighbor: X = list(set(nx.nodes(subgraph)) - set(curMap.subMap())) else: X = subMNeighbor subNMN_deg = list([nx.degree(subgraph, v), v] for v in X) subNMN_deg.sort(key=lambda t: t[0], reverse=True) subNMNeighbor = [subNMN_deg[0][1]] if not gMNeighbor: gNMNeighbor = list(set(nx.nodes(graph)) - set(curMap.gMap())) else: gNMNeighbor = gMNeighbor[:] pairs = self.candidate(subNMNeighbor, gNMNeighbor) if not pairs: return result for pair in pairs: v1 = pair[0] v2 = pair[1] if (self.isMeetRules(v1, v2, subgraph, graph, result, curMap.subMap(), curMap.gMap(), subMNeighbor, gMNeighbor)): result[v1] = v2 self.dfsMatch(subgraph, graph, result) if len(result) == len(nx.nodes(subgraph)): return result result.pop(v1) #sl the procedure stops when it either constructs a complete mapping or finds out that the current result is incompletable ## print(result) return result
def dfsMatch(self, subgraph, graph, result, stop): #sl stop is the time limit start_A = time.time() if not isinstance(result, dict): print( "Class Vf dfsMatch() arguments type error! result expected dict!" ) curMap = Map(result) #sl create a Map object! if len(result) == len(nx.nodes(subgraph)): return result '''Construct the current neighborhoods of the mapping''' subMNeighbor = curMap.neighbor( subgraph, 0) #unmapped nghbrs := all nghbrs - mapped nghbrs gMNeighbor = curMap.neighbor(graph, 1) if subMNeighbor and len(subMNeighbor) > len(gMNeighbor): return result if not subMNeighbor: '''If all nghbrs are mapped: either the whole cc are mapped or the result is empty''' '''The subgraph is disconnected or the result is empty!''' '''If the subgraph is connected, then subMNeighbour is empty iff curMap is full, which should have terminated the program!''' if nx.is_connected(subgraph) and len(result) > 0: raise Exception('The subgraph is disconnected!') X = list(set(nx.nodes(subgraph)) - set(curMap.subMap())) else: X = subMNeighbor '''sub- and gNMNeighbor are only used for selecting the candidate pairs''' '''Rank the unmapped neighbors by their degrees''' subNMN_deg = list([nx.degree(subgraph, v), v] for v in X) subNMN_deg.sort(key=lambda t: t[0], reverse=True) '''Select the node with the largest degree!''' '''In case subgraph is disconnected, this may result a problem!''' subNMNeighbor = [subNMN_deg[0][1]] '''Our AGs are always connected. gMNeighbor is empty iff result is empty!''' '''If subgraph is disconnected, we should expand the selection!''' #if not gMNeighbor: if not subMNeighbor: #sl@0906 gNMNeighbor = list(set(nx.nodes(graph)) - set(curMap.gMap())) else: gNMNeighbor = gMNeighbor[:] '''Remove those graph neighbours which cannot match the suggraph candidate node''' gNMNeighbor = [ t for t in gNMNeighbor if\ nx.degree(subgraph, subNMNeighbor[0]) <= nx.degree(graph,t)] if not gNMNeighbor: return result pairs = self.candidate(subNMNeighbor, gNMNeighbor) if not pairs: return result # step = 0 for pair in pairs: # step+=1 # print(step, pair, len(result)) v1 = pair[0] v2 = pair[1] '''Note we should use subMNeighbor & gMNeighbor, not xxNMNeighbor!''' if(self.isMeetRules(v1, v2, subgraph, graph, result, curMap.subMap(),\ curMap.gMap(), subMNeighbor, gMNeighbor)): result[v1] = v2 #step += 1 if time.time() - start_A > stop: print('dfsmatch time exceeds', stop) return result self.dfsMatch(subgraph, graph, result, stop) if len(result) == len(nx.nodes(subgraph)): return result result.pop(v1) #sl the procedure stops when it either constructs a complete mapping or\ # finds out that the current result is incompletable ## print(result) return result