資源排程問題——貪心演算法
資源排程:給定等待服務的客戶集合A = {1, 2, …, n},預計對客戶i的服務時間是ti,該客戶希望的完成時間是di,即T = {t1, t2,…, tn},D = {d1, d2,…, dn}。如果對客戶i的服務在di之前結束,那麼對客戶i的服務沒有延遲;如果在di之後結束,那麼這個服務就被延遲了,延遲的時間等於該服務時間減去di。假設都是ti和di正整數,一個排程是函式f:A→N,其中是對客戶i的服務開始的時間,要求所有區間互不重疊。一個排程f的最大延遲是所有客戶延遲時間的最大值,例如:
A ={1, 2, 3, 4, 5}
T= {5, 8, 4, 10, 3}
D = {10, 12 , 15, 11,20}
那麼對於排程f1
f1:{1, 2, 3, 4, 5} → N
f1(1)= 0, f1(2)= 5, f1(3)= 13, f1(4) = 17, f1(5)= 27
客戶1, 2, 3, 4, 5的延遲分別是0, 1, 2, 16, 10;最大延遲是max{0, 1, 2, 16 ,10}= 16。
但是,不同調度的最大延遲是不一樣的,再如對同一個例項的另一個排程f2
f2:{1, 2, 3, 4, 5} → N
f2(1)= 0, f2(2)= 15, f2
客戶1~5的延遲分別是0, 11, 12, 4 ,10;最大延遲是max{0, 11, 12, 4 ,10}= 12。
上述排程f1和f2的安排分別如圖1所示:
圖1 兩個不同的排程方案
顯然,排程f2比f1具有更小的延遲。
我們的問題是:給定 A = {1, 2, …, n},T= {t1, t2, …, tn}和D = {d1, d2, …, dn},用貪心演算法求解具有最小延遲的排程f(不要求給出理論上的正確性證明)。
import java.util.Scanner; public class 資源排程 { public static void main(String[] args) { Scanner in=new Scanner (System.in); System.out.println("輸入客戶數量n"); int n=in.nextInt();//客戶數量 int t[]=new int[n];//預計完成時間 int d[]=new int[n];//希望完成時間 System.out.println("輸入每個客戶預計完成所需時間:"); for(int i=0;i<n;i++) { t[i]=in.nextInt(); } System.out.println("輸入每個客戶希望完成時間:"); for(int i=0;i<n;i++) { d[i]=in.nextInt(); } int TempSumTime=0;//當前完成總時間 int maxDelayTime=0;//最大延遲時間 int TempDelayTime=0;//當前延遲時間 //氣泡排序 for(int i=1;i<n;i++) { for(int j=0;j<n-i;j++) { if(d[j]>d[j+1]) { swap(d,j,j+1); swap(t,j,j+1); } } } for(int i=0;i<n;i++) { TempSumTime+=t[i]; if(TempSumTime>d[i]) {//判斷是否有延遲時間 TempDelayTime=TempSumTime-d[i];//求出延遲時間 } if(TempDelayTime>maxDelayTime) { maxDelayTime=TempDelayTime;//更新最大延遲時間 } } System.out.println("此排程f最大延遲為:"+maxDelayTime); } private static void swap(int[] d, int j, int i) { // TODO 自動生成的方法存根 int temp=d[j]; d[j]=d[i]; d[i]=temp; } }