【算法】python实现优先级限制下的并行任务调度问题的关键路径算法CPM

# -*- 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

你可能感兴趣的:(python算法实践)