当前位置:   article > 正文

会议安排(贪心算法和动态规划)_会议安排 动态规划

会议安排 动态规划

1.问题:假设要在一个教室里安排一批活动,并希望使用尽可能多的安排活动。设计一个有效的算法进行安排。

2.1.贪心算法:一开始选择活动1,然后把剩下的活动按结束时间递增进行排序,以后的活动与s[i]进行比较,如果可以安排就安排此活动,因为活动已经按结束时间递增进行了排序,所以被选择的活动是可以选择活动中结束时间最早的。此处的贪心策略是每一次都选择可以上和上一个活动相容,而且结束时间最早的活动进行安排。

2.2动态规划:设计思路:首先把活动按结束时间最早进行递增排序;dp[i]记录活动以活动i为结尾的最大活动安排数,如果event[i].begin>=event[i-1].end,那么活动i可以被安排上,dp[i]=dp[i-1]+1;如果event[i].begin<event[i-1].end,那么活动i无法被安排,dp[i]=dp[i-1];另外用一个数组path[j]去记录最优解的路径,自底向上if(dp[i]>dp[i-1]),说明活动event[i].number被选了,path[j]=event[i].number;

3.1.贪心算法代码:

  1. /*贪心算法之活动安排问题*/
  2. #include <stdio.h>
  3. typedef struct{ //活动具有的属性
  4. int begin;
  5. int end;
  6. int number; //记录是第几个活动
  7. }activity;
  8. #define N 11
  9. int start[N]={1,3,0,5,3,5,6,8,8,2,12}; //活动开始的时间
  10. int end[N]={4,5,6,7,8,9,10,11,12,13,14}; //活动结束的时间
  11. activity event[100];
  12. void Sort(activity *array) //除了第一个活动,将剩下的活动按结束时间最早进行排序
  13. {
  14. activity temp;
  15. for(int i=1;i<N;i++) //简单的冒泡排序
  16. {
  17. for(int j=i+1;j<N;j++)
  18. {
  19. if(event[i].end>event[j].end)
  20. {
  21. temp=event[i];
  22. event[i]=event[j];
  23. event[j]=temp;
  24. }
  25. }
  26. }
  27. }
  28. void Greedy(activity *array) //贪婪策略
  29. {
  30. int count=1;
  31. printf("可以安排的最大活动如下:\n");
  32. printf("活动1 ");
  33. for(int i=0;i<N;i++)
  34. {
  35. for(int j=i+1;j<N;j++)
  36. {
  37. if(array[j].begin>=array[i].end)//下一个活动的开始时间大于当前活动的结束时间表示可以相容
  38. {
  39. //printf("test1\n");
  40. printf("活动%d\t",array[j].number);
  41. i=j; //把当活动的位置移动到j,方便下一次的比较
  42. count++;
  43. break;
  44. }
  45. }
  46. }
  47. printf("----->总共可以安排%d个会议\n",count);
  48. }
  49. int main()
  50. {
  51. for(int i=0;i<N;i++)
  52. {
  53. event[i].begin=start[i];
  54. event[i].end=end[i];
  55. event[i].number=i+1;
  56. }
  57. Sort(event);
  58. for(int i=0;i<N;i++)
  59. {
  60. printf("%d\t",event[i].number);
  61. }
  62. printf("\n");
  63. for(int i=0;i<N;i++)
  64. {
  65. printf("%d\t",event[i].begin);
  66. }
  67. printf("\n");
  68. for(int i=0;i<N;i++)
  69. {
  70. printf("%d\t",event[i].end);
  71. }
  72. printf("\n");
  73. Greedy(event);
  74. return 0;
  75. }

3.2.动态规划代码:

  1. /*动态规划之活动安排*/
  2. #include <stdio.h>
  3. typedef struct{ //活动具有的属性
  4. int begin;
  5. int end;
  6. int number; //记录是第几个活动
  7. }activity;
  8. #define N 12
  9. int start[N]={0,1,3,0,5,3,5,6,8,8,2,12}; //活动开始的时间
  10. int end[N]={0,4,5,6,7,8,9,10,11,12,13,14}; //活动结束的时间
  11. activity event[100];
  12. int dp[N]; //记录以i为结尾的最大活动安排数
  13. int path[N]; //记录最优解的路径
  14. void Sort(activity *array) //除了第一个活动,将剩下的活动按结束时间最早进行排序
  15. {
  16. activity temp;
  17. for(int i=1;i<N;i++) //简单的冒泡排序
  18. {
  19. for(int j=i+1;j<N;j++)
  20. {
  21. if(event[i].end>event[j].end)
  22. {
  23. temp=event[i];
  24. event[i]=event[j];
  25. event[j]=temp;
  26. }
  27. }
  28. }
  29. }
  30. void Dynamic(activity *array) //动态规划算法
  31. {
  32. bool flag;
  33. for(int i=2;i<N;i++)
  34. {
  35. flag=false; //标志变量,判断是否找到相容的活动
  36. for(int j=i-1;j>0;j--)
  37. {
  38. if(event[i].begin>=event[j].end) //从前往后遍历,直到找到可以相容的活动
  39. {
  40. dp[event[i].number]=dp[event[j].number]+1;//最优解为前一个最优解+1
  41. flag=true; //flag=true,说明活动j找到可以相容的活动
  42. break;
  43. }
  44. }
  45. if(flag==false) //如果flag=false,说明没有找到相容的活动,
  46. { //此活动为结尾的最优解,为以其前面一个活动为结尾的最优解
  47. dp[event[i].number]=dp[event[i-1].number];
  48. }
  49. }
  50. }
  51. int main()
  52. {
  53. dp[0]=0;
  54. dp[1]=1;
  55. int max=0; //记录可以安排的最大活动数
  56. for(int i=0;i<N;i++)
  57. {
  58. event[i].begin=start[i];
  59. event[i].end=end[i];
  60. event[i].number=i;
  61. }
  62. Sort(event);
  63. for(int i=0;i<N;i++)
  64. {
  65. printf("%d\t",event[i].number);
  66. }
  67. printf("\n");
  68. for(int i=0;i<N;i++)
  69. {
  70. printf("%d\t",event[i].begin);
  71. }
  72. printf("\n");
  73. for(int i=0;i<N;i++)
  74. {
  75. printf("%d\t",event[i].end);
  76. }
  77. printf("\n");
  78. Dynamic(event);
  79. //Greedy(event);
  80. printf("dp[0]=%d\n",dp[0]);
  81. printf("dp[]数组如下:\n");
  82. for(int i=0;i<N;i++)
  83. { printf("%d--",event[i].number);
  84. printf("%d\t",dp[event[i].number]);
  85. if(dp[event[i].number]>max)
  86. {
  87. max=dp[event[i].number];
  88. }
  89. }
  90. printf("\n可以安排的最大活动数为:%d\n",max);
  91. int amount=0;
  92. for(int i=N-1;i>=0;i--)
  93. {
  94. if(dp[event[i].number]>dp[event[i-1].number])
  95. {
  96. path[amount++]=event[i].number;
  97. }
  98. }
  99. printf("被选择的活动如下:\n");
  100. for(int i=amount-1;i>=0;i--)
  101. {
  102. printf("%d\t",path[i]);
  103. }
  104. return 0;
  105. }

4.1.贪心算法运行结果:

4.2动态规划运行结果:

 5.总结:

在会议安排上,贪心算法和动态规划的结果是一样的,而且贪心算法比较简单,所以一般面对会议安排问题时,使用贪心算法进行求解;动态规划的问题总结下来都是去求解:最优解和最优解的路径;动态规划的难题非常多,希望自己多通过练习可以学习更多的经验。0.0

 

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

闽ICP备14008679号