算法学习笔记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; }
运行结果:
相关文章推荐
- 算法导论学习笔记(十三):动态规划(三):01背包问题
- 算法设计和数据结构学习_3(《数据结构和问题求解》part2笔记)
- 算法设计和数据结构学习_3(《数据结构和问题求解》part2笔记)
- 蛮力法:设计算法求解背包问题,并编程实现。
- 算法设计和数据结构学习_4(《数据结构和问题求解》part4笔记)
- 【笔记】【算法学习】【动态规划】背包问题总结(1)
- 算法设计和数据结构学习_4(《数据结构和问题求解》part4笔记)
- 0/1背包问题的动态规划法求解 —— Java 实现
- 算法学习---关于哈密顿图的哈密顿通路求解问题
- 实验二 动态规划算法 用动态规划法求解0/1背包问题
- 算法学习之二——用DP和备忘录算法求解最长公共子序列问题
- MatLab建模学习笔记10——利用罚函数求解非线性规划问题
- 算法笔记_019-背包问题(Java)
- 算法学习笔记----用主方法求解递归式
- 程序员编程艺术学习笔记(三续)Top K算法问题的实现
- 【算法学习笔记】18.暴力求解法06 隐式图搜索2 八数码问题 未启发
- 算法学习:贪心求部分背包(使用结构体来求解)
- 数据结构经典算法学习之完全背包问题
- 动态规划法——求解0-1背包问题
- 算法笔记_019-背包问题(Java)