貪心-任務調度問題

問題描述:

假設給定n個任務的集合T,每個任務i有啓動時間si和完成時間fi(si<fi)。任務i必須在si時刻啓動,並在fi時刻結束。每個任務都必須在一臺機器上執行,每臺機器同時只能執行一個任務。如果兩個任務i和j的實行時間不重疊,即fi<= sj或fi<=si,則稱這兩個任務不衝突。顯然,只有兩個任務不衝突時纔可以安排它們在同一臺機器上執行。
如何安排T中所有任務在不衝突的條件下在最少的機器上完成?

問題分析:

要求: 在最少的機器上安排完所有任務。
如何選擇貪心策略才能使問題的解爲最優解?顯然,開始時間最早的任務需要被先執行,但是最優解要求我們使用的機器最少,因此我們每次選擇時應儘量使用相同的機器。若已使用過的機器上現處於空閒狀態,則應將待執行任務放到該機器上執行。若無空閒機器,則再使用新機器。

代碼示例O(n^2):

#include<iostream>
#include<algorithm>
using namespace std;

struct thread{
 	int s;
 	int e;
}trd[1001];

bool cmp(thread x, thread y){
 	return x.s < y.s;
}

int main(){
 	int n;
	cin >> n;
 	int k[n], ki = 0, rcd[n];
 	for(int i = 0; i < n; i++){
  		cin >> trd[i].s >> trd[i].e;
 	}
 	sort(trd, trd+n, cmp);
 	k[ki++] = trd[0].e;
 	rcd[0] = ki;
 	for(int i = 1, t = -1; i < n; i++){
  		for(int j = 0; j < ki; j++){
   			if(k[j] <= trd[i].s){
    				t = j;
    				break;
   			}
  		}
  		if(t != -1){
   			k[t] = trd[i].e;
   			rcd[i] = t+1;
  		} else {
   			k[ki++] = trd[i].e;
   			rcd[i] = ki;
  		}
 	}
 	for(int i = 0; i < n; i++){//輸出各任務在哪臺機器上運行
  		cout << rcd[i] << " ";
 	}
 	cout << "\n" << ki;
 	return 0;
}

最優解證明:

設在上述策略下最後一臺選擇的機器爲第k臺,i爲第一個在k上運行的任務。則1到k-1臺機器上都有任務正在運行,即i與前1到k-1個任務相沖突,並且1到k-1臺機器上運行的任務之間也是相互衝突的。因此任務集合T中至少有k個任務之間相互衝突,若使用k-1臺機器,則無法同時安排它們執行,因此最少使用k臺機器。

參考文獻《算法設計與應用》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章