源代码:https://github.com/gt11799/undirected_graph_compute
Coursera算法课的本周应用是建立在无向图的处理上的。根据要求,我写了四个处理模块。
def bfs_visited(ugraph, start_node):
visited = set([start_node])
tovisit = deque([start_node])
while tovisit:
node = tovisit.popleft()
for item in ugraph[node]:
if item not in visited:
visited.add(item)
tovisit.append(item)
return visited
Breadthfirst search visited。给定无向图(字典形式),和开始的node,把所有的与该node相连的点作为集合返回。deque不算是纯正的队,但是从头部或者尾部取值的效率是O(1),而列表则是O(n)。又append, appendleft, pop, popleft, extend, extendleft, extend就是对象是列表的时候使用。其他的可以顾名思义,实在是灵活的很。
def cc_visited(ugraph):
remain_node = ugraph.keys()
cc_set = []
while remain_node:
node = remain_node.pop()
visited = bfs_visited(ugraph, node)
cc_set.append(visited)
remain_node = [item for item in remain_node if item not in visited]
return cc_set
计算出Connected Components。把相连的node放到一个集合,然后把所有的集合作为一个列表返回。其中计算remain_node的这种形式是我在python核心编程中学到的,
既可以保持代码的简洁易懂,更是保证了高效率。
def largest_cc_size(ugraph):
cc_set = cc_visited(ugraph)
try:
return max([len(item) for item in cc_set])
except(ValueError):
return 0
返回相连的node的最大集合的大小,无向图以最大集合的大小去衡量紧密度(在我要做的作业中),这个模块使用了上两个模块。
def compute_resilience(ugraph, attack_order):
result = [largest_cc_size(ugraph)]
ugraph_attack = dict(ugraph)
for item in attack_order:
ugraph_attack.pop(item)
for node in ugraph_attack:
try:
ugraph_attack[node].remove(item)
except(KeyError):
pass
result.append(largest_cc_size(ugraph_attack))
return result
这个是用来计算无向图的适应能力。输入无向图和一个node的列表,返回的列表中,第一个是攻击前的CC-Size, 然后依次移除列表中的node后的CC-Size,注意移除时时叠加的。
从CC-Size的变化可以看出这个node在这个图的重要性。
然后写几个模块测试一下:
def test_bfs():
for node in UGRAPH10.keys():
print("start at: %s, bfs-visted: %s" %(node, bfs_visited(UGRAPH10,node)))
def test_cc():
print("cc-visited: %s" %cc_visited(UGRAPH10))
print("largest-cc-size: %s" %largest_cc_size(UGRAPH10))
def test_resilience():
print("when attack node: %s, the compute_resilience is: %s" \
%([1,4,5], compute_resilience(UGRAPH10, [1,4,5])))
结果就不贴了。
这些模块可以用来计算网络的结构,网络的受攻击能力,单个结点的重要性。具体应用下周贴出。
——————————————
github主页:https://github.com/gt11799
E-mail:gting405@163.com