0-1背包问题-贪心法和动态规划法求解1

  • 格式:docx
  • 大小:14.99 KB
  • 文档页数:6

实验四 “0-1”背包问题

一、 实验目的与要求

熟悉C/C++语言的集成开发环境:

通过本实验加深对贪心算法、动态规划算法的理解。

二、 实验内容:

掌握贪心算法、动态规划算法的概念和基本思想,分析并掌握“0-1”背包问题的求解 方法,并分析貝优缺点。

三、 实验题

1. “0-1”背包问题的贪心算法

2. “0-1”背包问题的动态规划算法

说明:背包实例采用教材P132习题六的6-1中的描述。要求每种的算法都给出最 大收益和最优解。

设有背包问题实例n=7, M=15,, (w0,wl,…w6)= (2, 3, 5, 7,1,4,1),物品装入背 包的收益为:(p0, pl,。。。,p6) = (10,5,15,7,6,18,3)。求这一实例的最优解和最大 收益。

四、 实验步骤

理解算法思想和问题要求;

编程实现题目要求:

上机输入和调试自己所编的程序:

验证分析实验结果;

整理岀实验报告。

五、 实验程序 //贪心法求解

#include〈iostream> #include,/iomanip// using namespace std;

//按照单位物品收益排序,传入参数单位物品收益,物品收益和物品重量的 数组,运用冒泡排序

void AvgBenefitsSort (float *arry_avgp, float *arry_p, float *arry_w );

/7获取最优解方法,传入参数为物品收益数组,物品重量数组,最后装载物 品最优解的数组和还可以装载物品的重量

float GetBestBenifit(float *arry_p,float *arry_w, float

*arry_x, float u);

int main() {

float w[7] = {2, 3, 5, 7, 1, 4, 1};

float p[7] = {10, 5, 15, 7, 6, 18,

3};

float avgp[7]={0);

float x[7]二{0};

const float M=15;

float ben=0;

AvgBenefitsSort(avgp, p, w); ben=GetBestBenif it (p, w, x, M);

cout«endK

system("pause"); return 0;

}

//按照单位物品收益排序,传入参数单位物品收益,物品收益和物品重量的 数组,运用冒泡排序

void AvgBenefitsSort (float *arry_avgp, float *arry_p, float *arry_w ) {

//求岀物品的单位收益

for (int i=0;i<7;i++)

{

arry_avgp[i]=arry_p[i]/arry_w[i];

} cout«endl;

//把求出的单位收益排序,冒泡排序法

int exchange二7;

int bound=0;

float temp=0; //物品重量数组

//物品收益数组

//单位毒品的收益数组

//最后装载物品的最优解数组

//背包所能的载重

//最后的收益 while(exchange)

bound=exchange; exchange二0;

for (int i=0;i

{

if (arry_avgp[i]

〃交换单位收益数组

temp=arry_avgp[i];

arry_avgp[i]=arry_avgp[i+1]; arry_avgp[i+1]=temp;

//交艇收益数组 temp=arry_p[i];

arry_p[i]=arry_p[i+1]; arry_p[i+l]=temp;

//交换重量数组 temp=arry_w[i]; arry_w[i]=arry_w[i+1];

arry_w[i+1]二t emp;

exchange=i;

}

}

}

}

//获取最优解方法,传入参数为物品收益数组,物品重量数组,最后装载物 品最优解的数组和还可以装载物品的重量

float GetBestBenifit (float *arry_p, float *arry_w, float

*arry_x, float u)

{

int i二0; ,7循坏变量i

float benifit=0; //最后收益

while (i<7)

{

if(u~arry_w[i]>0)

{

arry.X[i]=arry_w[i]; //把半前物品重量缴入最优解数

benif it+=arry_p[i]; //收益增加前物品收益

u-=arry_w[i]: //背包还能载逼量减去前物品巫

cout«arry_x[i] //输出最优解 } i++;

}

return benifit; //返回最后收益

}

//动态规划法求解

nclude〈>

#include<>

#define n 6

void DKNAP(int p[], int w[], int M, const int m): void

main()

{

int p[n+l], w[n+l];

int M, i, j;

int m^l;

for(i=l;i<=n;i++)

{

m=m*2;

printf C\nin put the weight and the p:〃); scanf (,z%d %d", &w[i], &p[i]);

)

printf (,z%d/z, m);

printf (,z\n in put the max weight H:〃);

scanf("%d", &M);

DKNAP (p, w, M, m);

}

void DKNAP(int p[], int w[], int M, const int m)

{

int p2[m], w2[m], pp, ww, px;

int F[n+1], pk, q, k, 1, h, u, i, j, next, max, s[n+l];

F[0]二1;

p2[l]=w2[l]=0;

l=h=l;

F[l]二next二2;

for(i=l;i

{

k二 1;

max=0;

u 二 1;

for (q=l;q<=h;q++)

if ((w2 [q]+w[i] <=M) &&max<=w2 [q] +w [ i ])

{

u二 q;

max=w2[q] +w[i];

} for(j=l;j<=u;j++)

{

PP二p2[j]+p[i];

ww二w2[j]+w[i];

while(k<=h&&w2[k]〈ww) {

p2[next]=p2[k];

w2[next]=w2[k];

next++;

k++;

}

辻(k<=h&&w2[k]二二ww)

{

if(pp<=p2[k])

pp二p2 [k];

k++;

}

else if(pp>p2[next-1])

{

p2[next]=pp;

w2[next]=ww;next++;

}

while (k<=h&&p2[k]<=p2[next-1])

k++;

}

while(k<=h)

{

p2[next]=p2[k];

w2[next]二w2[k];

next二next+1; k++;

}

1二h+1;

h二next-1;

F[i+1]二next;

}

for(i=l;i

printf C%2d%2d ", p2[i], w2[i]); for (i=n;i>0;i一一)

next二F[i];

next一一; pp=pk=p2[next];

ww=w2[next]; while (ww+w[i] >M&&next>F[iT])

next=next~l; pp=p2[next]; ww二w2[next];

}

if(ww+w[i]<=M&&next>F[i -1]) px=pp+p[i];

if(px>pk&&ww+w[i]<=M)

{

s[i]二 1; M=M-w[i]; printf (z,M=%d ",

M);

}

else s[i]二0;

)

for (i=l;i<=n;i++)

printf("%2d

",s[i]);

)

六、实验结果

1.贪心法截图:

惯:心袪求解为: 物品总量叢优解知 tali羸续:

七、实验分析