forked from prakhar1989/Algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgraph.py
More file actions
149 lines (129 loc) · 4.45 KB
/
graph.py
File metadata and controls
149 lines (129 loc) · 4.45 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
142
143
144
145
146
147
148
149
class graph(object):
"""
Graph class - made of nodes and edges
methods: add_edge, add_edges, add_node, add_nodes, has_node,
has_edge, nodes, edges, neighbors, del_node, del_edge, node_order,
set_edge_weight, get_edge_weight,
"""
DEFAULT_WEIGHT = 1
DIRECTED = False
def __init__(self):
self.node_neighbors = {}
def __str__(self):
return "Undirected Graph \nNodes: %s \nEdges: %s" % (self.nodes(), self.edges())
def add_nodes(self, nodes):
"""
Takes a list of nodes as input and adds these to a graph
"""
for node in nodes:
self.add_node(node)
def add_node(self, node):
"""
Adds a node to the graph
"""
if node not in self.node_neighbors:
self.node_neighbors[node] = {}
else:
raise Exception("Node %s is already in graph" % node)
def has_node(self, node):
"""
Returns boolean to indicate whether a node exists in the graph
"""
return node in self.node_neighbors
def add_edge(self, edge, wt=1, label=""):
"""
Add an edge to the graph connecting two nodes.
An edge, here, is a pair of node like C(m, n) or a tuple
"""
u, v = edge
if (v not in self.node_neighbors[u] and u not in self.node_neighbors[v]):
self.node_neighbors[u][v] = wt
if (u!=v):
self.node_neighbors[v][u] = wt
else:
raise Exception("Edge (%s, %s) already added in the graph" % (u, v))
def add_edges(self, edges):
""" Adds multiple edges in one go. Edges, here, is a list of
tuples"""
for edge in edges:
self.add_edge(edge)
def nodes(self):
"""
Returns a list of nodes in the graph
"""
return list(self.node_neighbors.keys())
def has_edge(self, edge):
"""
Returns a boolean to indicate whether an edge exists in the
graph. An edge, here, is a pair of node like C(m, n) or a tuple
"""
u, v = edge
if v not in self.node_neighbors[u]:
return False
return True
def neighbors(self, node):
"""
Returns a list of neighbors for a node
"""
if not self.has_node(node):
raise "Node %s not in graph" % node
return self.node_neighbors[node].keys()
def del_node(self, node):
"""
Deletes a node from a graph
"""
for each in list(self.neighbors(node)):
if (each != node):
self.del_edge((each, node))
del(self.node_neighbors[node])
def del_edge(self, edge):
"""
Deletes an edge from a graph. An edge, here, is a pair like
C(m,n) or a tuple
"""
u, v = edge
if not self.has_edge(edge):
raise Exception("Edge (%s, %s) not an existing edge" % (u, v))
del self.node_neighbors[u][v]
if (u!=v):
del self.node_neighbors[v][u]
def node_order(self, node):
"""
Return the order or degree of a node
"""
return len(self.neighbors(node))
def edges(self):
"""
Returns a list of edges in the graph
"""
edge_list = []
for node in self.nodes():
for each in self.neighbors(node):
edge_list.append((node, each))
return edge_list
# Methods for setting properties on nodes and edges
def set_edge_weight(self, edge, wt):
"""Set the weight of the edge """
u, v = edge
self.node_neighbors[u][v] = wt
if u != v:
self.node_neighbors[v][u] = wt
def get_edge_weight(self, edge):
"""Returns the weight of an edge """
u, v = edge
if not self.has_edge((u, v)):
raise Exception("%s not an existing edge" % edge)
return self.node_neighbors[u].get(v, self.DEFAULT_WEIGHT)
def get_edge_weights(self):
""" Returns a list of all edges with their weights """
edge_list = []
unique_list = {}
for u in self.nodes():
for v in self.neighbors(u):
if not unique_list.get(v) or u not in unique_list.get(v):
edge_list.append((self.node_neighbors[u][v], (u, v)))
if u not in unique_list:
unique_list[u] = [v]
else:
unique_list[u].append(v)
return edge_list