-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgraph.py
More file actions
141 lines (113 loc) · 3.91 KB
/
Copy pathgraph.py
File metadata and controls
141 lines (113 loc) · 3.91 KB
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
"""
CSCI-603: Graphs
Author: Sean Strout @ RIT CS
An implementation of a graph data structure as an adjacency list.
Code taken from the online textbook and modified:
http://interactivepython.org/runestone/static/pythonds/Graphs/Implementation.html
"""
from vertex import Vertex
class Graph:
"""
A graph implemented as an adjacency list of vertices.
:slot: vertList (dict): A dictionary that maps a vertex key to a Vertex
object
:slot: numVertices (int): The total number of vertices in the graph
"""
__slots__ = 'vertList', 'numVertices'
def __init__(self):
"""
Initialize the graph
:return: None
"""
self.vertList = {}
self.numVertices = 0
def addVertex(self, key):
"""
Add a new vertex to the graph.
:param key: The identifier for the vertex (typically a string)
:return: Vertex
"""
# count this vertex if not already present
if self.getVertex(key) == None:
self.numVertices += 1
vertex = Vertex(key)
self.vertList[key] = vertex
return vertex
def getVertex(self, key):
"""
Retrieve the vertex from the graph.
:param key: The vertex identifier
:return: Vertex if it is present, otherwise None
"""
if key in self.vertList:
return self.vertList[key]
else:
return None
def __contains__(self, key):
"""
Returns whether the vertex is in the graph or not. This allows the
user to do:
key in graph
:param key: The vertex identifier
:return: True if the vertex is present, and False if not
"""
return key in self.vertList
def addEdge(self, src, dest, cost=0):
"""
Add a new directed edge from a source to a destination of an edge cost.
:param src: The source vertex identifier
:param dest: The destination vertex identifier
:param cost: The edge cost (defaults to 0)
:return: None
"""
if src not in self.vertList:
self.addVertex(src)
if dest not in self.vertList:
self.addVertex(dest)
self.vertList[src].addNeighbor(self.vertList[dest], cost)
def getVertices(self):
"""
Return the collection of vertex identifiers in the graph.
:return: A list of vertex identifiers
"""
return self.vertList.keys()
def __iter__(self):
"""
Return an iterator over the vertices in the graph. This allows the
user to do:
for vertex in graph:
...
:return: A list iterator over Vertex objects
"""
return iter(self.vertList.values())
def testGraph():
"""
A test function for the Graph class.
:return: None
"""
STATES = {
'CT': ('MA', 'RI'),
'MA': ('CT', 'NH', 'RI', 'VT'),
'ME': ('NH',),
'NH': ('MA', 'ME', 'VT'),
'RI': ('CT', 'MA'),
'VT': ('MA', 'NH')
}
# add all the edges to the graph
northeast = Graph()
for state, neighbors in STATES.items():
for neighbor in neighbors:
# this automatically creates a new vertices if not already present
northeast.addEdge(state, neighbor)
# display the vertices, which will show the connected neighbors.
# this will call the __iter__() method to get the Vertex objects.
for state in northeast:
print(state)
print(northeast.getVertices())
# check the __contains__() method
print('MA in northeast (True)?', 'MA' in northeast)
print('CA in northeast (False)?', 'CA' in northeast)
# test getVertex()
print('MA vertex:', northeast.getVertex('MA'))
if __name__ == '__main__':
testGraph()