-
Notifications
You must be signed in to change notification settings - Fork 0
/
minmax_degree.py
104 lines (84 loc) · 2.87 KB
/
minmax_degree.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/usr/bin/env python
#
# Copyright (c) 2013-2016, ETH Zurich.
# All rights reserved.
#
# This file is distributed under the terms in the attached LICENSE file.
# If you do not find this file, copies can be found by writing to:
# ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
# Minimal spanning tree
# This is based on original maxmin implementation of the python-graph project.
# See https://code.google.com/p/python-graph/source/browse/trunk/core/pygraph/algorithms/minmax.py
def minimal_spanning_tree(graph, root):
"""
Minimal spanning tree.
@attention: Minimal spanning tree is meaningful only for weighted graphs.
@type graph: graph
@param graph: Graph.
@type root: node
@param root: Optional root node (will explore only root's connected component)
@rtype: dictionary
@return: Generated spanning tree.
"""
visited = [] # List for marking visited and non-visited nodes
spanning_tree = {} # MInimal Spanning tree
d = dict()
# Initialization
visited.append(root)
nroot = root
spanning_tree[root] = None
# Algorithm loop
while (nroot is not None):
ledge = _lightest_edge(graph, visited, d)
if (ledge == (-1, -1)):
if (root is not None):
break
nroot = _first_unvisited(graph, visited)
if (nroot is not None):
spanning_tree[nroot] = None
visited.append(nroot)
else:
spanning_tree[ledge[1]] = ledge[0]
visited.append(ledge[1])
if ledge[0] in d:
d[ledge[0]] += 1
else:
d[ledge[0]] = 1
return spanning_tree
def _first_unvisited(graph, visited):
"""
Return first unvisited node.
@type graph: graph
@param graph: Graph.
@type visited: list
@param visited: List of nodes.
@rtype: node
@return: First unvisited node.
"""
for each in graph:
if (each not in visited):
return each
return None
def _lightest_edge(graph, visited, d):
"""
Return the lightest edge in graph going from a visited node to an unvisited one.
@type graph: graph
@param graph: Graph.
@type visited: list
@param visited: List of nodes.
@type d: Dictionary for remembering the out-degree of every edge.
@param d: Dictionary
@rtype: tuple
@return: Lightest edge in graph going from a visited node to an unvisited one.
"""
lightest_edge = (-1, -1)
weight = -1
for each in visited:
if not each in d or d[each]<2:
for other in graph[each]:
if (other not in visited):
w = graph.edge_weight((each, other))
if (w < weight or weight < 0):
lightest_edge = (each, other)
weight = w
return lightest_edge