数学模型_贪心算法及实例

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

13
背包问题
给定n种物品和一个背包。物品i的重量是 Wi,其价值为Vi,背包的容量为C。应如何选 择装入背包的物品,使得装入背包中物品的总 价值最大?(假定物品可以分割成更小部分, 亦即物品可以部分装入)
14
例: 有5件物品,背包的容量为100,物品的重量 和价值分别如下所示: 1 W V 10 20 2 20 30 3 30 66 4 40 40 5 50 60
2
6. 最优化理论的三大非经典算法:模拟退火算法、 神经网络算法、遗传算法。这些问题是用来解决一 些较困难的最优化问题的,对于有些问题非常有帮助, 但是算法的实现比较困难,需慎重使用。 7. 网格算法和穷举法。两者都是暴力搜索最优点的 算法,在很多竞赛题中有应用,当重点讨论模型本 身而轻视算法的时候,可以使用这种暴力方案,最好 使用一些高级语言作为编程工具。 8. 一些连续数据离散化方法。很多问题都是实际来 的,数据可以是连续的,而计算机只能处理离散的 数据,因此将其离散化后进行差分代替微分、求和代 替积分等思想是非常重要的。
1
3. 线性规划、整数规划、多元规划、二次规划等规 划类算法。建模竞赛大多数问题属于最优化问题,很 多时候这些问题可以用数学规划算法来描述,通常使 用Lingo 软件求解。 4. 图论算法。这类算法可以分为很多种,包括最短 路、网络流、二分图等算法,涉及到图论的问题可以 用这些方法解决。 5. 动态规划、回溯搜索、分治算法、分支定界等计 算机算法。这些算法是算法设计中比较常用的方法, 竞赛中很多场合会用到。
12
活动安排问题
若被检查的活动i的开始时间Si小于最近选择的活 动j的结束时间fi,则不选择活动i,否则选择活动i 加入集合A中。 贪心算法并不总能求得问题的整体最优解。但对 于活动安排问题,贪心算法greedySelector却总能求 得的整体最优解,即它最终所确定的相容活动集合A 的规模最大。这个结论可以用数学归纳法证明。
23
单源最短路径
例如,对右图中的 有向图,应用Dijkstra 算法计算从源顶点1到 其他顶点间最短路径的 过程列在下页的表中。
24
单源最短路径
Dijkstra算法的迭代过程: 迭代 初始 1 2 3 4 S {1} {1,2} {1,2,4} {1,2,4,3} {1,2,4,3,5} u 2 4 3 5 dist[2] dist[3] dist[4] dist[5] 10 10 10 10 10 maxint 60 50 50 50 30 30 30 30 30 100 100 90 60 60
4
贪心算法
5
问题引入:
有下面几种面值的硬币:一元、五角、 一角、五分、一分,假设要付给顾客 2.89元的零钱,要求用最少的硬币。
6
顾名思义,贪心算法总是作出在当前看来最好的选择。 也就是说贪心算法并不从整体最优考虑,它所作出的 选择只是在某种意义上的局部最优选择。当然,希望 贪心算法得到的最终结果也是整体最优的。虽然贪心 算法不能对所有问题都得到整体最优解,但对许多问 题它能产生整体最优解。如单源最短路经问题,最小 生成树问题等。在一些情况下,即使贪心算法不能得 到整体最优解,其最终结果却是最优解的很好近似。
其基本思想是,设置顶点集合S并不断地作贪心选 择来扩充这个集合。一个顶点属于集合S当且仅当从 源到该顶点的最短路径长度已知。 初始时,S中仅含有源。设u是G的某一个顶点,把 从源到u且中间只经过S中顶点的路称为从源到u的特 殊路径,并用数组dist记录当前每个顶点所对应的最 短特殊路径长度。Dijkstra算法每次从V-S中取出具 有最短特殊路长度的顶点u,将u添加到S中,同时对 数组dist作必要的修改。一旦S包含了所有V中顶点, dist就记录了从源到所有其他顶点之间的最短路径长 度。
各活动的起始时间和结 束时间存储于数组s和f 中且按结束时间的非减 序排列
11
活动安排问题
例:设待安排的11个活动的开始时间和结束时间按结 束时间的非减序排列如下:
i
1
2 3 5
3 0 6
4 5 7
5 3 8
6 5 9
7 6
8 8
9 8
10 11 2 12
S[i] 1 f[i] 4
10 11 12 13 14
最小生成树
2.Prim算法
设G=(V,E)是连通带权图,V={1,2,…,n}。 构造G的最小生成树的Prim算法的基本思想是:首 先置S={1},然后,只要S是V的真子集,就作如下的 贪心选择:选取满足条件iS,jV-S,且c[i][j]最 小的边,将顶点j添加到S中。这个过程一直进行到 S=V时为止。 在这个过程中选取到的所有边恰好构成G的一棵最 小生成树。
7
主要知识点:


活动安排问题 背包问题 最优装载 单源最短路径 最小生成树
8
活动安排问题
活动安排问题就是要在所给的活动集合中选出最 大的相容活动子集合,是可以用贪心算法有效求解的 很好例子。该问题要求高效地安排一系列争用某一公 共资源的活动。贪心算法提供了一个简单、漂亮的方 法使得尽可能多的活动能兼容地使用公共资源。
25
最小生成树
设G =(V,E)是无向连通带权图,即一个网络。E中 每条边(v,w)的权为c[v][w]。如果G的子图G’是一棵包 含G的所有顶点的树,则称G’为G的生成树。生成树上 各边权的总和称为该生成树的耗费。在G的所有生成 树中,耗费最小的生成树称为G的最小生成树。
网络的最小生成树在实际中有广泛应用。例如, 在设计通信网络时,用图的顶点表示城市,用边(v,w) 的权c[v][w]表示建立城市v和城市w之间的通信线路 所需的费用,则最小生成树就给出了建立通信网络的 最经济的方案。 26
20
单源最短路径
给定带权有向图G =(V,E),其中每条边的权是非 负实数。另外,还给定V中的一个顶点,称为源。现 在要计算从源到所有其他各顶点的最短路长度。这里 路的长度是指路上各边权之和。这个问题通常称为单 源最短路径问题。
算法基本思想
Dijkstra算法是解单源最短路径问题的贪心算法。
21
单源最短路径
数学建模竞赛中十类常用算法
1. 蒙特卡罗算法。该算法又称随机性模拟算法,是 通过计算机仿真来解决问题的算法,同时可以通过模 拟来检验自己模型的正确性。 2. 数据拟合、参数估计、插值等数据处理算法。比 赛中通常会遇到大量的数据需要处理,而处理数据的 关键就在于这些算法,通常使用MATLAB 作为工具。
9
活动安排问题
设有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相容。
17
float knapsack(float c,float w[], float v[],float x[]) { int n=v.length; for (int i = 0; i < n; i++) d[i] = (w[i],v[i],i); MergeSort.mergeSort(d); int i; float opt=0; for (i=0;i<n;i++) x[i]=0; for (i=0;i<n;i++) { if (d[i].w>c) break; x[d[i].i]=1; opt+=d[i].v; c-=d[i].w; } if (i<n){ x[d[i].i]=c/d[i].w; opt+=x[d[i].i]*d[i].v; } return opt; }
最小生成树
1.最小生成树性质
用贪心算法设计策略可以设计出构造最小生成树 的有效算法。本节介绍的构造最小生成树的Prim算法 和Kruskal算法都可以看作是应用贪心算法设计策略 的例子。尽管这2个算法做贪心选择的方式不同,它 们都利用了下面的最小生成树性质: 设G=(V,E)是连通带权图,U是V的真子集。如果 (u,v)E,且uU,vV-U,且在所有这样的边中, (u,v)的权c[u][v]最小,那么一定存在G的一棵最小 生成树,它以(u,v)为其中一条边。这个性质有时也 称为MST性质。 27
3
9. 数值分析算法。如果在比赛中采用高级语言进行 编程的话,那些数值分析中常用的算法比如方程组 求解、矩阵运算、函数积分等算法就需要额外编写库 函数进行调用。 10. 图象处理算法。赛题中有一类问题与图形有关, 即使问题与图形无关,论文中也会需要图片来说明 问题,这些图形如何展示以及如何处理就是需要解决 的问题,通常使用MATLAB 进行处理。
10
活动安排问题
在下面所给出的解活动安排问题的贪心算法greedySelector :
int greedySelector(int s[], int f[], boolean a[]) { int n=s.length-1; a[1]=true; int j=1; int count=1; for (int i=2;i<=n;i++) { if (s[i]>=f[j]) { a[i]=true; j=i; count++; } else a[i]=false; } return count; }
18
最优装载
有一批集装箱要装上一艘载重量为c的轮船。其中 集装箱i的重量为Wi。最优装载问题要求确定在装载 体积不受限制的情况下,将尽可能多的集装箱装上轮 船。
1.算法描述百度文库
最优装载问题可用贪心算法求解。采用重量最轻 者先装的贪心选择策略,可产生最优装载问题的最优 解。具体算法描述如下页。
19
float loading(float c, float [] w, int [] x) { int n=w.length; for (int i = 0; i < n; i++) d[i] = (w[i],i); MergeSort.mergeSort(d); float opt=0; for (int i = 0; i < n; i++) x[i] = 0; for (int i = 0; i < n && d[i].w <= c; i++) { x[d[i].i] = 1; opt+=d[i].w; c -= d[i].w; } return opt; }
15
这个问题有三种看似合理的选择:
1、每次选择剩余物品中价值最大的 2、每次选择剩余物品中重量最轻的 3、每次选择剩余物品中单位重量价值最高的。
16
用贪心算法解背包问题的基本步骤:
首先计算每种物品单位重量的价值Vi/Wi,然后,依 贪心选择策略,将尽可能多的单位重量价值最高的物品 装入背包。若将这种物品全部装入背包后,背包内的物 品总重量未超过C,则选择单位重量价值次高的物品并尽 可能多地装入背包。依此策略一直地进行下去,直到背 包装满为止。 具体算法可描述如下页:
22
Void dijkstra(int v,float a[][],float dist[]) {for (int i=1;i<=n;i++) {dist[i]=a[v][i];s[i]=false;} dist[v]=0;s[v]=true; For (int I=1;I<n;I++) { float temp=MAX_Value; int u=v; for (int j=1;j<=n;j++) if((! s[j])&&dist[j]<temp) { u=j; temp=dist[j]; } s[u]=true; For(int j=1;j<=n;j++) if((! s[j])&&a[u][j]< MAX_Value) if (dist[u]+a[u][j]<dist[j]) dist[j]= dist[u]+a[u][j]; } }
28
最小生成树
利用最小生成树性质 和数学归纳法容易证明, 上述算法中的边集合T始 终包含G的某棵最小生成 树中的边。因此,在算法 结束时,T中的所有边构 成G的一棵最小生成树。 例如,对于右图中的 带权图,按Prim算法选取 边的过程如下页图所示。 29
相关文档
最新文档