def moralize(dag): """ Moralizes a DAG. :param dag: DAG. :return: Moralized (undirected) graph. """ ug = Ug() for node in dag.get_nodes(): ug.add_node(node) for edge in dag.get_edges(): ug.add_edge(Edge(edge.i, edge.j, EdgeType.UNDIRECTED)) for node in dag.get_nodes(): parents = [dag.get_node(pa) for pa in dag.get_parents(node.id)] size = len(parents) for i in range(size): pa1 = parents[i] for j in range(i + 1, size): pa2 = parents[j] ug.add_edge(Edge(pa1, pa2, EdgeType.UNDIRECTED)) for node in dag.get_nodes(): parents = [dag.get_node(pa) for pa in dag.get_parents(node.id)] node.add_metadata('parents', parents) return ug
def process_core(self, part, node_map, all_nodes, edges, d): from_nodes = [] to_node = None for source in d['sources']: self.upsert_node( node_map, source) # first, check and upsert if not in node_map from_nodes.append(node_map[source]) if source.startswith('MODULE_'): self.connect_module_params(node_map, all_nodes, edges, node_map[source], d.get('params', [])) if '.' in source: main_node_name = source.split('.')[0] if main_node_name in node_map: edges.append( Edge(node_map[main_node_name], node_map[source])) if len(from_nodes) == 0: from_nodes.append(node_map['last_node']) if d['assign_var']: attr = {} node_name = d['assign_var'] if node_name in node_map: attr = node_map[node_name].attr # for those like PROCESS ... USING if 'using' in d: attr['using'] = d['using'] new_node = Node(node_name, attr=attr) node_map[node_name] = new_node # update to_node = new_node else: if not node_map['last_node']: new_node = Node("SCOPE_IMPLICIT") to_node = new_node else: to_node = node_map['last_node'] for from_node in from_nodes: edges.append(Edge(from_node, to_node)) all_nodes.append(from_node) all_nodes.append(to_node) node_map['last_node'] = to_node
def from_dict(d): """ Creates a BBN from a dictionary (deserialized JSON). :param d: Dictionary. :return: BBN. """ def get_variable(d): return Variable(d['id'], d['name'], d['values']) def get_bbn_node(d): return BbnNode(get_variable(d['variable']), d['probs']) nodes = {k: get_bbn_node(n) for k, n in d['nodes'].items()} edges = d['edges'] bbn = Bbn() for k, n in nodes.items(): bbn.add_node(n) for e in edges: pa_id = e['pa'] ch_id = e['ch'] pa = nodes[pa_id] if pa_id in nodes else nodes[str(pa_id)] ch = nodes[ch_id] if ch_id in nodes else nodes[str(ch_id)] bbn.add_edge(Edge(pa, ch, EdgeType.DIRECTED)) return bbn
def build_bbn(variable_profiles, g, p): """ Builds a BBN from a DAG, g, and paremeters, p. :param variable_profiles: Variable profiles. :param g: DAG. :param p: Parameters. :return: BBN. """ bbn = Bbn() nodes = list(g.nodes) bbn_node_dict = {} for idx in nodes: name = g.nodes[idx]['name'] domain = variable_profiles[name] cpt = p[idx] v = Variable(idx, name, domain) n = BbnNode(v, cpt) bbn.add_node(n) bbn_node_dict[idx] = n edges = list(g.edges) for edge in edges: pa = bbn_node_dict[edge[0]] ch = bbn_node_dict[edge[1]] e = Edge(pa, ch, EdgeType.DIRECTED) bbn.add_edge(e) return bbn
def add_edge(self, target, value): """ Adds an edge to this node. :param target: The target of the edge. :param value: The weight of this edge. :return: """ self.edges.append(Edge(start=self, end=target, val=value))
def connect_module_params(self, node_map, all_nodes, edges, dest_node, params): for param in params: if not param in node_map: # do nothing if param not appeared before continue param_node = node_map[param] edges.append(Edge(param_node, dest_node))
def testAddRoute(self): self.g.add_route('TYO', 'YYZ', 2000) node = self.g.get_node_from_code('TYO') e = Edge('YYZ', 2000) bool = False for edge in node.edges: if e.destination == edge.destination and e.distance == edge.distance: bool = True break assert bool == True
def get_edges(bn, nodes): edges = [] for k, v in bn.Vdata.items(): ch = nodes[k] if v['parents'] is not None and len(v['parents']) > 0: parents = [nodes[pa] for pa in v['parents']] for pa in parents: edge = Edge(pa, ch, EdgeType.DIRECTED) edges.append(edge) return edges
def add_edge(self, start_node, end_node, label=""): key = frozenset([start_node, end_node, label]) if key not in self.edges: if start_node not in self.needed_nodes: self.needed_nodes.append(start_node) if end_node not in self.needed_nodes: self.needed_nodes.append(end_node) self.edges[key] = Edge(start_node, end_node, label) start_node.add_out(end_node) end_node.add_inc(start_node) return self.edges[key]
def get_simple(): """ Gets a simple BBN graph. :return: BBN. """ a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.5, 0.5]) b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.5, 0.5, 0.4, 0.6]) c = BbnNode(Variable(2, 'c', ['on', 'off']), [0.7, 0.3, 0.2, 0.8]) d = BbnNode(Variable(3, 'd', ['on', 'off']), [0.9, 0.1, 0.5, 0.5]) e = BbnNode(Variable(4, 'e', ['on', 'off']), [0.3, 0.7, 0.6, 0.4]) f = BbnNode(Variable(5, 'f', ['on', 'off']), [0.01, 0.99, 0.01, 0.99, 0.01, 0.99, 0.99, 0.01]) bbn = Bbn() \ .add_node(a) \ .add_node(b) \ .add_node(c) \ .add_node(d) \ .add_node(e) \ .add_node(f) \ .add_edge(Edge(a, b, EdgeType.DIRECTED)) \ .add_edge(Edge(a, c, EdgeType.DIRECTED)) \ .add_edge(Edge(b, d, EdgeType.DIRECTED)) \ .add_edge(Edge(c, e, EdgeType.DIRECTED)) \ .add_edge(Edge(d, f, EdgeType.DIRECTED)) \ .add_edge(Edge(e, f, EdgeType.DIRECTED)) return bbn
def process_output(self, part, node_map, all_nodes, edges): d = self.output.parse(part) self.logger.debug(d) to_node = Node(d['path'], attr={ 'type': 'output', 'style': 'filled', 'fillcolor': 'tomato' }) source_names = d['idents'] if not source_names: from_node = node_map['last_node'] edges.append(Edge(from_node, to_node)) else: for source_name in source_names: from_node = node_map.get(source_name, node_map['last_node']) edges.append(Edge(from_node, to_node)) all_nodes.append(to_node)
def filter_objects(self, adj_map, rev_map, nodes_map, type_='SCRIPT'): ''' To remove event nodes, reserve script mapping only current graph is script -> event -> script -> event -> ... :param adj_map: adjacency map (a -> (node_b, node_c)) :param rev_map: reverse map (b -> (node_a, node_d)) :param nodes_map: contains all nodes by now :return: the new nodes and edges ''' # reconstruct edges from nodes nodes = set() edges = set() for from_name in adj_map: from_node = nodes_map[from_name] # always keep root event node if from_node.attr['type'] == 'EVENT' and from_name not in rev_map: nodes.add(from_node) for to_node in adj_map[from_name]: edges.add(Edge(from_node, to_node)) if from_node.attr['type'] != type_: continue nodes.add(from_node) for to_node in adj_map[from_name]: to_name = to_node.name # map child's children to parent if to_name in adj_map: for grand_to_node in adj_map[to_name]: edges.add(Edge(from_node, grand_to_node)) return nodes, edges
def generateEdges(self, inQueriedTweets, directed): edgeIDcount = 0 tweets = inQueriedTweets tempEdges = dict() for tweet in tweets: entities = tweet.getEntities() # Edges establishment for k in range(0, len(entities) - 1): for j in range(k + 1, len(entities)): if entities[k] == entities[j]: continue fromNode = entities[k] toNode = entities[j] nEdge = Edge.Edge_without_id(fromNode, toNode, 1) hCode = nEdge.__hash__() if hCode in tempEdges: # tempEdges.__contains__(hCode)): tempEdges[hCode]._mWeight += 1 else: tempEdges[hCode] = nEdge print("There are %d edges in buff" % len(tempEdges)) # Load edges into mEdges col = tempEdges.values() for edge in col: officialEdge = Edge(edgeIDcount, edge.getFromNode(), edge.getToNode(), edge.getWeight()) check = self.addEdge(officialEdge) if check: edgeIDcount += 1 if directed == False: reservedEdge = Edge(edgeIDcount, edge.getToNode(), edge.getFromNode(), edge.getWeight()) check2 = self.addEdge(reservedEdge) if check2: edgeIDcount += 1 print("Loading edges completed. Number of edges:%d" % len(self._mEdges)) self.constructTransitionMatrix() self.constructTransitionTransposeMatrix() print("Constructing transition matrices completed!")
def get_random_edges(no_points, no_edges): edges = [] i = 0 while i < no_edges: start = random.randint(0, no_points - 1) end = random.randint(0, no_points - 1) new_edge = Edge(start, end) for edge in edges: if str(edge) == str(new_edge): continue edges.append(new_edge) i += 1 # print('random edges : ' + edges) return edges
def get_edges_to_add(n, m): """ Gets edges to add. :param n: BBN node. :param m: Graph. :return: Array of edges. """ neighbors = [m.get_node(i) for i in m.get_neighbors(n.id)] return [ Edge(neighbors[i], neighbors[j], EdgeType.UNDIRECTED) for i, j in combinations(range(len(neighbors)), 2) if not m.edge_exists(neighbors[i].id, neighbors[j].id) ]
def add_movie(self,movie): ''' add an movie into structure and update edges ''' self.movieList.append(movie) num_actor = len(movie.actors) if (num_actor==0): return weight_base= (1+num_actor)*num_actor/2 for actor in self.actorList: if (movie.name in actor.movies and actor.name in movie.actors): weight = (num_actor-movie.actors.index(actor.name)-1)/weight_base weight = weight*movie.gross edge = Edge(actor,movie,weight) self.edgeList.append(edge) actor.total_gross=actor.total_gross+weight
def from_csv(path): """ Converts the BBN in CSV format to a BBN. :param path: Path to CSV file. :return: BBN. """ with open(path, 'r') as f: nodes = {} edges = [] for line in f: tokens = line.split(',') if 3 == len(tokens): edge = int(tokens[0]), int(tokens[1]) edges.append(edge) else: tokens = line.split('|') v_part = [ item.strip() for item in tokens[0].split(',') if len(item.strip()) > 0 ] p_part = [ item.strip() for item in tokens[1].split(',') if len(item.strip()) > 0 ] i = int(v_part[0]) v = Variable(i, v_part[1], v_part[2:]) p = [float(p) for p in p_part] node = BbnNode(v, p) nodes[i] = node bbn = Bbn() for _, node in nodes.items(): bbn.add_node(node) for edge in edges: pa_id, ch_id = edge pa = nodes[pa_id] ch = nodes[ch_id] bbn.add_edge(Edge(pa, ch, EdgeType.DIRECTED)) return bbn
def get_huang_graph(): """ Gets the Huang reference BBN graph. :return: BBN. """ a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.5, 0.5]) b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.5, 0.5, 0.4, 0.6]) c = BbnNode(Variable(2, 'c', ['on', 'off']), [0.7, 0.3, 0.2, 0.8]) d = BbnNode(Variable(3, 'd', ['on', 'off']), [0.9, 0.1, 0.5, 0.5]) e = BbnNode(Variable(4, 'e', ['on', 'off']), [0.3, 0.7, 0.6, 0.4]) f = BbnNode(Variable(5, 'f', ['on', 'off']), [0.01, 0.99, 0.01, 0.99, 0.01, 0.99, 0.99, 0.01]) g = BbnNode(Variable(6, 'g', ['on', 'off']), [0.8, 0.2, 0.1, 0.9]) h = BbnNode(Variable(7, 'h', ['on', 'off']), [0.05, 0.95, 0.95, 0.05, 0.95, 0.05, 0.95, 0.05]) bbn = Bbn() \ .add_node(a) \ .add_node(b) \ .add_node(c) \ .add_node(d) \ .add_node(e) \ .add_node(f) \ .add_node(g) \ .add_node(h) \ .add_edge(Edge(a, b, EdgeType.DIRECTED)) \ .add_edge(Edge(a, c, EdgeType.DIRECTED)) \ .add_edge(Edge(b, d, EdgeType.DIRECTED)) \ .add_edge(Edge(c, e, EdgeType.DIRECTED)) \ .add_edge(Edge(d, f, EdgeType.DIRECTED)) \ .add_edge(Edge(e, f, EdgeType.DIRECTED)) \ .add_edge(Edge(c, g, EdgeType.DIRECTED)) \ .add_edge(Edge(e, h, EdgeType.DIRECTED)) \ .add_edge(Edge(g, h, EdgeType.DIRECTED)) return bbn
def add_actor(self,actor): ''' add an actor into structure and update edges ''' self.actorList.append(actor) total_gross=0 for movie in self.movieList: num_actor = len(movie.actors) if (num_actor==0): continue weight_base= (1+num_actor)*num_actor/2 if (movie.name in actor.movies and actor.name in movie.actors): weight = (num_actor-movie.actors.index(actor.name)-1)/weight_base weight = weight*movie.gross edge = Edge(actor,movie,weight) self.edgeList.append(edge) total_gross=total_gross+weight if (actor.total_gross==0): actor.total_gross=total_gross
def make_edge(self): ''' construct edgeList using self.movieList and self.actorList Each edge connects a actor and a movie and weight weight is an approximate value of how much the actor earned in the movie weight is partially determined by how top the actor appear in the movie's cast list ''' self.edgeList=[] for movie in self.movieList: num_actor = len(movie.actors) if (num_actor==0): continue weight_base= (1+num_actor)*num_actor/2 for actor in self.actorList: if (movie.name in actor.movies and actor.name in movie.actors): weight = (num_actor-movie.actors.index(actor.name)-1)/weight_base weight = weight*movie.gross edge = Edge(actor,movie,weight) self.edgeList.append(edge) actor.total_gross=actor.total_gross+weight
class GraphUtility(object): def __init__(self, nodes, edges): self.nu = NetworkXUtility() for node in nodes: self.nu.add_node(node, **node.attr) for edge in edges: self.nu.add_edge(edge.from_, edge.to_, **edge.attr) def to_gexf_file(self, dest_file): return self.nu.to_gexf(dest_file) def to_dot_file(self, dest_file): return self.nu.to_dot(dest_file) def dot_to_graphviz(self, dot_file_path, format='pdf'): s = Source.from_file(dot_file_path, format=format) s.render(dot_file_path, view=False) if __name__ == '__main__': nodes = [] edges = [] nodes.append(Node('a')) nodes.append(Node('b')) edges.append(Edge('a', 'b')) GraphUtility(nodes, edges).to_gexf_file('d:/tmp/tt.gexf')
self.__adj[v].add(w) self.__adj[w].add(v) def adj(self, v): return self.__adj[v] class EdgeWeightedDirectedGraph: def __init__(self, size): self.__adj = [set() for i in range(size)] self.size = size def add_edge(self, edge): if edge in self.__adj[edge.v]: self.__adj[edge.v].remove(edge) self.__adj[edge.v].add(edge) def adjacency_of(self, vertex): return self.__adj[vertex] if __name__ == '__main__': g = EdgeWeightedDirectedGraph(5) g.add_edge(Edge(1, 2, 12)) g.add_edge(Edge(2, 4, 13)) g.add_edge(Edge(2, 3, 4)) g.add_edge(Edge(2, 3, 5)) g.add_edge(Edge(2, 5, 4)) for i in g.adjacency_of(2): print(i)
def read_file_bif_format(filepath): ''' read file in bif format and create bayesian network and build junction tree @ params: filepath : path to input file in bif format @ returns join_tree: junction tree ''' f = open(filepath, "r") var_to_values = dict() probabilities = defaultdict(list) dependencies = dict() allnames = [] # iterate all rows of the file with open(filepath, 'r') as f: lines = f.readlines() i = 0 while i < len(lines): # next line line = lines[i] tokens = line.split(" ") if tokens[0] == 'variable': # new variable name = tokens[1] allnames.append(name) # next line contains values i += 1 line = lines[i] # get all the values assuming they are always expressed in the same way this_var_values = line.split("{")[-1][1:-3].split(", ") var_to_values[name] = this_var_values # next line is closed curly brackets - we skip it i += 2 elif tokens[0] == 'probability': name = tokens[2] dependencies[name] = [ token.replace(',', '') for token in tokens[4:-2] ] # get probabilities i += 1 line = lines[i] while line != "}\n": tokens = line.split(" ") for token in tokens: if sum([char.isdigit() for char in token[:-1]]) > 0 and "." in token: #and not any(c.isalpha() for c in token[:-1]) : try: probabilities[name].append(float(token[:-1])) except: probabilities[name].append(float(token[:-2])) i += 1 line = lines[i] # finished the while loop we go to the next i += 1 else: # only next line (extra lines e.g. first) i += 1 # now create bbn bbn = Bbn() name_to_node = dict() #add nodes for i in range(len(allnames)): name = allnames[i] node = BbnNode(Variable(i, name, var_to_values[name]), probabilities[name]) bbn.add_node(node) # for edges name_to_node[name] = node #add edges for i in range(len(allnames)): name = allnames[i] this_dependecies = dependencies[name] for dependency in this_dependecies: bbn.add_edge( Edge(name_to_node[dependency], name_to_node[name], EdgeType.DIRECTED)) # convert bbn to junction tree join_tree = InferenceController.apply(bbn) return join_tree
def get_target_objects(self, adj_map, rev_map, nodes_map, target_node_names=[]): ''' To reserve only nodes related to target nodes The relationship is defined as up(direct parent node), down(all children node) :param adj_map: adjacency map (a -> (node_b, node_c)) :param rev_map: reverse map (b -> (node_a, node_d)) :param nodes_map: contains all nodes by now :param target_node_names: if specified, only trace 'related' nodes :return: the new nodes and edges ''' target_map = {} # init for node_name in target_node_names: if node_name not in nodes_map: self.logger.info( 'specified node [{}] not in node_map. skip.'.format( node_name)) continue target_map[node_name] = set(['up', 'down']) # highlight target nodes nodes_map[node_name].attr['style'] = 'filled' nodes_map[node_name].attr['fillcolor'] = 'yellow' # reconstruct edges from nodes nodes = set() edges = set() visited = set() while len(target_map) > 0: target_name, mode_list = target_map.popitem() the_node = nodes_map[target_name] visited_key = '{}.{}'.format(the_node, mode_list) if visited_key in visited: continue visited.add(visited_key) nodes.add(the_node) if 'down' in mode_list: if target_name not in adj_map: continue for to_node in adj_map[target_name]: nodes.add(to_node) if to_node.name not in target_map: target_map[to_node.name] = set() target_map[to_node.name].add('down') edges.add(Edge(the_node, to_node)) if 'up' in mode_list: if target_name not in rev_map: continue for from_node in rev_map[target_name]: nodes.add(from_node) if from_node.name not in target_map: target_map[from_node.name] = set() target_map[from_node.name].add('up') edges.add(Edge(from_node, the_node)) return nodes, edges
def to_workflow_dep_graph(self, workflow_obj, dest_filepath=None, target_node_names=[], filter_type=None): obj = workflow_obj event_deps = obj.process_event_deps workflows = obj.workflows process_master_map = obj.process_master_map event_interval_map = obj.event_interval_map nodes_map = {} edges = [] adj_map = {} rev_map = {} for process_name in workflows: # only show those enabled in master config if process_name not in process_master_map: self.logger.debug( 'skip process [{}] because it is not in master config.'. format(process_name)) continue script_fullpath = workflows[process_name]['ScriptFile'] script_name = os.path.basename(script_fullpath) script_attr = { 'id': script_name, 'label': script_name, 'type': 'SCRIPT', 'tooltip': script_fullpath } if not script_name in nodes_map: script_node = Node(script_name, attr=script_attr) nodes_map[script_name] = script_node script_node = nodes_map.get(script_name) # the output event of this process output_event_name = workflows[process_name]['EventName'] if output_event_name not in nodes_map: script_out_event_node = Node(output_event_name, attr={ 'id': output_event_name, 'label': output_event_name, 'type': 'EVENT' }) nodes_map[output_event_name] = script_out_event_node script_out_event_node = nodes_map.get(output_event_name) # add edge edges.append(Edge(script_node, script_out_event_node)) # for target filtering self.update_adj_map(script_node, script_out_event_node, adj_map, rev_map) # input events dep_events = event_deps[process_name] for event_name in dep_events: # to make the graph less complex normalized_event_name = self.normalize_event_name(event_name) if normalized_event_name not in nodes_map: event_attr = { 'id': normalized_event_name, 'label': normalized_event_name, 'type': 'EVENT' } script_in_event_node = Node(normalized_event_name, attr=event_attr) nodes_map[normalized_event_name] = script_in_event_node script_in_event_node = nodes_map.get(normalized_event_name) # add edge edges.append(Edge(script_in_event_node, script_node)) # for target filtering self.update_adj_map(script_in_event_node, script_node, adj_map, rev_map) # update event interval for node_name in nodes_map: if nodes_map[node_name].attr['type'] == 'EVENT': # external event if node_name not in event_interval_map: continue interval = event_interval_map[node_name] nodes_map[node_name].attr['label'] += ' ({})'.format(interval) nodes_map[node_name].attr['interval'] = interval self.logger.debug('node_map.keys = {}'.format(nodes_map.keys())) if target_node_names: nodes, edges = self.get_target_objects( adj_map, rev_map, nodes_map, target_node_names=target_node_names) else: nodes = nodes_map.values() # for now not support target_node_names go together with filter if filter_type: nodes, edges = self.filter_objects(adj_map, rev_map, nodes_map, type_=filter_type) if dest_filepath: self.logger.info('change node color for output') self.change_node_color(nodes) gu = GraphUtility(nodes, edges) gexf_output_file = gu.to_gexf_file(dest_filepath) self.logger.info( 'output .gexf file to [{}]'.format(gexf_output_file)) dot_output_file = gu.to_dot_file(dest_filepath) self.logger.info( 'output .dot file to [{}]'.format(dot_output_file)) self.logger.info('render graphviz file pdf') gu.dot_to_graphviz(dot_output_file, format='pdf') self.logger.info('render graphviz file svg') gu.dot_to_graphviz(dot_output_file, format='svg')
def add_edge(self, edge: Edge): """ Append edge to vertex """ edge.start = self self.edges.append(edge)
0 7 0.16 1 5 0.32 0 4 0.38 2 3 0.17 1 7 0.19 0 2 0.26 1 2 0.36 1 3 0.29 2 7 0.34 6 2 0.40 3 6 0.52 6 0 0.58 6 4 0.93 ''' g = EdgeWeightedGraph(8) e = Edge(4, 5, 0.35) g.add_edge(e) e = Edge(4, 7, 0.37) g.add_edge(e) e = Edge(5, 7, 0.28) g.add_edge(e) e = Edge(0, 7, 0.16) g.add_edge(e) e = Edge(1, 5, 0.32) g.add_edge(e) e = Edge(0, 4, 0.38) g.add_edge(e) e = Edge(2, 3, 0.17) g.add_edge(e) e = Edge(1, 7, 0.19) g.add_edge(e)
self.__pq_indices[dist_source[1]] = _to else: dist_source = [dist, to] self.__pq_indices[to] = dist_source heappush(self.__pq, dist_source) def dist_to(self, vertex): return self.__dist_to[vertex] if __name__ == '__main__': size = 8 source = 0 g = EdgeWeightedDirectedGraph(size) vertices = {i for i in range(size) if not i == source} g.add_edge(Edge(0, 1, 5)) g.add_edge(Edge(0, 4, 9)) g.add_edge(Edge(0, 7, 8)) g.add_edge(Edge(1, 3, 15)) g.add_edge(Edge(1, 2, 12)) g.add_edge(Edge(1, 7, 4)) g.add_edge(Edge(2, 3, 3)) g.add_edge(Edge(2, 6, 11)) g.add_edge(Edge(3, 6, 9)) g.add_edge(Edge(4, 5, 4)) g.add_edge(Edge(4, 6, 20)) g.add_edge(Edge(4, 7, 5)) g.add_edge(Edge(5, 2, 1)) g.add_edge(Edge(5, 6, 13)) g.add_edge(Edge(7, 2, 7)) g.add_edge(Edge(7, 5, 6))