假定给定任务集合 S = { a 1 , a 2 , ⋯ , a n } S=\{a_1,a_2,\cdots,a_n\} S={a1,a2,⋯,an},其中任务 a i a_i ai在启动后需要 p i p_i pi个时间单位完成。你有一台计算机来运行这些任务,每个时刻只能运行一个任务。令 c i c_i ci表示任务 a i a_i ai的完成时间,即任务 a i a_i ai被执行完的时间。你的目标是最小化平均完成时间,即最小化 ( 1 / n ) ∑ i = 1 n c i (1/n)\sum_{i=1}^{n}c_i (1/n)∑i=1nci。例如,假定有两个任务 a 1 a_1 a1和 a 2 a_2 a2, p 1 = 3 p_1 = 3 p1=3, p 2 = 5 p_2 = 5 p2=5,如果 a 2 a_2 a2首先运行,然后运行 a 1 a_1 a1,则 c 2 = 5 c_2 = 5 c2=5, c 1 = 8 c_1 = 8 c1=8,平均完成时间为 ( 5 + 8 ) / 2 = 6.5 (5+8)/2=6.5 (5+8)/2=6.5。如果 a 1 a_1 a1先于 a 2 a_2 a2执行,则 c 1 = 3 c_1 = 3 c1=3, c 2 = 8 c_2 = 8 c2=8,平均完成时间为 ( 3 + 8 ) / 2 = 5.5 (3+8)/2 = 5.5 (3+8)/2=5.5。
a. 设计算法,求平均完成时间最小的调度方案。任务的执行都是非抢占的,即一旦 a i a_i ai开始运行,它就持续运行 p i p_i pi个时间单位。证明你的算法能最小化平均完成时间,并分析算法的运行时间。
b. 现在假定任务并不是在任意时刻都可以开始执行,每个任务都有一个释放时间 r i r_i ri,在此时间之后才可以开始。此外假定任务执行是可以抢占的 (preemption),这样任务可以被挂起,稍后再重新开始。例如,一个任务 a i a_i ai的运行时间为 p i = 6 p_i = 6 pi=6,释放时间为 r i = 1 r_i = 1 ri=1,它可能在时刻1开始运行,在时刻4被抢占。然后在时刻10恢复运行,在时刻11再次被强占,最后在时刻13恢复运行,在时刻15运行完毕。任务 a i a_i ai共运行了6个时间单位,但运行时间被分割成三个部分。在此情况下, a i a_i ai的完成时间为15.设计算法,对此问题求解平均时间最小的调度方案。证明你的算法确实能最小化完成时间,分析算法的运行时间。
Answer:
a. 算法设计如下:按照运行时间从小到大的顺序依次运行每个任务,算法的时间复杂度为排序时间 O ( n lg n ) O(n\lg n) O(nlgn)。下证该算法能最小化平均完成时间:
首先假设算法最后得到的任务序列为 { i 1 , i 2 , ⋯ , i n } \{i_1,i_2,\cdots,i_n\} {i1,i2,⋯,in},取一个最优序列 { j 1 , j 2 , ⋯ , j n } \{j_1,j_2,\cdots,j_n\} {j1,j2,⋯,jn}。假设存在一个 r r r,使得两个序列的前 r r r项相同,第 r + 1 r+1 r+1项相同。那么我们能够得到如下推论:
- 用时最短的任务。我们使用 p k i p^i_k pki来表示算法得到的任务序列的第 k k k个任务用时; p k j p^j_k pkj来表示算法得到的任务序列的第 k k k个任务用时;使用 P k i P^i_k Pki来表示算法序列的第 k k k个任务的完成时间;使用 P k j P^j_k Pkj来表示最优序列的第 k k k个任务的完成时间。
- 两种序列的前
r
r
r个任务的完成时间之和相同,设第
r
r
r个任务的完成时间为
A
A
A。那么最优序列的剩余
n
−
r
n-r
n−r个任务的完成时间之和为:
∑ d = r + 1 n P d j = ∑ d = r + 1 n ( A + ∑ e = r + 1 d p e j ) \sum_{d = r+1}^{n}P^j_d = \sum_{d = r+1}^{n}\left(A + \sum_{e = r+1}^{d}p^j_e\right) d=r+1∑nPdj=d=r+1∑n(A+e=r+1∑dpej)
由于
i
r
+
1
≠
j
r
+
1
i_{r+1} \ne j_{r+1}
ir+1=jr+1,故存在
j
k
=
i
r
+
1
(
r
+
1
<
k
≤
n
)
j_k = i_{r+1}\quad(r+1 < k \le n)
jk=ir+1(r+1<k≤n),不妨交换最优序列中的
j
r
+
1
j_{r+1}
jr+1和
j
k
j_k
jk。此时最优序列剩余的
n
−
r
n-r
n−r个任务的完成时间之和为:
∑
d
=
r
+
1
n
P
^
d
j
=
∑
d
=
r
+
1
n
(
A
+
∑
e
=
r
+
1
d
p
e
j
)
+
(
n
−
r
)
(
p
k
j
−
p
r
+
1
j
)
+
(
n
−
k
+
1
)
(
p
r
+
1
j
−
p
k
j
)
\sum_{d = r+1}^{n}\hat{P}^j_d = \sum_{d = r+1}^{n}\left(A + \sum_{e = r+1}^{d}p^j_e\right) + (n-r)(p^j_k - p^j_{r+1}) + (n-k+1)(p^j_{r+1} - p^j_k)
d=r+1∑nP^dj=d=r+1∑n(A+e=r+1∑dpej)+(n−r)(pkj−pr+1j)+(n−k+1)(pr+1j−pkj)
有
p
k
j
≤
p
r
+
1
j
p^j_k \le p^j_{r+1}
pkj≤pr+1j以及
r
+
1
<
k
≤
n
r+1 < k \le n
r+1<k≤n,故:
∑
d
=
r
+
1
n
P
^
d
j
=
∑
d
=
r
+
1
n
P
d
j
+
(
k
−
r
−
1
)
(
p
k
j
−
p
r
+
1
j
)
≤
∑
d
=
r
+
1
n
P
d
j
\sum_{d = r+1}^{n}\hat{P}^j_d = \sum_{d = r+1}^{n}P^j_d + (k-r-1)(p^j_k - p^j_{r+1}) \le \sum_{d = r+1}^{n}P^j_d
d=r+1∑nP^dj=d=r+1∑nPdj+(k−r−1)(pkj−pr+1j)≤d=r+1∑nPdj
这说明交换后的新序列的平均完成时间小于等于最优序列的平均完成时间,这与最优序列的假设相矛盾,故此处的小于等于只能取等于号,即 p k j = p r + 1 j p^j_k = p^j_{r+1} pkj=pr+1j,此时交换两个任务不会使平均完成时间发生变化,因此该最优序列可以保持最优序列的性质。
- 根据上一条推论,我们可以知道对于任意前 r ( r < n ) r\quad (r < n) r(r<n)项相同的一组算法生成的序列和一组最优序列,都可以通过交换操作在保持最优序列性质的前提下,使得两个序列的第 r + 1 r+1 r+1位也相同,直到两个序列完全相同。故该算法能最小化平均完成时间。
b. 采用最短用时优先算法:优先执行当前剩余时间最短的可执行任务。
首先假设算法最后得到的每个时刻所执行的任务的任务序列为 { i 1 , i 2 , ⋯ , i m } \{i_1,i_2,\cdots,i_m\} {i1,i2,⋯,im},取一个最优序列 { j 1 , j 2 , ⋯ , j m } \{j_1,j_2,\cdots,j_m\} {j1,j2,⋯,jm},此处 m m m为所有任务的总用时。假设该最优序列能满足在所有其他的最优序列中拥有一个最大的 r r r,使得两个序列的前 r r r项不相同,第 r + 1 r+1 r+1项相同。那么我们能够得到如下推论:
- 对于指代不同任务的 i r + 1 i_{r+1} ir+1和 j r + 1 j_{r+1} jr+1,由算法定义可知任务 T r + 1 i T^i_{r+1} Tr+1i的剩余用时小于等于任务 T r + 1 j T^j_{r+1} Tr+1j的剩余用时。若相等,则将后续序列中所有的 i r + 1 i_{r+1} ir+1和 j r + 1 j_{r+1} jr+1互换,该操作不影响最优序列的性质,并使最优序列的前 r + 1 r+1 r+1项与算法提供的序列前 r + 1 r+1 r+1项相同,这与最大 r r r的假设相矛盾。因此任务 T r + 1 i T^i_{r+1} Tr+1i的剩余用时必然小于任务 T r + 1 j T^j_{r+1} Tr+1j的剩余用时。
- 已知算法优先执行当前剩余时间最少的任务,记两个序列当前完成的任务为 R R R个,则第 R + 1 R+1 R+1个任务的完成时间必然是算法序列的完成时间更小。此处记算法序列第 r + 1 r+1 r+1个时刻执行的任务为 T i T^i Ti,记最优序列第 r + 1 r+1 r+1个时刻执行的任务为 T j T^j Tj。那么两个任务在第 r + 1 r+1 r+1个时刻前各自都还有剩余用时,记 T i T^i Ti的剩余用时为 t i t^i ti; T j T^j Tj的剩余用时为 t j t^j tj,特别地,有 t i < t j t^i < t^j ti<tj。根据上述内容,我们知道在最优序列从第 r + 2 r+2 r+2个时刻起的后续的 m − r − 1 m-r-1 m−r−1个时刻里,任务 T i T^i Ti还要执行 t i t^i ti次,而任务 T j T^j Tj还要执行 t j − 1 t^j-1 tj−1次。
- 我们将最优序列中自第
r
+
1
r+1
r+1个时刻起的所有执行任务
T
j
T^j
Tj的
t
j
t^j
tj个时刻记为一个集合
U
(
∣
U
∣
=
t
j
>
t
i
)
U\quad(|U| = t^j > t^i)
U(∣U∣=tj>ti),以及所有执行任务
T
i
T^i
Ti的时刻即为一个集合
V
V
V,将两个集合合并记做
W
=
U
+
V
W = U + V
W=U+V。则
W
W
W中有
t
i
+
t
j
t^i+t^j
ti+tj个元素,我们使时刻最小的前
t
i
t^i
ti个时刻在最优序列中都执行任务
T
i
T^i
Ti,剩余的后
t
j
t^j
tj个时刻在最优序列中执行任务
T
j
T^j
Tj。已知原先任务
T
i
T^i
Ti与任务
T
j
T^j
Tj的完成时间分别为
F
i
=
M
A
X
k
∈
[
1
,
t
i
]
(
u
k
∣
u
k
∈
U
)
F^i = MAX_{k \in [1,t^i]}\left(u_k|u_k \in U\right)
Fi=MAXk∈[1,ti](uk∣uk∈U)和
F
j
=
M
A
X
k
∈
[
1
,
t
j
]
(
u
k
∣
u
k
∈
V
)
F_j = MAX_{k \in [1,t^j]}\left(u_k|u_k \in V\right)
Fj=MAXk∈[1,tj](uk∣uk∈V)。同时,两者之和也可以表示为:
Q = F i + F j = M A X ( F i , F j ) + M I N ( F i , F j ) Q = F^i + F^j = MAX\left(F^i,F^j\right) + MIN\left(F^i,F^j\right) Q=Fi+Fj=MAX(Fi,Fj)+MIN(Fi,Fj)
那么交换后的新序列中,除了任务
T
i
T^i
Ti与任务
T
j
T^j
Tj,其他任务的完成时间完全不变,而任务
T
i
T^i
Ti的完成时间变为
W
W
W中第
t
i
t^i
ti大的时刻,记为
w
t
i
,
w
t
i
<
M
I
N
(
F
i
,
F
j
)
w_{t^i},\quad w_{t^i} < MIN\left(F^i,F^j\right)
wti,wti<MIN(Fi,Fj)。而任务
T
j
T^j
Tj的完成时间变为
M
A
X
(
F
i
,
F
j
)
MAX\left(F^i,F^j\right)
MAX(Fi,Fj),故交换后的两者之和:
Q
′
=
w
t
i
+
M
A
X
(
F
i
,
F
j
)
<
M
A
X
(
F
i
,
F
j
)
+
M
I
N
(
F
i
,
F
j
)
=
Q
Q' = w_{t^i} + MAX\left(F^i,F^j\right) < MAX\left(F^i,F^j\right) + MIN\left(F^i,F^j\right) = Q
Q′=wti+MAX(Fi,Fj)<MAX(Fi,Fj)+MIN(Fi,Fj)=Q
故在其他任务的完成时间都不变的情况下,交换后的这两个任务的完成时间之和变小了,这与原序列为最优序列的假设不相符。故假设不成立,不存在这样的最大 r r r使得前 r r r项相同,第 r + 1 r+1 r+1项不同。即所有项都相同。故该算法能够获取最小平均完成时间。