defcomponents(nodes, edges): G = {u: set() for u in nodes} for u, v in edges: G[u].add(v) G[v].add(u)
seen = set() comps = [] for u in nodes: if u in seen: continue q = [u] seen.add(u) comp = [] while q: x = q.pop() comp.append(x) for y in G[x]: if y notin seen: seen.add(y) q.append(y) comps.append(tuple(sorted(comp))) returntuple(sorted(comps))
defedge_betweenness(nodes, edges): G = {u: set() for u in nodes} for u, v in edges: G[u].add(v) G[v].add(u)
defall_shortest_paths(s, t): q = deque([s]) dist = {s: 0} parents = defaultdict(list) while q: u = q.popleft() for v in G[u]: if v notin dist: dist[v] = dist[u] + 1 parents[v].append(u) q.append(v) elif dist[v] == dist[u] + 1: parents[v].append(u)
paths = [] defbacktrack(x, path): if x == s: paths.append(list(reversed(path + [x]))) return for p in parents[x]: backtrack(p, path + [x]) backtrack(t, []) return paths
score = defaultdict(float) for i, s inenumerate(nodes): for t in nodes[i + 1:]: paths = all_shortest_paths(s, t) for path in paths: for j inrange(len(path) - 1): e = tuple(sorted((path[j], path[j + 1]))) score[e] += 1 / len(paths) return score
for level inrange(1, 4): bet = edge_betweenness(nodes, cur_edges) mx = max(bet.values()) remove_edges = [e for e, v in bet.items() if v == mx] cur_edges = [e for e in cur_edges iftuple(sorted(e)) notin remove_edges] print(f'Level {level}:', components(nodes, cur_edges))