您的位置:首页 > 其它

算法学习笔记9——蛮力法和动态规划法求解0/1背包问题

2020-06-27 05:24 393 查看

完整代码:

#include<iostream>
#include <windows.h>
#include<iomanip>

using namespace std;
int c;  //背包的容量
int bag_values=0;//背包(装入)的价值 初始化为0
int goods_num;   //货物的数量
int maxValue = -1;  //定义最大的价值
int calc_arrangement(); //函数   在后面实现

/*结构体 物品*/
struct Goods
{
int id;				//物品编号
int is_in_bag;	    //当前物品是否在背包中,1表示在背包,0表示不在
int weight;			//当前物品的重量
int value;			//当前物品的价值
}goods[50];                             //目前所支持最大物品数量为50,可根据实际情况调整

struct things
{
int weight;
int value;
//这个是用来计算 全排列的时候那些结果是由哪些下标的货物计算而来
int innerindex[10] = {0};
}Goods[1001];

/*求背包的最大价值*/
// n——n个物品
// C——背包容量为C
int KnapSack(struct Goods goods[50] ,int n,int C)
{
int i,j;
int V[50][50]={0};	//存放迭代结果
//初始化第0列
for(i=0;i<=n;i++)
{
V[i][0]=0;
}
//初始化第0行
for(j=0;j<=C;j++)
{
V[0][j]=0;
}
//分别计算每一行
for(i=1;i<=n;i++)
{
for(j=1;j<=C;j++)
{
if(j<goods[i-1].weight) //物品重量大于背包重量,不能放入
V[i][j]=V[i-1][j];
else					//物品重量小于等于背包重量
{
V[i][j]=(V[i-1][j]>V[i-1][j-goods[i-1].weight]+goods[i-1].value)?V[i-1][j]:V[i-1][j-goods[i-1].weight]+goods[i-1].value;
}
}
}
//求装入背包的物品
for(j=C,i=n;i>0;i--)
{
if(V[i][j]>V[i-1][j])
{
goods[i-1].is_in_bag=1;
j=j-goods[i-1].weight;
}
else
{
goods[i-1].is_in_bag=0;
}
}

//返回背包最大价值
return V[n][C];
}

//直接计算所有货物的全排列
int calc_arrangement()
{
int head = 1;
int tail = goods_num + 1;   //tail指向的是最后一个元素的后一位

while (head <= goods_num)
{
for (int i = head + 1; i <= tail - 1; i++)
{
if (Goods[i].innerindex[head] != 1)  //就是说这个要与head的相加值的 其获得时候 并没有head的值参与其中
{
Goods[tail].value = Goods[head].value + Goods[i].value;
Goods[tail].weight = Goods[head].weight + Goods[i].weight;
//因为现在的这个goods[tail]的值的由来goods[i]参与了进来
//所以要把参与goods[i]的其他index标识到goods[tail]之中
for(int temp=1;temp<=goods_num;temp++)
Goods[tail].innerindex[temp] = Goods[i].innerindex[temp];
Goods[tail].innerindex[head] = 1;
tail++;
}
else
continue;
}
head++;
}

int index=-1;   //用这个来记录我所取得的value最大的下标
for (int j = tail - 1; j > 0; j--)
{
if (Goods[j].weight <= c)
{
if (Goods[j].value > maxValue)
{
maxValue = Goods[j].value;
index = j;
}
}
else
continue;
}
return index;
}

/*主函数*/
int main()
{
LARGE_INTEGER nFreq;
LARGE_INTEGER nBeginTime;
LARGE_INTEGER nEndTime;
double time;

int i;
int capacity;		//背包的容量
int goods_number;	//物品的个数
int max_value;		//最大价值
cout<<"--------------动态规划法-------------------"<<endl;

QueryPerformanceFrequency(&nFreq);
QueryPerformanceCounter(&nBeginTime);

/*输入背包容量、物品个数、物品重量、物品价值*/
cout<<"请输入背包容量:";
cin>>capacity;

cout<<"请输入物品的个数:";
cin>>goods_number;
while(goods_number > 50)
{
cout<<"抱歉,当前所容许最大物品数量为50,请您重新输入";
cin>>goods_number;
}
cout<<"请输入"<<goods_number<<"个物品的重量:";
for(i=0;i<goods_number;i++)
{
goods[i].id=i+1;
goods[i].is_in_bag=0;//默认表示当前物品不在背包
cin>>goods[i].weight;
}
cout<<"请输入"<<goods_number<<"个物品的价值:";
for(i=0;i<goods_number;i++)
{
cin>>goods[i].value;
}

/*求最大价值*/
max_value=KnapSack(goods,goods_number,capacity);

/*输出最大价值*/
cout<<"最大价值为"<<max_value<<endl;

QueryPerformanceCounter(&nEndTime);
time=(double)(nEndTime.QuadPart-nBeginTime.QuadPart)*1000000000/(double)(nFreq.QuadPart);
cout <<"动态规划法所花的时间为:" << time<<"纳秒"<<endl;

cout<<"--------------蛮力法--------------"<<endl;

QueryPerformanceFrequency(&nFreq);
QueryPerformanceCounter(&nBeginTime);

cout << "请输入背包的容量:";
cin >> c;
//cout << endl;
cout << "请输入货物的数量:";
cin >> goods_num;

cout << "请输入每个货物的重量:";
for (int i = 1; i <= goods_num; i++)
{
cin >> Goods[i].weight;
//初始化所给数据的innerindex
Goods[i].innerindex[i] = 1;
}
cout << "请输入每个货物的价值:";
for (int i = 1; i <= goods_num; i++)
{
cin >> Goods[i].value;
//初始化所给数据的innerindex
Goods[i].innerindex[i] = 1;
}
int index=calc_arrangement();
cout <<"最大价值为"<< maxValue<<endl;

QueryPerformanceCounter(&nEndTime);
time=(double)(nEndTime.QuadPart-nBeginTime.QuadPart)*1000000000/(double)(nFreq.QuadPart);
cout <<"蛮力法所花的时间为:" << time<<"纳秒"<<endl;

return 0;
}

运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: