2、区间图着色问题(多个教室的活动安排)

算法导论 16.1-4题(多个教室活动选择的问题):

CLRS 16.1-3 假设要用很多个教室对一组活动进行调度。我们希望使用尽可能少的教室来调度所有的活动。请给出一个有效的贪心算法,来确定哪一个活动应使用哪一个教室。来源: <算法导论16.1-3 区间图着色(interval-graph coloring)问题(贪心算法)>

http://blog.csdn.net/heyongluoyao8/article/details/6934198(区间图着色贪心算法C++实现)

解决方法一:

1.对于所有活动的时间点按升序进行排序(n个活动,就有2n个时间点),记录每个时间是起始的还是终止的,在排序的时候,对于值相同的时间点,如果是终止时间点的话,就排在前面。
2.最开始,选择第一个起始时间点,把它对应的活动放入一个教室,同时记录这个起始时间点对应的终止时间点。
3.接着按序选择第i个起始时间点(只选择起始时间点),对于第i个起始时间点,比较它和已有教室中的活动的终止时间点,若大于某个终止时间点,则直接将第i个起始时间点对应的活动放进相应的教室,否则新开辟一个教室来放入这个活动。

  1. struct Active{
  2. int start_time; //活动的起始时间
  3. int end_time; //活动的结束时间
  4. int flag; //是否己被选择
  5. int room_num;//被分配到的房间号
  6. };
  7. /*区间图着色问题(多个教室的活动选择问题)*/
  8. int active_select_room(struct Active *act,int act_num){
  9. for(int i=0;i<act_num; i++){
  10. act[i].flag=0;
  11. act[i].room_num=0;
  12. }
  13. int sumRoom=1; //目前使用的教室数目
  14. int *roomTime=new int[act_num]; //每个教室目前的最晚结束时间
  15. roomTime[sumRoom]=act[0].end_time; //将教室0结束时间初使化为第一个活动的结束时间
  16. act[0].flag=1;
  17. act[0].room_num=1;
  18. for(int i=1;i<act_num; i++){ //对所有活动进行循环,安排该活动到合适的教室
  19. int j;
  20. for(j=1;j<=sumRoom; j++){ //对所有教室的结束时间进行比较,看能否安排下这个活动
  21. if(act[i].start_time>=roomTime[j]&&!act[i].flag){
  22. act[i].flag=1;
  23. act[i].room_num=j;
  24. roomTime[j]=act[i].end_time;
  25. break;
  26. }
  27. }
  28. if(j>sumRoom){
  29. sumRoom++;
  30. act[i].flag=1;
  31. act[i].room_num=sumRoom;
  32. roomTime[sumRoom]=act[i].end_time;
  33. }
  34. }
  35. for(int i=0;i<act_num; i++){
  36. std::cout<<"active number-> "<<i<<std::endl;
  37. std::cout<<"active start_time->"<<act[i].start_time<<std::endl;
  38. std::cout<<"active end_time->"<<act[i].end_time<<std::endl;
  39. std::cout<<"active room_num->" <<act[i].room_num<<std::endl;
  40. std::cout<<std::endl;
  41. }
  42. return sumRoom;
  43. }
  1. 实验数据
  2. int start_time[11]={1,3,0,5,3,5,6,8,8,2,12};
  3. int end_time[11]={4,5,6,7,9,9,10,11,12,14,16};

如上面代码所示,我们使用最小结束时间排序,然后对每个活动的开始时间进行判断,当当前的活动的开始时间

大于某一个教室的结束时间(教室的结束时间为该教室里最晚的活动的结束时间)。如果找不到这么一个合适的

数据,则新建一个教室,将当前教室的结束时间为当前活动的结束是间,然后这个活动的flag(表示当前活动是否

己被安排了)。

教训:

?在该程序中,以前写的版本,是这样的(错误段)

  1. .........
  2. .........
  3. for(j=1;j<=sumRoom; j++){ //
  4. if(act[i].start_time>=roomTime[j]&&!act[i].flag){
  5. act[i].flag=1;
  6. act[i].room_num=j;
  7. roomTime[j]=act[i].end_time;
  8. }
  9. }
  10. ...........
  11. ..........

上面的代码相对于正确的代码而言,是少有break; 这条语句的,当我们找到一个合适的教室时候,没有这段语

句后,还是要进行循环,在后面的教室中再找一个合适的教室中,如果没有找到,就再新建一个。。于是教室

的数目就是你的活动数目。

来自为知笔记(Wiz)

时间: 2024-10-19 02:25:21

2、区间图着色问题(多个教室的活动安排)的相关文章

区间图着色问题(贪心算法的解法)

问题描述:假设要用很多个教室对一组活动进行调度.我们希望使用尽可能少的教室来调度所有活动.请给出一个算法,来确定哪一个活动使用哪一间教室.这个问题也被称为区间图着色问题,即相容的活动着同色,不相容的着不同颜色,使得所用颜色数最少. 解法思想: 其实我们知道,对于单个教室我们可以用贪心算法进行求解,但是对于这个区间图的问题,我们采用的方法是多次的贪心.其实你想想看,你无非就是要使那些活动 全部被安排完吧,当然这样安排的方法很多,如何使得安排后的教室最小呢???? 这明显也是个贪心的问题.聪明的人很

51nod 1428 活动安排问题(优先队列)

1428 活动安排问题 首先按照开始时间从小到大排序. 其实只要维护一个结束时间的最小堆,每次比较开始时间和堆中最小时间的大小,如果比它大就放入堆中并且时间就要变成当前任务的结束时间, 否则就要新开一个教室.并且把结束时间加入堆中,注意判断堆是否为空. #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; struct p

贪心基础入门讲解二——活动安排问题

有若干个活动,第i个开始时间和结束时间是[Si,fi),只有一个教室,活动之间不能交叠,求最多安排多少个活动? 分析: 我们就是想提高教室地利用率,尽可能多地安排活动.考虑容易想到的几种贪心策略: (1) 开始最早的活动优先,目标是想尽早结束活动,让出教室.然而, 这个显然不行,因为最早的活动可能很长,影响我们进行后面的活动.例如活动开始和结束时间分别为[0, 100), [1,2) ,[2, 3), [3, 4),[4,5],安排[0,100)的这个活动之后,其他活动无法安排,可是最优解是安排

贪心基础入门讲解三——活动安排问题二

有若干个活动,第i个开始时间和结束时间是[Si,fi),活动之间不能交叠,要把活动都安排完,至少需要几个教室? 分析:能否按照之一问题的解法,每个教室安排尽可能多的活动,即按结束时间排序,再贪心选择不冲突的活动,安排一个教室之后,剩余的活动再分配一个教室,继续贪心选择…… 反例: A:[1,2)  B:[1,4) C:[5,6) D:[3,7) 已经按结束时间排好顺序,我们会选择教室1: A C教室2:  B教室3:  D需要3个教室.但是如果换一种安排方法,我们可以安排AD在一个教室,而BC在

[贪心入门]活动安排问题之二

有若干个活动,第i个开始时间和结束时间是[Si,fi),活动之间不能交叠,要把活动都安排完,至少需要几个教室? 分析:能否按照之一问题的解法,每个教室安排尽可能多的活动,即按结束时间排序,再贪心选择不冲突的活动,安排一个教室之后,剩余的活动再分配一个教室,继续贪心选择…… 反例: A:[1,2)  B:[1,4) C:[5,6) D:[3,7) 已经按结束时间排好顺序,我们会选择教室1: A C教室2:  B教室3:  D需要3个教室.但是如果换一种安排方法,我们可以安排AD在一个教室,而BC在

贪心入门——活动安排问题

贪心入门的几个例题来自51nod 问题描述 有若干个活动,第i个开始时间和结束时间是[Si,fi),只有一个教室,活动之间不能交叠,求最多安排多少个活动? 输入 第1行:1个数N,线段的数量(2 <= N <= 10000) 第2 - N + 1行:每行2个数,线段的起点和终点(-10^9 <= S,E <= 10^9) 输出 输出最多可以选择的线段数量. 输入示例 3 1 5 2 3 3 6 输出示例 2 求解思路 按照活动的结束时间早的优先 算法代码 #include <

51nod贪心算法入门-----活动安排问题

有若干个活动,第i个开始时间和结束时间是[Si,fi),只有一个教室,活动之间不能交叠,求最多安排多少个活动? 输入 第1行:1个数N,线段的数量(2 <= N <= 10000) 第2 - N + 1行:每行2个数,线段的起点和终点(-10^9 <= S,E <= 10^9) 输出 输出最多可以选择的线段数量. 输入示例 3 1 5 2 3 3 6 输出示例 2 我们可以知道先安排最早结束的活动可以更多的安排活动.首先就是将所有的活动结束时间按先后顺序给排序:然后以结束时间为线索

51nod1428 活动安排问题 (贪心加暴力)

1428 活动安排问题 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 有若干个活动,第i个开始时间和结束时间是[Si,fi),同一个教室安排的活动之间不能交叠,求要安排所有活动,最少需要几个教室? Input 第一行一个正整数n (n <= 10000)代表活动的个数. 第二行到第(n + 1)行包含n个开始时间和结束时间. 开始时间严格小于结束时间,并且时间都是非负整数,小于1000000000 Output 一行包含一个整数表示最少教室的

[贪心入门]活动安排问题

有若干个活动,第i个开始时间和结束时间是[Si,fi),只有一个教室,活动之间不能交叠,求最多安排多少个活动? 分析: 我们就是想提高教室地利用率,尽可能多地安排活动.考虑容易想到的几种贪心策略: (1) 开始最早的活动优先,目标是想尽早结束活动,让出教室.然而, 这个显然不行,因为最早的活动可能很长,影响我们进行后面的活动.例如活动开始和结束时间分别为[0, 100), [1,2) ,[2, 3), [3, 4),[4,5],安排[0,100)的这个活动之后,其他活动无法安排,可是最优解是安排