# -*- coding: utf-8 -*-
# /usr/bin/python
# 作者:kimicr
# 实验日期:20190827
# Python版本:3.6.3
'''
问题描述:
“并行任务调度”,给定一组需要完成的任务和每个任务所需要的时间,以及一组关于
任务完成的先后次序的优先级限制。在满足限制条件的前提条件下,该如何在若干相同处理
器上安排任务并在最短的时间内完成所有任务?P429
思路分析:
由于现在有多个处理器并能够同时处理多个任务,所以受到的只是优先级的限制。最后
一种叫“关键路径”方法能够证明“这个问题” <=>(等价于) 无环加权有向图中的最长路径
问题等价。(即是顶点S到顶点t的最长路径),详见P431
'''
inf = float("-inf")
class CPM(object):
def __init__(self,Graph,time):
self.Graph = Graph
self.time = time
self.path = []
self.marked = []
for i in range(len(self.Graph[0])):
self.marked.append(0)
#深度优先搜索
def dfs(self,v):
if self.marked[v] == 1:
return
else:
self.marked[v] = 1
self.path.append(v)
count = 0
for key in self.Graph[v]:
if key != inf:
self.dfs(count)
count += 1
# 打印顶点S到某一点的最短路径
def PrintPath(self, edgeTo, end):
road = [end]
while edgeTo[end] != None:
road.insert(0, edgeTo[end])
end = edgeTo[end]
return road
#等价最长路径算法
def cpm(self):
#初始化阶段
self.dfs(len(self.Graph[0])-2) # 加入起点
deque = self.path[:] # 得到处理顶点的顺序
edgeTo = [] # 横切边
distTo = [] # 最长距离
for i in range(len(self.marked)): # 初始化
edgeTo.append(None)
distTo.append(inf)
distTo[len(self.Graph[0])-2] = 0 # 顶点S到S的距离为0
s = deque.pop(0)
count = 0
for i in self.Graph[s]:
if i != inf:
distTo[count] = i
edgeTo[count] = s
count += 1
#print(distTo)
# 开始求解
while deque:
count = 0
s = deque.pop(0)
for i in self.Graph[s]:
if i != inf and distTo[s] + i > distTo[count]:
distTo[count] = distTo[s] + i
edgeTo[count] = s
deque.append(count)
elif i != inf and distTo[s] + i <= distTo[count]:
self.Graph[s][count] = inf
deque.append(count)
count += 1
#print(edgeTo,distTo,self.path)
print("Start time: ")
for i in range(len(self.Graph[0])-1):
print("%d to %d(%.2f):" %(self.path[0],i,distTo[i]),end="")
PATH = self.PrintPath(edgeTo[:],i)
if len(PATH) == 1 and PATH[0] == self.path[0]:
print('')
else:
for i in PATH[:-1]:
print('%d->' %(i),end = "")
print(PATH[-1])
print("Finished time: %d" %(distTo[-1]))
if __name__ == "__main__":
Graph = [[inf, 41, inf, inf, inf, inf, inf, 41, inf, 41, inf, 41],
[inf, inf, 51, inf, inf, inf, inf, inf, inf, inf, inf, 51],
[inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 50],
[inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 36],
[inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 38],
[inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 45],
[inf, inf, inf, 21, inf, inf, inf, inf, 21, inf, inf, 21],
[inf, inf, inf, 32, inf, inf, inf, inf, 32, inf, inf, 32],
[inf, inf, 32, inf, inf, inf, inf, inf, inf, inf, inf, 32],
[inf, inf, inf, inf, 29, inf, 29, inf, inf, inf, inf, 29],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, inf, inf],
[inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf]
]
time = (41,51,50,36,38,45,21,32,32,29,0,0)
Graph1 = {"0":[1,7,9],
"1":[2],
"2":[],
'3':[],
'4':[],
'5':[],
'6':[3,8],
'7':[3,8],
'8':[2],
'9':[4,6],
'10':[],
'11':[],
}
C = CPM(Graph,time)
C.cpm()
#结果
Start time:
10 to 0(0.00):10->0
10 to 1(41.00):10->0->1
10 to 2(123.00):10->0->9->6->8->2
10 to 3(91.00):10->0->9->6->3
10 to 4(70.00):10->0->9->4
10 to 5(0.00):10->5
10 to 6(70.00):10->0->9->6
10 to 7(41.00):10->0->7
10 to 8(91.00):10->0->9->6->8
10 to 9(41.00):10->0->9
10 to 10(0.00):
Finished time: 173