Subversion Repositories programming

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
376 ira 1
#!/usr/bin/env python
2
 
3
__author__    = "Ira W. Snyder (devel@irasnyder.com)"
4
__copyright__ = "Copyright (c) 2006 Ira W. Snyder (devel@irasnyder.com)"
5
__license__   = "GNU GPL v2 (or, at your option, any later version)"
6
 
7
class Graph:
8
	"""Class that will handle weighted, undirected graphs. It can have
9
	   arbitrary data stored at each vertex. Note that the simple way
10
	   of creating a graph does not allow you to assign data, you must
11
	   do it manually."""
12
 
13
	def __init__ (self, vertices=[], edges=[]):
14
		"""Constructor"""
15
		self.vertices = {}
16
		self.edges = {}
17
 
18
		for v in vertices:
19
			self.add_vertex (v)
20
 
21
		for e in edges:
22
			(v1, v2) = e
23
			self.add_edge (v1, v2)
24
 
25
	def __get_key (self, v1, v2):
26
		"""Create a key for this set of nodes"""
27
		key = [v1, v2]
28
		key.sort ()
29
		return tuple (key)
30
 
31
	def add_vertex (self, label, data=0):
32
		"""Add a vertex to the graph"""
33
		if self.has_vertex (label):
34
			raise ValueError
35
 
36
		# Create vertex and set the value
37
		self.set_value (label, data)
38
 
39
	def add_edge (self, v1, v2, weight=1):
40
		"""Add an edge from v1 to v2 (undirected)"""
41
 
42
		key = self.__get_key (v1, v2)
43
 
44
		if self.has_vertex (v1) and self.has_vertex (v2):
45
			self.edges[key] = weight
46
		else:
47
			raise ValueError
48
 
49
	def has_edge (self, v1, v2):
50
		"""Check if an edge exists in this graph"""
51
 
52
		key = self.__get_key (v1, v2)
53
 
54
		if key in self.edges.keys():
55
			return True
56
 
57
		return False
58
 
59
	def has_vertex (self, label):
60
		"""Check if a vertex exists in this graph"""
61
		return label in self.vertices.keys ()
62
 
63
	def get_children (self, v):
64
		"""Get a list of all children of v. In this graph, that
65
		   means any adjacent nodes."""
66
		children = set()
67
 
68
		# Check that the vertex exists
69
		if not self.has_vertex (v):
70
			raise ValueError
71
 
72
		for k in self.edges.keys ():
73
			if v in k:
74
				for i in k:
75
					if i != v:
76
						children.add (i)
77
 
78
		return list(children)
79
 
80
	def set_value (self, v, data):
81
		"""Store some data at a vertex"""
82
		self.vertices[v] = data
83
 
84
	def get_value (self, v):
85
		"""Get the data at a vertex"""
86
		return self.vertices[v]
87
 
88
 
89
################################################################################
90
###                      Tests are below this point                          ###
91
################################################################################
92
 
93
 
94
def run_test (graph, vertex, should_be, suite, test_num):
95
	"""Run a test, check the result. Print the status."""
96
	c = graph.get_children (vertex)
97
	c.sort ()
98
 
99
	if (c != should_be):
100
		print 'Failed test #%d in suite: %s' % (test_num, suite)
101
 
102
def run_tests_1 ():
103
	"""Run the first set of tests."""
104
	SUITE = 'Tests 1'
105
 
106
	vertices = range (11)
107
	edges = ( [0, 1], [0, 9], [0, 8], [8, 10], [8, 7], [9, 6], [9, 5],
108
			[6, 7], [1, 4], [1, 3], [1, 2], [2, 0] )
109
 
110
	g = Graph (vertices, edges)
111
 
112
	run_test (g, 0, [1, 2, 8, 9], SUITE, 0)
113
	run_test (g, 1, [0, 2, 3, 4], SUITE, 1)
114
	run_test (g, 2, [0, 1], SUITE, 2)
115
	run_test (g, 3, [1], SUITE, 3)
116
	run_test (g, 4, [1], SUITE, 4)
117
	run_test (g, 5, [9], SUITE ,5)
118
	run_test (g, 6, [7, 9], SUITE, 6)
119
	run_test (g, 7, [6, 8], SUITE, 7)
120
	run_test (g, 8, [0, 7, 10], SUITE, 8)
121
	run_test (g, 9, [0, 5, 6], SUITE, 9)
122
	run_test (g, 10, [8], SUITE, 10)
123
 
124
def run_tests_2 ():
125
	"""Run the second set of tests."""
126
	SUITE = 'Tests 2'
127
 
128
	vertices = ['a', 'b', 'c', 'd', 'e']
129
	edges = ( ['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'a'], ['b', 'c'],
130
			['b', 'e'], ['e', 'b'], ['e', 'c'], ['e', 'd'],
131
			['d', 'a'], ['d', 'c'], ['d', 'e'], ['c', 'a'],
132
			['c', 'b'], ['c', 'd'], ['c', 'e'] )
133
 
134
	g = Graph (vertices, edges)
135
 
136
	run_test (g, 'a', ['b', 'c', 'd'], SUITE, 0)
137
	run_test (g, 'b', ['a', 'c', 'e'], SUITE, 1)
138
	run_test (g, 'c', ['a', 'b', 'd', 'e'], SUITE, 2)
139
	run_test (g, 'd', ['a', 'c', 'e'], SUITE, 3)
140
	run_test (g, 'e', ['b', 'c', 'd'], SUITE, 4)
141
 
142
def main ():
143
	"""Main function."""
144
 
145
	print 'Running self tests. Any failures will be reported below'
146
 
147
	run_tests_1 ()
148
	run_tests_2 ()
149
 
150
 
151
if __name__ == '__main__':
152
	main ()
153