当前位置:   article > 正文

贪心算法区间调度问题思路&代码&证明_区间调度贪心算法证明

区间调度贪心算法证明

1、活动安排问题

问题:有若干个活动,第i个开始时间和结束时间是[Si,fi),只有一个教室,活动之间不能交叠,求最多安排多少个活动?

解题思路:将活动按照结束时间进行从小到大排序,挑选出结束时间尽量早的活动,并且满足后一个活动的起始时间晚于前一个活动的结束时间,全部找出这些活动就是最大的相容活动子集合。

C代码示例

正确性证明:我们可以从贪心算法得到的结果集仅进行倒推。首先去掉结果集中的第一个活动A,那么在剩下的活动中,结束时间最早的活动B的结束时间一定不早于A,那么A活动在最优解中一定合理。再用同样的方式判断活动B,依次类推,则结果集就是最优解。

2、最小延迟问题

问题:顾客在饭店中点餐,ti 表示i顾客所有菜加工的时间,di 表示i顾客要求菜全部完成的时间。如果实际完成的时间小于规定完成时间,那么就没有延迟。由于有很多顾客,所以会有很多不同的拖延值,我们的目标是,求得所有拖延值中的最大值,并使得这个最大的拖延值最小。

解题思路:使用贪心算法,按照截止时间ddl排序,越早截止的任务越早完成。该算法是一个没有空闲的最优调度,即从时刻0开始都有在处理请求,直到最后一个请求执行完释放资源之后才空闲。

C代码示例

  1. const int MAX_SIZE = 100;
  2. struct Request {
  3. int time, ddl;
  4. int begin, end;
  5. } req[MAX_SIZE];
  6. bool operator<(const Request& req1, const Request& req2) {
  7. return req1.ddl < req2.ddl;
  8. }
  9. int main() {
  10. int requestNum;
  11. cin >> requestNum;
  12. for (int i = 0; i < requestNum; ++i) {
  13. cin >> req[i].time >> req[i].ddl;
  14. }
  15. sort(req, req + requestNum); //按照截止时间进行顺序排序
  16. int start = 0, maxDelay = 0;
  17. for (int i = 0; i < requestNum; ++i) {
  18. req[i].begin = start;
  19. req[i].end = start + req[i].time;
  20. start += req[i].time;
  21. if (maxDelay < req[i].end - req[i].ddl) {
  22. maxDelay = req[i].end - req[i].ddl;
  23. }
  24. }
  25. cout << "最小的最大延迟: " << maxDelay << endl;
  26. return 0;
  27. }

正确性证明

3、多区间调度问题

问题:有很多间课室,某个周末有多个社团需要申请课室办活动,每个社团都有一个对应的申请时间(包括开始时间和结束时间),求最少需要多少间课室才能够满足所有社团的需求(在这个问题之中时间重叠的社团需要安排在其他课室,即会使用到多个资源,需要考虑多个资源上的调度安排,故称为多区间调度)。

解题思路:使用贪心算法,将需求按照开始时间的早晚进行排序,然后开始为这些资源打标签,每个标签代表都一个资源,需求req-i被打上标签k表示该请求分配到的资源是k。遍历排序后的需求,如果一个需求与某个已分配资源上的其他安排不冲突,则把该需求也放进该资源的安排考虑中;如果冲突,那么应该要给此需求分配新的资源,已用资源数量加一。

C++代码示例

  1. const int MAX_SIZE = 100;
  2. struct Request {
  3. int begin, end, tag;
  4. } req[MAX_SIZE];
  5. bool operator<(const Request& req1, const Request& req2) {
  6. return req1.begin < req2.begin;
  7. }
  8. int main() {
  9. int requestNum;
  10. cin >> requestNum;
  11. for (int i = 0; i < requestNum; ++i) {
  12. cin >> req[i].begin >> req[i].end;
  13. }
  14. sort(req, req + requestNum);
  15. int tagSize = 1;
  16. req[0].tag = 0;
  17. bool tags[MAX_SIZE];
  18. for (int i = 1; i < requestNum; ++i) {
  19. memset(tags, 1, sizeof(tags));
  20. for (int j = 0; j < i; ++j) {
  21. if (req[j].end > req[i].begin) {
  22. tags[req[j].tag] = false;
  23. }
  24. }
  25. bool isTagsEmpty = true;
  26. int tag;
  27. for (int j = 0; j < tagSize; ++j) {
  28. if (tags[j]) {
  29. isTagsEmpty = false;
  30. tag = j;
  31. break;
  32. }
  33. }
  34. if (isTagsEmpty) {
  35. req[i].tag = tagSize;
  36. ++tagSize;
  37. } else {
  38. req[i].tag = tag;
  39. }
  40. }
  41. cout << "最小资源使用量: " << tagSize << endl;
  42. return 0;
  43. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/284796
推荐阅读
相关标签
  

闽ICP备14008679号