Weighted Interval Scheduling VS Interval Scheduling

一、Interval Scheduling

初学算法设计与分析,老师就讲到了这个比较难的问题,听的时候就似懂非懂。现在搞清楚记录如下。

本问题涉及到的算法:贪心算法(Greedy Algorithm)

1.1 问题描述:

假设我们有多个任务,图中给出了,每个任务的开始时间和终止时间。不同任务不重叠的情况下,求任务的最大组合数。

input:具有起始时间(Si)和终止时间(Fi)的任务集合
goal:不同任务的最大组合数

image.png

1.2 问题分析:

分析一个问题,我们首先分析出一个可行的算法,然后再对算法进行优化,尽可能降低复杂度,达到最优的情况。

备选方案:

1、任务按开始时间排序(Si);
2、任务按终止时间排序(Fi);
3、任务按照所用时间长短(Fi - Si)排序;
4、对于每一个任务,计算与它冲突的任务个数Ci,然后对Ci排序。

由于本问题比较简单,我们不过多讨论。容易发现,使用贪心算法,我们按照终止时间排序,可以成功的求解问题。

1.3 问题求解:

首先我们按照终止时间,对任务进行排序,然后依次选择,不重叠的任务,即可求出,最大的任务组合数。

伪代码:
Sort jobs by finish times so that f1 <= f2 <= ... <= fn.
select a task ——>A 
for j = 1 to n {
   if (job j compatible with A)
      A and {j} ——> A
}
return A  

算法复杂度:O(n logn)
其实这个问题是有别的算法的,我们课上同学讨论出一个,老师都惊呆了。老师本来想推翻同学的算法,结果发现,同学的算法非常正确。

二、Weighted Interval Scheduling

在问题一的基础上,稍加修改,问题变难很多,成为带权值的任务调度问题。上课睡觉的后果就是,课上成功听不懂,课下自己想办法。

本问题涉及到的算法:动态规划(Dynamic Programming)

讲真提到动态规划,比较头大,尤其是对于没有算法的基础新手。在此贴上知乎大佬的解释:https://www.zhihu.com/question/23995189

2.1 问题描述:

在问题1的基础上,我们对每个任务增加权值。实际情况下,我们可以认为,我们的任务优先级不同,重要性不同。即使有些任务,用到的时间短,重要性却很高。在这种情况下,我们求解,固定时间内,求完成任务权值和的最大值。

input:具有起始时间(Si),终止时间(Fi)和权值(Wi)的任务集合
goal:任务组合的权值最大值

image.png

2.2 问题分析:

首先我们考虑贪心算法,能否用于本问题。容易发现,问题1其实是问题2的权值为1的特例,在权值为1的情况下,贪心算法是可以求解的。若权值是任意值,算法便会失效。从图中我们可以看出,任务b的权值很大,却不会被选出,明显权值和,不是最大。
image.png
这里直接说算法,求解吧,毕竟我也不知道到底是怎么想出来的。前人的经验,我们看懂,理解,也算成功了。

2.2 问题求解:

当然,本问题,是可以暴力求解的,也就是枚举(遍历),但这必然复杂度,爆炸,如果都用枚举,我们还学算法有毛用。
这里还需要说下,有两种算法,一种是使用回归算法,另一种Bottom to Up
直接上算法,稍后再解释。

2.2.1回归算法:

sort:首先我们按照结束时间对任务进行排序;
define:定义一个函数P(i),是指与任务i不重叠的索引最大值,该索引小于i;
OPT(j)=max(Wj+OPT(p(j)),OPT(j−1))

算法伪代码:
image.png

首先我们对任务按结束时间排序,这里就不多说了。然后我们定义了一个函数P(i),是指与任务i不重叠的索引最大值,该索引小于i。比如说下图:
image.png
当i=8,P(8)也就是,与任务8不重叠的任务索引的最大值,从图中看出是5,所以P(8)=5。
然后我们定义OPT(i)也就是,对于i个任务,该问题的最优解的值。对于j个任务的最优解,我们按照是否选择任务j,可以划分为两种情况。情况一:选择任务j,取它的权值Wj,然后往前找与任务j不重叠的任务索引最大值,求OPT(P(j)),然后将二者相加;情况二:不选择任务j,选择任务j-1。然后我们比较这两种情况的大小,作为j个任务的最优解。
image.png
算法缺陷:
当我们有大量的子问题的时,回归算法需要大量的计算,成为指数问题,算法便会失效。
其实我们这个算法,是从任务的最后一个,依次向前求,需要不停地回归,用到前面的值,同时我们需要不停地存储最优解。

2.2.2 :Bottom-up dynamic programming

image.png
从公式我们可以看出每一个OPT值依赖于前一个值,OPT(p(j))或者是OPT(j-1)。因此,我们能否倒过来,将n的顺序,也就是从第一个开始开始,计算OPT(j)的值呢。实际是我们是可以的,也就是按照下图给出的伪代码。
伪代码:
image.png
强烈建议看下这个网站:https://farazdagi.com/2013/weighted-interval-scheduling/
除了详细的解释,还有python的代码实现,而且详细的解释了,具体每一步的复杂度。

参考资料:

1.http://www.tceic.com/3l9850lg1711ii7930h71614.html
2.https://www.daniweb.com/programming/software-development/threads/449426/weighted-interval-scheduling
3.https://en.wikipedia.org/wiki/Interval_scheduling
4.https://farazdagi.com/2013/weighted-interval-scheduling/

猜你喜欢

转载自blog.csdn.net/linxid/article/details/79655238
今日推荐