当前位置:   article > 正文

算法实验3:贪心算法的应用

算法实验3:贪心算法的应用

实验内容

(1)活动安排问题

    设有n个活动的集合E={1, 2, …, n},其中每个活动都要求使用同一资源,而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si <fi 。如果选择了活动i,则它在半开时间区间[si, fi)内占用资源。若区间[si, fi)与区间[sj, fj)不相交,则称活动i与活动j是相容的。 随机生成n个任务(n=8,16,32…),用贪心法求解,分析算法的时间复杂度,做出图像,横坐标为活动个数,纵坐标为执行时间。

(2)线段覆盖

问题描述:在一维空间中随机生成N(N=8,16,32…)条线段的起始坐标与终止坐标,要求求出这些线段一共覆盖了多大的长度(重叠区域只算一次)。分析算法的时间复杂度,画出算法的执行时间随N变化的曲线图。

实验结果

(1)活动安排问题

运行时间与n输入大小的曲线图

算法中将各个活动按照结束时间从小到大排序,时间复杂度为O(nlogn),依次考察每个活动,时间复杂度为O(n),算法的时间复杂度为O(nlogn)

(2)线段覆盖

运行时间由于输入个数的曲线图

算法中对线段进行按起点排序的时间复杂度是O(nlogn),依次对剩余线段进行判断时的时间复杂度时O(n),整个算法的时间复杂度应为O(nlogn)

源代码

活动安排问题

  1. #include<iostream>
  2. #include<time.h>
  3. using namespace std;
  4. void sort(int n, int s[], int f[])//按照结束时间非递减排序
  5. {
  6. int a, b, i, j;
  7. for (i = 0; i < n; i++)
  8. for (j = i + 1; j < n; j++)
  9. if (f[i] > f[j])
  10. {
  11. a = f[i]; f[i] = f[j]; f[j] = a;
  12. b = s[i]; s[i] = s[j]; s[j] = b;
  13. }
  14. }
  15. int Greedy(int n, int s[], int f[], bool B[])
  16. {
  17. B[1] = true;//将第一个活动先安排
  18. int j = 1, count = 1; //count为被安排的节目个数
  19. for (int i = 2; i <= n; i++)
  20. {
  21. if (s[i] >= f[j])//活动i与集合B中最后结束的活动相容
  22. {
  23. B[i] = 1;//安排活动i
  24. j = i;
  25. count++;
  26. }
  27. else
  28. B[i] = 0;
  29. }
  30. return count;//返回已安排的活动个数
  31. }
  32. int main()
  33. {
  34. srand((unsigned int)time(NULL));
  35. int a, b, n, i;
  36. bool B[2048];
  37. int s[2048], f[2048];
  38. clock_t start, end;
  39. cout << "输入n的大小:";
  40. cin >> n;
  41. for (i = 0; i < n; i++)
  42. {
  43. a = rand() % 1000 + 1;
  44. b = rand() % 1000 + 1;
  45. if (a > b)
  46. {
  47. f[i] = a;
  48. s[i] = b;
  49. }
  50. else
  51. {
  52. s[i] = a;
  53. f[i] = b;
  54. }
  55. }
  56. start = clock();
  57. for (i = 0; i < n; i++)
  58. sort(n, s, f);
  59. int g=Greedy(n, s, f, B);
  60. cout << "活动安排的个数是:" << g << endl;
  61. for (i = 1; i <= n; i++)
  62. cout << B[i] << " ";
  63. end = clock();
  64. cout << endl;
  65. cout << "安排活动耗时:" << double(end - start)*1000 / CLOCKS_PER_SEC<<" ms";
  66. return 0;
  67. }

线段覆盖

  1. #include<iostream>
  2. #include<time.h>
  3. using namespace std;
  4. struct line//线段结构体
  5. {
  6. int start;
  7. int end;
  8. };
  9. void sort(line l[], int n)//将线段按照大小排序
  10. {
  11. int i, j;
  12. line temp, temp1;
  13. for (i = 0; i < n; i++)
  14. for (j = 0; j < n - i - 1; j++)
  15. {
  16. if (l[j].start > l[j + 1].start)
  17. {//起点小的在前面
  18. temp = l[j];
  19. l[j] = l[j + 1];
  20. l[j + 1] = temp;
  21. }
  22. if (l[j].start == l[j + 1].start && l[j].end > l[j + 1].end)
  23. {//起点相同则终点小的在前面
  24. temp1 = l[j];
  25. l[j] = l[j + 1];
  26. l[j + 1] = temp1;
  27. }
  28. }
  29. }
  30. int cover(line l[], int n, int length)
  31. {
  32. int i, len = length;
  33. if (n == 1)//只有一个线段直接返回长度
  34. return len;
  35. for (i = 1; i < n; i++)
  36. {
  37. if (l[i].start >= l[i - 1].start && l[i].start <= l[i - 1].end && l[i].end >= l[i - 1].end)
  38. len += l[i].end - l[i - 1].end;//线段长度增加两终点之差
  39. else if (l[i].start >= l[i - 1].end)
  40. len += l[i].end - l[i].start;//线段长度增加当前线段的长度
  41. else if (l[i].start >= l[i - 1].start && l[i].end <= l[i - 1].end)
  42. l[i].end = l[i - 1].end;//线段长度不增加
  43. }
  44. return len;
  45. }
  46. int main()
  47. {
  48. line l[16384];
  49. int n, i, ln, length;
  50. clock_t cstart, cend;
  51. srand((unsigned)time(NULL));
  52. cout << "输入线段的个数:";
  53. cin >> n;
  54. cstart = clock();
  55. for (i = 0; i < n; i++)
  56. {
  57. l[i].start = rand() % 100 + 1;
  58. l[i].end = rand() % 100 + 1;
  59. }
  60. sort(l, n);//对所有线段进行排序
  61. ln = l[0].end - l[0].start;
  62. length = cover(l, n, ln);//求线段覆盖的长度
  63. cend = clock();
  64. cout <<"线段覆盖长度:"<< length << endl;
  65. cout << "耗时" << double(cend - cstart) * 1000 / CLOCKS_PER_SEC << " ms" << endl;
  66. return 0;
  67. }

感谢大家的观看

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号