背包问题与贪心策略分析

我们在求全局最优解时,有时候局部最优解可能就是全局最优解或者说,在局部最优解不是全局最优解时,局部最优解接近全局最优解,这便是贪心策略,采用贪心策略需要证明局部最优解不劣于全局最优解。以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;

}

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值