來自:http://topic.csdn.net/u/20090504/21/1992403a-69b0-4a97-ada5-4ef8153f2078.html?seed=1381913772
--
假設有一臺機器,以及在此機器上處理的n個作業a1,a2,...,an的集合。處理作業aj所需的時間爲tj,作業aj的完成帶來的收益爲pj,作業 aj完成的最後期限爲dj。機器在一個時刻只能處理一個作業,而且如果某作業被處理,那麼一定要在連續的時間內進行處理。如果某作業aj在最後期限dj之 前完成,則獲得收益pj,若在最後期限之前沒有完成,則沒有收益。請給出一個算法,來尋找能獲得最大收益的調度,假設所有作業所需的處理時間都爲整數。
解:
假設數據如下:
a1 | a2 | a3 |
a4 |
a5 |
a6 |
a7 |
|
---|---|---|---|---|---|---|---|
t | 10 | 8 |
5 |
7 |
4 |
2 |
7 |
p | 5 | 4 |
9 |
4 |
5 |
1 |
3 |
d | 10 | 39 |
50 |
47 |
36 |
11 |
23 |
法一(近似算法):
思路:每次對剩餘作業重新計算優先級,選取優先級最高者投入處理。直至所有作業處理完畢。
優先級公式爲prio=p/(d-currentTime-t)。
matlab程序如下:
clear; |
運行結果:
最大收益:
30
加工順序:
1 7 5 3 4 2 6
法二(精確算法):
用動態規劃算法,另外由於是調度問題,所以只要每次取S最小的狀態進行轉移,就可以改進爲dijkstra算法。
matlab程序如下:
clear; a(1)=struct('t',10,'p',5,'d',10); a(2)=struct('t',8,'p',4,'d',49); a(3)=struct('t',5,'p',9,'d',50); a(4)=struct('t',7,'p',4,'d',47); a(5)=struct('t',4,'p',5,'d',36); a(6)=struct('t',2,'p',1,'d',11); a(7)=struct('t',7,'p',3,'d',23); statlist(1)=struct('time',0,'S',[0 0 0 0 0 0 0],'prof',0,'per',-1,'open',true); while(1) %找open=true的狀態中S最小者 minS=1000000000; minI=-1; for i=1:length(statlist) if statlist(i).open==true&&sum(statlist(i).S)<minS minI=i; minS=sum(statlist(i).S); end end%找到minI statlist(minI).open=false; if veceq(statlist(minI).S,[1 1 1 1 1 1 1]) break; end stat=statlist(minI); %對狀態stat作推進 for i=1:length(a) if stat.S(i)==0 %將a(i)執行,stat轉移到linstat linstat=stat; linstat.time=linstat.time+a(i).t; linstat.S(i)=1; if linstat.time<=a(i).d linstat.prof=linstat.prof+a(i).p; end linstat.per=minI; linstat.open=true; %新狀態加入狀態列表 exist=false; for j=1:length(statlist) if veceq(statlist(j).S,linstat.S) exist=true; end end%得到exist if exist if linstat.prof>statlist(j).prof statlist(j)=linstat; end else statlist=[statlist,linstat]; end end end end %顯示結果 disp('最大收益:') disp(statlist(minI).prof); %回溯路徑 i=minI; rs=zeros(0,7); while i~=-1 rs=[rs;statlist(i).S]; i=statlist(i).per; end %將路徑處理成易讀形式 order=[]; for i=1:size(rs,1)-1 rs(i,:)=rs(i,:)-rs(i+1,:); order=[order,find(rs(i,:)==1)]; end order=order(7:-1:1); disp('加工順序:'); disp(order); |
運行結果:
最大收益:
30
加工順序:
1 6 7 3 2 5 4
注:
(1),用到的輔助函數:
function yn=veceq(A,B) %比較兩個向量是否相等 if all(size(A)==size(B))&&all(A==B) yn=true; return; end yn=false; end |
(2),可見,對於本例而言,近似算法得到了與精確算法相同的結果。但近似算法是多項式算法,而精確算法不是多項式算法,但也比窮舉所有排列複雜度低得多。