def ICM_Diffuse(g: nx.Graph, activated): current_activated = [] # While there is a node in activated list chech diffusion while activated: if activated: node = activated.pop(0) for edge in g.out_edges(node, data=True): if edge[1] in set(g.graph['free']): r = np.random.random() New_Weight = edge[2]['new_weight'] if r < New_Weight: # Node is activated edge[2]['alpha'] = edge[2]['alpha'] + 1 current_activated.append(edge[1]) g.graph['free'].remove(edge[1]) else: edge[2]['beta'] = edge[2]['beta'] + 1 if node in g.graph['free']: g.graph['free'].remove(node) return current_activated
def get_bn_node_for_conv(graph: nx.Graph, conv_node: dict): out_edges = graph.out_edges(conv_node['key']) for _, out_node_key in out_edges: out_node = graph.nodes[out_node_key] if out_node['op_exec_context'].operator_name == 'batch_norm': return out_node return None
def check_no_outgoing_edges(component: nx.Graph, G: nx.Graph) -> bool: """ Given a connected component of a graph, returns true if it has outgoing edges, and false otherwise. :param component: :param G: :return: """ for node in component.nodes(): out_edges = G.out_edges(node) for coming, going in out_edges: if going not in component.nodes: return False return True
def ExitBlockIterator(g: nx.Graph): """Iterate over the exit blocks of a graph. An exit block is a statement with no control successor. """ for node, data in StatementNodeIterator(g): # Filter out the root node. if data["function"] is None: continue for _, _, flow in g.out_edges(node, data="flow"): if flow == programl_pb2.Edge.CONTROL: break else: yield node, data
def _random_rr_set(g: nx.Graph, sb): free_nodes = g.graph['free'] free_nodes_set = set(free_nodes) - set(sb) q = list(sb) B = set(sb) visited = set() while q: node = q.pop(0) B.add(node) for edge in g.out_edges(node, data=True): u = edge[0] if u not in visited: r = np.random.random() if r < edge[2]['w']: q.append(u) visited.add(u) v = random.sample(free_nodes_set, 1)[0] q = [v] visited = set() rr_set = set() while q: node = q.pop(0) rr_set.add(node) for edge in g.in_edges(node, data=True): u = edge[0] if (u not in rr_set) and (u not in B) and (u not in visited): r = np.random.random() if r < edge[2]['w']: q.append(u) visited.add(u) return rr_set
def minimax(G: nx.Graph): """ Perform minimax from node n on a NetworkX graph G. Return graph with scores for moves and best move """ maxplayer = True minplayer = False G = G.copy() G.nodes[0].update({'player': 'max'}) # Recursive tree search def _minimax(G, n, player): # Base case, winning node found if G.out_degree(n) == 0: if G.nodes[n]['winner'] == 'R': score = 100 elif G.nodes[n]['winner'] == 'Y': score = -100 else: score = 0 G.nodes[n].update({'score': score}) return score if player == maxplayer: bestv = -1 for child in G.successors(n): v = _minimax(G, child, minplayer) G.nodes[child].update({'score': v, 'player': 'min'}) bestv = max(bestv, v) else: bestv = 1 for child in G.successors(n): v = _minimax(G, child, maxplayer) G.nodes[child].update({'score': v, 'player': 'max'}) bestv = min(bestv, v) return bestv # Find the best first move from the given node # Assume given node n is a maximiser node. best_node = None bestv = -1 for child in G.successors(0): v = _minimax(G, child, minplayer) G.nodes[child].update({'score': v, 'player': 'min'}) if v > bestv: best_node = child bestv = v # Add best minimax move to each node for n in G.nodes(): scores = [(v, c['move'], G.nodes[v]['score']) for (u, v, c) in G.out_edges(n, data=True)] if scores: best_move = max(scores, key=lambda t: t[2])[1] G.nodes[n]['best_move'] = best_move # Analyze next move move_scores = [(v, c['move'], G.nodes[v]['score']) for (u, v, c) in G.out_edges(0, data=True)] # If all next moves (G[0]) have zero score, try center moves if set([n[2] for n in move_scores]) == {0}: return None else: return G.nodes[0]['best_move']
class LangGraph(object): """ A graph of all the relationships in a document and/or sentence """ def __init__(self, directed=False): """ Builds a graph out of the given document """ self.isDirected = directed #a graph that is meant to be full of class Instance if self.isDirected: self.graph = DiGraph() else: self.graph = Graph() self.start = None #an Instance #keep the graph also according to temporal, redundant probably needs #refactoring self.temporal = None self.temporalMap = None def setStart(self, start): """ Sets the starting instance, also builds the temporal ordering of the graph """ self.start = start self.temporal = self.narrativeOrder() self.temporalMap = self.narrativeMapping() def indexToInst(self, index): """ Returns the instance corresponding to the given index """ result = index #if the index is an int, lookup the instance associated with it if type(index) == int: result = self.temporal[index] return result def instToIndex(self, instance): """ Return the index associated with the instance """ return self.temporalMap[instance] def narrativeOrder(self): """ Returns the instances in narrative order """ results = [] node = self.start prev = None #while there are more nodes, keep adding them while node is not None: #record the current node results.append(node) #get the connected nodes fringe = [n for n in self.adj(node, WORD_EDGE) if n != prev] nextNode = fringe[0] if fringe else None #advance to the next node prev = node node = nextNode return results def narrativeMapping(self): """ Makes the mapping from instances to their narrative index """ return {inst:i for i,inst in enumerate(self.temporal)} def addNode(self, node): """ Adds a node to the graph """ self.graph.add_node(node) def addEdge(self, start, end, type): """ Adds an edge between the two instances """ #if the edge exists, just add the type if self.graph.has_edge(start, end): self.addType(start, end, type) else: self.graph.add_edge(start, end, TYPES=set([type])) def removeEdge(self, start, end, edgeType): """ Removes an edge with a given type from the edge type """ #remove the type self.removeType(start, end, edgeType) #if there are no types, remove the edge itself types = self.edgeTypes(start, end) #remove the edge if not len(types) and self.graph.has_edge(start, end): self.graph.remove_edge(start, end) def addType(self, start, end, type): """ Adds a type between the edges """ #look for existing types types = self.graph[start][end].get(TYPES, set()) #add the new type types.add(type) self.graph[start][end][TYPES] = types def removeType(self, start, end, edgeType): """ Removes the type on the edge """ for prefix in [PARENT, CHILD]: edgeType = removePrefix(prefix, edgeType) types = self.graph[start][end][TYPES] #if the types contains the edge, remove if edgeType in types: types.remove(edgeType) def hasType(self, start, end, type): """ Returns true if the edge between the two nodes has the given type """ return type in self.edgeTypes(start, end) def singleEdgeTypes(self, start, end): """ Returns the types on the edge if any, or an empty set is returned """ #make sure we are using instances rather than indexes start = self.indexToInst(start) end = self.indexToInst(end) data = self.graph.get_edge_data(start,end) result = set() #if there is data, get the types if data is not None: result = data.get(TYPES, set()) return result def edgeTypes(self, start, end): """ Returns the types on the edge if any, or an empty set is returned """ if self.isDirected: parent = addPrefixes(PARENT, self.singleEdgeTypes(end, start)) child = addPrefixes(CHILD, self.singleEdgeTypes(start, end)) types = parent.union(child) else: types = self.singleEdgeTypes(start, end) return types def allEdgeTypes(self): """ Returns all the edge types """ results = set() #collect all the edges with all the types for s,e,types in self.allEdges(): #look up the edge types to make sure everything is covered for edgeType in types: results.add(edgeType) #add in the reverse types for edgeType in self.edgeTypes(e,s): results.add(edgeType) return results def allEdges(self): """ Yield all the edges in the graph """ for start, end in self.graph.edges(): yield start, end, self.edgeTypes(start, end) def contains(self, instance): """ Returns true if the graph contains the instance """ return self.graph.has_node(instance) def instances(self): """ Return all the instances in the graph """ return self.graph.nodes() def edges(self, instance): """ Returns all the edges connected to this instance """ inst = self.indexToInst(instance) #make get the directed edges if self.isDirected: results = [t for _, t in self.graph.out_edges(inst)] + [t for t, _ in self.graph.in_edges(inst)] else: results = self.graph.adj[inst] return results def docType(self): """ Returns the document type (String) """ return self.temporal[0].event.docType def adj(self, instance, type=None): """ Returns the adjancent node with a given type """ return [other for other in self.edges(instance) if self.hasType(instance, other, type) or type is None] def nonNarrativeAdj(self, instance, returnIndex=False): """ Returns the nodes that are not adjancent to the given instance """ results = [] #add each node if it has a non-narrative (temporal) connection for node in self.edges(instance): #get the non narrative types edgeTypes = nonNarrativeTypes(self.edgeTypes(instance, node)) #if there is a non-narrative edge, add it if edgeTypes: #lookup the index of the node nodeMarker = self.instToIndex(node) if returnIndex else node results.append((nodeMarker, edgeTypes)) return results def words(self): """ Returns the words in narrative order """ return [t.word for t in self.tokens()] def tokens(self): """ Returns the tokens in narrative order """ return [i.token for i in self.temporal] def labels(self): """ Returns the sequence of labels for the instances """ return [i.event.type for i in self.temporal] def removeAny(self, blackList): """ Removes any nodes/tokens/instances that match the words in the blacklist """ #if a token or its lemma match any of the words in the blacklist #mark it for removal toRemove = {inst.token for inst in self.temporal if inst.token.word.lower() in blackList or inst.token.lemma.lower() in blackList} self.removeNodes(toRemove) def removeNodes(self, tokens): """ Removes the token from the graph """ startLen = len(self) #mark all the instances/indexes to remove instances = {inst:i for inst,i in self.temporalMap.items() if inst.token in tokens} #determine the remaining nodes remaining = sorted(list(set(range(startLen)) - {i for i in instances.values()})) #add in all the bypasses for startIndex, endIndex in iterPairs(remaining): start = self.temporal[startIndex] end = self.temporal[endIndex] self.addEdge(start, end, WORD_EDGE) #remove the edges for inst in instances: self.graph.remove_node(inst) #if there are remaining nodes then reset the temporal mapping if remaining: startIndex = min(remaining) self.start = self.temporal[startIndex] #redo narrative order self.temporal = self.narrativeOrder() self.temporalMap = self.narrativeMapping() else: self.start = None self.temporal = [] self.temporalMap = {} def copy(self): """ Performs a shallow copy of the graph """ newGraph = LangGraph(self.isDirected, self.entEdges) #create new instances newInst = {i:me.Instance(copy(i.token), i.event) for i in self.temporal} #add in all the edges for start, end in self.graph.edges(): for eType in self.edgeTypes(start, end): newGraph.addEdge(newInst[start], newInst[end], eType) newGraph.setStart(newInst[self.start]) return newGraph def graphString(self): """ Returns the graph as a string """ return " ".join([t.word for t in self.tokens()]) def __len__(self): """ Returns the number of nodes (tokens) in the graph """ return len(self.graph) def __repr__(self): """ Returns a summary string of the graph """ return "LangGraph {} nodes, {} edges".format(len(self.graph.nodes()), len(self.graph.edges()))