算法导论16.1-3 区间图着色(interval-graph coloring)问题(贪心算法)
2012-05-15 15:11
429 查看
CLRS 16.1-3 假设要用很多个教室对一组活动进行调度。我们希望使用尽可能少的教室来调度所有的活动。请给出一个有效的贪心算法,来确定哪一个活动应使用哪一个教室。
(这个问题也被成为区间图着色(interval-graph coloring)问题。我们可作出一个区间图,其顶点为已知的活动,其边连接着不兼容的活动。为使任两个相邻结点的颜色均不相同,所需的最少颜色对应于找出调度给定的所有活动所需的最少教室数。)
方法一:
我们很容易就可以想到用P227页的GREEDY-ACTIVITY-SELECTOR(s, f)来解决这个问题,首先调用这个函数,得到可以兼容的最大活动数,然后再在余下的活动中再次调用这个函数,直至活动为0。 见代码清单-1
方法二:
1.对于所有活动的时间点按升序进行排序(n个活动,就有2n个时间点),记录每个时间是起始的还是终止的,在排序的时候,对于值相同的时间点,如果是终止时间点的话,就排在前面。
2.最开始,选择第一个起始时间点,把它对应的活动放入一个教室,同时记录这个起始时间点对应的终止时间点。
3.接着按序选择第i个起始时间点(只选择起始时间点),对于第i个起始时间点,比较它和已有教室中的活动的终止时间点,若大于某个终止时间点,则直接将第i个起始时间点对应的活动放进相应的教室,否则新开辟一个教室来放入这个活动。 见代码清单-2
对于区间图着色(interval-graph coloring)问题,先在一个集合中放入一个点,然后把不与这个点相邻的所有元素放入这个集合,对于剩下的点,重复前面的动作即可,依此循环,直至没有点可选。最后,有多少个集合就是多少种颜色,集合中的元素用相同的色渲染。
代码清单-1:
View Code
输入数据为:
(这个问题也被成为区间图着色(interval-graph coloring)问题。我们可作出一个区间图,其顶点为已知的活动,其边连接着不兼容的活动。为使任两个相邻结点的颜色均不相同,所需的最少颜色对应于找出调度给定的所有活动所需的最少教室数。)
方法一:
我们很容易就可以想到用P227页的GREEDY-ACTIVITY-SELECTOR(s, f)来解决这个问题,首先调用这个函数,得到可以兼容的最大活动数,然后再在余下的活动中再次调用这个函数,直至活动为0。 见代码清单-1
方法二:
1.对于所有活动的时间点按升序进行排序(n个活动,就有2n个时间点),记录每个时间是起始的还是终止的,在排序的时候,对于值相同的时间点,如果是终止时间点的话,就排在前面。
2.最开始,选择第一个起始时间点,把它对应的活动放入一个教室,同时记录这个起始时间点对应的终止时间点。
3.接着按序选择第i个起始时间点(只选择起始时间点),对于第i个起始时间点,比较它和已有教室中的活动的终止时间点,若大于某个终止时间点,则直接将第i个起始时间点对应的活动放进相应的教室,否则新开辟一个教室来放入这个活动。 见代码清单-2
对于区间图着色(interval-graph coloring)问题,先在一个集合中放入一个点,然后把不与这个点相邻的所有元素放入这个集合,对于剩下的点,重复前面的动作即可,依此循环,直至没有点可选。最后,有多少个集合就是多少种颜色,集合中的元素用相同的色渲染。
代码清单-1:
View Code
#include <stdio.h> #include <stdlib.h> //每个时间点;是起始时间,还是终止时间;及其对应的结束时间 typedef struct point_t { int time; int is_start; int end_time;//若is_start为1,end_time写对应的时间;若is_start为0,end_time为-1 } point; //升序排列,若时间相同,则为终止时间的时间点排在前面 int compare(const void* a, const void* b) { if ((*(point*)a).time != (*(point*)b).time) return (*(point*)a).time > (*(point*)b).time; else return (*(point*)a).is_start < (*(point*)b).is_start;//这里得用小于 } void process(point* points, const int n) { //排序 qsort(points, n, sizeof(point), compare); //最多n/2个教室 int classrooms[n/2]; int count = 0; classrooms[count++] = points[0].end_time; printf("[%d, %d)在教室%d\n", points[0].time, points[0].end_time, count); int i; int j; for (i = 1; i < n; i++) { if (points[i].is_start == 1) { for (j = 0; j < count; j++) { if (classrooms[j] <= points[i].time) { classrooms[j] = points[i].end_time; printf("[%d, %d)在教室%d\n", points[i].time, points[i].end_time, j+1); break; } } if (j == count) { classrooms[count++] = points[i].end_time; printf("[%d, %d)在教室%d\n", points[i].time, points[i].end_time, count); } } } printf("总共需要%d个教室.\n", count); } int main() { int rows; scanf("%d", &rows); //2*rows个点 point* points = (point*)malloc(2*rows*sizeof(point)); //point p; int n = rows; //point p; int start_time; int end_time; while (rows--) { int id = n - rows - 1; scanf("%d%d", &start_time, &end_time); point p1; p1.is_start = 1; p1.time = start_time; p1.end_time = end_time; points[2*id] = p1; point p2; p2.is_start = 0; p2.time = end_time; p2.end_time = -1; points[2*id + 1] = p2; } process(points, 2*n); free(points); return 0; }
输入数据为:
11 1 4 3 5 0 6 5 7 3 8 5 9 6 10 8 11 8 12 2 13 12 14
相关文章推荐
- [算法导论]练习16.1-4 活动教室分配(区间着色问题)
- 区间图着色问题(算法导论课后题目16.1.3)
- 区间图着色问题(算法导论课后题目16.1.3)
- 算法导论第三版16.1-4 贪心算法(区间图着色问题)
- 【贪心】区间图着色 Interval-graph Coloring Problem
- 活动选择问题(算法导论第16章(贪心算法)
- poj 1419 Graph Coloring uva 193 - Graph Coloring (图着色问题,dfs)
- POJ 1419--Graph Coloring(最大团求二着色问题)
- 图的点着色、区间着色问题及其应用(基于贪心思想的DFS回溯法求点着色问题和区间着色算法求解任务调度问题)
- 区间图着色问题(贪心算法)C++实现
- 活动选择问题(算法导论第十六章贪心算法)
- POJ 1419 Graph Coloring 图的着色 最大团问题
- 贪心算法之区间图着色问题
- 采用C++实现区间图着色问题(贪心算法)实例详解
- poj 1419 Graph Coloring 图着色问题
- 算法导论 第16章 贪心算法-活动选择问题C++实现
- 贪心算法之区间图着色问题
- 区间图着色问题(贪心算法)C++实现
- Graph Coloring 图着色问题
- 算法导论-->约瑟夫问题