-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathp082.py
120 lines (89 loc) · 3.16 KB
/
p082.py
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
from time import time
start = time()
# Problem Code
from collections import namedtuple
from heapq import heappop, heappush
node_heap = [] # list of entries arranged in a heap
entry_finder = {} # mapping of tasks to entries
REMOVED = -1 # placeholder for a removed task
#counter = itertools.count() # unique sequence count
def add_task(task, priority=0):
'Add a new task or update the priority of an existing task'
if task in entry_finder:
remove_task(task)
#count = next(counter)
entry = [priority, task]
entry_finder[task] = entry
heappush(node_heap, entry)
def remove_task(task):
'Mark an existing task as REMOVED. Raise KeyError if not found.'
entry = entry_finder.pop(task)
entry[-1] = REMOVED
def pop_task():
'Remove and return the lowest priority task. Raise KeyError if empty.'
while node_heap:
priority, task = heappop(node_heap)
if task is not REMOVED:
del entry_finder[task]
return task
raise KeyError('pop from an empty priority queue')
Edge = namedtuple('Edge', ['length','n1','n2'])
class Network:
def __init__(self,num_nodes):
self._net = [ [0 for _ in range(num_nodes)] for __ in range(num_nodes)]
def get_children(self,node):
return [ idx for idx in range(len(self._net)) if self._net[node][idx] != 0 ]
def get_edge(self,node1,node2):
return self._net[node1][node2]
def set_edge(self,node1,node2,edge_length):
self._net[node1][node2] = edge_length
#self._net[node2][node1] = edge_length
def remove_edge(self,node1,node2):
self.set_edge(node1,node2,0)
def export_edges(self):
edges = []
for n1 in range(len(self._net)):
for n2 in range(n1,len(self._net)):
if self._net[n1][n2] != 0:
edges.append(Edge(self._net[n1][n2],n1,n2))
return edges
n = 80
net = Network(n**2+2)
mat = [ [ 0 for _ in range(n) ] for __ in range(n) ]
with open('inputs/p082.txt','r') as infile:
for idx,line in enumerate(infile):
mat[idx] = list(map(int,line.strip().split(',')))
for r in range(n):
for c in range(n):
if c == 0:
net.set_edge(0,r*n+1,mat[r][c])
else:
net.set_edge(r*n+c,r*n+c+1,mat[r][c])
if c == n-1:
net.set_edge(r*n+c+1,n**2+1,0.00001)
if r != 0:
net.set_edge( (r-1)*n+c+1, r*n+c+1,mat[r][c])
if r != n-1:
net.set_edge( (r+1)*n+c+1, r*n+c+1,mat[r][c])
#
prev = [ None for _ in range(n**2+2) ]
dist = [ float('Inf') for _ in range(n**2+2) ]
dist[0] = 0
add_task(0,0)
for i in range(1,n**2+2):
add_task(i,float('Inf'))
traversed = set()
while node_heap:
try:
node = pop_task()
except KeyError:
break
if node not in traversed:
traversed.add(node)
for c in net.get_children(node):
if dist[c] > dist[node]+net.get_edge(node,c):
dist[c] = dist[node]+net.get_edge(node,c)
prev[c] = node
add_task(c,dist[c])
print(dist[n**2+1])
print('Time Elapsed: %.2fs' % (time()-start,))