|
@@ -1,26 +1,53 @@
|
1
|
1
|
import numpy as np
|
2
|
2
|
|
3
|
|
-def shortest(i, j, ABG):
|
|
3
|
+def directDist(i, j, ABG):
|
|
4
|
+ dist = -1
|
|
5
|
+ for A, B, G in ABG:
|
|
6
|
+ if ((A == i and B == j) or (A == j and B == i)) and (dist == -1 or G < dist):
|
|
7
|
+ dist = G
|
|
8
|
+ return dist
|
|
9
|
+
|
|
10
|
+# From http://stackoverflow.com/a/22899400
|
|
11
|
+def shortest(i, j, ABG, nodes):
|
|
12
|
+ # print("i={0}, j={1}, ABG={2}, nodes={3}".format(i, j, ABG, nodes))
|
|
13
|
+ distances = {}
|
|
14
|
+ for A, B, G in ABG:
|
|
15
|
+ # print(distances)
|
|
16
|
+ if A not in distances or B not in distances:
|
|
17
|
+ distances[A] = {B: G}
|
|
18
|
+ distances[B] = {A: G}
|
|
19
|
+ continue
|
|
20
|
+ if B not in distances[A]:
|
|
21
|
+ distances[A][B] = G
|
|
22
|
+ distances[B][A] = G
|
|
23
|
+ continue
|
|
24
|
+ if G < distances[A][B]:
|
|
25
|
+ distances[A][B] = G
|
|
26
|
+ distances[B][A] = G
|
|
27
|
+
|
|
28
|
+ unvisited = {node: None for node in nodes} #using None as +inf
|
4
|
29
|
visited = {}
|
5
|
|
- level = 0
|
|
30
|
+ current = i
|
|
31
|
+ currentDistance = 0
|
|
32
|
+ unvisited[current] = currentDistance
|
|
33
|
+
|
6
|
34
|
while True:
|
7
|
|
- L[level] = {}
|
8
|
|
- for A, B, G in ABG:
|
9
|
|
- if A != i and B != i:
|
10
|
|
- continue
|
11
|
|
- if A == i:
|
12
|
|
- x = B
|
13
|
|
- else:
|
14
|
|
- x = A
|
15
|
|
- if x not in L[level] or L[level][x] > G:
|
16
|
|
- L[level][x] = G
|
17
|
|
- direct = -1
|
18
|
|
- if j in minis:
|
19
|
|
- direct = minis[j]
|
20
|
|
- for x, dist in enumerate(minis):
|
21
|
|
- if direct > dist:
|
22
|
|
- distToJ = shortest(x, j, ABG)
|
23
|
|
- if distToJ < ...
|
|
35
|
+ for neighbour, distance in distances[current].items():
|
|
36
|
+ if neighbour not in unvisited: continue
|
|
37
|
+ newDistance = currentDistance + distance
|
|
38
|
+ if unvisited[neighbour] is None or unvisited[neighbour] > newDistance:
|
|
39
|
+ unvisited[neighbour] = newDistance
|
|
40
|
+ visited[current] = currentDistance
|
|
41
|
+ if current == j:
|
|
42
|
+ return visited
|
|
43
|
+ del unvisited[current]
|
|
44
|
+ if not unvisited: break
|
|
45
|
+ candidates = [node for node in unvisited.items() if node[1]]
|
|
46
|
+ # print("unvisited", unvisited)
|
|
47
|
+ # print("candidates", candidates)
|
|
48
|
+ current, currentDistance = sorted(candidates, key = lambda x: x[1])[0]
|
|
49
|
+
|
|
50
|
+ return visited
|
24
|
51
|
|
25
|
52
|
def routes(ABG, SD):
|
26
|
53
|
r = {}
|
|
@@ -35,16 +62,20 @@ def routes(ABG, SD):
|
35
|
62
|
# print("A={0}, B={1}, G={2}".format(A, B, G))
|
36
|
63
|
townsInABG.add(A)
|
37
|
64
|
townsInABG.add(B)
|
38
|
|
- print(townsInSD)
|
39
|
|
- print(townsInABG)
|
|
65
|
+ # print(townsInSD)
|
|
66
|
+ # print(townsInABG)
|
40
|
67
|
if len(townsInABG) < len(townsInSD):
|
41
|
68
|
return {}
|
42
|
69
|
allTowns = townsInSD | townsInABG
|
|
70
|
+
|
|
71
|
+ # print("Shortest:", shortest(1, 2, ABG, allTowns))
|
43
|
72
|
for i in townsInSD:
|
44
|
73
|
for j in townsInSD:
|
45
|
74
|
if (i,j) in r:
|
46
|
75
|
continue
|
47
|
|
- dist = shortest(i, j, ABG)
|
|
76
|
+ shortst = shortest(i, j, ABG, allTowns)
|
|
77
|
+ print("Shortest:", shortst)
|
|
78
|
+ dist = shortst[j]
|
48
|
79
|
r[(i,j)] = dist
|
49
|
80
|
r[(j,i)] = dist
|
50
|
81
|
return r
|
|
@@ -54,6 +85,7 @@ def solve(N, M, K, ABG, SD):
|
54
|
85
|
if K <= 0:
|
55
|
86
|
return 0
|
56
|
87
|
r = routes(ABG, SD)
|
|
88
|
+ print(r)
|
57
|
89
|
if r == {}:
|
58
|
90
|
return -1
|
59
|
91
|
return 'gnagna'
|