贪心算法在几个基本算法里面算是相对简单的算法了,思路也是非常简单的,每一步总是做出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。基本思路就是从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到某算法中的某一步不能再继续前进时,算法停止。
对于这个比较简单的算法,我们就先了解一下他的利弊吧,利当然就是简单,省时,好用。下面我们看看贪心法存在的一些问题。
贪心法存在的问题:
1. 不能保证求得的最后解是最佳的;
2. 不能用来求最大或最小解问题;
3. 只能求满足某些约束条件的可行解的范围
上述的这些问题可以在其他算法里面得到相应的解决,请继续关注我的博客,但是我们也不会因此放弃对贪心算法的使用。这正是敏捷开发所提倡的,永远没有最好的,只有最适合的.我们选用贪心算法的原因就是因为他能够满足当前的需要并且比其他算法更加简单。
下面请看示例题:
有N个商品,每个商品的重量为WI,价格为:PI,现有一个背包,最多能装M的重量.其中(0<=I<N,0<wi<M)。问:怎样装能使包中装入的商品价值最高(对于每个商品可以只装该商品的一部分)
代码如下:
#include<stdio.h>
//参数:n表示是背包可以存放物品的种类
//参数:指针p指向的数组是存放物品价值的数组
//参数:指针q指向的数组是存放物品重量的数组
static void sort(int n,float *p,float *q)
{
int i;
int j;
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
if((*(p+i))/(*(q+i))<(*(p+j))/(*(q+j)))
{
float f;
f=*(p+i);
*(p+i)=*(p+j);
*(p+j)=f;
f=*(q+i);
*(q+i)=*(q+j);
*(q+j)=f;
}
}
//参数:指针x指向的数组是存放物品的情况
//参数:m表示的是背包的容量
//参数:n表示的是背包可以存放物品的种类
static void knapsack(int n,float m,float *v,float *w,float *x)
{
sort(n,v,w);
int i;
for(i=0;i<n;i++)
{
if(*(w+i)>m)
break;
//可以存放该物品时,置1
*(x+i)=1;
//放入后,背包的容量减少
m-=*(w+i);
}
//当此时背包的容量不够存放整个物品的情况时,存放一部分
if(i<n)
*(x+i)=m/(*(w+i));
}
int main()
{
int n=6;//物品种类
int m=100;//背包容量
float w1[6]={15,5,60,25,55,80};//各种物品的重量
float v1[6]={20,30,30,10,55,40};//各种物品的价值
float x1[6];//存放各种物品的存放情况
float *x;
float *w;
float *v;
w=w1;
v=v1;
x=x1;
int i;
for(i=0;i<n;i++)
*(x+i)=0;
knapsack(n,m,v1,w1,x);
printf("\n===========输出物品容量数组内容======================\n");
for(i=0;i<n;i++)
printf("%.1f\t",*(w+i));
printf("\n============输出物品价值数组内容=====================\n");
for(i=0;i<n;i++)
printf("%.1f\t",*(v+i));
printf("\n============输出物品存放情况数组=====================\n");
for(i=0;i<n;i++)
printf("%.1f\t",*(x+i));
printf("\n============END=====================\n");
return 0;
}
简单的例子,说明贪心算法如何使用。贪心算法是非常简单的算法,就像在生活中,如果我们想给别人找38块钱的话,我们最先考虑的是先找一张20元,在找一张10元,在找一张5元和三张一元,而不会直接找38张一元,这就是一个典型的贪心算法。所以,生活中处处有算法,缺少发现的眼睛。