基础算法 —— 调度问题 —— 流水调度问题
【概述】
流水調(diào)度問題的表達(dá)為:有n 個(gè)作業(yè)在兩臺(tái)機(jī)器?M1、M2 組成的流水線上進(jìn)行加工,每個(gè)作業(yè) i 都必須花費(fèi) ai 在 M1 上行加工,然后再花費(fèi) bi 在 M2 上加工,確定 n 個(gè)作業(yè)的加工順序,使得 n 個(gè)作業(yè)完成加工的時(shí)間最短。
關(guān)于流水調(diào)度問題,可用 Johnson 法則來求最優(yōu)調(diào)度方案,其時(shí)間復(fù)雜度為?O(nlogn)
算法描述為:設(shè) N1 位 a<b 的作業(yè)集合,N2 為 a>=b 的作業(yè)集合,將 N1 的作業(yè)按 a 非減序排列,N2 中的作業(yè)按 b 非增序排列,則 N1 作業(yè)接 N2 作業(yè)構(gòu)成最優(yōu)順序。
【問題分析】
求一個(gè)加工順序使加工總時(shí)間最短,就是讓機(jī)器空閑時(shí)間最短,一旦機(jī)器 M1?開工,那么 M1?會(huì)不停的進(jìn)行作業(yè)沒有空閑時(shí)間,而機(jī)器 M2 會(huì)有兩種情況:機(jī)器空閑、作業(yè)積壓,而且在第一個(gè)部件在機(jī)器 M1 開始加工時(shí),機(jī)器 M2 必須等待,最后一個(gè)部件在機(jī)器 M2 加工時(shí),機(jī)器 M1 也在等待機(jī)器 M2 的完工。
要使機(jī)器總空閑時(shí)間最短,就要將在機(jī)器 M1 上加工時(shí)間最短的部件先進(jìn)行加工,這樣使得機(jī)器 M2 在最短的時(shí)間內(nèi)可以開工,再把機(jī)器 M2 上加工時(shí)間最短的部件最后加工,這樣使得機(jī)器 M1 在最短的時(shí)間內(nèi)等待機(jī)器 M2 完工。
根據(jù) Johnson 法則,設(shè):Mi=min{ai,bi}
將 M 按照從小到大的順序排序,然后從第一個(gè)開始處理:
- 若 Mi=ai,則:將第 i 個(gè)部件放在其從頭開始的加工的部件后面
- 若 Mi=bi,則:將第 i 個(gè)部件放在其從尾開始的加工的部件的前面
最后得到的序列即為最優(yōu)加工順序。
例如:n=5,(a1,a2,a3,a4,a5)=(3,5,8,7,10),(b1,b2,b3,b4,b5)=(6,2,1,4,9)
則 M=(m1,m2,m3,m4,m5)=(3,2,1,4,9)
將 M 進(jìn)行排序,有:(m3,m2,m1,m4,m5),然后進(jìn)行處理
- 處理 m3:由于 m3=b3,因此 m3 放在后面,加工順序?yàn)?#xff1a;(? ,? ,? ,? ,3)
- 處理 m2:由于 m2=b2,因此 m2?放在后面,加工順序?yàn)?#xff1a;(? ,? ,? ,2,3)
- 處理 m1:由于 m1=a1,因此 m1?放在前面,加工順序?yàn)?#xff1a;(1,? ,? ,2,3)
- 處理 m4:由于 m4=b4,因此 m4?放在后面,加工順序?yàn)?#xff1a;(1,? ,4,2,3)
- 處理 m5:由于 m5=b5,因此 m5?放在后面,加工順序?yàn)?#xff1a;(1,5,4,2,3)
因此,最優(yōu)的加工順序就是 (1,5,4,2,3),最短時(shí)間為 34
【實(shí)現(xiàn)】
struct Node{int num;int id;bool operator < (const Node &rhs)const{return num<rhs.num;} }m[N]; int a[N],b[N]; int res[N]; int main(){int n;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);for(int i=1;i<=n;i++)scanf("%d",&b[i]);//記錄mfor(int i=1;i<=n;i++){m[i].num=min(a[i],b[i]);m[i].id=i;}//對(duì)m進(jìn)行排序sort(m+1,m+1+n);//對(duì)m進(jìn)行處理int head=0,tail=n+1;for(int i=1;i<=n;i++){int num=m[i].num;int id=m[i].id;if(num==a[id])res[++head]=id;elseres[--tail]=id;}//計(jì)算最優(yōu)時(shí)間int timeA=0,timeB=0;for(int i=1;i<=n;i++){timeA+=a[res[i]];if(timeB<timeA)timeB=timeA;timeB+=b[res[i]];}printf("%d\n",timeB);for(int i=1;i<=n;i++)printf("%d ",res[i]);printf("\n");return 0; }?
總結(jié)
以上是生活随笔為你收集整理的基础算法 —— 调度问题 —— 流水调度问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数列分块入门 3(LibreOj-627
- 下一篇: 图论 —— 网络流