defnaive_celeb(G): n = len(G) for u inrange(n): # For every candidate... for v inrange(n): # For everyone else... if u == v: continue# Same person? Skip. if G[u][v]: break# Candidate knows other ifnot G[v][u]: break# Other doesn't know candidate else: return u # No breaks? Celebrity! returnNone# Couldn't find anyone
defceleb(G): n = len(G) u, v = 0, 1# The first two for c inrange(2, n + 1): # Others to check if G[u][v]: u = c # u knows v? Replace u else: v = c # Otherwise, replace v if u == n: c = v # u was replaced last; use v else: c = u # Otherwise, u is a candidate for v inrange(n): # For everyone else... if c == v: continue# Same person? Skip. if G[c][v]: break# Candidate knows other ifnot G[v][c]: break# Other doesn't know candidate else: return c # No breaks? Celebrity! returnNone# Couldn't find anyone
3.3. 拓扑排序
Linux系统中软件的安装,检测依赖
递归,每次去掉一个节点,解决剩下的拓扑排序,在将去掉的节点插入合适的位置
1 2 3 4 5 6 7 8 9 10 11 12 13
defnaive_topsort(G, S=None): if S isNone: S = set(G) # Default: All nodes iflen(S) == 1: returnlist(S) # Base case, single node v = S.pop() # Reduction: Remove a node seq = naive_topsort(G, S) # Recursion (assumption), n-1 min_i = 0 for i, u inenumerate(seq): if v in G[u]: min_i = i + 1# After all dependencies seq.insert(min_i, v) return seq
deftopsort(G): count = dict((u, 0) for u in G) # The in-degree for each node for u in G: for v in G[u]: count[v] += 1# Count every in-edge Q = [u for u in G if count[u] == 0] # Valid initial nodes S = [] # The result while Q: # While we have start nodes... u = Q.pop() # Pick one S.append(u) # Use it as first of the rest for v in G[u]: count[v] -= 1# "Uncount" its out-edges if count[v] == 0: # New valid start nodes? Q.append(v) # Deal with them next return S