贪心算法区间调度问题思路代码证明
1、活動安排問題
問題:有若干個活動,第i個開始時間和結束時間是[Si,fi),只有一個教室,活動之間不能交疊,求最多安排多少個活動?
解題思路:將活動按照結束時間進行從小到大排序,挑選出結束時間盡量早的活動,并且滿足后一個活動的起始時間晚于前一個活動的結束時間,全部找出這些活動就是最大的相容活動子集合。
C代碼示例:
正確性證明:我們可以從貪心算法得到的結果集僅進行倒推。首先去掉結果集中的第一個活動A,那么在剩下的活動中,結束時間最早的活動B的結束時間一定不早于A,那么A活動在最優解中一定合理。再用同樣的方式判斷活動B,依次類推,則結果集就是最優解。
2、最小延遲問題
問題:顧客在飯店中點餐,ti?表示i顧客所有菜加工的時間,di?表示i顧客要求菜全部完成的時間。如果實際完成的時間小于規定完成時間,那么就沒有延遲。由于有很多顧客,所以會有很多不同的拖延值,我們的目標是,求得所有拖延值中的最大值,并使得這個最大的拖延值最小。
解題思路:使用貪心算法,按照截止時間ddl排序,越早截止的任務越早完成。該算法是一個沒有空閑的最優調度,即從時刻0開始都有在處理請求,直到最后一個請求執行完釋放資源之后才空閑。
C代碼示例:
const int MAX_SIZE = 100; struct Request {int time, ddl;int begin, end; } req[MAX_SIZE]; bool operator<(const Request& req1, const Request& req2) {return req1.ddl < req2.ddl; } int main() {int requestNum;cin >> requestNum;for (int i = 0; i < requestNum; ++i) {cin >> req[i].time >> req[i].ddl;}sort(req, req + requestNum); //按照截止時間進行順序排序int start = 0, maxDelay = 0;for (int i = 0; i < requestNum; ++i) {req[i].begin = start;req[i].end = start + req[i].time;start += req[i].time;if (maxDelay < req[i].end - req[i].ddl) {maxDelay = req[i].end - req[i].ddl;}}cout << "最小的最大延遲: " << maxDelay << endl;return 0; }正確性證明:
3、多區間調度問題
問題:有很多間課室,某個周末有多個社團需要申請課室辦活動,每個社團都有一個對應的申請時間(包括開始時間和結束時間),求最少需要多少間課室才能夠滿足所有社團的需求(在這個問題之中時間重疊的社團需要安排在其他課室,即會使用到多個資源,需要考慮多個資源上的調度安排,故稱為多區間調度)。
解題思路:使用貪心算法,將需求按照開始時間的早晚進行排序,然后開始為這些資源打標簽,每個標簽代表都一個資源,需求req-i被打上標簽k表示該請求分配到的資源是k。遍歷排序后的需求,如果一個需求與某個已分配資源上的其他安排不沖突,則把該需求也放進該資源的安排考慮中;如果沖突,那么應該要給此需求分配新的資源,已用資源數量加一。
C++代碼示例:
const int MAX_SIZE = 100; struct Request {int begin, end, tag; } req[MAX_SIZE]; bool operator<(const Request& req1, const Request& req2) {return req1.begin < req2.begin; } int main() {int requestNum;cin >> requestNum;for (int i = 0; i < requestNum; ++i) {cin >> req[i].begin >> req[i].end;}sort(req, req + requestNum); int tagSize = 1;req[0].tag = 0;bool tags[MAX_SIZE];for (int i = 1; i < requestNum; ++i) {memset(tags, 1, sizeof(tags));for (int j = 0; j < i; ++j) {if (req[j].end > req[i].begin) {tags[req[j].tag] = false;}}bool isTagsEmpty = true;int tag;for (int j = 0; j < tagSize; ++j) {if (tags[j]) {isTagsEmpty = false;tag = j;break;}}if (isTagsEmpty) {req[i].tag = tagSize;++tagSize;} else {req[i].tag = tag;}}cout << "最小資源使用量: " << tagSize << endl;return 0; }?
總結
以上是生活随笔為你收集整理的贪心算法区间调度问题思路代码证明的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql数据库各表、数据库数据容量查询
- 下一篇: telegraf output inpu