算法:贪心法

 贪心法 

将问题的求解过程看作是一系列选择,每次选择一个输入,每次选择都是当前状态下的最好选择(局部最优解).每作一次选择后,所求问题会简化为一个规模更小的子问题. 从而通过每一步的最优解逐步达到整体的最优解。
[适用问题] 具备贪心选择(整体的最优解可通过一系列局部最优解达到.每次的选择可以依赖以前作出的选择,但不能依赖于后
面的选择)和最优子结构性质(问题的整体最优解中包含着它的子问题的最优解)的最优化问题
可以依赖前面 不管后面
给的是个例 要从整体出发
1、活动安排问题

设有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相容。

解法:每次总是选择具有最早完成时间的相容活动加入集和中

活动安排问题贪心算法
 template<class Type>
 void GreedySelector(int n, Type s[], Type f[], bool A[])//各活动的起始时间和结束时间存储于数组s和f中且按结束时间的非减序排列
 {
 A[1]=true;
 int j=1;
 for (int i=2;i<=n;i++) {
 if (s[i]>=f[j]) { A[i]=true; j=i; }
 else A[i]=false;
 }
 }//未排序时:T(n)=O(nlogn),排序时为n

2、最优装载

有一批集装箱要装上一艘载重量为c的轮船。其中集装箱i的重量为Wi。最优装载问题要求确定在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船。

解法:最优装载问题可用贪心算法求解。采用重量最轻者先装的贪心选择策略,可产生最优装载问题的最优解。

最优装载的贪心算法
template<class Type>
 void Loading(int x[], Type w[], Type c, int n)
 {
 int *t = new int [n+1]; //按货箱重量排序/
 Sort(w, t, n);
 for (int i = 1; i <= n; i++) x[i] = 0;
 for (int i = 1; i <= n && w[t[i]] <= c; i++) {x[t[i]] = 1; c -= w[t[i]];} //调整剩余空间/
 }
算法分析: 排序为主要算法时间,所以T(n)=O(nlogn)

3、背包问题

给定n种物品和一个背包。物品i的重量是Wi,其价值为Vi,背包的容量为C。应如何选择装入背包的物品,使得装入背包中物品的总价值最大?在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部装入背包,1≤i≤n。

[算法思路]

1).将各物体按单位价值由高到低排序. 2).取价值最高者放入背包.3).计算背包剩余空间.4).在剩余物体中取价值最高者放入背包.若背包剩余容量=0或物体全部装入背包为止

背包问题的贪心算法
 void Knapsack(int n,float M,float v[],float w[],float x[])
 {
 Sort(n,v,w); //按单位价值排序/
 int i;
 for (i=1;i<=n;i++) x[i]=0; 
 float c=M; //c为背包剩余空间/
 for (i=1;i<=n;i++) {
 if (w[i]>c) break;
 x[i]=1;
 c-=w[i];
 }
 if (i<=n) x[i]=c/w[i];
 }//T(n)=O(nlogn)

多机调度问

题要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。约定,每个作业均可在任何一台机器上加工处理,但未完工前不允许中断处理。作业不能拆分成更小的子作业.

按此策略,当 n<=m时,只要将机器i的[0, ti]时间区间分配给作业i即可,算法只需要O(1)时间。当 n>m 时,首先将n个作业依其所需的处理时间从大到小排序。然后依此顺序将作业分配给空闲的处理机。算法所需的计算时间为O(nlogn)

猜你喜欢

转载自blog.csdn.net/wangqianqianya/article/details/80033486
今日推荐