Graph Coloring Algorithm (Greedy/ Welsh Powell)
I am trying to learn graphs, and I couldn't find a Python implementation of the Welsh Powell algorithm online, so I tried to write my own. Here are the steps.
- Order the nodes in descending degree. (Most neighbors ... Least neighbors)
- For each node, check the colors of neighbor nodes and mark them as unavailable.
- Choose the lowest available color. (from [0, 1, 2, ..., len(graph) -1])
def color_nodes(graph):
# Order nodes in descending degree
nodes = sorted(list(graph.keys()), key=lambda x: len(graph[x]), reverse=True)
color_map = {}
for node in nodes:
available_colors = [True] * len(nodes)
for neighbor in graph[node]:
if neighbor in color_map:
color = color_map[neighbor]
available_colors[color] = False
for color, available in enumerate(available_colors):
if available:
color_map[node] = color
break
return color_map
if __name__ == '__main__':
graph = {
'a': list('bcd'),
'b': list('ac'),
'c': list('abdef'),
'd': list('ace'),
'e': list('cdf'),
'f': list('ce')
}
print(color_nodes(graph))
# {'c': 0, 'a': 1, 'd': 2, 'e': 1, 'b': 2, 'f': 2}
example
For the input graph, it produced the above result. Is the implementation correct?
1 Answer 1
PEP 8, the official Python style guide, says that indentation should be 4 spaces per level. Since whitespace is significant in Python, that is a pretty strong convention.
The implementation could be less verbose:
sorted(list(graph.keys()), ...)
could be shortened tosorted(graph, ...)
.- Instead of defining
available_colors
as a list of booleans, you could definetaken_colors
as a set, ideally using a generator expression. - The loop that assigns
color_map[node]
can be simplified down tonext(generator expression with a condition)
.
def color_nodes(graph):
color_map = {}
# Consider nodes in descending degree
for node in sorted(graph, key=lambda x: len(graph[x]), reverse=True):
neighbor_colors = set(color_map.get(neigh) for neigh in graph[node])
color_map[node] = next(
color for color in range(len(graph)) if color not in neighbor_colors
)
return color_map
-
\$\begingroup\$ Thank you for your solid feedback! Concise and elegant! I especially like the idea of using a set rather than an array of booleans. \$\endgroup\$Thawsitt– Thawsitt2018年09月08日 13:34:28 +00:00Commented Sep 8, 2018 at 13:34