def sccg(G: Graph): """ strongly connected component graph efficiency: O(V+E) """ _, _, f = dfs(G) f = [(item[0], item[1]) for item in f.items()] f.sort(key=lambda item: item[1], reverse=True) for v, i in zip(f, range(len(G.V))): v[0].data['i'] = i G_t = G.transpose() def dfs_visit(v: Vertex): color[v] = 'gray' for u in v.Adj: if color[u] == 'white': tie_well[len(tie_well) - 1].append(f[u.data['i']][0]) dfs_visit(u) color, V, tie_well = {v: 'white' for v in G_t.V }, sorted(G_t.V.keys(), key=lambda v: v.data['i']), [] for v in V: if color[v] == 'white': tie_well.append([f[v.data['i']][0]]) dfs_visit(v) return tie_well
def tie_well_graph(G): """ efficiency: O(V+E) """ tie_well = sccg(G) G_scc = Graph() for v_group, i in zip(tie_well, range(len(tie_well))): v = Vertex(name=str(v_group), data={'group': v_group}) for v1 in v_group: v1.data['group'] = v for v in G.V: for u in v.Adj: if v.data['group'] != u.data['group']: G_scc.connect(from_=v.data['group'], to=u.data['group'], weight=v.Adj[u].weight) return G_scc
def init_G_r(G): """ init the Residual graph @params: @G: graph efficiency: O(|E|+|V|) """ G_r = Graph() V = [Vertex(name=v.name) for v in G.V] dic = {} for v1, v2 in zip(G.V, V): dic[v1] = v2 for e in G.E: G_r.connect(from_=dic[e.from_], to=dic[e.to], weight=e.weight) return G_r, dic
def max_pairs(V1, V2, func=dfs): """ ford fulkerson algorithm For maximum pairing: @params: @G: graph @V1,V2: groups of vertex for finding mach @func: function to use for find adding way by default is dfs, can be bfs return: list of vertexes pairs for max pairing (=Original vertices) efficiency: O(|E|*n) where n is max pairing, in worst case n=|V1| """ G_pairs = Graph() dic1, dic2 = {v: Vertex(name=v.name) for v in V1}, {v: Vertex(name=v.name) for v in V2} dic, s, t = {**dic1, **dic2}, Vertex(name='s'), Vertex(name='t') dic = {dic[k]: k for k in dic} for v in dic1: G_pairs.connect(from_=s, to=dic1[v], weight=1) for v in dic2: G_pairs.connect(from_=dic2[v], to=t, weight=1) for v in dic1: for u in v.Adj: if u in dic2: G_pairs.connect(from_=dic1[v], to=dic2[u], weight=1) max_flow_ = ford_fulkerson(G_pairs, s, t, func=func) pairs = [] for e in max_flow_: if max_flow_[e] and e.from_ != s and e.to != t: # pairs.append(dic[e.from_].Adj[dic[e.to]]) pairs.append((dic[e.from_], dic[e.to])) return pairs
for v1 in v_group: v1.data['group'] = v for v in G.V: for u in v.Adj: if v.data['group'] != u.data['group']: G_scc.connect(from_=v.data['group'], to=u.data['group'], weight=v.Adj[u].weight) return G_scc if __name__ == '__main__': V = [Vertex(name=str(i)) for i in range(5)] # r = Edge(from_=V[0], to=V[1], weight=3) G = Graph(V={v: None for v in V}) G.connect(from_=V[1], to=V[2], weight=1) G.connect(from_=V[2], to=V[1], weight=1) # G.connect(e=r) G.connect(from_=V[3], to=V[2]) G.connect(from_=V[4], to=V[0]) G.connect(from_=V[3], to=V[0]) G.connect(from_=V[1], to=V[4]) dfs(G, list(G.V.keys())[0]) search_circle(G) forest(G, list(G.V.keys())[0]) # print(G.V.keys()[0]) topology(G) print(topology(G)) print(sccg(G)) print(leaves(G))
G_pairs.connect(from_=dic1[v], to=dic2[u], weight=1) max_flow_ = ford_fulkerson(G_pairs, s, t, func=func) pairs = [] for e in max_flow_: if max_flow_[e] and e.from_ != s and e.to != t: # pairs.append(dic[e.from_].Adj[dic[e.to]]) pairs.append((dic[e.from_], dic[e.to])) return pairs if __name__ == '__main__': V = [Vertex(name=str(i)) for i in range(8)] V[0].name, V[1].name, V[2].name, V[3].name, V[4].name, V[5].name, V[6].name, V[7].name = \ 's', '1', '2', '3', '4', '5', '6', 't' G = Graph() for i in range(8): G.V[V[i]] = None G.connect(from_=V[0], to=V[1], weight=3) G.connect(from_=V[0], to=V[2], weight=3) G.connect(from_=V[1], to=V[2], weight=1) G.connect(from_=V[1], to=V[3], weight=3) G.connect(from_=V[2], to=V[3], weight=1) G.connect(from_=V[2], to=V[4], weight=3) G.connect(from_=V[3], to=V[4], weight=2) G.connect(from_=V[3], to=V[5], weight=3) G.connect(from_=V[4], to=V[5], weight=2) G.connect(from_=V[4], to=V[6], weight=3) G.connect(from_=V[5], to=V[6], weight=3) G.connect(from_=V[5], to=V[7], weight=3) G.connect(from_=V[6], to=V[7], weight=3)
pi1 = dijkstra(G, s) print('------------------------') # print([v.data['key'] for v in G.V]) # print(pi.values()) pi2 = bellman_ford(G, s) pi3 = bellman_ford(G, s) pi4 = dag(G, s) print('dijkstra:', np.array_equal(pi1, pi2)) print('bellman_ford:', np.array_equal(pi1, pi3)) if pi4: print('dag:', np.array_equal(pi1, pi4)) print('-------------------- all pairs ---------------------') # print('------------------------') # print([v.data['key'] for v in G.V]) # print(pi.values()) G = Graph() V = [Vertex(name=str(i)) for i in range(8)] for i in range(1, 7): G.V[V[i]] = None G.connect(from_=V[1], to=V[2], weight=4) G.connect(from_=V[2], to=V[3], weight=6) G.connect(from_=V[2], to=V[5], weight=16) G.connect(from_=V[2], to=V[6], weight=20) G.connect(from_=V[3], to=V[5], weight=5) G.connect(from_=V[4], to=V[1], weight=2) G.connect(from_=V[4], to=V[2], weight=8) G.connect(from_=V[5], to=V[1], weight=7) G.connect(from_=V[5], to=V[4], weight=9) G.connect(from_=V[5], to=V[6], weight=7) G.connect(from_=V[6], to=V[3], weight=8)