def has_cycle_b(self): d = Digraph() d.add_edge(1, 2) d.add_edge(2, 3) d.add_edge(3, 1) dc = DirectedCycle(d) self.assertEquals(True, dc.has_cycle())
class SymbolDigraph: def __init__(self, file_name, separator): self.__symbols = {} with open(file_name, 'r') as f: for line in f: tokens = line.strip().split(separator) for token in tokens: if token not in self.__symbols: self.__symbols[token] = len(self.__symbols) self.__keys = [0] * len(self.__symbols) for k, v in self.__symbols.items(): self.__keys[v] = k self.__g = Digraph(len(self.__symbols)) with open(file_name, 'r') as f: for line in f: tokens = line.strip().split(separator) v = self.__symbols[tokens[0]] for token in tokens[1:]: self.__g.add_edge(v, self.__symbols[token]) def contains(self, s): return s in self.__symbols def index_of(self, s): return self.__symbols[s] def name_of(self, v): return self.__keys[v] def digraph(self): return self.__g
def __save_obj(data_path, sentence_path): sentences = ["""我 想 去 北京""", """我 想 吃饭 了""", """北京 在 哪里""", """我 想要 办理 汉口 银行 的 信用卡""", """怎么 办理 信用卡""", """信用卡 怎么 办理""", """我 要 取号""", """我 想去 天安门""",] # for i in [['我', '要', '取号'], ['我', '要', '吃饭']]: with open(sentence_path, 'r', encoding='utf-8') as f: for content in f.readlines(): sentences_list = get_participle(content) sentences.extend(w.gen_sentences(sentences_list, subsystem_id='hm256f8c953411e8aea35254004210bf')) # sentences = [w.gen_sentences(i, subsystem_id='hm256f8c953411e8aea35254004210bf') for i in [['我', '要', '取号'], ['我', '要', '吃饭']]] # sentences.extend(sentences) word_list = [item.split() for item in sentences] # temp = [set(item) for item in word_list] # word_set = reduce(lambda a, b: a | b, temp) # 保证词语不重复 # logger.debug(word_set) begin1 = time.time() # dg = Digraph(word_set) # # 构建词序 # for words in word_list: # l = len(words) # for i in range(l): # if i < l - 1: # dg.addEdge(words[i], words[i + 1]) dg = Digraph() for w_l in word_list: dg.build(w_l) logger.debug("构建耗时:{}秒".format(time.time() - begin1)) save_obj(dg, file_name=data_path) return dg
def __init__(self): self.box_dl = Digraph() # box node -> deadlocks self._boxes_to_deadlock = defaultdict(list) self._box_to_size_to_nodeA = defaultdict(dict) self._nbox_to_size_to_nodeA = defaultdict(dict) self._last_node = -1
def __init__(self, filename, sp): self.st = {} with open(filename, 'r') as f: while True: line = f.readline() if line == '': break line = line.split('\n')[0] for a in line.split(sp): if a not in self.st: self.st[a] = len(self.st) self.keys = [0] * len(self.st) for name in self.st.keys(): self.keys[self.st[name]] = name self.g = Digraph(len(self.st)) with open(filename, 'r') as f: while True: line = f.readline() if line == '': break line = line.split('\n')[0] a = line.split(sp) v = self.st[a[0]] for t in a[1:]: self.g.addEdge(v, self.st[t])
def kosaraju(graph: Digraph) -> list: connected_components = [] vertex_stack = [] # S visited_vertex_map = {v: False for v in graph.vertices} while len(vertex_stack) < len(graph.vertices): # dfs_vertex = 3 # dfs_vertex = 0 dfs_vertex = choice(list(graph.vertices - set(vertex_stack))) dfs_kosaraju(graph, dfs_vertex, vertex_stack=vertex_stack, visited_vertex_map=visited_vertex_map) #vertex_stack = list(reversed(vertex_stack)) transposed_graph = graph.transpose() visited_vertex_map_t = {v: False for v in transposed_graph.vertices} while vertex_stack: top_stack_vertex = vertex_stack.pop() connected_component = list() dfs_kosaraju(transposed_graph, top_stack_vertex, connected_component, visited_vertex_map_t) connected_component = set(connected_component) connected_components.append(connected_component) remaining_edges = [edge for edge in transposed_graph.edges if edge[0] and edge[1] not in connected_component] transposed_graph = Digraph(edges=remaining_edges, vertices=transposed_graph.vertices) for component_vertex in connected_component: try: vertex_stack.remove(component_vertex) except ValueError: continue return connected_components
def graph_from_adj_matrix(matrix): """ Devuelve el Digrafo generado a partir de la matriz de ady. """ graph = Digraph(len(matrix)) for i in range(len(matrix)): for j in range(len(matrix[i])): if matrix[i][j] != 0: graph.add_edge(i, j, matrix[i][j]) return graph
def test_has_node(self): """ test has_node """ dgraph = Digraph() dgraph.add_node('one') self.assertTrue(dgraph.has_node('one'))
def test_add_node(self): """ test add_node """ dgraph = Digraph() dgraph.add_node('one') self.assertIn('one', dgraph.nodes)
def test4(): dag = Digraph() dag.add_edge("v1", "v2") dag.add_edge("v2", "v3") bn = BayesianNetwork() bn.set_dag(dag) bn.set_pd("v1", [], {1 : 0.8, 0 : 0.2}) bn.set_pd("v2", ["v1"], {1 : {"1" : 0.4, "0" : 0.9}, 0 : {"1" : 0.6, "0" : 0.1}}) bn.set_pd("v3", ["v2"], {1 : {"1" : 0.7, "0" : 0.5}, 0 : {"1" : 0.3, "0" : 0.5}}) evidence = {"v3" : {1 : 1, 0 : 0}} bn.compute_posterior(evidence)
def test6(): dag = Digraph() dag.add_edge("v1", "v2") dag.add_edge("v2", "v3") bn = BayesianNetwork() bn.set_dag(dag) bn.set_pd("v1", [], {"v1_true" : 0.8, "v1_false" : 0.2}) bn.set_pd("v2", ["v1"], {"v2_true" : {"v1_true" : 0.4, "v1_false" : 0.9}, "v2_false" : {"v1_true" : 0.6, "v1_false" : 0.1}}) bn.set_pd("v3", ["v2"], {"v3_true" : {"v2_true" : 0.7, "v2_false" : 0.5}, "v3_false" : {"v2_true" : 0.3, "v2_false" : 0.5}}) evidence = {"v3" : {"v3_true" : 1, "v3_false" : 0}} bn.compute_posterior(evidence)
def test7(): dag = Digraph() dag.add_edge("v1", "v2") dag.add_edge("v2", "v3") bn = BayesianNetwork() bn.set_dag(dag) bn.set_pd("v1", [], {"v1_true" : 1e-300, "v1_false" : 1.0 - 1e-300}) bn.set_pd("v2", ["v1"], {"v2_true" : {"v1_true" : 1e-300, "v1_false" : 1.0 - 1e-300}, "v2_false" : {"v1_true" : 1e-300, "v1_false" : 1.0 - 1e-300}}) bn.set_pd("v3", ["v2"], {"v3_true" : {"v2_true" : 0.7, "v2_false" : 0.5}, "v3_false" : {"v2_true" : 0.3, "v2_false" : 0.5}}) evidence = {"v3" : {"v3_true" : 1, "v3_false" : 0}} post = bn.compute_posterior(evidence) print "Posterior:", post
def test_add_edge_to_empty(self): d = Digraph() self.assertEquals(0, d.count_vertices()) d.add_vertice() d.add_vertice() d.add_vertice() d.add_edge(0, 1) d.add_edge(2, 0) self.assertEquals(2, d.count_edges())
def test2(): dag = Digraph() dag.add_edge("v1", "v2") dag.add_edge("v2", "v3") bn = BayesianNetwork() bn.set_dag(dag) bn.set_pd("v1", [[0.2, 0.8]]) bn.set_pd("v2", [[0.9, 0.1], [0.6, 0.4]]) bn.set_pd("v3", [[0.5, 0.5], [0.3, 0.7]]) evidence = {"v3" : {0 : 0.0, 1 : 1.0}} bn.compute_posterior(evidence)
def test_get_nodes(self): """ test get_nodes We will add a bunch of nodes and make sure it returns all of them. We're using a set comparison, because """ dgraph = Digraph() node_list = ['one', 'two', 'three'] for n in node_list: dgraph.add_node(n) self.assertEquals(set(dgraph.get_nodes()), set(node_list))
def _do_view_stategraph(self): """ Generates a stategraph of analyzed data. """ # Check if the analysis is complete if not self._analysis_complete: print("No data to generate stategraph from!") return if self._probe.get_num_states == 0: print("Cannot draw a stategraph of a non-stateful graph!") return print("Building stategraph") inputs = self._probe.get_num_inputs() outputs = self._probe.get_num_outputs() states = self._probe.get_num_states() # Build the edges for the graph print("Compiling edges") m = self._probe.get_matrix() edges = [ (self._probe.get_numerical_state_representation(row[inputs:(inputs+states)]), self._probe.get_numerical_state_representation(row[(inputs+states+outputs):(inputs+2*states+outputs)])) for row in m ] # Build the list of edge labels attrs = { "edge_label": {} } index = 0 for row in m: if edges[index] in attrs["edge_label"]: attrs["edge_label"][edges[index]] += ", " + "".join([str(c) for c in row[0:inputs]]) else: attrs["edge_label"][edges[index]] = "".join([str(c) for c in row[0:inputs]]) index += 1 # Create a digraph to use print("Creating Digraph") graph = Digraph(edges) # Draw the graph into a dot file print("Creating dotfile") graph.draw(filename="stategraph.dot", attr=attrs) # Run graphviz on the dotfile print("Launching xdot") subprocess.Popen(["xdot", "stategraph.dot"])
def test3(): dag = Digraph() dag.add_edge("v2", "v1") dag.add_edge("v3", "v1") bn = BayesianNetwork() bn.set_dag(dag) bn.set_pd("v1", ["v2", "v3"], {0 : {"11" : 0.8, "01" : 0.9, "10" : 0.5, "00" : 0.6}, 0 : {"11" : 0.2, "01" : 0.1, "10" : 0.5, "00" : 0.4}}) bn.set_pd("v2", [], {1 : 0.1, 0 : 0.9}) bn.set_pd("v3", [], {1 : 0.4, 0 : 0.6}) print bn evidence = {} print bn.compute_posterior(evidence)
def test_add_vertice(self): d = Digraph() self.assertEquals(0, d.count_vertices()) d.add_vertice() self.assertEquals(1, d.count_vertices()) d.add_vertice() d.add_vertice() self.assertEquals(3, d.count_vertices())
def __enter__(self): """ Startup commands for the context manager. """ engine = create_engine(self.db) Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) self.session = Session() edges = self.session.query(Edge) self._graph = Digraph(len(edges.all())) for edge in edges: if not self._graph.has_edge(edge.stop_from_id, edge.stop_to_id): self._graph.add_edge(DirectedEdge( edge.stop_from_id, edge.stop_to_id, edge.length )) return self
def __init__(self): # contents: { vertex_id: ( lat, long ) } # lat and long values are stored in 100,000th of degrees self.vertex_locations = {} # contents: { ( v1, v2 ): name } self.edges = {} self.graph = Digraph()
def main(): import sys from digraph import Digraph txt_file = sys.argv[1] G = Digraph.from_txt(txt_file) dfo = DepthFirstOrder(G) print(" v pre post") print("--------------") for v in range(G.V()): print("%4d %4d %4d" % (v, dfo.pre(v), dfo.post(v))) message = "Preorder: " message += ' '.join([str(v) for v in dfo.pre_order()]) print(message) message = "Postorder: " message += ' '.join([str(v) for v in dfo.post_order()]) print(message) message = "Reverse postorder: " message += ' '.join([str(v) for v in dfo.reverse_post()]) print(message)
def test5(): dag = Digraph() dag.add_edge("v1", "v2") dag.add_edge("v2", "v3") dag.add_edge("v2", "v4") bn = BayesianNetwork() bn.set_dag(dag) bn.set_pd("v1", [], {0 : 0.5, 1 : 0.5}) bn.set_pd("v2", ["v1"], {0 : {"0" : 0.5, "1" : 0.5}, 1 : {"0" : 0.5, "1" : 0.5}}) bn.set_pd("v3", ["v2"], {0 : {"0" : 0.5, "1" : 0.5}, 1 : {"0" : 0.5, "1" : 0.5}}) bn.set_pd("v4", ["v2"], {0 : {"0" : 0.5, "1" : 0.5}, 1 : {"0" : 0.5, "1" : 0.5}}) print bn evidence = {"v3" : {0 : 0.0, 1 : 1.0}, "v4" : {0 : 0.9, 1 : 0.1}} bn.compute_posterior(evidence)
def test3(): dag = Digraph() dag.add_edge("v2", "v1") dag.add_edge("v3", "v1") bn = BayesianNetwork() bn.set_dag(dag) bn.set_pd("v1", ["v2", "v3"], {0 : {"11" : 0.8, "01" : 0.9, "10" : 0.5, "00" : 0.6}, 0 : {"11" : 0.2, "01" : 0.1, "10" : 0.5, "00" : 0.4}}) bn.set_pd("v2", [], {1 : 0.1, 0 : 0.9}) bn.set_pd("v3", [], {1 : 0.4, 0 : 0.6}) print bn evidence = {} #evidence = {"v1" : {1 : 1, 0 : 0}} bn.compute_posterior(evidence)
def save_dot(self, dot_file): assert self.root is not None g = Digraph(len(self.nodes)) for n in self.nodes: g.set_vertex_label(n.idx, n.op) if n.pred is not None: g.add_edge(n.pred.idx, n.idx) g.save_dot(dot_file)
def save_dot(self, dot_file): g = Digraph(len(self.obj.infos)) for infos in self.obj.infos: n = infos.node g.set_vertex_label(n.idx, get_label(infos)) if n.pred is not None: g.add_edge(n.pred.idx, n.idx) g.save_dot(dot_file)
def test(): dag = Digraph() dag.add_edge("v1", "v2") dag.add_edge("v2", "v3") dag.add_edge("v2", "v4") bn = BayesianNetwork() bn.set_dag(dag) bn.set_pd("v1", [], {0 : 0.6, 1 : 0.4}) bn.set_pd("v2", ["v1"], {0 : {"0" : 0.9, "1" : 0.1}, 1 : {"0" : 0.7, "1" : 0.3}}) bn.set_pd("v3", ["v2"], {0 : {"0" : 0.1, "1" : 0.9}, 1 : {"0" : 0.8, "1" : 0.2}}) bn.set_pd("v4", ["v2"], {0 : {"0" : 0.5, "1" : 0.5}, 1 : {"0" : 0.25, "1" : 0.75}}) print bn evidence = {} bn.compute_posterior(evidence)
def to_digraph(self): """to digraph class""" G = Digraph.from_v(self.V()) for e in self.edges(): G.add_edge(e.v_from(), e.v_to()) return G
def __init__(self, dl_set=None, fname=None, sample_state=None): self.fname = fname self.dependencies = Digraph() # deadlock -> descendants if dl_set is None: dl_set = DeadlockSet() self.dl_set = dl_set self._last_full_index = -1 self.debug_data = [] self.debug_fname = "bug.log" if fname is not None: assert sample_state is not None if os.path.exists(fname): print("loading deadlocks...") try: blocks = deadlocks_from_file(fname, sample_state) except: blocks = None def backup_fnames_gen(): base_fname = fname + "_backup" yield base_fname i = 0 while True: yield base_fname + str(i) backup_fnames = backup_fnames_gen() while True: backup_fname = next(backup_fnames) if not os.path.exists(backup_fname): break os.rename(fname, backup_fname) print("deadlock file corrupted, renamed to '{}'".format( backup_fname)) if blocks is not None: for dl in chain.from_iterable(blocks): self.debug_data.append( "dummy_deadlocks[{}] = make_dummy_deadlock({})". format(id(dl), dl.full_index)) self.dl_set.add(dl) self._last_full_index = dl.full_index print("loaded {} deadlocks".format(self._last_full_index + 1))
def save_dot(self, dot_file): g = Digraph(len(self.obj.infos)) for infos in self.obj.infos: n = infos.node if n.pred is not None: g.add_edge(n.pred.idx, n.idx) self.obj.apply(self) for (u, label) in enumerate(self.labels): g.set_vertex_label(u, label) g.save_dot(dot_file)
def test_del_edge(self): """ Test del_edge """ dgraph = Digraph() node_list = ['one', 'two', 'three'] for n in node_list: dgraph.add_node(n) if n != 'one': dgraph.add_edge(('one', n)) dgraph.del_edge(('one', 'two')) self.assertNotIn('two', dgraph.nodes['one'])
def dfs_visit_vertex_kosaraju(graph: Digraph, vertex, visited_vertex_map: dict, visited_edges: list or None, visited_vertices: list): for neighbour_vertex in graph.get_vertex_neighbours(vertex): visited = visited_vertex_map[neighbour_vertex] if not visited: visited_vertex_map[neighbour_vertex] = True dfs_visit_vertex_kosaraju(graph, neighbour_vertex, visited_vertex_map, visited_edges, visited_vertices) if vertex not in visited_vertices: visited_vertices.append(vertex)
def test_has_edge(self): """ test has_edge """ dgraph = Digraph() node_list = ['one', 'two', 'three'] for n in node_list: dgraph.add_node(n) if n != 'one': dgraph.add_edge(('one', n)) self.assertTrue(dgraph.has_edge(('one', 'two'))) self.assertTrue(dgraph.has_edge(('one', 'three')))
def __init__(self, file_name, separator): self.__symbols = {} with open(file_name, 'r') as f: for line in f: tokens = line.strip().split(separator) for token in tokens: if token not in self.__symbols: self.__symbols[token] = len(self.__symbols) self.__keys = [0] * len(self.__symbols) for k, v in self.__symbols.items(): self.__keys[v] = k self.__g = Digraph(len(self.__symbols)) with open(file_name, 'r') as f: for line in f: tokens = line.strip().split(separator) v = self.__symbols[tokens[0]] for token in tokens[1:]: self.__g.add_edge(v, self.__symbols[token])
class SymbolGraph: """用符号作为顶点名的图,符号图""" def __init__(self, filename, sp): self.st = {} with open(filename, 'r') as f: while True: line = f.readline() if line == '': break line = line.split('\n')[0] for a in line.split(sp): if a not in self.st: self.st[a] = len(self.st) self.keys = [0] * len(self.st) for name in self.st.keys(): self.keys[self.st[name]] = name self.g = Digraph(len(self.st)) with open(filename, 'r') as f: while True: line = f.readline() if line == '': break line = line.split('\n')[0] a = line.split(sp) v = self.st[a[0]] for t in a[1:]: self.g.addEdge(v, self.st[t]) # print(self.st) def contains(self, s): return s in self.st def index(self, s): return self.st[s] def name(self, v): return self.keys[v] def G(self): return self.g
def test_get_node_order(self): """ Test get_node_order """ dgraph = Digraph() node_list = ['one', 'two', 'three'] for n in node_list: dgraph.add_node(n) if n != 'one': dgraph.add_edge(('one', n)) self.assertEquals(dgraph.get_node_order('one'), 2)
def main(): import sys from digraph import Digraph txt_file = sys.argv[1] G = Digraph.from_txt(txt_file) finder = DirectedCycle(G) if finder.has_cycle(): message = "Directed cycle: " message += ' '.join([str(v) for v in finder.cycle()]) print(message) else: print("No directed cycle")
def test_del_node(self): """ test del_node """ dgraph = Digraph() node_list = ['one', 'two', 'three'] for n in node_list: dgraph.add_node(n) dgraph.del_node('one') self.assertNotIn('one', dgraph.nodes)
def build_dag(T, use_tree=True, blast=True, gtg=True): parents, children = findParentsAndChildren(T, ROOT_NODE) dag = Digraph() observed_species = set() ancestors = set() if use_tree: for u in children: ancestors.add(u) for v in children[u]: dag.add_edge(u, v) for u in T: if u not in children: observed_species.add(u) if blast: dag.add_edge(u, get_blast_node_name(u)) if gtg: dag.add_edge(u, get_gtg_node_name(u)) return dag, observed_species, ancestors
def test_add_edge(self): """ test add_edge """ dgraph = Digraph() node_list = ['one', 'two', 'three'] for n in node_list: dgraph.add_node(n) dgraph.add_edge(('one', 'two')) self.assertIn('two', dgraph.nodes['one'])
def build_dag(T, use_tree = True, blast = True, gtg = True): parents, children = findParentsAndChildren(T, ROOT_NODE) dag = Digraph() observed_species = set() ancestors = set() if use_tree: for u in children: ancestors.add(u) for v in children[u]: dag.add_edge(u, v) for u in T: if u not in children: observed_species.add(u) if blast: dag.add_edge(u, get_blast_node_name(u)) if gtg: dag.add_edge(u, get_gtg_node_name(u)) return dag, observed_species, ancestors
def testSP(): nodes = [] for name in range(6): nodes.append(str(name)) g = Digraph() for n in nodes: g.addNode(n) g.addEdge(Edge(nodes[0], nodes[1])) g.addEdge(Edge(nodes[1], nodes[2])) g.addEdge(Edge(nodes[2], nodes[3])) g.addEdge(Edge(nodes[2], nodes[4])) g.addEdge(Edge(nodes[3], nodes[4])) g.addEdge(Edge(nodes[3], nodes[5])) g.addEdge(Edge(nodes[0], nodes[2])) g.addEdge(Edge(nodes[1], nodes[0])) g.addEdge(Edge(nodes[3], nodes[1])) g.addEdge(Edge(nodes[4], nodes[0])) sp = search(g, nodes[0], nodes[5]) print "Shortest path by BFS: ", printPath(sp)
class Network: session = None engine = None def __init__(self, db): """ Creates a transport network interface between the database and the algorithm. Args: db (str): String describing the database location. """ self.db = db def __enter__(self): """ Startup commands for the context manager. """ engine = create_engine(self.db) Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) self.session = Session() edges = self.session.query(Edge) self._graph = Digraph(len(edges.all())) for edge in edges: if not self._graph.has_edge(edge.stop_from_id, edge.stop_to_id): self._graph.add_edge(DirectedEdge( edge.stop_from_id, edge.stop_to_id, edge.length )) return self def __exit__(self, type, value, traceback): """ Shutdown commands for the context manager. """ if type is not None: pass self.session.commit() self.session.close() @property def stops(self): """ List of stops in the transport network. SQLAlchemy query object. """ return self.session.query(Stop) @property def routes(self): """ List of routes in the transport network. SQLAlchemy query object. """ return self.session.query(Route) @property def graph(self): """ Digraph representing the transport network. """ return self._graph @property def edges(self): """ Edges present in the graph, and routes associated with each edge. SQLAlchemy query object. """ return self.session.query(Edge) @property def route_frequencies(self): """ Frequency tables associated with each route. SQLAlchemy query object. """ return self.session.query(RouteFrequency)
def testOverflow(self): d = Digraph(5) d.add_edge(0, 1) self.assertRaises(Exception, d.add_edge, 10, 1)
class SymbolDigraph(object): """Like digraph but operates with strings, you can never remove edges""" def __init__(self,size=0): self.symboltable = {} self.names = [] self.digraph = Digraph(size) def add_vertice(self, edge_from): """Add named vertice""" index_from = self._check_index(edge_from) self._check_digraph_size(index_from) self.names[index_from] = edge_from def add_edge(self, edge_from, edge_to): """Add named edge link""" index_from = self._check_index(edge_from) index_to = self._check_index(edge_to) self._check_digraph_size(max(index_from, index_to)) self.digraph.add_edge(index_from, index_to) def _check_index(self, key): """if exists, returns id, otherwise adds a new one and also returns""" keyname = str(key) #print "_check_index", key, "len(keyname)", len(keyname) if key == None or not(len(keyname)): raise Exception("Edge name cannot be none") if self.index(keyname) == -1: index = len(self.symboltable) self.symboltable[keyname] = index self._check_names_size(index) self.names[index] = key return self.symboltable[keyname] def index(self, key): """returns internal index by key""" if self.symboltable.has_key(key): return self.symboltable[key] return -1 def _check_digraph_size(self, index): """resizes graph accordingly""" i = index - self.digraph.count_vertices() while i >= 0: self.digraph.add_vertice() i -= 1 def _check_names_size(self, index): """resizes graph accordingly""" i = index - len(self.names) while i >= 0: self.names.append(None) i -= 1 def count_vertices(self): """returns number of vertices (nodes)""" return self.digraph.count_vertices() def count_edges(self): """returns number of edges(links)""" return self.digraph.count_edges() def vertices(self): "Named vertices" return self.names def links(self, key): "Links from node" names = [] for linkid in self.digraph.links(self.index(key)): names.append(self.name(linkid)) return names def name(self, index): """Symbol by index""" return self.names[index]
def test_init(self): d = Digraph(13) d.add_edge(2,3) d.add_edge(0,6) d.add_edge(0,1) d.add_edge(2,0) d.add_edge(11,12) d.add_edge(9,12) d.add_edge(9,10) d.add_edge(9,11) d.add_edge(3,5) d.add_edge(8,7) d.add_edge(5,4) d.add_edge(0,5) d.add_edge(6,4) d.add_edge(6,9) d.add_edge(7,6) order = DepthFirstOrder(d) self.assertEquals([0,3,9,10,2,1,4,11,12,5,8,6,7], order.pre) self.assertEquals([0,5,4,1,6,9,11,12,10,2,3,7,8], order.preorder) self.assertEquals([8,2,10,9,0,1,7,11,12,6,5,4,3], order.post) self.assertEquals([4,5,1,12,11,10,9,6,0,3,2,7,8], order.postorder)
def addEdge(self, edge): Digraph.addEdge(self, edge) rev = Edge(edge.dest, edge.src) Digraph.addEdge(self, rev)
def __init__(self,size=0): self.symboltable = {} self.names = [] self.digraph = Digraph(size)
def has_no_cycle(self): d = Digraph() d.add_edge(2, 3) dc = DirectedCycle(d) self.assertEquals(False, dc.has_cycle())
class Server: def __init__(self): # contents: { vertex_id: ( lat, long ) } # lat and long values are stored in 100,000th of degrees self.vertex_locations = {} # contents: { ( v1, v2 ): name } self.edges = {} self.graph = Digraph() def import_file(self, filename): """ Builds the graph and associated information from specified text file. """ print('Importing {}...'.format(filename)) scale = 100000 count = 0 for line in open(filename, 'r'): count += 1 split_line = line.rstrip().split(',') line_type = split_line[0] if line_type == 'V': v = split_line[1] self.graph.add_vertex(v) self.vertex_locations[v] = (float(split_line[2]) * scale, float(split_line[3]) * scale) if line_type == 'E': t = (split_line[1], split_line[2]) self.graph.add_edge(t) self.edges[t] = split_line[3] print('{} lines processed. Ready for input.'.format(count)) def cost_distance(self, e): """ cost_distance returns the straight-line distance between the two vertices at the endpoints of the edge e. >>> s = Server() >>> s.vertex_locations[29577354] = (400,-400) >>> s.vertex_locations[29770958] = (500,-500) >>> tcompare(100 * math.sqrt(2), s.cost_distance((29577354, 29770958))) True """ #print('cost_distance: e = {}'.format(e)) v1 = self.vertex_locations[e[0]] v2 = self.vertex_locations[e[1]] #print('cost_distance: v1 = {}; v2 = {}'.format(v1, v2)) return euclidean_distance(v1, v2) def closest_vertex(self, lat, long): """ Returns the id of the closest vertex to the specified lat and long >>> s = Server() >>> s.vertex_locations[29577354] = (5343099.6,-11349133.1) >>> s.vertex_locations[29770958] = (5357142.9,-11362729.9) >>> s.closest_vertex(5343099,-11349133) 29577354 """ coords = (lat, long) closest = min(self.vertex_locations.items(), key=lambda x: euclidean_distance(coords, x[1])) return closest[0] def find_shortest_path(self, lat1, long1, lat2, long2): """ Returns a least cost path of coordinates from (lat1, long1) to (lat1, long1) """ v1 = self.closest_vertex(lat1, long1) v2 = self.closest_vertex(lat2, long2) #print('Closest vertices: {} and {}'.format(v1, v2)) vertex_path = least_cost_path(self.graph, v1, v2, self.cost_distance) #print('vertex_path: {}'.format(vertex_path)) path = [] if vertex_path is not None: for v in vertex_path: path.append(self.vertex_locations[v]) return path
def readgraph(digraph_file_name): # create logger readgraph_logger = logging.getLogger('MappingServer.readgraph') readgraph_logger.info("Opening graphfile:" + str(digraph_file_name)) digraph_file = open(digraph_file_name, 'r') readgraph_logger.info("Open successful.") V = set() E = set() V_coord = {} E_name = {} G = Digraph() readgraph_logger.info("Parsing file...") # process each line in the file for line in digraph_file: # strip all trailing whitespace line = line.rstrip() fields = line.split(",") type = fields[0] if type == 'V': # got a vertex record (id, lat, long) = fields[1:] # vertex id's should be ints id = int(id) # lat and long are floats lat = float(lat) long = float(long) V.add(id) V_coord[id] = (lat, long) elif type == 'E': # got an edge record (start, stop, name) = fields[1:] # vertices are ints start = int(start) stop = int(stop) e = (start, stop) # get rid of leading and trailing quote " chars around name name = name.strip('"') # consistency check, we don't want auto adding of vertices when # adding an edge. if start not in V or stop not in V: readgraph_logger.error("Edge {} has an endpoint that is not a vertex".format(e)) raise Exception("Edge {} has an endpoint that is not a vertex".format(e)) G.add_edge(e) E_name[e] = name else: # weird input readgraph_logger.error("Error: weird line |{}|".format(line)) raise Exception("Error: weird line |{}|".format(line)) readgraph_logger.info("Parsing finished.") readgraph_logger.debug("Graph has " + str(G.num_vertices()) + " vertices and " + str(G.num_edges()) + " edges") V_Rev = {} for key in V_coord: V_Rev[key] = (int(V_coord[key][0] * 100000), int(V_coord[key][1] * 100000)) V_coord_rev = dict([(v, k) for (k, v) in V_Rev.items()]) names = (V_coord, E_name, V_coord_rev) return (G, names)
def read_graph(input_file): """ Read in Digraph data from a file, and return it as a tuple containing a Digraph as well as a map of metadata with vertex positions and edge names. Returns: (digraph, { (node id or edge tuple): (position or edge name) }) """ # # graph and metadata to populate # graph = Digraph() # metadata = {} # # set of vertices that we have read in. Used to check that # # we aren't adding verts through |add_edge| that won't have any # # location metadata. # vert_set = set() # # process each line in the file # for line in input_file: # # strip all trailing whitespace # line = line.rstrip() # fields = line.split(",") # type = fields[0] # if type == 'V': # # got a vertex record # (id,lat,long) = fields[1:] # # vertex id's should be ints # id=int(id) # # lat and long are floats # lat=float(lat) # long=float(long) # vert_set.add(id) # graph.add_vertex(id) # metadata[id] = (lat,long) # elif type == 'E': # # got an edge record # (start,stop,name) = fields[1:] # # vertices are ints # start=int(start) # stop=int(stop) # e = (start,stop) # if start not in vert_set: # raise Exception("Vertex %d is an endpoint for an edge but has no metadata" % start) # if stop not in vert_set: # raise Exception("Vertex %d is an endpoint for an edge but has no metadata" % stop) # # get rid of leading and trailing quote " chars around name # name = name.strip('"') # graph.add_edge(e) # metadata[e] = name # else: # # weird input # raise Exception("Error: weird line |{}|".format(line)) vert_map = {} # vert_id => {at = (lat,lon), ine = set(), oute = set()} edge_map = {} # (id,id) => name for line in input_file: # strip all trailing whitespace line = line.rstrip() fields = line.split(",") type = fields[0] if type == "V": # got a vertex record (id, lat, long) = fields[1:] # vertex id's should be ints id = int(id) # lat and long are floats lat = float(lat) long = float(long) # todo vert_map[id] = {"at": (lat, long), "id": id, "ine": set(), "oute": set()} elif type == "E": # got an edge record (start, stop, name) = fields[1:] # vertices are ints start = int(start) stop = int(stop) e = (start, stop) # get rid of leading and trailing quote " chars around name name = name.strip('"') # todo edge_map[(start, stop)] = name else: # weird input raise Exception("Error: weird line |{}|".format(line)) graph = Digraph() cached_aux_verts = {} def get_aux_verts(e): if e not in cached_aux_verts: aux_vert = {} # first assign ine and oute on verts for e in edge_map: vert_map[e[0]]["oute"].add(e) vert_map[e[1]]["ine"].add(e) # metadata metadata = {} # now, make the aux vert set aux_vert_map = {} # {vert_id => {adjacent_id => aux_vert_id}} aux_vert_current_id = 1 for v_id in vert_map: my_aux_verts = {} vdat = vert_map[v_id] for e in vdat["ine"]: my_aux_verts[e[0]] = aux_vert_current_id aux_vert_current_id += 1 for e in vdat["oute"]: my_aux_verts[e[1]] = aux_vert_current_id aux_vert_current_id += 1 for id in my_aux_verts.values(): metadata[id] = vdat["at"] graph.add_vertex(id) aux_vert_map[v_id] = my_aux_verts # aux verts have been created, add the main edges for (a, b) in edge_map: graph.add_edge((aux_vert_map[a][b], aux_vert_map[b][a])) metadata[(aux_vert_map[a][b], aux_vert_map[b][a])] = 0 # and finally, we need to add the junction virtual edges for v_id in vert_map: vdat = vert_map[v_id] # for each incomming edge, join it to each outgoing edge for (a, b) in vdat["ine"]: in_aux_vert_id = aux_vert_map[v_id][a] for (b, c) in vdat["oute"]: out_aux_vert_id = aux_vert_map[v_id][c] # calculate cost cost = 0 if len(vdat["ine"]) == 1 and len(vdat["oute"]) == 1: # ignore turn cost for nodes that just represent curves cost = 0 else: # use the angle at_a = vert_map[a]["at"] at_b = vert_map[b]["at"] at_c = vert_map[c]["at"] dir_1 = (at_b[0] - at_a[0], at_b[1] - at_a[1]) dir_2 = (at_c[0] - at_b[0], at_c[1] - at_b[1]) theta = math.acos( (dir_1[0] * dir_2[0] + dir_1[1] * dir_2[1]) / ((dir_1[0] ** 2 + dir_1[1] ** 2) ** 0.5 * (dir_2[0] ** 2 + dir_2[1] ** 2) ** 0.5) * 0.9999 ) cost = theta * 10 # add graph.add_edge((in_aux_vert_id, out_aux_vert_id)) metadata[(in_aux_vert_id, out_aux_vert_id)] = cost # return the data return (graph, metadata)
def find_order(word_sorted_list): """ Given a list of words in an alien language in dictionary sorted order, return the alphabetical order of the letters in the alien language. The algorithm is as follows: 1) Find the number of letters in the alphabet, by going 1 pass over the input array. This takes time O(wl). if there are w words and l letters on an avg per word. Lets call the result, alpha 2) Create a digraph with num_vertices = alpha 3) For every pair of consecutive words (word1, word2) in the input list (there are w - 1 pairs in a w-word list), compare letters of word1 & word2 until you find the 1st mismatching character. Add an edge in the digraph from letter in word1 to letter in word2 4) Topologically sort the digraph. This takes time O(V + E) = O(alpha + alpha - 1) Total time = O(wL) + O(1) + O[(w-1)(L)] + O(alpha) = O(wL) where L = avg number of letters per word :param word_sorted_list: :return: """ alphabet = set() for word in word_sorted_list: for letter in word: alphabet.add(letter) num_vertices = len(alphabet) dg = Digraph(num_vertices) # graph takes vertex values as integers, # so using 2 maps for letter -> vertex_id and inverse mapping letter_to_vertex_id_dict = {} vertex_id_to_letter = [] for i in xrange(len(word_sorted_list) - 1): word1 = word_sorted_list[i] word2 = word_sorted_list[i + 1] if len(word1) < len(word2): smaller_word = word_sorted_list[i] else: smaller_word = word_sorted_list[i + 1] for word_index in xrange(len(smaller_word)): if word1[word_index] == word2[word_index]: continue else: letter1 = word1[word_index].lower() letter2 = word2[word_index].lower() vertex1 = _get_vertex_for_letter(letter1, letter_to_vertex_id_dict, vertex_id_to_letter) vertex2 = _get_vertex_for_letter(letter2, letter_to_vertex_id_dict, vertex_id_to_letter) dg.add_edge(vertex1, vertex2) # no need to consider other characters in this word pair, # break out of inner for-loop break # now just do a topological sort of the letters ordered_vertex_ids = topological_sort(dg) lst = [vertex_id_to_letter[vertex] for vertex in ordered_vertex_ids] return ''.join([i for i in lst])
def testCycle(self): d = Digraph(13) d.add_edge(4,2) d.add_edge(2,3) d.add_edge(3,2) d.add_edge(6,0) d.add_edge(0,1) d.add_edge(2,0) d.add_edge(11,12) d.add_edge(12,9) d.add_edge(9,10) d.add_edge(9,11) d.add_edge(7,9) d.add_edge(10,12) d.add_edge(11,4) d.add_edge(4,3) d.add_edge(3,5) d.add_edge(6,8) d.add_edge(8,6) d.add_edge(5,4) d.add_edge(0,5) d.add_edge(6,4) d.add_edge(6,9) d.add_edge(7,6) self.assertEquals(13, d.count_vertices()) finder = DirectedCycle(d) self.assertEquals([3,4,5,3], finder.cycle)
def digraph_factory(spec): graph1 = Digraph() graph1.add_vertex('a') graph1.add_vertex('b') graph1.add_vertex('c') graph2 = Digraph() graph2.add_vertex('a') graph2.add_vertex('b') graph2.add_vertex('c') graph2.add_edge('a', 'b') graph2.add_edge('b', 'c') spec_dict = {'no_edge': graph1, 'with_edges': graph2} return spec_dict[spec]
def test_add_vertex(self): dg = Digraph() dg.add_vertex('a') self.assertTrue('a' in dg.vertex_names)
def test_add_edge_to_non_empty(self): d = Digraph(3) d.add_edge(1,2) self.assertEquals(1, len(d.links(1))) self.assertEquals(0, len(d.links(2)))