def __init__(self, F, arg): """ If arg is a list: Generate the core graph corresponding to the group generated by group_gens. If arg is a graph: Check for validity and do all folds. """ assert is_FreeGroup(F), "F must be a free group" self.F = F self.F_rank = F.rank() self.letter_types = range(1, self.F_rank + 1) self.letters = list(range(-self.F_rank, 0)) + list(range(1, self.F_rank + 1)) # -r, ..., -1, 1, ..., r if isinstance(arg, list): group_gens = arg assert all([gen in F for gen in group_gens]), "The generators must be elements of F." self.group_gens = group_gens G = MultiDiGraph() G.add_node((0,)) # the marked vertex (id) for i, gen in enumerate(self.group_gens): word = gen.Tietze() word_len = len(word) # new_nodes = [(i, j) for j in range(1, word_len)] # G.add_nodes_from(new_nodes) get_node = lambda j: (0,) if (j % word_len == 0) else (i, j) for j in range(word_len): G.add_edge(get_node(j), get_node(j + 1), label=word[j]) G.add_edge(get_node(j + 1), get_node(j), label=-word[j]) elif isinstance(arg, MultiDiGraph): # We are going to copy the graph, add reverse edges when needed, # and sort the edges. # The reason we sort the edges is to get a "canonical" version # of the object, so subgroup_gens would be the same in different # objects with the same graph. G = MultiDiGraph() G.add_nodes_from(arg.nodes()) edges = arg.edges(data='label') G_edges = [e for e in edges] assert len(edges) == len(arg.edges()), "Every edge has to be labelled." for src, dst, letter in edges: assert letter in self.letters, \ f"The edge betwen {src} and {dst} has an invalid label" if (dst, src, -letter) not in G.edges(data='label'): G_edges.append((dst, src, -letter)) G.add_weighted_edges_from(sorted(G_edges), weight='label') else: raise ValueError("arg must be a list of words or a MultiDiGraph.") self.G = do_all_folds(G) # The subgraph of positive edges G_pos = MultiDiGraph() G_pos.add_edges_from([e for e in self.G.edges(data=True) if e[2]['label'] > 0]) self.G_pos = G_pos self.subgroup_gens = tuple(sorted(self.get_subgroup()))
def scale_free_graph(n, alpha=0.41, beta=0.54, delta_in=0.2, delta_out=0): def _choose_node(G, distribution, delta): cumsum = 0.0 psum = float(sum( distribution.values())) + float(delta) * len(distribution) r = random.random() for i in range(0, len(distribution)): cumsum += (distribution[i] + delta) / psum if r < cumsum: break return i G = MultiDiGraph() G.add_edges_from([(0, 1), (1, 2), (2, 0)]) gamma = 1 - alpha - beta while len(G) < n: r = random.random() if r < alpha: v = len(G) w = _choose_node(G, G.in_degree(), delta_in) elif r < alpha + beta: v = _choose_node(G, G.out_degree(), delta_out) w = _choose_node(G, G.in_degree(), delta_in) else: v = _choose_node(G, G.out_degree(), delta_out) w = len(G) G.add_edge(v, w) return G
def add_ref_edges(g: nx.MultiDiGraph, node): """Add edges with attr `data` for data references of the given node""" if isinstance(node, clang.graph.StmtInfo): for ref_rel in node.ref_relations: g.add_node(ref_rel, attr=(filter_type(ref_rel.type))) g.add_edge(node, ref_rel, attr="data")
def replace_pattern(self, graph: nx.MultiDiGraph, match: dict): input = match['input'] lstm = match['lstm'] params = match['params'].value.copy() hidden_state = match['hidden_state'] cell_state = match['cell_state'] hidden_state_edge_attrs = deepcopy(graph.get_edge_data(hidden_state.id, lstm.id)[0]) cell_state_edge_attrs = deepcopy(graph.get_edge_data(cell_state.id, lstm.id)[0]) graph.remove_edge(match['params'].id, lstm.id) graph.remove_edge(match['hidden_state'].id, lstm.id) graph.remove_edge(match['cell_state'].id, lstm.id) self.repack_weights(graph, input, lstm, params) reshape = Reshape(graph, dict(dim=[lstm.in_node(0).shape[0], lstm.hidden_size])) if len(lstm.in_nodes()) > 2: hidden_state_edge_attrs['in'] = 3 new_init_h = reshape.create_node_with_data([hidden_state], attrs=dict(name=lstm.name + '/HiddenStateResize')) graph.add_edge(new_init_h.id, lstm.id, **hidden_state_edge_attrs) if len(lstm.in_nodes()) > 3: cell_state_edge_attrs['in'] = 4 new_init_c = reshape.create_node_with_data([cell_state], attrs=dict(name=lstm.name + '/CellStateResize')) graph.add_edge(new_init_c.id, lstm.id, **cell_state_edge_attrs)
def _add_cross_feed_edges(G: nx.MultiDiGraph, sid_lookup: Dict[str, str], cross_feed_edges: pd.DataFrame, walk_speed_kmph: float) -> nx.MultiDiGraph: # Add the cross feed edge connectors to the graph to # capture transfer points for i, row in cross_feed_edges.iterrows(): # Extract the row column values as discrete variables sid = row.stop_id to = row.to_node d = row.distance # Use the lookup table to get converted stop id name full_sid = sid_lookup[sid] # Convert to km/hour kmph = (d / 1000) / walk_speed_kmph # Convert to seconds in_seconds = kmph * 60 * 60 # And then add it to the graph G.add_edge(full_sid, to, length=in_seconds, mode='walk') # also add reverse edge G.add_edge(to, full_sid, length=in_seconds, mode='walk')
def _add_entry_point_for_graph(graph: nx.MultiDiGraph, tag=True): entry_points = [] name = graph.graph["name"] for node_id in graph.nodes: if graph.in_degree(node_id) == 0: # 入口节点 entry_points.append(node_id) if tag is True: graph.add_node("{}@entry".format(name), label="ENTRY", type="ENTRY", expression="ENTRY") else: graph.add_node("entry", label="ENTRY", type="ENTRY", expression="ENTRY") for entry_point in entry_points: if tag is True: graph.add_edge("{}@entry".format(name), entry_point) else: graph.add_edge("entry", entry_point) return graph
def scale_free_graph(n, alpha=0.41,beta=0.54,delta_in=0.2,delta_out=0): def _choose_node(G,distribution,delta): cumsum = 0.0 psum = float(sum(distribution.values()))+float(delta)*len(distribution) r = random.random() for i in range(0, len(distribution)): cumsum += (distribution[i]+delta)/psum if r < cumsum: break return i G = MultiDiGraph() G.add_edges_from([(0,1),(1,2),(2,0)]) gamma = 1 - alpha - beta while len(G)<n: r = random.random() if r < alpha: v = len(G) w = _choose_node(G, G.in_degree(),delta_in) elif r < alpha+beta: v = _choose_node(G, G.out_degree(),delta_out) w = _choose_node(G, G.in_degree(),delta_in) else: v = _choose_node(G, G.out_degree(),delta_out) w = len(G) G.add_edge(v,w) return G
def MaybeAddSingleExitBlock(self, g: nx.MultiDiGraph) -> None: """Add a magic exit block to unite the exit statements of a CFG. Args: g: The graph to add the exit block to. """ exit_blocks = list(nx_utils.ExitBlockIterator(g)) if not exit_blocks: raise ValueError("No exit blocks found in graph!") if ( self.only_add_entry_and_exit_blocks_if_required and len(exit_blocks) == 1 ): exit_block = exit_blocks[0][0] else: exit_block = f"{g.name}_exit" g.add_node( exit_block, name=exit_block, type="magic", x=self.dictionary["!MAGIC"] ) # Connect exit blocks. for node, data in exit_blocks: g.add_edge(node, exit_block, flow="control") # Add a dataflow edge out, if there is one. for src, dst, data in nx_utils.DataFlowEdgeIterator(g): if dst == node: g.add_edge(node, exit_block, flow="data") break g.exit_block = exit_block
def MaybeAddDataFlowElements( self, g: nx.MultiDiGraph, tag_hook: typing.Optional[llvm_util.TagHook] ) -> None: if self.dataflow == "none": return prefix = lambda s: f"{g.name}_{s}" unprefix = lambda s: s[len(f"{g.name}_") :] # Collect the edges to add so that we don't modify the graph while # iterating. edges_to_add: typing.List[typing.Tuple[str, str, str, int]] = [] for statement, data in nx_utils.StatementNodeIterator(g): # TODO(github.com/ChrisCummins/ProGraML/issues/9): Separate !IDENTIFIER # and !IMMEDIATE uses. def_, uses = GetLlvmStatementDefAndUses( data["text"], store_destination_is_def=self.store_destination_is_def ) if def_: # Data flow out edge. def_name = f"{prefix(def_)}_operand" edges_to_add.append( (statement, def_name, def_name, 0, def_, data, "def") ) for position, identifier in enumerate(uses): # Data flow in edge. identifier_name = f"{prefix(identifier)}_operand" edges_to_add.append( ( identifier_name, statement, identifier_name, position, identifier, data, "use", ) ) for ( src, dst, identifier, position, name, original_node, dtype, ) in edges_to_add: g.add_edge(src, dst, flow="data", position=position) node = g.nodes[identifier] # TODO(github.com/ChrisCummins/ProGraML/issues/9): Separate !IDENTIFIER # and !IMMEDIATE nodes. node["type"] = "identifier" node["name"] = name node["text"] = name node["x"] = self.dictionary["!IDENTIFIER"] if tag_hook is not None: other_attrs = tag_hook.OnIdentifier(original_node, node, dtype) or {} for attrname, attrval in other_attrs.items(): node[attrname] = attrval
def get_connection_multigraph(connections): G = MultiDiGraph() for c in connections: dp1 = c.dp1 dp2 = c.dp2 G.add_edge(dp1, dp2, s1=c.s1) return G
def get_connection_multigraph_weighted(name2dp, connections): G = MultiDiGraph() for c in connections: dp1 = c.dp1 dp2 = c.dp2 if not G.has_edge(dp1, dp2): already = [] G.add_edge(dp1, dp2) else: already = G.edge[dp1][dp2]['spaces'] R = name2dp[c.dp1].get_rtype(c.s1) already.append(R) G.edge[dp1][dp2]['spaces'] = already # cycles = list(simple_cycles(G)) # for cycle in cycles: # cycle = list(cycle) # cycle = cycle + [cycle[0]] # # for i in range(len(cycle) - 1): # # XXX # _val = G.edge[cycle[i]][cycle[i + 1]]['spaces'] # # print('%s -> %s -> %s' % (cycle[i], val, cycle[i + 1])) return G
def _add_nodes_and_edges(G: nx.MultiDiGraph, name: str, stops_df: pd.DataFrame, summary_edge_costs: pd.DataFrame, bidirectional: bool = False) -> Dict[str, str]: # As we convert stop ids to actual nodes, let's keep track of those names # here so that we can reference them when we add connector edges across # the various feeds loaded into the graph sid_lookup = {} for i, row in stops_df.iterrows(): sid = str(row.stop_id) full_sid = nameify_stop_id(name, sid) # Add to the lookup crosswalk dictionary sid_lookup[sid] = full_sid G.add_node(full_sid, boarding_cost=row.avg_cost, y=row.stop_lat, x=row.stop_lon) for i, row in summary_edge_costs.iterrows(): sid_fr = nameify_stop_id(name, row.from_stop_id) sid_to = nameify_stop_id(name, row.to_stop_id) G.add_edge(sid_fr, sid_to, length=row.edge_cost, mode='transit') # If want to add both directions in this step, we can # by reversing the to/from node order on edge if bidirectional: G.add_edge(sid_to, sid_fr, length=row.edge_cost, mode='transit') return sid_lookup
def EdmondsKarp(layered_network: LayeredGraph, network: Graph, s: int, t: int, capacity_label: str = 'c') -> int: # unite_sinks(network=layered_network, t=t) # united_sink = layered_network.max_node * layered_network.layers # cut_dead_ends(layered_network, s=s, t=t) source_net = MultiDiGraph() for src, dst, key, data in network.edges(data=True, keys=True): new_key = data[ArcAttrs.arc_type] source_net.add_edge(src, dst, key=new_key, **data) source_net[src][dst][new_key][ ArcAttrs.res_capacity] = data[capacity_label] flow_network = build_flow_network( layered_network) # create auxiliary network with reversed arcs while True: path = search_path(flow_network=flow_network, source_network=source_net, s=s, t=t) if path: augment(path, flow_network=flow_network, source_network=source_net) else: return gather_in_flows(node=t, flow_network=flow_network)
def axiom(G: networkx.MultiDiGraph): axioms = ("(i)nitial", "(w)eakening", "(s)ubstitute") while command := get_required(f"{'|'.join(axioms)}").lower(): print() if command == "i": wffs = get_formulas() G.add_node(Sequent(wffs, wffs)) return elif command == "w": sequent = select(G) if sequent: sides = {"(l)eft", "(r)ight"} while side := get_required(f"{'|'.join(sides)}") in sides: if side == "l": print("<<weakening left side>>") wffs = get_formulas() weakened = sequent for wff in wffs: weakened = InferenceRules.l_weakening( weakened, wff) G.add_node(weakened) G.add_edge(sequent, weakened, label="(l_weakening)") return elif side == "r": print("<<weakening right side>>") wffs = get_formulas() weakened = sequent for wff in wffs: weakened = InferenceRules.r_weakening( weakened, wff) G.add_node(weakened) G.add_edge(sequent, weakened, label="(r_weakening)") return
def pad_op_transform(graph: nx.MultiDiGraph, match: dict): op = match['op'] pad_op = match['pad_op'] input_data = pad_op.in_node(0) pads = pad_op.in_node(1).value if len( pad_op.in_nodes()) == 2 else pad_op.pads if pad_op.mode != 'constant': log.info( 'The pad node "{}" with pad mode "{}" cannot be fused.'.format( pad_op.soft_get('name'), pad_op.mode)) return if pad_op.mode == 'constant' and pad_op.fill_value != 0.0: log.info('The pad node "{}" with non-zero fill value cannot be fused.'. format(pad_op.soft_get('name'))) return input_tensor_dims = len(match['pad_output'].shape) if np.any(pads[get_features_dim(op.graph.graph['layout'],input_tensor_dims)] != 0) or \ np.any(pads[get_batch_dim(op.graph.graph['layout'], input_tensor_dims)] != 0): log.info( 'The pad node "{}" with padding over feature/batch dimension cannot be fused.' .format(pad_op.soft_get('name'))) return op.pad += pads op.pad_spatial_shape = op.pad[op.spatial_dims] op['auto_pad'] = None assert (graph[match['pad_output'].node][match['op'].node][0]['in'] == 0) edge_attrs = graph.get_edge_data(match['pad_output'].id, match['op'].id)[0] graph.remove_edge(match['pad_output'].id, match['op'].id) graph.add_edge(input_data.id, match['op'].id, **{'in': 0, **edge_attrs})
def add_all_edges(g1: nx.MultiDiGraph, g2: nx.MultiDiGraph, preserve: bool = True) -> int: """ Add all edges from source graph (``g2``) to target graph (``g1``). Parameters ---------- g1: networkx.MultiDiGraph Target graph g2: networkx.MultiDiGraph Source graph preserve: bool Whether or not to preserve conflicting properties Returns ------- int Number of edges merged during this operation """ logging.info(f"Adding {g2.number_of_edges()} edges from {g2} to {g1}") merge_count = 0 for u, v, key, data in g2.edges(keys=True, data=True): if g1.has_edge(u, v, key): merge_edge(g1, u, v, key, data, preserve) merge_count += 1 else: g1.add_edge(u, v, key, **data) return merge_count
def get_graphs(): g1 = MultiDiGraph() g1.name = 'Graph 1' g1.add_node('A', id='A', name='Node A', category=['biolink:NamedThing']) g1.add_node('B', id='B', name='Node B', category=['biolink:NamedThing']) g1.add_node('C', id='C', name='Node C', category=['biolink:NamedThing']) g1.add_edge('C', 'B', key='C-biolink:subclass_of-B', edge_label='biolink:sub_class_of', relation='rdfs:subClassOf') g1.add_edge('B', 'A', key='B-biolink:subclass_of-A', edge_label='biolink:sub_class_of', relation='rdfs:subClassOf', provided_by='Graph 1') g2 = MultiDiGraph() g2.name = 'Graph 2' g2.add_node('A', id='A', name='Node A', description='Node A in Graph 2', category=['biolink:NamedThing']) g2.add_node('B', id='B', name='Node B', description='Node B in Graph 2', category=['biolink:NamedThing']) g2.add_node('C', id='C', name='Node C', description='Node C in Graph 2', category=['biolink:NamedThing']) g2.add_node('D', id='D', name='Node D', description='Node D in Graph 2', category=['biolink:NamedThing']) g2.add_node('E', id='E', name='Node E', description='Node E in Graph 2', category=['biolink:NamedThing']) g2.add_edge('B', 'A', key='B-biolink:related_to-A', edge_label='biolink:related_to', relation='biolink:related_to') g2.add_edge('D', 'A', key='D-biolink:related_to-A', edge_label='biolink:related_to', relation='biolink:related_to') g2.add_edge('E', 'A', key='E-biolink:related_to-A', edge_label='biolink:related_to', relation='biolink:related_to') g3 = MultiDiGraph() g3.name = 'Graph 3' g3.add_edge('F', 'E', key='F-biolink:same_as-E', edge_label='biolink:same_as', relation='OWL:same_as') return [g1, g2, g3]
def add_path_step(line_code: int, current_node, from_node_label: str, step_count: int, line_graph: nx.DiGraph, graph: nx.MultiDiGraph, taboo_list: Set[int]): if step_count == 5: return for neighbour in nx.neighbors(line_graph, current_node): if neighbour in taboo_list: continue edge = line_graph.get_edge_data(current_node, neighbour) cluster_number = edge['cluster'] to_node_label = str(step_count + 1) + '_' + str(cluster_number) existing_edges = graph.get_edge_data(from_node_label, to_node_label, default=None) if not edge_exists(existing_edges, line_code, current_node, neighbour): graph.add_edge(from_node_label, to_node_label, line_code=line_code, from_node=current_node, to_node=neighbour, cluster=cluster_number) taboo_list.add(neighbour) add_path_step(line_code, neighbour, to_node_label, step_count + 1, line_graph, graph, taboo_list)
def relationship_edges(schema_graph_nx: nx.MultiDiGraph, class_add_mod: dict, **kwargs) -> nx.MultiDiGraph: """ Notes: ===== # pass the below dictionary as the third argument (kwargs) to relationship_edges(). # "in" indicates that the relationship has an in-edges behaviour. # "out" indicates that the relationship has an out-edges behaviour. rel_dict = { "rdfs:subClassOf": { "parentOf": "in" }, "schema:domainIncludes": { "domainValue": "in" }, "sms:requiresDependency": { "requiresDependency": "out" }, "sms:requiresComponent": { "requiresComponent": "out" }, "schema:rangeIncludes": { "rangeValue": "out" } } """ for rel, rel_lab_node_type in kwargs.items(): for rel_label, node_type in rel_lab_node_type.items(): if rel in class_add_mod: parents = class_add_mod[rel] if type(parents) == list: for _parent in parents: if node_type == "in": n1 = extract_name_from_uri_or_curie(_parent["@id"]) n2 = class_add_mod["rdfs:label"] if node_type == "out": n1 = class_add_mod["rdfs:label"] n2 = extract_name_from_uri_or_curie(_parent["@id"]) # do not allow self-loops if n1 != n2: schema_graph_nx.add_edge(n1, n2, key=rel_label) elif type(parents) == dict: if node_type == "in": n1 = extract_name_from_uri_or_curie(parents["@id"]) n2 = class_add_mod["rdfs:label"] if node_type == "out": n1 = class_add_mod["rdfs:label"] n2 = extract_name_from_uri_or_curie(parents["@id"]) # do not allow self-loops if n1 != n2: schema_graph_nx.add_edge(n1, n2, key=rel_label) return schema_graph_nx
def convert_grandalf_graph_to_networkx_graph(G): from networkx import MultiDiGraph nxg = MultiDiGraph() for v in G.V(): nxg.add_node(v.data) for e in G.E(): nxg.add_edge(e.v[0].data, e.v[1].data) return nxg
def add_edge(mygraph: MultiDiGraph, edge: str, origincolor: str, colormap: dict) -> MultiDiGraph: edge = reduce(str.removesuffix, [" bags", " bag"], edge) origincolornum = colormap.get(origincolor) num, tcolor = edge.split(" ", 1) for _ in range(int(num)): mygraph.add_edge(origincolornum, colormap.get(tcolor)) return mygraph
def get_meausurements_graph(po: PlacedObject) -> MultiDiGraph: G = MultiDiGraph() for name, sr in iterate_measurements_relations((), po): a = sr.a b = sr.b attr_dict = dict(sr=sr) G.add_edge(a, b, attr_dict=attr_dict) return G
def simplify_twoways(n, g: nx.MultiDiGraph, check_lanes: bool): edge_u1 = list(g.out_edges(n, data=True))[0][:2] edge_u2 = list(g.out_edges(n, data=True))[1][:2] temp1 = reversed(edge_u1) edge_u1 = tuple(temp1) temp2 = reversed(edge_u2) edge_u2 = tuple(temp2) new_id_out = list(g.out_edges(n, data=True))[0][2]['id'] new_id_in = list(g.in_edges(n, data=True))[0][2]['id'] coords_out = list( filter( None, list(g.in_edges(n, data=True))[1][2]['others'] + [[n[1], n[0]]] + list(g.out_edges(n, data=True))[0][2]['others'])) coords_in = list(reversed(coords_out)) edge_v1 = list(g.in_edges(n, data=True))[0][:2] edge_v2 = list(g.in_edges(n, data=True))[1][:2] edges_u = (edge_u1, edge_u2) edges_v = (edge_v1, edge_v2) lanes_u1 = list(g.out_edges(n, data=True))[0][2]['lanes'] lanes_u2 = list(g.out_edges(n, data=True))[1][2]['lanes'] lanes_v1 = list(g.in_edges(n, data=True))[0][2]['lanes'] lanes_v2 = list(g.in_edges(n, data=True))[1][2]['lanes'] if edges_u == edges_v: # remove edges and node is_deleted = [False, False] is_loop = False # finding oneway loop (from_id == to_id) for i in edges_u: if check_oneway_loop(i): is_loop = True for i in edges_v: if check_oneway_loop(i): is_loop = True if is_loop: return if lanes_u1 == lanes_v2 or lanes_u1 is None or lanes_v2 is None or check_lanes: # merge only edges with same number of lanes g.remove_edge(edge_u1[1], edge_u1[0]) g.remove_edge(edge_u2[0], edge_u2[1]) g.add_edge(edge_v2[0], edge_v1[0], id=new_id_out, others=coords_out, lanes=lanes_u1) is_deleted[0] = True if lanes_u2 == lanes_v1 or lanes_u2 is None or lanes_v1 is None or check_lanes: # merge only edges with same number of lanes if edge_u1[1] != edge_u1[0] or edge_u2[0] != edge_u2[ 1]: # check loops g.remove_edge(edge_u1[0], edge_u1[1]) g.remove_edge(edge_u2[1], edge_u2[0]) g.add_edge(edge_v1[0], edge_v2[0], id=new_id_in, others=coords_in, lanes=lanes_v1) is_deleted[1] = True if is_deleted[0] and is_deleted[1] or check_lanes: g.remove_node(n)
def read_cref_table( inmap, strip_paths=["/usr", "lib/STM32Cube_FW_F4_V1.16.0"], simplify_paths=["libgcc.a", "libc_nano.a", "libnosys.a"], hide_aeabi_symbols=True ): # Helper function to simplify filenames in order to increase graph clarity def process_filename(last_module): # Strip certain file paths for key in strip_paths: if last_module.find(key) > -1: s = last_module.split("/") print(last_module + " - " + s[len(s)-1]) last_module = s[len(s)-1] # Remove symbol names (in round brackets) from certain libraries for key in simplify_paths: if last_module.find(key) > -1: s = last_module.split("(") print(last_module + " - " + s[0]) last_module = s[0] return last_module # Create new graph modules = MultiDiGraph() # Parse all table lines redundant_associations = [] while True: l = inmap.readline() words = l.split() if len(words) == 2: # New symbol A, which is defined in file B last_symbol = words[0] last_module = process_filename(words[1]) elif len(words) == 1: # One more file uses the previous symbol filename = process_filename(words[0]) # References of a file to itself are not particularly interesting if filename != last_module: if last_symbol.find("__aeabi") > -1 and hide_aeabi_symbols: t = (filename, last_module) if not (t in redundant_associations): redundant_associations.append(t) modules.add_edge(filename, last_module); else: modules.add_edge(filename, last_module, label=last_symbol); elif len(l) == 0: # End of table break # Return the generated graph return modules
def find_and_replace_pattern(self, graph: nx.MultiDiGraph): data_nodes = [ Node(graph, node) for node in graph.node if Node(graph, node).kind == 'data' ] for node in data_nodes: # Get all requested shapes for current node # This mapping will contain pairs like {shape:[list of consumers nodes]} mapping = {} for consumer in node.out_nodes(): edge_attrs = graph.get_edge_data(node.id, consumer.id)[0] if 'new_shape' in edge_attrs: if np.array_equal(edge_attrs['new_shape'], node.shape): continue new_shape = tuple([x for x in edge_attrs['new_shape']]) if not new_shape in mapping: mapping.update({new_shape: [consumer]}) else: mapping[new_shape].append(consumer) if node.has_valid('value'): # Check that requested shape are the same # In case if they are different, we duplicate them for shape_key in mapping.keys(): shape = list(shape_key) new_value = np.reshape(node.value, shape) node_copy = Op.create_input_data_node( graph, node.id + '/copy', value=np.array(new_value)) for consumer in mapping[shape_key]: edge_attrs = graph.get_edge_data(node.id, consumer.id)[0] del edge_attrs['new_shape'] # Remove edge from previous data node and connect new data node with its consumer graph.remove_edge(node.id, consumer.id) graph.add_edge(node_copy.id, consumer.id, **edge_attrs) else: # Insert Reshape layer between data node and consumer for shape_key in mapping.keys(): shape = list(shape_key) reshape = Reshape(graph, attrs={ 'dim': shape, 'name': 'EltwiseReshapeNormalization' }) reshape_data = reshape.create_node_with_data(inputs=[node]) # Iterate over consumers and reconnect them to Reshape layer output for consumer in mapping[shape_key]: edge_attrs = graph.get_edge_data(node.id, consumer.id)[0] del edge_attrs['new_shape'] # Reconnect edge from original data node to Reshape output datanode graph.remove_edge(node.id, consumer.id) graph.add_edge(reshape_data.id, consumer.id, **edge_attrs)
def get_graphs(): g1 = MultiDiGraph() g1.name = 'Graph 1' g1.add_node('HGNC:12345', id='HGNC:12345', name='Test Gene', category=['biolink:Gene']) g1.add_node('B', id='B', name='Node B', category=['biolink:NamedThing']) g1.add_node('C', id='C', name='Node C', category=['biolink:NamedThing']) g1.add_edge('C', 'B', key='C-biolink:subclass_of-B', edge_label='biolink:sub_class_of', relation='rdfs:subClassOf') g1.add_edge('B', 'A', key='B-biolink:subclass_of-A', edge_label='biolink:sub_class_of', relation='rdfs:subClassOf', provided_by='Graph 1') return [g1]
def FullConnection(group1: Group, group2: Group, graph: nx.MultiDiGraph): for node in group1.get_nodes(): graph.add_node(node) for node in group2.get_nodes(): graph.add_node(node) for i in group1.get_nodes(): for j in group2.get_nodes(): graph.add_edge(i, j)
def construct_multi_di_graph(edges: List[Tuple[str, str, Any]]) -> MultiDiGraph: """Constructs a multi directed graph from a list of edges. Arguments: edges: A list of tuples with entries: start, end and identifier. """ g = MultiDiGraph() for start, end, key in edges: g.add_edge(start, end, key=key) return g
def inserir_nodo_grafo(grafo: MultiDiGraph, chave: int, nodo: dict, nodo_novo: dict): grafo.add_node(chave,\ posicao_labirinto=nodo_novo["posicao_labirinto"],\ chave=chave,\ acao=nodo_novo["acao"],\ custo_caminho=nodo_novo["custo_caminho"]) if nodo is not None: grafo.add_edge(nodo["chave"], chave)
def add_cfg_edges(g: nx.MultiDiGraph, node): """Add edges with attr `cfg` or `in` for control flow for the given node""" if isinstance(node, clang.graph.FunctionInfo): for cfg_b in node.cfgBlocks: g.add_node(cfg_b, attr="cfg") for succ in cfg_b.successors: g.add_edge(cfg_b, succ, attr="cfg") g.add_node(succ, attr="cfg") for stmt in cfg_b.statements: g.add_edge(stmt, cfg_b, attr="in") g.add_node(stmt, attr=(stmt.name))
def add_data_from_single_image_graph_to_cluster_graph(line_graph: nx.DiGraph, graph: nx.MultiDiGraph): for node in line_graph.adj: for neighbour in nx.neighbors(line_graph, node): edge = line_graph.get_edge_data(node, neighbour) for neighbour2 in nx.neighbors(line_graph, neighbour): edge2 = line_graph.get_edge_data(neighbour, neighbour2) graph.add_edge(edge['cluster'], edge2['cluster'], key=None, nodes_from=str(node) + "_" + str(neighbour), nodes_to=str(neighbour) + "_" + str(neighbour2))
def AddInterproceduralCallEdges( graph: nx.MultiDiGraph, call_multigraph: nx.MultiDiGraph, function_entry_exit_nodes: typing.Dict[str, typing.Tuple[int, int]], ) -> None: """Add call edges between procedures to match the call graph. Args: graph: The disconnected per-function graphs. call_multigraph: A call graph with parallel edges to indicate multiple calls from the same function. function_entry_exit_nodes: A mapping from function name to a tuple of entry and exit statements. """ # Drop the parallel edges by converting the call graph back to a regular # directed graph. Iterating over the edges in this graph then provides the # functions that need connecting, while the multigraph tells us how many # connections to expect. call_graph = nx.DiGraph(call_multigraph) for src, dst in call_graph.edges: # Ignore connections to the root node, we have already processed them. if src == "external node": continue call_sites = llvm_statements.FindCallSites(graph, src, dst) if not call_sites: continue # Check that the number of call sounds we found matches the expected number # from the call graph. # multigraph_call_count = call_multigraph.number_of_edges(src, dst) # if len(call_sites) != multigraph_call_count: # raise ValueError("Call graph contains " # f"{humanize.Plural(multigraph_call_count, 'call')} from " # f"function `{src}` to `{dst}`, but found " # f"{len(call_sites)} call sites in the graph") for call_site in call_sites: if dst not in function_entry_exit_nodes: continue # Lookup the nodes to connect. call_entry, call_exit = function_entry_exit_nodes[dst] # Connect the nodes. graph.add_edge(call_site, call_entry, flow=programl_pb2.Edge.CALL, position=0) graph.add_edge(call_exit, call_site, flow=programl_pb2.Edge.CALL, position=0)
def read_cref(inmap): modules = MultiDiGraph() while True: l = inmap.readline() words = l.split() if len(words) == 2: last_symbol = words[0] last_module = words[1] elif len(words) == 1: modules.add_edge(words[0], last_module, label=last_symbol); elif len(l) == 0: break return modules
def InjectConnection(group1: Group, group2: Group, graph: nx.MultiDiGraph): neuron_group_1 = group1.get_nodes() neuron_group_2 = group2.get_nodes() if len(neuron_group_1) != len(neuron_group_2): raise Exception('Size of group do not match for inject connection') for node in neuron_group_1: graph.add_node(node) for node in neuron_group_2: graph.add_node(node) for i in range(len(neuron_group_1)): graph.add_edge(neuron_group_1[i], neuron_group_2[i])
def selector(request): request.session['viewer'] = request.path_info if request.method == 'POST': form = Neo4jQueryForm(request.POST) if form.is_valid(): host = request.session.get('host', None) if host: gdb = GraphDatabase(host) node = gdb.node[form.cleaned_data['node']] depth = form.cleaned_data['depth'] new_nodes = [] graph = MultiDiGraph() node_id = str(node.id) graph.add_node(node_id, **node.properties) new_nodes.append(node_id) for i in range(depth): added_nodes = [] for node_id in new_nodes: node = gdb.node[node_id] for relation in node.relationships.all(): start = relation.start end = relation.end if start not in new_nodes: start_id = str(start.id) graph.add_node(start_id, **start.properties) added_nodes.append(start_id) if end not in new_nodes: end_id = str(end.id) graph.add_node(end_id, **end.properties) added_nodes.append(end_id) graph.add_edge(start_id, end_id, **relation.properties) new_nodes += added_nodes interactor = NetworkxInteractor(graph) request.session['interactor'] = interactor request.session['layout'] = None response_dictionary = set_response_dictionary(request) else: form = Neo4jConnectionForm() return render_to_response('neo4j/index.html', { 'form': form, }) return render_to_response('neo4j/explorer.html', response_dictionary) else: interactor = request.session.get('interactor') return render_to_response('neo4j/explorer.html', set_response_dictionary(request))
def scale_free_graph(n, G=None, alpha=0.41, beta=0.54, gamma=0.05, delta_in=0.2, delta_out=0, seed=None): """Return a scale free directed graph Parameters ---------- n : integer Number of nodes in graph G : NetworkX graph (optional) Use as starting graph in algorithm alpha : float Probability for adding a new node conecgted to an existing node chosen randomly according to the in-degree distribution. beta : float Probability for adding an edge between two existing nodes. One existing node is chosen randomly according the in-degree distribution and the other chosen randomly according to the out-degree distribution. gamma : float Probability for adding a new node conecgted to an existing node chosen randomly according to the out-degree distribution. delta_in : float Bias for choosing ndoes from in-degree distribution. delta_out : float Bias for choosing ndoes from out-degree distribution. delta_out : float Bias for choosing ndoes from out-degree distribution. seed : integer (optional) Seed for random number generator Examples -------- >>> G=nx.scale_free_graph(100) Notes ----- The sum of alpha, beta, and gamma must be 1. Algorithm from @article{bollobas2003dsf, title={{Directed scale-free graphs}}, author={Bollob{\'a}s, B. and Borgs, C. and Chayes, J. and Riordan, O.}, journal={Proceedings of the fourteenth annual ACM-SIAM symposium on Discrete algorithms}, pages={132--139}, year={2003}, publisher={Society for Industrial and Applied Mathematics Philadelphia, PA, USA} } """ def _choose_node(G,distribution,delta): cumsum=0.0 # normalization psum=float(sum(distribution.values()))+float(delta)*len(distribution) r=random.random() for i in range(0,len(distribution)): cumsum+=(distribution[i]+delta)/psum if r < cumsum: break return i if G is None: # start with 3-cycle G=MultiDiGraph() G.add_edges_from([(0,1),(1,2),(2,0)]) if alpha <= 0: raise ValueError('alpha must be >= 0.') if beta <= 0: raise ValueError('beta must be >= 0.') if gamma <= 0: raise ValueError('beta must be >= 0.') if alpha+beta+gamma !=1.0: raise ValueError('alpha+beta+gamma must equal 1.') G.name="directed_scale_free_graph(%s,alpha=%s,beta=%s,gamma=%s,delta_in=%s,delta_out=%s)"%(n,alpha,beta,gamma,delta_in,delta_out) # seed random number generated (uses None as default) random.seed(seed) while len(G)<n: r = random.random() # random choice in alpha,beta,gamma ranges if r<alpha: # alpha # add new node v v = len(G) # choose w according to in-degree and delta_in w = _choose_node(G, G.in_degree(with_labels=True),delta_in) elif r < alpha+beta: # beta # choose v according to out-degree and delta_out v = _choose_node(G, G.out_degree(with_labels=True),delta_out) # choose w according to in-degree and delta_in w = _choose_node(G, G.in_degree(with_labels=True),delta_in) else: # gamma # choose v according to out-degree and delta_out v = _choose_node(G, G.out_degree(with_labels=True),delta_out) # add new node w w = len(G) G.add_edge(v,w) return G
def add_edge(self,node1,node2,**kwargs):# inefficient but nobody cares and it's convenient e=Edge(node1,node2,self.keycounter,kwargs) MultiDiGraph.add_edge(self,node1,node2,object = e,key = self.keycounter) self.InverseLookUp[kwargs["morphism"]] = e self.keycounter+=1 return e
def parseArnetminerDataset(): """ Parse the four area dataset, and use only barebones structures to keep everything efficient. Skips papers that: (1) The final parsed network """ inputFile = open(os.path.join(projectRoot, 'data','DBLP-citation-Feb21.txt')) graph = MultiDiGraph() # Sets for authors, papers, conferences, and terms found so far indexToPaperIdMap = {} citationCountMap = {} indexSet = set() beginning = inputFile.tell() print "Parsing nodes for graph..." # Counts for statistics VALID_PAPERS = 1566322 # 99.62% of total papers in DBLP dataset papersProcessed = 0 skippedPaperIndices = set() invalidPaperIndices = set() # Add each paper to graph (adding missing associated terms, authors, and conferences) for title, authors, conference, terms, citationCount, index in __papersFromFile(inputFile, skippedPaperIndices, invalidPaperIndices): # Check that index is unique, and record it assert index not in indexSet indexSet.add(index) # Create unique identifier with paper index & title paperId = '%d----%s' % (index, title) citationCountMap[paperId] = citationCount indexToPaperIdMap[index] = paperId # Add symmetric edges & nodes (if they don't already exist in the network) for author in authors: graph.add_edges_from([(author, paperId), (paperId, author)]) graph.add_edges_from([(conference, paperId), (paperId, conference)]) for term in terms: graph.add_edges_from([(term, paperId), (paperId, term)]) # Output progress papersProcessed += 1 sys.stdout.write("\r Processed %d / %d papers..." % (papersProcessed, VALID_PAPERS)) # Rewind file inputFile.seek(beginning) print "Parsing citations for graph..." # Counts for statistics papersProcessed = 0 successfulCitations = 0 omittedPaperCitations = 0 invalidPaperCitations = 0 invalidCitations = 0 # Add citations to the graph for title, index, citations in __citationsFromFile(inputFile): citingId = '%d----%s' % (index, title) for citationIndex in citations: # Add citation edge if it was found if citationIndex in indexToPaperIdMap: successfulCitations += 1 graph.add_edge(citingId, indexToPaperIdMap[citationIndex]) # Tally missing citation appropriately elif citationIndex in skippedPaperIndices: omittedPaperCitations += 1 elif citationIndex in invalidPaperIndices: invalidPaperCitations += 1 else: print "\nCitation '%d' not found for '%s'" % (citationIndex, title) invalidCitations += 1 # Output progress papersProcessed += 1 sys.stdout.write("\r Processed Citations for %d / %d papers..." % (papersProcessed, VALID_PAPERS)) # Basic statistics about cleanliness of citations totalCitations = invalidCitations + successfulCitations successfulCitationsPercent = 100 * float(successfulCitations) / totalCitations omittedPaperCitationsPercent = 100 * float(omittedPaperCitations) / totalCitations invalidPaperCitationsPercent = 100 * float(invalidPaperCitations) / totalCitations invalidCitationsPercent = 100 * float(invalidCitations) / totalCitations print "\n\nTotal Citations: %d" % totalCitations print " Citations Added (Successful): %d (%2.2f%%)" % (successfulCitations, successfulCitationsPercent) print " Citations Skipped (Skipped Paper): %d (%2.2f%%)" % (omittedPaperCitations, omittedPaperCitationsPercent) print " Citations Skipped (Invalid Paper): %d (%2.2f%%)" % (invalidPaperCitations, invalidPaperCitationsPercent) print " Citations Invalid (Unknown): %d (%2.2f%%)" % (invalidCitations, invalidCitationsPercent) return graph
class Grafatality(object): def __init__(self, filename='graph.json'): self.filename=filename self.graph = MultiDiGraph() self.typed_nodes = {} self.typed_nodes[None] = [] try: self.load_file(filename) except IOError as e: print 'file "%s" does not exist, creating' % filename def handle(self, line): obj = ujson.loads(line) action = obj['action'] if action == 'add_node': self.load_node(obj) elif action == 'add_edge': self.load_edge(obj) elif action == 'remove_edge': self.load_remove_edge(obj) def load_file(self, filename): f = open(filename) for line in f: self.handle(line) f.close() def listify_typed_node(self, node): if type(node) == list: node = tuple(node) if len(node) == 2: node = tuple(node) return node def load_edge(self, obj): data = obj.get('data', None) key = obj.get('key', None) src_node = obj['src_node'] dst_node = obj['dst_node'] src_node = self.listify_typed_node(src_node) dst_node = self.listify_typed_node(dst_node) if data: self.graph.add_edge(src_node, dst_node, key=key, **data) else: self.graph.add_edge(src_node, dst_node, key=key) def load_remove_edge(self, obj): key = obj.get('key', None) self.graph.remove_edge(obj['src_node'], obj['dst_node'], key=key) def load_node(self, obj): data = obj.get('data', None) node = obj['node'] node_type = None node = self.listify_typed_node(node) if data: self.graph.add_node(node, node_type=node_type, **data) else: self.graph.add_node(node, node_type=node_type) def add_node(self, node, node_type=None, **attr): if node_type: if not node_type in self.typed_nodes: self.typed_nodes[node_type] = [] node = (node, node_type) self.typed_nodes[node_type].append(node) else: self.typed_nodes[None].append(node) data = {"action": "add_node", "node": node} if len(attr): data['data'] = attr self.append_log(data) return self.graph.add_node(node, **attr) def nodes_of_type(self, node_type=None, full=True): if full: return self.typed_nodes[node_type] else: return self.typed_nodes[node_type][0] def add_edge(self, src_node, dst_node, key=None, **attr): data = {"action": "add_edge", "src_node": src_node, "dst_node": dst_node} if len(attr): data['data'] = attr if key: data['key'] = key self.append_log(data) return self.graph.add_edge(src_node, dst_node, key=key, **attr) def remove_edge(self, src_node, dst_node, key): data = {"action": "remove_edge", "src_node": src_node, "dst_node": dst_node, "key": key} self.append_log(data) return self.graph.remove_edge(src_node, dst_node, key) def append_log(self,data): """ This persists the data and while it may be true that the logfile could be kept open indefinitely, for some reason this causes dataloss when running multiprocess files. """ self.log = open(self.filename, 'a') self.log.write(ujson.encode(data)) self.log.write("\n") self.log.close() def shutdown(self): self.log.close()
class AbstractGame: def __init__(self, player1, player2, initial_gamestate): self.game_graph = MultiDiGraph() self.player1 = player1 self.player2 = player2 self.initial_gamestate = self.canonicalize(initial_gamestate) def canonicalize(self, gamestate): raise NotImplementedError def possible_moves(self, gamestate, player): raise NotImplementedError def other_player(self, player): if player == self.player1: return self.player2 elif player == self.player2: return self.player1 else: raise ValueError("%s is neither %s nor %s" % (player, self.player1, self.player2)) def is_winning_position(self, gamestate, player): raise NotImplementedError def is_losing_position(self, gamestate, player): raise NotImplementedError def good_moves(self, gamestate, player, lookahead_depth): if lookahead_depth == 0: yield from self.possible_moves(gamestate, player) else: lookahead_depth -= 1 sign = {self.player1: 1, self.player2: -1} def is_game_over(gamestate): return evaluate_gamestate(gamestate, 0) != 0 def evaluate_gamestate(gamestate, depth): """ Returns 1 if this gamestate favors the first player, -1 if it favors the second player, and 0 if it is neutral. """ if self.is_winning_position(gamestate, self.player1): return 1000 - depth elif self.is_winning_position(gamestate, self.player2): return -1000 + depth else: return 0 def negamax(gamestate, current_depth, current_player): if is_game_over(gamestate) or current_depth > lookahead_depth: return sign[current_player] * evaluate_gamestate(gamestate, current_depth) max_score = -1000 for possible_gamestate in self.possible_moves(gamestate, current_player): max_score = max(max_score, -negamax(possible_gamestate, current_depth + 1, self.other_player(current_player))) return max_score moves_and_lookaheads = {move: -negamax(move, 1, self.other_player(player)) for move in self.possible_moves(gamestate, player)} if len(moves_and_lookaheads) == 0: return best_lookahead = max(moves_and_lookaheads.values()) good_moves = {self.canonicalize(move) for move, lookahead in moves_and_lookaheads.items() if lookahead == best_lookahead} for move in good_moves: yield move def play(self, lookahead=0): new_moves = set() # A set of node, player tuples containing all new moves that can be played in this graph. def play_new_moves(): new_new_moves = set() # The moves that will be new after current new moves have been played. for gamestate, player in new_moves: next_player = self.other_player(player) for move_result in self.good_moves(gamestate, player, lookahead): move_result = self.canonicalize(move_result) if move_result not in self.game_graph: # Add the result to the graph if it's not there. self.game_graph.add_node(move_result, players=set()) self.game_graph.add_edge(gamestate, move_result, key=player) # Add this move to the graph if next_player not in self.game_graph.node[move_result]['players']: self.game_graph.node[move_result]['players'].add(next_player) new_new_moves.add((move_result, next_player)) new_moves.clear() new_moves.update(new_new_moves) new_moves.add((self.initial_gamestate, self.player1)) self.game_graph.add_node(self.initial_gamestate, players=set()) while len(new_moves) != 0: play_new_moves() self.game_graph