经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 编程经验 » 查看文章
贪心算法-会场安排问题
来源:cnblogs  作者:DNE  时间:2018/10/15 9:05:46  对本文有异议

问题描述:假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的贪心算法进行安排。(这个问题实际上是著名的图着色问题。若将每个活动作为图的一个顶点,不相容活动间用边相连。使用相邻顶点着有不同颜色的最小着色数,相应于要找的最小会场数)。

[之所以想记录这个问题,就在于括号内的描述。看完题目的描述,我心想:图着色问题不是有一个四色定理。换而言之,即任何活动,只要四个会场就够了。而这显然不符合常理。后来发现,问题在于四色定理只适用于地图,在地图上最多四个国家相互接壤。而活动显然不满足这个条件]

算法描述:

算法实现:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. void makemap(int **map,int *early,int *late,int n)
  4. {
  5. for(int i=0;i<n;i++)//当前被判断活动
  6. for(int j=i+1;j<n;j++)//其余活动
  7. {
  8. if((early[i]>=early[j]&&early[i]<=late[j])||
  9. (late[i]>=early[j]&&late[i]<=late[j]))
  10. {//判断当前活动与其余活动是否交叉
  11. map[i][j]=map[j][i]=1;//交叉的话在图上做标记
  12. map[i][i]++;//记录与当前活动交叉活动的数目
  13. map[j][j]++;
  14. }
  15. }
  16. }//标记交叉活动
  17. void sortpoint(int **map,int *node,int low,int high)
  18. {
  19. int i,j,temp,t,x;
  20. if(low<high)
  21. {
  22. t=rand()%(high-low+1)+low;
  23. temp=node[t];
  24. node[t]=node[low];
  25. node[low]=temp;
  26. i=low;
  27. j=high;
  28. x=node[i];
  29. do
  30. {
  31. while(i<j && map[node[j]][node[j]]>=map[x][x]) j--;
  32. if(i<j) {node[i]=node[j];i++;}
  33. while(i<j && map[node[i]][node[i]]<map[x][x]) i++;
  34. if(i<j) {node[j]=node[i];j--;}
  35. }while(i!=j);
  36. node[i]=x;
  37. sortpoint(map,node,low,i-1);
  38. sortpoint(map,node,i+1,high);
  39. }
  40. }//依照活动与其他活动交叉的数目对活动进行随机快速排序
  41. //形成递增序列
  42. void colorit(int **map,int *node,int n)
  43. {
  44. int *color;
  45. color=(int *)malloc((sizeof(int))*n);
  46. for(int i=0;i<n;i++)color[i]=0;
  47. color[node[n-1]]=0;
  48. for(int i=n-2;i>=0;i--)
  49. {
  50. int elem[5]={0,0,0,0,0};
  51. for(int j=i+1;j<n;j++)
  52. if(map[i][j])elem[color[j]]=1;
  53. //根据图五色原理
  54. //设置数组标记与当前活动交叉且已分配会场的活动的举办会场
  55. for(int j=0;j<5;j++)
  56. if(elem[j]==0)
  57. {
  58. color[i]=j;
  59. break;
  60. }
  61. //根据标记会场数组分配当前活动举办会场
  62. }
  63. int count=0;
  64. for(int i=0;i<n;i++)
  65. if(color[i]>count)count=color[i];
  66. count++;
  67. printf("%d",count);
  68. //统计开设会场的数目(结果)
  69. }//为每个活动分配会场
  70. int main()
  71. {
  72. int n;
  73. scanf("%d",&n);
  74. //活动数目n
  75. int **map;
  76. map=(int **)malloc((sizeof(int *))*n);
  77. for(int i=0;i<n;i++)
  78. map[i]=(int *)malloc((sizeof(int))*n);
  79. //用于记录活动间的交叉情况
  80. int *early;
  81. int *late;
  82. early=(int *)malloc((sizeof(int))*n);
  83. late=(int *)malloc((sizeof(int))*n);
  84. //用于记录活动的开始时间和结束时间
  85. for(int i=0;i<n;i++)
  86. {
  87. scanf("%d %d",&early[i],&late[i]);
  88. for(int j=0;j<n;j++)map[i][j]=0;
  89. }
  90. makemap(map,early,late,n);
  91. int *node;
  92. node=(int *)malloc((sizeof(int))*n);
  93. for(int i=0;i<n;i++)node[i]=i;
  94. sortpoint(map,node,0,n-1);
  95. colorit(map,node,n);
  96. return 0;
  97. }
View Code

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号