The directef graph file (dgraph.py) content:
The following file is taken from
http://code.activestate.com/recipes/522995-priority-dict-a-priority-queue-with-updatable-prio/
which has the implementation of a priority queue with updatable priorities.
priority_dict.py
#!/usr/bin/python
from collections import namedtuple
import Queue
import priority_dict
Edge = namedtuple("Edge", ['fromm','to', 'weight','color'])
""" directed graph class"""
class dgraph:
def __init__(self):
# empty underlying dictionary
self.g = {}
""" adds an edge from fromN to toN. if fromN or toN doesn't
exist then they are created """
def addEdge(self,fromN,toN,w=0,color='white'):
#check if fromN Node is not available
if not self.g.has_key(fromN):
self.g[fromN]=[]
#check if toN Node is not available
if not self.g.has_key(toN):
self.g[toN]=[]
self.g[fromN].append(Edge(fromN,toN,w,color))
""" adds a new node to the graph if it is not already there"""
def addNode(self, N):
if not self.g.has_key(N):
self.g[N]=[]
""" returns the list of edges from node N"""
def edgesOf(self, N):
if self.g.has_key(N):
edges=[]
for edge in self.g[N]:
edges.append(edge.to)
return edges
return None
""" dyes edge from node fromN to node toN with the given color"""
def setEdgeColor(self,fromN,toN,color):
for edge in (self.g[fromN]):
if edge.to == toN:
self.g[fromN].remove(edge)
self.g[fromN].append(Edge(fromN,toN,edge.weight,color))
""" gets teh color of the edge from fromN node to toN node"""
def edgeColor(self,fromN,toN):
for edge in self.g[fromN]:
if edge.to == toN:
return edge.color
""" returns nodes of the graph as a list"""
def nodes(self):
return self.g.keys()
""" returns number of nodes in te graph"""
def numOfNodes(self):
return len(self.g.keys())
""" returns number of edges in the graph"""
def numOfEdges(self):
num=0
for key in self.g.keys():
num = num + len(self.g[key])
return num
""" returns number of edges node N have """
def numOfEdgesNode(self,N):
return len(self.g[N])
""" returns True if there is an edge from sourceN node to toN node
False otherwise"""
def hasEdge(self,fromN, toN):
for edge in self.g[fromN]:
if edge.to == toN:
return True
return False
""" returns the weight from fromN node to toN node,
None if there is no edge between them"""
def weight(self,fromN,toN):
for edge in self.g[fromN]:
if edge.to == toN:
return edge.weight
return None
def readFileContent(self,file_name):
file_location = file_name.strip()
input_data_file = open(file_location, 'r')
input_data = ''.join(input_data_file.readlines())
input_data_file.close()
return input_data
""" implements dijkstra's shortest path algorithm """
def shortestPathDijkstra(self,fromN,toN=None):
dist ={} #define distance dictionary
prev ={} #define previous node dictionary
S =[] #list of shortest path
Q = priority_dict.priority_dict()
#initialize distances and predecessors
for node in self.g.keys():
if node != fromN :
dist[node]=float('inf')
else:
dist[node] =0
prev[node]=None
Q.setdefault(node,dist[node])
while not Q.empty():
u = Q.pop_smallest()
if u == toN:
break
if dist[u] == float('inf'):
break
#traverse each neighbour of u
for edge in self.g[u]:
alt = dist[u] + self.weight(u,edge.to)
if alt < dist[edge.to]:
dist[edge.to] = alt
prev[edge.to] = u
Q.update([(edge.to,alt)])
while prev[toN] != None:
S.append(toN)
toN = prev[toN]
S.append(toN)
return S
if __name__ == '__main__':
x = dgraph()
x.addEdge('1','2',w=6)
x.addEdge('1','3',w=2)
x.addEdge('1','4',w=16)
x.addEdge('2','4',w=5)
x.addEdge('2','5',w=4)
x.addEdge('3','2',w=7)
x.addEdge('3','5',w=3)
x.addEdge('3','6',w=8)
x.addEdge('4','7',w=3)
x.addEdge('5','4',w=4)
x.addEdge('5','7',w=10)
x.addEdge('6','7',w=1)
"""x.addNode('Yalova')
x.addEdge('Adana','Yalova',weight=300)
x.addEdge('Yalova','Istanbul',weight=200,color='blue')
#x.addEdge('Yalova','Adana',600)
print x.edgesOf('Yalova')
print x.edgesOf('Adana')
print x.edgeColor('Yalova','Istanbul')
x.setEdgeColor('Adana','Istanbul','red')
print x.edgeColor('Adana','Istanbul')
print x.numOfNodes(),x.nodes(),x.numOfEdges(),x.numOfEdgesNode('Yalova')
print x.hasEdge('Adana','Istanbul')
print x.hasEdge('Adana','Adana')"""
print x.shortestPathDijkstra('1','7')
The following file is taken from
http://code.activestate.com/recipes/522995-priority-dict-a-priority-queue-with-updatable-prio/
which has the implementation of a priority queue with updatable priorities.
priority_dict.py
from heapq import heapify, heappush, heappop
class priority_dict(dict):
"""Dictionary that can be used as a priority queue.
Keys of the dictionary are items to be put into the queue, and values
are their respective priorities. All dictionary methods work as expected.
The advantage over a standard heapq-based priority queue is
that priorities of items can be efficiently updated (amortized O(1))
using code as 'thedict[item] = new_priority.'
The 'smallest' method can be used to return the object with lowest
priority, and 'pop_smallest' also removes it.
The 'sorted_iter' method provides a destructive sorted iterator.
"""
def __init__(self, *args, **kwargs):
super(priority_dict, self).__init__(*args, **kwargs)
self._rebuild_heap()
def _rebuild_heap(self):
self._heap = [(v, k) for k, v in self.iteritems()]
heapify(self._heap)
def smallest(self):
"""Return the item with the lowest priority.
Raises IndexError if the object is empty.
"""
heap = self._heap
v, k = heap[0]
while k not in self or self[k] != v:
heappop(heap)
v, k = heap[0]
return k
def pop_smallest(self):
"""Return the item with the lowest priority and remove it.
Raises IndexError if the object is empty.
"""
heap = self._heap
v, k = heappop(heap)
while k not in self or self[k] != v:
v, k = heappop(heap)
del self[k]
return k
def __setitem__(self, key, val):
# We are not going to remove the previous value from the heap,
# since this would have a cost O(n).
super(priority_dict, self).__setitem__(key, val)
if len(self._heap) < 2 * len(self):
heappush(self._heap, (val, key))
else:
# When the heap grows larger than 2 * len(self), we rebuild it
# from scratch to avoid wasting too much memory.
self._rebuild_heap()
def setdefault(self, key, val):
if key not in self:
self[key] = val
return val
return self[key]
def update(self, *args, **kwargs):
# Reimplementing dict.update is tricky -- see e.g.
# http://mail.python.org/pipermail/python-ideas/2007-May/000744.html
# We just rebuild the heap from scratch after passing to super.
super(priority_dict, self).update(*args, **kwargs)
self._rebuild_heap()
def sorted_iter(self):
"""Sorted iterator of the priority dictionary items.
Beware: this will destroy elements as they are returned.
"""
while self:
yield self.pop_smallest()
def empty(self):
return (len(self._heap) == 0)
No comments:
Post a Comment