Mercurial > public > think_complexity
diff Graph.py @ 5:8e44660965ef
Completed chapter 2, exercise 3 on regular graphs.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Sat, 01 Dec 2012 16:51:39 -0600 |
parents | 9d0cf96b6a3b |
children | 950a34c7e26b |
line wrap: on
line diff
--- a/Graph.py Thu Nov 29 20:37:03 2012 -0600 +++ b/Graph.py Sat Dec 01 16:51:39 2012 -0600 @@ -9,6 +9,11 @@ import itertools +class GraphError(Exception): + """Exception for Graph errors""" + pass + + class Vertex(object): """A Vertex is a node in a graph.""" @@ -117,20 +122,76 @@ return self[v].values() + def remove_all_edges(self): + """Removes all edges in the graph.""" + for v in self.iterkeys(): + self[v] = {} + def add_all_edges(self): """Makes the graph complete by adding edges between all pairs of vertices. """ # Clear all edges first - for v in self.iterkeys(): - self[v] = {} + self.remove_all_edges() + # For each combination of 2 vertices, create an edge between them: for v, w in itertools.combinations(self.iterkeys(), 2): e = Edge(v, w) self[v][w] = e self[w][v] = e + def add_regular_edges(self, k): + """Makes the graph regular by making every vertex have k edges. + + It is not always possible to create a regular graph with a given degree. + If a graph has n vertices, then a regular graph can be constructed with + degree k if n >= k + 1 and n * k is even. If these conditions are not + met a GraphError exception is raised. + + """ + n = len(self.vertices()) + if n < k + 1: + raise GraphError("Can't make a regular graph with degree >= number" + " of vertices") + if (n * k) % 2 != 0: + raise GraphError("Can't make a regular graph of degree k and" + " order n where k * n is odd") + + # Remove all edges first + self.remove_all_edges() + + if k % 2 != 0: # if k is odd + self._add_regular_edges_even(k - 1) + self._add_regular_edges_odd() + else: + self._add_regular_edges_even(k) + + def _add_regular_edges_even(self, k): + """Make a regular graph with degree k. k must be even.""" + + vs = self.vertices() + vs2 = vs * 2 + + for i, v in enumerate(vs): + for j in range(1, k / 2 + 1): + w = vs2[i + j] + self.add_edge(Edge(v, w)) + + def _add_regular_edges_odd(self): + """Adds an extra edge across the graph to finish off a regular graph + with odd degree. The number of vertices must be even. + + """ + vs = self.vertices() + vs2 = vs * 2 + n = len(vs) + + for i in range(n / 2): + v = vs2[i] + w = vs2[i + n / 2] + self.add_edge(Edge(v, w)) + def main(script, *args): import pprint