#include <stdio.h>
//#include <conio.h>
#include <fstream>
#include <iostream>
#include <stdlib.h>
#define N 6//物品数量
#define M 3
using namespace std;
double dataArr[N*M+1];
double c;//背包容量
double v[N + 1];//各个物品的价值
double w[N + 1];//各个物品的重量
double cw = 0.0;//当前背包重量
double cp = 0.0;//当前背包中物品价值
double bestp = 0.0;//当前最优价值
int order[N + 1];
int put[N + 1];//设置是否装入
int ans[N + 1] = {0};
double perp[N + 1];
void knapsack()
{
int i, j;
int temporder = 0;
double temp = 0.0;
for (i = 1; i <= N; i++)
perp[i] = v[i] / w[i];
for (i = 1; i <= N - 1; i++)
{
for (j = i + 1; j <= N; j++)
if (perp[i] < perp[j])
{
temp = perp[i];
perp[i] = perp[j];
perp[j] = temp;
temporder = order[i];
order[i] = order[j];
order[j] = temporder;
temp = v[i];
v[i] = v[j];
v[j] = temp;
temp = w[i];
w[i] = w[j];
w[j] = temp;
}
}
}
//回溯函数
void backtrack(int i)
{
double bound(int i);
if (i > N)
{
if (cp >= bestp) //只要走过一次右子树,就满足bestp, 为了安全,强制加这个判断
{
bestp = cp;
//bestX=put[];
for (int i=1;i<=N;i++)
{
ans[i]=put[order[i]];//这里很重要
//要注意每次bestp更新时
//我们就要把所选择的路径
//(这里打出来是选择的路径,比如说0101这样)更新一下
//如果在最后才输出的话,很有可能只是得到了一个中间值(甚至不是可行解)
}
}
// }
return;
}
if (cw + w[i] <= c)
{
cw += w[i];
cp += v[i];
put[i] = 1;
backtrack(i + 1);
cw -= w[i];
cp -= v[i];
}
if (bound(i + 1) >= bestp)//符合条件搜索右子数
{
put[i] = 0;
backtrack(i + 1);
}
}
//限界函数
double bound(int i)
{
double leftw = c - cw;//剩余承重量
double b = cp;//当前背包价值
while (i <= N && w[i] <= leftw)
{
leftw -= w[i];
b += v[i];
i++;
}
b += v[i] / w[i] * leftw;
return b;
}
int main()
{
ifstream fileinput;
fileinput.open("input.txt");
for (int i = 0; i < N*M + 1; i++)
{
fileinput >> dataArr[i];
//把txt文件中的数字全部放在data中
}
c = dataArr[0];//例子中是把50赋值给C
//cout<<"c="<<c<<endl;
for (int i = 1; i <= N; i++)
{
w[i] = dataArr[2 + M * (i - 1)]; //赋值重量到w中
v[i] = dataArr[3 + M * (i - 1)]; //赋值价值到v中
order[i] = i;
}
knapsack();
backtrack(1);
cout << endl;
cout << "最大价值为" << bestp << endl;
for (int i = 1; i <= N; i++)
{cout<<ans[i]; }
cout << endl;
cout << "背包价值排序(性价比由高到低)为" << endl;
for (int i = 1; i <= N; i++)
{
printf("%d ", order[i]);
// cout<<put[i]<<" ";
}
cout << endl;
cout << "选择的物品是:" << endl;
for (int i = 1; i <= N; i++)
{
if (put[i] == 1) {
printf("%d ", order[i]);
}
}
cout << endl;
cout << "最终路径为" << endl;
for (int i = 1; i <= N; i++)
{
cout << ans[i] << " ";
}
return 0;
}
来源:CSDN
作者:派先森
链接:https://blog.csdn.net/qq_41731283/article/details/103464180