任务调度问题(贪心思想)

28 篇文章 0 订阅
7 篇文章 0 订阅
题目描述

  一个单位时间任务是恰好需要一个单位时间完成的任务。给定一个单位时间任务的有限集S。关于S 的一个时间表用于描述S 中单位时间任务的执行次序。时间表中第1 个任务从时间0 开始执行直至时间1 结束,第2 个任务从时间1 开始执行至时间2 结束,…,第n个任务从时间n-1 开始执行直至时间n结束。具有截止时间和误时惩罚的单位时间任务时间表问题可描述如下:
    (1) n 个单位时间任务的集合S={1,2,…,n}(n≤500);
    (2) 任务i的截止时间d[i],1≤i≤n,1≤d[i]≤n,即要求任务i在时间d[i]之前结束;
    (3) 任务i 的误时惩罚1≤w[i]< 1000,1≤i≤n,即任务i 未在时间d[i]之前结束将招致w[i]的惩罚;若按时完成则无惩罚。
  任务时间表问题要求确定S 的一个时间表(最优时间表)使得总误时惩罚达到最小。

输入数据

  第一行是正整数 n ,表示任务数。接下来的 2 行中,每行有 n 个正整数,分别表示各任务的截止时间和误时惩罚。

输出数据

  将计算出的最小总误时惩罚输出

样例输入
7
4 2 4 3 1 4 6
70 60 50 40 30 20 10
样例输出
50
程序分析
解题思路
  • 贪心思路:贪心考虑的是局部的最优解,而不是全局的最优解,为了达到最小的误时惩罚,按照贪心策略,肯定是先去按时完成或提前完成惩罚较大的任务。若一个时间片上已经安排了按时完成的、有着较大惩罚的任务,那么,这个有着较小惩罚的任务,则需要提前完成(提前完成有着很多种方法,按照贪心策略,应该是放在紧邻的上一个时间片完成,若这个时间片也有任务,继续往前移,直到有空闲的时间片可以执行这个任务,否则,这个任务会带来惩罚)。
  • 解题步骤1:根据罚时的长短进行排序,将罚时时间长的放在前面。开一个数组作为时间槽,记录每个单位时间是否有任务安排。若截止日期相同,根据罚时的时间长短判断哪个优先 (罚时长的优先),尽量将任务安排在截至时间完成,否则放在放在前一天,以此类推。若在截至时间前都有任务安排,先不要将该任务加入到时间槽中(可能产生后效性),可以将这个任务舍去,同时,将其增加到罚时中,等到对全部的任务过滤一遍后,可以将罚时的任务随意地插入到时间槽中 (既然都有罚时了,那么在截止时间后的任何一个时间片,完成该任务都一样)
代码
class Optimal:
    def __init__(self):
        self.penaltyTTime = 0
        self.punishDescent()
        self.optimalOrder()
    # 获取最优的安排顺序
    def optimalOrder(self):
        for i in range(1, n+1):  # [1:n]的时间片,每个位置用于安排一个任务
            for j in range(deadlines[i], -1, -1):
                if optimalChoice[j] == 0:   # 如果该时间片还没有任务,则将这个任务放在这里,即置为1
                    optimalChoice[j] = 1
                    break
            # 若[1:i]的时间片都有安排的任务,则这个任务肯定会产生罚时。
            # 注意,此时不要将其安排在optimalChoice[i+1,n]中,以免产生后效性。已经产生了罚时的任务,最后安排在[i+1,n]中
            # 时间片中,因为可能有punishments[i+1,n]中的一个任务,的deadlines的时间在[i+1:n]中
            if j == 0:
                self.penaltyTTime += punishments[i]
        print(self.penaltyTTime)

    # 排序:对相同截止时间的误时惩罚进行降序排列
    def punishDescent(self):
        # 冒泡排序n-1次
        for i in range(1, n):
            for j in range(1, n+1-i):
                if punishments[j] < punishments[j+1]:
                        punishments[j], punishments[j+1] = punishments[j+1], punishments[j]
                        deadlines[j], deadlines[j+1] = deadlines[j+1], deadlines[j]
if __name__ =='__main__':
    n = int(input())
    deadlines = [0]      # 截至时间
    punishments = [0]    # 误时惩罚
    optimalChoice = [0]*(n+1)  # 最优安排顺序
    deadlines += list(map(int, input().rstrip().split()))
    punishments += list(map(int, input().rstrip().split()))
    Optimal()

  1. https://blog.csdn.net/lvbcy/article/details/52072268 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

还能坚持

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值