def transpose(g): gt = Digraph() for u in g.vertices: gt.add_vertex(u) for u, v in g.edges: gt.add_edge(v, u, g.weight(u, v)) return gt
def random_graph(n, p, directed=False): """ Create a random graph :param n: number of nodes :param p: probability of edge creation (0 to 100) :param directed: set to True to generate a directed graph. Default is False (undirected graph) :return: graph """ if not directed: g = Graph() for i in range(n): g.add_vertex(i) for u, v in combinations(g.vertices, 2): # print(u, v) if randrange(1, 101) <= p: g.add_edge(u, v) return g else: dg = Digraph() for i in range(n): dg.add_vertex(i) for u, v in permutations(dg.vertices, 2): # print(u, v) if randrange(1, 101) <= p: dg.add_edge(u, v) return dg
list0 = [k for k, v in in_degrees.items() if v == 0] # vertices with in-degree = 0 for u in list0: for v in g.neighbors(u): in_degrees[v] -= 1 if in_degrees[v] == 0: list0.append(v) return len(list0) == len(g.vertices) if __name__ == '__main__': dress_order = [['shirt', 'tie'], ['tie', 'jacket'], ['belt', 'jacket'], ['shirt', 'belt'], ['undershorts', 'pants'], ['pants', 'shoes'], ['socks', 'shoes']] g = Digraph() g.add_edges_from(dress_order) g.add_vertex('jacket') g.add_vertex('watch') g.add_vertex('shoes') print(g) print(is_directed_acyclic_graph(g)) print(is_directed_acyclic_dfs(g)) # print(is_directed_acyclic_bfs(g)) # g1 = Digraph() # g1.add_vertex(1) # g1.add_vertex(2) # print(is_directed_acyclic_bfs(g1)) # g2 = Digraph()
g = Graph() # clrs Figure B.2(b) g.add_edges_from([(1, 2), (1, 5), (2, 5), (3, 6)]) g.add_vertex(4) print(f'connected: {is_connected(g)}') # print(connected_components_dj(g)) print(connected_components(g)) assert connected_components(g) == [[1, 2, 5], [3, 6], [4]] g = Graph() g.add_edges_from([(1, 2), (1, 5), (2, 3), (2, 5), (3, 6), (4, 5)]) print(f'connected: {is_connected(g)}') # print(connected_components_dj(g)) print(connected_components(g)) assert connected_components(g) == [[1, 2, 3, 6, 5, 4]] dg = Digraph() dg.add_edges_from([ ('a', 'b'), ('b', 'c'), ('b', 'e'), ('c', 'd'), ('c', 'g'), ('d', 'c'), ('d', 'h'), ('e', 'a'), ('e', 'f'), ('f', 'g'), ('g', 'f'), ('g', 'h'), ('h', 'h'), ])
from Graph import Digraph def topological_sort(g): def dfs(g, u): seen.add(u) for v in g.neighbors(u): if v not in seen: dfs(g, v) sortedv.appendleft(u) seen = set() sortedv = deque() for u in g.vertices: if u not in seen: dfs(g, u) return list(sortedv) if __name__ == '__main__': dress_order = [['shirt', 'tie'], ['tie', 'jacket'], ['belt', 'jacket'], ['shirt', 'belt'], ['undershorts', 'pants'], ['pants', 'shoes'], ['socks', 'shoes']] g = Digraph() g.add_edges_from(dress_order) g.add_vertex('jacket') g.add_vertex('watch') g.add_vertex('shoes') print(g) print(topological_sort(g))
if dist[u] < d: # skip if the value in dist is smaller continue for v in g.neighbors(u): d = dist[u] + g.weight(u, v) if d < dist[v]: # relaxation dist[v] = d pred[v] = u heappush(minq, (dist[v], v)) # could have duplicate vertices in minq return pred, dist # to get the path, refer to the predecessors dictionary if __name__ == '__main__': dg = Digraph() # clrs example dg.add_weighted_edges_from([('s', 't', 10), ('s', 'y', 5), ('t', 'x', 1), ('t', 'y', 2), ('x', 'z', 4), ('y', 't', 3), ('y', 'x', 9), ('y', 'z', 2), ('z', 's', 7), ('z', 'x', 6)]) print(dg) print(dijkstra(dg, 's')) print('-----') dg = Digraph() # graph theory example youtube dg.add_weighted_edges_from([(0, 1, 4), (0, 2, 1), (1, 3, 1), (2, 1, 2), (2, 3, 5), (3, 4, 3)]) print(dg) print(dijkstra(dg, 0)) print('-----')
# while pred[curr] != source: # if pred[curr] not in sp: # cycle check # sp.appendleft(pred[curr]) # curr = pred[curr] # else: # print(f'No path to {v}') # break # cycles are ignored # else: # sp.appendleft(source) # all_sp.append(list(sp)) # # return all_sp if __name__ == '__main__': dg = Digraph() # clrs example dg.add_weighted_edges_from([('t', 'x', 5), ('t', 'y', 8), ('t', 'z', -4), ('x', 't', -2), ('y', 'x', -3), ('y', 'z', 9), ('z', 'x', 7), ('z', 's', 2), ('s', 't', 6), ('s', 'y', 7)]) print(f'Graph: {dg}') print(f'Weights: {dg.weights}') print(bellman_ford(dg, 's')) print('') # dg = Digraph() # dg.add_edge('s', 'a', 3) # cormen book example # dg.add_edge('s', 'c', 5) # dg.add_edge('s', 'e', 2) # dg.add_edge('a', 'b', -4) # dg.add_edge('b', 'g', 4) # dg.add_edge('c', 'd', 6)
for v in g.neighbors(u): queue.append((v, path + [v])) return paths # def all_simple_paths_bfs(g, s, t): # seen = set() # paths = [] # queue = deque([(s, s)]) # while queue: # u, path = queue.popleft() # if u == t: # paths.append(path) # else: # for v in g.neighbors(u): # if v not in seen: # queue.append((v, path + v)) # seen.add(v) # return paths if __name__ == '__main__': g = Digraph() # clrs Figure 22.8 g.add_edges_from([ ('m', 'q'), ('m', 'r'), ('m', 'x'), ('n', 'o'), ('n', 'q'), ('n', 'u'), ('o', 'r'), ('o', 's'), ('o', 'v'), ('p', 'o'), ('p', 's'), ('p', 'z'), ('q', 't'), ('r', 'u'), ('r', 'y'), ('s', 'r'), ('v', 'w'), ('v', 'x'), ('y', 'v') ]) print(all_simple_paths_dfs(g, 'p', 'v')) print(all_simple_paths_bfs(g, 'p', 'v'))
def dfs_tree(g, src): def dfs(g, u): for v in g.neighbors(u): if v not in seen: tree.add_edge(u, v) seen.add(v) dfs(g, v) tree = Graph() tree.add_vertex(src) seen = {src} dfs(g, src) return tree if __name__ == '__main__': # dg = Digraph() # clrs book example # dg.add_edges_from([('u', 'v'), ('u', 'x'), ('v', 'y'), ('w', 'y'), # ('w', 'z'), ('x', 'v'), ('y', 'x'), ('z', 'z')]) # t = dfs_tree(dg, 'u') # print(t.vertices) # print(t.edges) dg = Digraph() # dg.add_edges_from([(0, 1), (1, 0), (2, 1)]) dg.add_edges_from([(1, 0), (1, 4), (4, 0), (4, 2)]) t = dfs_tree(dg, 0) print(t.vertices) print(t.edges)
def test_topological_sort(self): # cp3 4.4 dag in https://visualgo.net/en/dfsbfs dg = Digraph() dg.add_edges_from([(0, 1), (0, 2), (1, 2), (1, 3), (2, 3), (2, 5), (3, 4), (7, 6)]) self.assertEqual([7, 6, 0, 1, 2, 5, 3, 4], topological_sort(dg)) # cp3 4.17 dag in https://visualgo.net/en/dfsbfs dg = Digraph() dg.add_edges_from([(0, 1), (0, 2), (0, 3), (1, 3), (1, 4), (2, 4), (3, 4)]) self.assertEqual([0, 2, 1, 3, 4], topological_sort(dg)) # cp3 4.18 dag bipartite in https://visualgo.net/en/dfsbfs dg = Digraph() dg.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3), (3, 4)]) self.assertEqual([0, 2, 1, 3, 4], topological_sort(dg))
# dfs_path = deque(vertex) # curr = vertex # while pred[curr] != source and pred[curr] is not None: # dfs_path.appendleft(pred[curr]) # curr = pred[curr] # if pred[curr] is None: # dfs_path = [] # else: # dfs_path.appendleft(pred[curr]) # # print('path from ' + source + ' to ' + vertex + ' ' + str(bfs_path)) # print(f'path from {source} to {vertex} : {str(list(dfs_path)):20} ' # f'discovery at {dtime[vertex]} finishing at {ftime[vertex]}') # print('') if __name__ == '__main__': dg = Digraph() dg.add_edge('u', 'v') # Cormen book example dg.add_edge('u', 'x') dg.add_edge('v', 'y') dg.add_edge('w', 'y') dg.add_edge('w', 'z') dg.add_edge('x', 'v') dg.add_edge('y', 'x') dg.add_edge('z', 'z') print('Digraph:', dg) print('Vertices:', dg.vertices) print('Edges:', dg.edges) print('') print('dfs print ', end='')
# The transpose of a directed graph G=(V, E) is the graph Gᵀ = (V, Eᵀ) , where # Eᵀ = {(v,u) ∈ V x V : (u,v) ∈ E}. Thus, GT is G with all its edges reversed. from Graph import Digraph def transpose(g): gt = Digraph() for u in g.vertices: gt.add_vertex(u) for u, v in g.edges: gt.add_edge(v, u, g.weight(u, v)) return gt if __name__ == '__main__': g = Digraph() g.add_edges_from([ ('a', 'b'), ('b', 'c'), ('b', 'e'), ('b', 'f'), ('c', 'd'), ('c', 'g'), ('d', 'c'), ('d', 'h'), ('e', 'a'), ('e', 'f'), ('f', 'g'), ('g', 'f'), ('g', 'h'), ('h', 'h') ]) gt = transpose(g) print(gt.edges)
# dist[v] = sys.maxsize # pred[v] = None # dist[source] = 0 # # for v1 in sortedv: # for v2 in g.neighbors(v1): # if dist[v1] + g.weight(v1, v2) < dist[v2]: # relaxation # dist[v2] = dist[v1] + g.weight(v1, v2) # pred[v2] = v1 # # for v in g.vertices(): # generate all shortest paths # if v == source or pred[v] is None: # continue # sp = deque(v) # shortest path # curr = v # while pred[curr] != source: # sp.appendleft(pred[curr]) # curr = pred[curr] # sp.appendleft(source) # all_sp.append(list(sp)) # # return all_sp if __name__ == '__main__': dg = Digraph() # clrs example dg.add_weighted_edges_from([('r', 's', 5), ('r', 't', 3), ('s', 't', 2), ('s', 'x', 6), ('t', 'x', 7), ('t', 'y', 4), ('t', 'z', 2), ('x', 'y', -1), ('x', 'z', 1), ('y', 'z', -2)]) print(dag_sssp(dg, 's'))
# def transitive_closure(g): # n = len(g.vertices()) # edges = g.edges() # t = [[[0] * n for _ in range(n)] for _ in range(n + 1)] # for i in range(n): # for j in range(n): # if i == j or (i + 1, j + 1) in edges: # t[0][i][j] = 1 # for k in range(1, n + 1): # for i in range(n): # for j in range(n): # t[k][i][j] = t[k - 1][i][j] or (t[k - 1][i][k - 1] and t[k - 1][k - 1][j]) # return t if __name__ == '__main__': dg = Digraph() dg.add_edge(2, 3) dg.add_edge(2, 4) dg.add_edge(3, 2) dg.add_edge(4, 1) dg.add_edge(4, 3) print(dg) print(dg.edges()) t = transitive_closure(dg) # for i, tc in enumerate(t): # print(f't[{i}]') # for row in tc: # print(row)