1. 程式人生 > 實用技巧 >貪心法之多機排程問題

貪心法之多機排程問題

問題描述:

設有n個獨立的作業,由m臺相同的機器進行加工處理。作業i所需的處理時間為t[i]。任何作業可以在任何一臺機器上面加工處理,但未完工之前不允許中斷處理。任何作業不能拆分成更小的作業。要求給出一種作業排程方案,使所給的n個作業在儘可能短的時間內由m臺機器加工處理完成。 這個問題是NP完全問題,到目前為止還沒有有效的解法(求最優解),但是可以用貪心選擇策略設計出較好的近似演算法(求次優解)。 演算法分析:
採用最長處理時間作業優先的貪心選擇策略,可以設計出解多機排程問題較好的近似演算法。 當n<=m(作業數小於機器數)時,只要將機器 i 的 時間區間分配給作業 i 即可; 當n>m時,首先將n個作業從大到小排序,然後依此順序將作業分配給空閒的處理機。也就是說從剩下的作業中,選擇需要處理時間最長的,然後依次選擇處理時間次長的,直到所有的作業全部處理完畢,或者機器不能再處理其他作業為止。如果我們每次是將需要處理時間最短的作業分配給空閒的機器,那麼可能就會出現其它所有作業都處理完了只剩所需時間最長的作業在處理的情況,這樣勢必效率較低。
假定有7個獨立作業,所需處理時間分別為{2,14,4,16,6,5,3},由三臺機器M1,M2,M3加工。按照貪心演算法產生的作業排程如下圖所示,所需總加工時間為17. 程式碼實現:
#include<stdio.h>
#define N 7 //作業數
#define M 3 //機器數 
int s[M] = {0,0,0};//每臺機器當前已分配的作業總耗時 

//求出目前處理作業的時間和 最小的機器號
int min(int m)
{
    int min = 0;
    int i;
    for(i=1;i<m;i++)
    {
        
if(s[min] > s[i]) { min = i; } } return min; } //求最終結果(最長處理時間) int max(int s[],int num) { int max = s[0]; int i; for(i=1;i<num;i++) { if(max < s[i]) { max = s[i]; } } return max; } //機器數大於待分配作業數
int setwork1(int t[],int n) { int i; for(i=0;i<n;i++) { s[i] = t[i]; } int ma = max(s,N); return ma; } //機器數小於待分配作業數 int setwork2(int t[],int n) { int i; int mi = 0; for(i=0;i<n;i++) { mi = min(M); printf("第%d號作業,時間和最小的機器號為%d.時間和為%d:\n",i,mi,s[mi]); s[mi] = s[mi]+t[i]; } int ma = max(s,M); return ma; } int main(void) { int time[N] = {16,14,6,5,4,3,2};//處理時間按從大到小排序 int maxtime = 0; if(M >= N) { maxtime = setwork1(time,N); } else { maxtime = setwork2(time,N); } printf("最多耗費時間%d。",maxtime); }
View Code

執行結果:

時間複雜度分析:當n<=m時,演算法所需O(1)時間

當n>m時,所需時間為O(nlogn)時間

參考文獻:王曉東《演算法設計與分析》第二版

https://blog.csdn.net/liufeng_king/article/details/874057