算法导论之贪心算法:活动选择问题

骑猪看日落 2022-07-24 08:08 273阅读 0赞

问题描述

每个活动都共享同一个公共的资源(比如教室等)所以同一时间只能有一个活动。现在的问题就是要在指定的时间内让举办的活动数量做大。

这是一个典型的贪心算法。我们不在这里证明算法的正确性。

我们给出贪心算法的定义:它在每一步都作出当时看起来最佳的选择。(它总是做出局部最优的选择,寄希望这样的选择能导致全局最优解)

一般的贪心算法有以下的步骤

1.确定问题的最优子结构。

2.设计一个递归算法。

3.证明如果我们做出一个贪心选择,则只剩下一个子问题。

4.证明贪心选择总是安全的。(步骤3、4的顺序可以调换)

5.设计一个递归算法实现贪心策略。

6.将递归算法转换为迭代算法。

代码实现如下:

  1. #include <stdio.h>
  2. struct Activty{
  3. int start;
  4. int finish;
  5. };
  6. typedef struct Activty Activty;
  7. struct List{
  8. Activty *value;
  9. struct List *next;
  10. };
  11. typedef struct List List;
  12. //迭代贪心算法
  13. List *GREEDY_ACTIVITY_SELECTOR(Activty action[],int n){
  14. List *rs = (List *)malloc(sizeof(List));
  15. rs->value=action;
  16. List *position = rs;
  17. int k=0,m=1;
  18. for(;m<n;m++){
  19. if(action[m].start>=action[k].finish){
  20. List *temp = (List *)malloc(sizeof(List));
  21. temp->value=&action[m];
  22. position->next=temp;
  23. position=temp;
  24. k=m;
  25. }
  26. }
  27. position->next=NULL;
  28. return rs;
  29. }
  30. //递归贪心算法
  31. List *RECURSIVE_SELECTOR(Activty action[],int k,int n){
  32. int m = k+1;
  33. while(m<n && action[m].start<action[k].finish){
  34. m++;
  35. }
  36. if(m<n){
  37. List *rs = (List *)malloc(sizeof(List));
  38. rs->value=&action[m];
  39. rs->next=RECURSIVE_SELECTOR(action,m,n);
  40. return rs;
  41. }else
  42. return NULL;
  43. }
  44. int main(int argc, char *argv[])
  45. {
  46. int n = 11;
  47. Activty action[n];
  48. //下面是测试数据
  49. action[0].start=1;action[0].finish=4;
  50. action[1].start=3;action[1].finish=5;
  51. action[2].start=0;action[2].finish=6;
  52. action[3].start=5;action[3].finish=7;
  53. action[4].start=3;action[4].finish=9;
  54. action[5].start=5;action[5].finish=9;
  55. action[6].start=6;action[6].finish=10;
  56. action[7].start=8;action[7].finish=11;
  57. action[8].start=8;action[8].finish=12;
  58. action[9].start=2;action[9].finish=14;
  59. action[10].start=12;action[10].finish=16;
  60. List *rs = (List *)malloc(sizeof(List));
  61. rs->value=&action[0];
  62. rs->next= RECURSIVE_SELECTOR(action,0,n);
  63. List *temp = rs;
  64. printf("the follow is RECURSIVE_SELECTOR.\n");
  65. while(temp!=NULL){
  66. printf("%d,%d\n",temp->value->start,temp->value->finish);
  67. temp=temp->next;
  68. }
  69. List *rs_GREEDY=GREEDY_ACTIVITY_SELECTOR(action,n);
  70. temp = rs_GREEDY;
  71. printf("\nthe follow is GREEDY_ACTIVITY_SELECTOR.\n");
  72. while(temp!=NULL){
  73. printf("%d,%d\n",temp->value->start,temp->value->finish);
  74. temp=temp->next;
  75. }
  76. return 0;
  77. }

在上述代码中,实现了递归方式的贪心算法和迭代方式的贪心算法,两者的时间复杂度都是O(n)。

参考资料
算法导论

备注
转载请注明出处:http://blog.csdn.net/wsyw126/article/details/51439202
作者:WSYW126

发表评论

表情:
评论列表 (有 0 条评论,273人围观)

还没有评论,来说两句吧...

相关阅读

    相关 算法导论16.1 活动选择问题

    这篇文章主要讲述一个经典问题:活动选择问题。并给出该问题的贪心算法实现和动态规划实现。 对于该问题的描述,在算法导论第16章给出了详细的讲解,这里就不做解释说明了,下面给出贪