贪心算法之活动选择问题--求解现实问题的思路

参考《算法导论第二版P222页)

一,如何把现实的问题转变成数学问题?即数学建模的思路?

1,问题描述:现有一组相互竞争的活动,如何调度能够找出一组最大的活动(活动数目最多)使得它们相互兼容?

2,问题转化:

首先,按活动的结束时间单调递增进行排序。那么,为什么要按结束时间排序呢?这个问题留到后面解释。

其次,定义合适的问题子空间,即定义集合S(i,j)。问题子空间描述的是现实生活中的问题,而集合S(i,j)则是数学概念,通过某种方式定义一个合适的集合将问题子空间的解转化为集合的解(即求出集合中符合某种条件的所有元素)。

3,那么问题来了,怎样才能让定义的这个集合问题能够描述现实问题呢?----

a,将S(i,j)中元素表示成与活动a(i)、a(j)兼容的活动

b,将活动a(1)、a(2)……a(i)、a(i+1)、……a(j)、a(j+1)……a(n) 按照结束时间单调递增排序!每个集合元素有一个特征:有开始时间和结束时间。

这就是为什么要按结束时间单调递增排序的原因,因为只有这样,才能够成功的建模,将现实问题转化成数学问题。

当定义的集合中的元素(活动)满足了这两个因素之后,就可以将子问题空间(从a(1)、a(2)……a(i)、a(i+1)、……a(j)、a(j+1)……a(n)活动中选出最大兼容活动集合)

转化成

数学上的集合问题(求解集合S(i,j)的元素中满足开始时间和结束时间不相互冲突的最多的元素个数)

4,如何证明子问题S(i,j)的解是最优的?

剪贴技术 即 反证法。建模出来的集合的性质,它可以将S(i,j)的最优解分成S(i,k)S(k,j)的最优解!

5,如何根据子问题的解构造出原问题的解?

构造虚构的活动 a(0)和a(n+1)。那么,S(0,n+1)就表示原问题的解!

6,写出问题的解的数学表达式

数学表达式见 《算法导论第二版》P244 上。

--------------------------------------------------------------------------

《算法导论》介绍了很多算法分析的方法:从某个现实生活中的问题入手,然后将之一步步地转化成数学问题,再运用一些分析技术(动态规划、贪心、随机化、概率分析、分治……)将之表示成伪代码,最后就可以用编程语言将这些伪代码实现!

时间: 2024-08-07 12:27:51

贪心算法之活动选择问题--求解现实问题的思路的相关文章

【算法导论】贪心算法之活动选择问题

动态规划总是在追求全局最优的解,但是有时候,这样有点费时.贪心算法,在求解过程中,并不追求全局最优解,而是追求每一步的最优,所以贪心算法也不保证一定能够获得全局最优解,但是贪心算法在很多问题却额可以求得最优解. 一.问题概述 活动选择问题: 假定一个有n个活动(activity)的集合S={a1,a2,....,an},这些活动使用同一个资源(例如同一个阶梯教室),而这个资源在某个时刻只能供一个活动使用.每个活动ai都有一个开始时间si和一个结束时间fi,其中0<=si<fi<正无穷.如

算法导论贪心算法之活动选择

活动选择问题的递归调用算法 #include<iostream> using namespace std; #define N 11 struct node{ int id; int satrt; int end; }A[N+1]; void recursive_activity_seclect(int k,int n) { int m=k+1; while(m<=n&&A[m].satrt<A[k].end) m=m+1; if(m<=n) { cout&l

贪心算法之活动选择问题

import java.util.ArrayList; import java.util.List; public class ActiveSelector { private int[] s= {0,1,3,0,5,3,5,6,8,8,2,12}; //a0 a1..a11活动开始时间数组 private int[] f = {0,4,5,6,7,9,9,10,11,12,14,16}; //a0 a1..a11活动结束时间数组 List<Activity> ls = new ArrayLi

贪心算法之活动分配问题

贪心算法之活动分配问题 在此之前,我们还讨论过贪心算法的活动选择问题,活动选择问题里面的选择策略在这篇文章里面作为贪心选择策略用到.好吧,让我们进入主题. 问题描述 有一个活动集合S={a1,a2,a3,...an},每一个活动ai都有一个开始时间si和结束时间fi,那么活动ai占用的时间段为[si,fi).如果活动ai和aj的时间段没有交集重叠,那么这两个活动是兼容的,即满足si≤fj或者fi≥sj,[ai,aj]就是兼容的.现在我们需要为这些活动安排教室,保证活动之间各不冲突.请问怎么安排才

贪心算法解决加油站选择问题(未解决)

//贪心算法解决加油站选择问题 //# include<iostream> # include<stdio.h> using namespace std; # include<algorithm> struct Node { float p, d; }; bool cmp(Node a, Node b) { return a.d < b.d; } int main() { Node node[501]; float Cmax, D, Davg, distance,

[C++] 贪心算法之活动安排、背包问题

一.贪心算法的基本思想 在求解过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次的贪心选择,最终得出整个问题的最优解. 从贪心算法的定义可以看出,贪心算法不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解.如果一个问题可以同时用几种方法解决,贪心算法应该是最好的选择之一. 二.贪心算法的基本要素 (1)最优子结构性质 (2)贪心选择性质(局部最优选择) 三.贪心算法实例 1.活动安排 设有n个活

贪心算法_活动安排问题_哈弗曼编码

问题表述:设有n个活动的集合E = {1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源.每个活i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si < fi .如果选择了活动i,则它在半开时间区间[si, fi)内占用资源.若区间[si, fi)与区间[sj, fj)不相交,则称活动i与活动j是相容的.也就是说,当si >= fj或sj >= fi时,活动i与活动j相容. 由于输入的活动以其完成时间的非减序排列,所以算法

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

题目大意就是给几个活动,问要几个教室能够弄完. 这个题目的想法就是把活动的开始——结束的时间看做是数轴上的一段线段,教室的个数就是在某点的时间厚度,求最大的时间厚度就是所需要的教室个数. 1 #include<stdio.h> 2 #include<iostream> 3 #include<stdlib.h> 4 #include<queue> 5 using namespace std; 6 struct node 7 { 8 int start; 9 i

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 我们可以知道先安排最早结束的活动可以更多的安排活动.首先就是将所有的活动结束时间按先后顺序给排序:然后以结束时间为线索