0.测试数据
'''test-1.txt'''
1
2
1 2 1
1
2
'''test-2.txt'''
282
100
1 2 10
2 3 7
3 4 7
4 5 8
5 6 9
6 7 9
7 8 8
8 9 1
9 10 9
10 11 7
11 12 9
12 13 10
13 14 9
14 15 4
15 16 7
16 17 2
17 18 8
18 19 5
19 20 10
20 21 3
21 22 1
22 23 9
23 24 3
24 25 8
25 26 9
26 27 5
27 28 5
28 29 2
29 30 8
30 31 7
31 32 10
32 33 5
33 34 2
34 35 6
35 36 10
36 37 8
37 38 2
38 39 4
39 40 6
40 41 8
41 42 4
42 43 7
43 44 7
44 45 8
45 46 10
46 47 2
47 48 10
48 49 7
49 50 1
50 51 4
51 52 9
52 53 5
53 54 2
54 55 5
55 56 6
56 57 1
57 58 4
58 59 2
59 60 5
60 61 5
61 62 5
62 63 1
63 64 1
64 65 9
65 66 5
66 67 7
67 68 10
68 69 4
69 70 4
70 71 3
71 72 2
72 73 3
73 74 2
74 75 4
75 76 5
76 77 2
77 78 2
78 79 1
79 80 8
80 81 9
81 82 5
82 83 4
83 84 6
84 85 7
85 86 4
86 87 3
87 88 10
88 89 9
89 90 2
90 91 5
91 92 1
92 93 9
93 94 4
94 95 10
95 96 6
96 97 6
97 98 2
98 99 8
99 100 9
45 93 7
65 69 5
68 76 8
10 94 4
22 59 6
88 95 4
89 98 7
13 72 5
66 90 8
47 72 4
82 88 1
26 99 6
10 31 10
81 87 4
80 96 8
65 84 6
89 91 6
30 50 9
20 35 1
40 73 9
66 76 4
58 91 7
32 56 10
36 99 4
76 95 3
56 85 8
1 38 1
54 60 4
39 80 1
18 98 4
5 48 7
59 91 2
2 68 10
42 78 3
12 59 10
83 95 5
1 16 10
54 67 2
43 64 4
76 81 3
7 76 5
48 52 10
77 82 8
53 94 5
79 95 10
21 80 5
24 38 2
50 56 3
65 97 8
51 88 3
35 84 4
94 98 10
43 57 8
22 96 7
1 12 7
44 68 3
60 63 4
63 99 7
95 99 1
68 87 9
47 83 1
21 72 8
28 43 7
42 44 6
37 48 10
87 99 7
12 15 6
52 69 3
33 88 8
1 40 2
20 67 10
43 95 3
57 98 3
78 81 6
4 99 7
14 55 5
73 93 3
27 94 3
53 57 2
62 77 1
68 82 10
12 99 1
78 92 3
76 93 9
25 55 4
22 48 1
81 83 9
33 65 9
14 86 2
57 82 1
80 90 6
19 60 9
55 71 3
12 51 4
94 96 6
2 98 4
45 70 9
25 93 7
83 99 5
4 81 7
36 59 4
62 68 7
12 97 3
11 66 7
38 67 6
3 31 6
84 94 10
24 78 5
52 99 7
21 75 6
30 98 2
36 76 4
10 84 4
42 66 9
4 51 10
91 94 6
4 36 6
10 21 7
28 74 1
72 80 10
62 84 8
45 80 6
35 60 2
34 40 6
76 79 7
70 92 7
81 90 9
62 64 8
82 99 6
36 93 4
37 86 3
26 94 10
36 87 10
31 61 4
34 53 3
18 21 6
70 76 5
13 58 2
67 83 6
92 98 9
40 80 4
76 99 6
31 49 9
71 79 5
19 63 2
84 86 8
42 72 9
47 69 2
74 93 3
97 99 2
74 86 2
82 92 8
37 68 6
25 89 1
68 88 5
9 66 2
20 93 2
72 96 7
14 73 7
26 59 1
43 58 3
87 92 4
83 88 8
23 31 10
73 87 3
9 89 5
80 92 10
5 45 1
93 99 7
27 80 10
50 78 3
52 88 5
19 54 8
52 83 4
54 98 1
56 75 6
46 70 5
66 73 1
54 85 3
60 77 4
27 63 2
59 69 8
45 59 2
1
100
1.堆实现
'''graphheap.py'''
class Vertex(object):
def __init__(self,name):
self.min_distance = None
self.name = name
self.parent = None
self.adjacents = []
def __eq__ (self,other):
return True
def __lt__(self,other):
return True
class WDGraph(object):
def __init__(self):
self.VertexNumber = 0
self.EdgeNumber = 0
self.VertexSet = {}
self.origin = None
self.destn = None
def generate_graph(self,p,v,w):
if not p in self.VertexSet:
self.VertexSet.setdefault(p,Vertex(p))
if not v in self.VertexSet:
self.VertexSet.setdefault(v,Vertex(v))
self.VertexSet[p].adjacents.append((w,self.VertexSet[v]))
'''Dijstrak_heap.py'''
import heapq
import string
from graphheap import *
def main():
Graph = initial_graph()
S = list(Graph.origin.name)
CS_Heap = []
for w,adj in Graph.origin.adjacents:
adj.min_distance = w
adj.parent = Graph.origin
CS_Heap.append((adj.min_distance,adj))
heapq.heapify(CS_Heap)
while (not Graph.destn.name in S) or CS_Heap:
Nearest = heapq.heappop(CS_Heap)[1]
S.append(Nearest.name)
if Nearest.adjacents:
for w,adj in Nearest.adjacents:
distance = w+Nearest.min_distance
if adj.min_distance is None:
adj.min_distance = distance
adj.parent = Nearest
heapq.heappush(CS_Heap,(adj.min_distance,adj))
elif distance < adj.min_distance:
index = CS_Heap.index((adj.min_distance,adj))
adj.min_distance = distance
adj.parent = Nearest
CS_Heap[index] = CS_Heap[-1]
heapq._siftup(CS_Heap,index)
CS_Heap.pop()
heapq.heappush(CS_Heap,(adj.min_distance,adj))
if not Graph.destn.name in S:
print("{} cannot reach {}".format(Graph.origin.name,Graph.destn.name))
else:
print(Graph.destn.min_distance)
node = Graph.destn
path = list()
while not node is None:
path.append(node.name)
node = node.parent
path.reverse()
print(path)
def initial_graph():
Graph = WDGraph()
with open('test-1.txt','r') as f:
Graph.EdgeNumber = int(f.readline().strip())
Graph.VertexNumber = int(f.readline().strip())
for i,line in enumerate(f.readlines()):
if i == Graph.EdgeNumber:
Graph.origin = line.strip()
elif i == Graph.EdgeNumber + 1:
Graph.destn = line.strip()
else:
p,v,w = line.strip().split()
Graph.generate_graph(str(p),str(v),int(w))
Graph.origin = Graph.VertexSet[Graph.origin]
try:
Graph.destn = Graph.VertexSet[Graph.destn]
except:
print("{} cannot reach {}".format(Graph.origin.name,Graph.destn))
exit()
Graph.origin.min_distance = int(0)
return Graph
if __name__ == "__main__":
main()
2.循环桶实现
'''graphcbucket.py'''
class WDGraph(object):
def __init__(self):
self.maxedge = 0
self.EdgeNumber = 0
self.VertexNumber = 0
self.orgin = None
self.destn = None
self.distance = {}
self.adjencets = {}
def generate_graph(self,p,v,w):
if self.maxedge < w:
self.maxedge = w
if not p in self.adjencets:
self.adjencets.setdefault(p,[(w,v)])
else:
self.adjencets[p].append((w,v))
self.adjencets.setdefault(v,[])
self.distance.setdefault(p,None)
self.distance.setdefault(v,None)
class LoopBucket(object):
def __init__(self,maxedge):
self.pointer = 0
self.VertexNum = 0
self.cyclebase = maxedge+1
self.Bucket = [ [] for i in range(0,self.cyclebase)]
def join(self,distance,parent,vertex):
index = distance % self.cyclebase
self.Bucket[index].append((distance,parent,vertex))
self.VertexNum += 1
def popmin(self):
while not self.Bucket[self.pointer]:
self.pointer = (self.pointer+1) % self.cyclebase
self.VertexNum -=1
return self.Bucket[self.pointer].pop()
def isEmptyBucket(self):
if self.VertexNum == 0:
return True
else:
return False
'''dijstrak_cbucket.py'''
import string
from graphcbucket import *
def main():
Graph = initial_graph()
Bucket = LoopBucket(Graph.maxedge)
path = []
CurrentSet = {}
distance = 0
parent = None
Bucket.join(distance,parent,Graph.origin)
while not (Graph.destn in CurrentSet.keys() and Bucket.isEmptyBucket()):
Closest_dist,Closest_parent,Closest_name = Bucket.popmin()
if not Closest_name in CurrentSet.keys():
CurrentSet.setdefault(Closest_name,Closest_parent)
if Graph.adjencets[Closest_name]:
for weight,adj_name in Graph.adjencets[Closest_name]:
distance = Closest_dist + weight
if Graph.distance[adj_name] is None:
Graph.distance[adj_name] = distance
parent = Closest_name
Bucket.join(distance,parent,adj_name)
elif Graph.distance[adj_name] > distance:
Graph.distance[adj_name] = distance
parent = Closest_name
Bucket.join(distance,parent,adj_name)
if not Graph.destn in CurrentSet.keys():
print("{} cannot reach {}".format(Graph.origin,Graph.destn))
else:
print(Graph.distance[Graph.destn])
node = Graph.destn
path = list()
while not node is None:
path.append(node)
node = CurrentSet[node]
path.reverse()
print(path)
def initial_graph():
Graph = WDGraph()
with open('test-3.txt','r') as f:
Graph.EdgeNumber = int(f.readline().strip())
Graph.VertexNumber = int(f.readline().strip())
for i,line in enumerate(f.readlines()):
if i == Graph.EdgeNumber:
Graph.origin = line.strip()
elif i == Graph.EdgeNumber + 1:
Graph.destn = line.strip()
else:
p,v,w = line.strip().split()
Graph.generate_graph(str(p),str(v),int(w))
Graph.distance[Graph.origin] = int(0)
return Graph
if __name__ == "__main__":
main()