背包问题贪心法

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

背包问题贪心法

实验报告

学院:计算机科学与技术学院班级:****

学号:****

姓名:****

一、实验目的

1)以背包问题为例,掌握贪心法的基本设计策略。

2)熟练掌握各种贪心策略情况下的背包问题的算法并实现;其中:量度标准分别取:效益增量P 、物品重量w 、P/w 比值;

3) 分析实验结果来验证理解贪心法中目标函数设计的重要性。

二、问题基本思想描述

(1)贪心法的基本思路

从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到某算法中的某一步不能再继续前进时,算法停止。

该算法存在问题:

1. 不能保证求得的最后解是最佳的;

2. 不能用来求最大或最小解问题;

3. 只能求满足某些约束条件的可行解的范围。

(2)背包问题的描述

已知有n 种物品和一个可容纳M 重量的背包,每种物品i 的重量为i

w 。假定将物品i 的一部分

i

x 放入背包就会得到

i

i x p 的效益,这里,

1

0≤≤i x ,

>i p 。

显然,由于背包容量是M ,因此,要求所有选中要装入背包的物品总重量不得超过M.。如果这n 件物品的总重量不超过M ,则把所有物品装入背包自然获得最大效益。现需解决的问题是,在这些物品重量的和大于M 的情况下,该如何装包,使得得到更大的效益值。由以上叙述,可将这个问题形式表述如下:

极 大 化目标函数

∑≤≤n

i i

x

p 1i

约束条件 M x w n i i ≤∑

≤≤1i

n

i w p x i i i ≤≤>>≤≤1,0,0,10

(3)用贪心策略求解背包问题

首先需确定最优的量度标准。这里考虑三种策略:

策略1:按物品价值p降序装包,

策略2:按物品重w升序装包

策略3:按物品价值与重量比值p/w的降序装包

(4)算法描述

以策略3为例:

procedure GREEDY-KNAPSACK(P,W,M,X,n)

//P(1:n)和W(1:n)分别含有按P(i)/W(i)≥P(i+1)/ W (i+1)排序的n件物品的效益值和重量。M是背包的容量,而X(1:n)是解向量。// real P(1:n),W(1:n),X(1:n),M,cu;

integer i,n;

X←0 //将解向量初始化为零

cu←M //cu是背包剩余容量

for i←1 to n do

if W(i)>cu then exit endif

X(i) ←1

cu←cu-W(i)

repeat

if i≤n then X(i) ←cu/W(i)

endif

end GREEDY-KNAPSACK

三、程序流程图

以策略三为例:(此时物品已经按物品价值与重量比值p/w降序排列)

四、以策略三为例程序清单

#include

#include

struct good

{

double v,w; //权值及重量

double x; //解向量

};

void cpygood(good a,good b){

a.v =

b.v;

a.w =

b.w;

a.x =

b.x;

}

void insertionsort(good *goods, int n){

int i,j;

good item;

for(j=1;j

//cpygood(item, goods[j]);

item.v = goods[j].v;

item.w = goods[j].w;

item.x = goods[j].x;

i = j-1;

while(item.v/item.w > goods[i].v/goods[i].w && i>=0)

{

//cpygood(goods[i+1], goods[i]);

goods[i+1].v = goods[i].v;

goods[i+1].w = goods[i].w;

goods[i+1].x = goods[i].x;

i--;

}

//cpygood(goods[i+1],item);

goods[i+1].v = item.v;

goods[i+1].w = item.w;

goods[i+1].x = item.x;

}

}

void greedy(int n, double c, good *goods)

{ //n为物品数量,c为背包能承受的重量double m = c;

int i;

insertionsort(goods,n);

for(i=0;i

goods[i].x = 0;

for(i=0;i

if(goods[i].w > m)

break;

goods[i].x = 1;

m -= goods[i].w;

}

if(i < n)

goods[i].x = m/goods[i].w;

}

void main(){

good *goods;

int n,i;

double c;

freopen("goods.in","r",stdin);

freopen("goods.out","w",stdout);

scanf("%lf",&c);

scanf("%d",&n);

goods = (good *)malloc(n);

for(i=0; i

相关文档
最新文档