我们在求全局最优解时,有时候局部最优解可能就是全局最优解或者说,在局部最优解不是全局最优解时,局部最优解接近全局最优解,这便是贪心策略,采用贪心策略需要证明局部最优解不劣于全局最优解。以c语言代码7个物品为例:若需要n个物品可以用scanf函数键入值,
7个商品的容量:float weight[]={35,30,60,50,40,10,25};//物品重量;
7个商品的价值: float value[]={10,40,30,50,35,40,30};//物品价值
问题:使得物品的价值最大,且容量不能超过150,物品不可放入一部分,求最优解。
首先要想放入物品的价值最大,必然是希望物品的重量小,价值大,因此首先选取品单位重量价值最大的的物品,v_a[i]=value[i]/weight[i];然后对v_a[i]得到的数组进行排序,优先选择最大单位重量价值最大的的物品。
for(i=0;i<6;i++)
{
for(j=0;j<=6;j++)
{
if (v_a[j]<=v_a[j+1])
{
t=v_a[j];
v_a[j]=v_a[j+1];
v_a[j+1]=t;
}
}
}
//排序结束
for(k=0;k<7;k++ )
{
printf("%f\t %f\n " ,v_a[k],b[k] );
printf("\n");
}
//排序输出
然后还要找到v_a[i]中从大到小在没有排序数组之前的索引值,所以在排序之前要拷贝v_a[i],b[i]=v_a[i];通过拷贝的数组b[i]寻找索引值。
for(i=0;i<6;i++)
{
for(j=0;j<=6;j++)
{
if(v_a[i]==b[j])
{
index=j;
index++;
printf("选择第%d物品\n" ,index);//选取的第j+1个物品。
sum_weight+=weight[j];
sum_value+=c[j];
printf("容量和为%d\n" ,sum_weight);
printf("总价值和为%d\n" ,sum_value);
if(sum_weight>=150)
break;
}
if(sum_weight>=150)
break;
}
printf("剩余容量%d\n" ,150-sum_weight);
if(sum_weight>=150)
break;
}
}
在找到索引值之后对容量和价值进行累加,输出剩余容量,当容量大于150的时候停止寻找索引值。全部代码如下:
#include <stdio.h>
void main()
{
float weight[]={35,30,60,50,40,10,25};//物品重量;
float value[]={10,40,30,50,35,40,30};//物品价值
//假设背包的容量为150
float v_a[]={};
float b[7]={};
float c[7]={10,40,30,50,35,40,30};
int sum_weight=0,sum_value=0;
//贪心策略的局部最优解可能是全局最优解,之后证明贪心策略不劣于最优解。
//采用选取单位价值最大物品
int i,j,k,index;
float t;
for(i=0;i<7;i++)
{
printf("%f\n",value[i]);
v_a[i]=value[i]/weight[i];
b[i]=v_a[i];
printf("%f\n",v_a[i]);
printf("重量是%f的物品的单位价值是%f\n",weight[i],b[i]);
}
//本次选取物品为7个,若为n个物品,for循环n-1次。
for(i=0;i<6;i++)
{
for(j=0;j<=6;j++)
{
if (v_a[j]<=v_a[j+1])
{
t=v_a[j];
v_a[j]=v_a[j+1];
v_a[j+1]=t;
}
}
}
//排序结束
for(k=0;k<7;k++ )
{
printf("%f\t %f\n " ,v_a[k],b[k] );
printf("\n");
}
//排序输出
//v_a[i]从大到小的输出排序,因为要优先选择最大的单位价值。
//索引v_a原本的值,寻找第一个v_a[1]对应与第几个物品。
for(i=0;i<6;i++)
{
for(j=0;j<=6;j++)
{
if(v_a[i]==b[j])
{
index=j;
index++;
printf("选择第%d物品\n" ,index);//选取的第j+1个物品。
sum_weight+=weight[j];
sum_value+=c[j];
printf("容量和为%d\n" ,sum_weight);
printf("总价值和为%d\n" ,sum_value);
if(sum_weight>=150)
break;
}
if(sum_weight>=150)
break;
}
printf("剩余容量%d\n" ,150-sum_weight);
if(sum_weight>=150)
break;
}
}