计算机算法设计与分析 ——(二)

本文介绍了如何运用贪心算法解决带期限的单机调度问题,确保作业集合中选出效益值最大的相容子集。算法通过选取效益最大的作业,并验证加入新作业后仍满足可行性条件。通过证明,展示了贪心算法得到的解集至少与最优解等效,从而证明算法的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

贪心算法–带期限的单机调度问题

算法求解问题:

已知n项作业 E={1, 2, … ,n}要求使用同台机器完成,而且每项作业需要的时间都是1。第k项作业要求在时刻dk之前完成, 而且完成这项作业将获得效益pk,k=1, 2, … , n 。

现在我们要求解的是:
要在所给的作业集合中选出总效益值最大的相容子集。
(其中pk为算法的贪心标准)

算法思想:

proc GreedyJob(d, p, n) //带期限的单机作业安排算法
     //d[1..n]和p[1..n]分别代表各项作业的限期和效益值,
    //而且n项作业的排序满足:p1 >= p2 >=>= pn   
    local  J;
    J:={1}; //初始化解集
    for i from 2 to n do       
      if  J 并上 {i} 中的作业是相容的   //检验规则:(放在后面解释)
       then  //对任一j ∈ J 并上 {i},作业期限≤d(j)的数量≤ d(j)个
        J:= J 并上 {i};   // 将i加入解中
      end{if}
    end{for}
   end{GreedyJob}    //贪心准则:尽量选取效益大的作业安排  (该算法关键在于检验规则)

算法实例:
在这里插入图片描述7是问题最优解

算法证明:

假设贪心算法所选择的作业集J不是最优解,则一定有相容作
业集I,其产生更大的效益值。证 I=J。

也就是说现在有两个集合,分别是:
贪心集:J
最有集:I
因为假设贪心算法得到的不是最优,那么必定存在一个最优,如果证明J=I则算法得证。
如果J不等于I则有以下关系:

1.最优I 是  贪心J的子集,显然不成立,既然贪心得到了更大的集合且合理那I又怎么能称为最优
2.贪心J 是 最优I的子集,显然也不成立,因为这样违背了贪心规则
3.那么只有第三种情况就是两个集合各自存在对方没有的元素
   即至少存在两个作业a,b   其中a属于J,不属于I   , b属于I,不属于J

在这里插入图片描述
此时对于a,pa>=I中所有的pb,因为如果将I和J从大到小排列后逐一比较,到a时与相应位置的b比较由于贪心算法,此时会选择大的,因为选择了a所以pa>=pb

设SJ和SI是J和I两个可行解的调度序列:

其中i是既属于J又属于I的一个作业,其调度时刻在两个集合中如图分别是[t,t+1]和[t’,t’+1]。
现在在两个调度表中做如下调整:
在这里插入图片描述
1.t<t’
将SJ中t‘时刻的作业和i相交换,如果存在则交换,如果不存在则直接将i移过去。
(新调度表依然可行,因为t‘时刻的作业提前完成肯定是可行的,而t时刻的i在最优解中在t’时刻执行是可行的所以在J中移动后依然可行)

在这里插入图片描述
2.t’<t
操作与上述类似,同样新的调度表依然可行

对J和I 中所有作业如此操作后,得到的新SJ和SI的共有作业将会在相同时间进行调度,而不相同的则如下:

在这里插入图片描述此时将 I中的ta时刻作业如果替换成a,则对于I 来说,效益值并不会减少,且替换后仍然可执行。重复上述转换后,I其实也就已经替换成了J,且效益值不会减小,所以J其实就是等于I的。证毕

检验规则

好,现在回过头来再看一下前面说到的检验规则,也就是加入i后J是否仍然可行。
首先我们需要找到一个特定序列,该序列为按照作业期限的非降次序排列,设该序列为σ。
J是一个可行解,当且仅当J中的作业可以按照σ的次序而又不违反规则任何一个期限的情况来处理。
在这里插入图片描述在这里插入图片描述只有满足上述条件,加入i后的J才是可行的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值