#include <iostream>
#include <algorithm>
#include <iomanip>
using namespace std;
typedef struct Thing{
double weight;
double value;
int index;
};
Thing *things;
const int goods = 7;//物品的数量
int Max_Weigth = 150;//背包承受的重量
int information[2][goods] = {{35, 30, 60, 50, 40, 10, 25}, {10, 40, 30, 50, 35, 40, 30}};//第一行为重量,第二行为价值
int solution[goods];//解空间
int Best_solution[goods];//最优解向量
int Best_value = 0;//最优解的价值
int Best_weight = 0;//最优解的重量
bool cmp(Thing &t1, Thing &t2)//重定义sort
{
return (t1.value / t1.weight) > (t2.value / t2.weight);
}
double get_best_value(int t, int limit_weight)//完全背包问题即限界函数的参数比较
{
double sum_weight = 0, sum_value = 0;
int i;
for( i = t; i < goods; i++)
{
if(sum_weight + things[i].weight > limit_weight)
break;
else{
sum_value += things[i].value;
sum_weight += things[i].weight;
}
}
if(i < goods && limit_weight > sum_weight)
{
sum_value += (limit_weight - sum_weight) * things[i].value / things[i].weight;
}
return sum_value;
}
void RecursiveBacktrack(int t, int cv, int cw)//t 第几次递归(从0开始), 父节点的价值 cw剩余空间
{
if(t > goods)
return;
if(t == goods)//到达叶子节点
{
Best_value = cv;
for(int i = 0; i < goods; i++)
Best_solution[i] = solution[i];
cout << "the best solution: " << endl;
int value = 0;
for(int i = 0; i < goods; i++)
{
cout << " " <<Best_solution[i];
value += things[i].value * solution[i];
}
cout << " value :" << Best_value << endl;
return;
}
if(cw - things[t].weight >= 0)//约束函数
{
solution[t] = 1;
RecursiveBacktrack(t + 1, cv + things[t].value, cw - things[t].weight);
}
if(cv + get_best_value(t + 1, cw) > Best_value)//限界函数
{
solution[t] = 0;
RecursiveBacktrack(t + 1, cv, cw);
}
}
void IterativeBacktrack(int t, int cv, int cw)//t 为
{
while(t >= 0)
{
while(t < goods && cw - things[t].weight >= 0)//直接装包至不能装,及直接遍历解空间的左孩子,及利用约束函数
{
solution[t] = 1;
cw -= things[t].weight;
cv += things[t].value;
t++;
}
if(t >= goods)//已经把能装的装了,又因为限界函数和约束函数,此解比之前Best_solutio更好,更新输出
{
for(int i = 0; i < goods; i++)
Best_solution[i] = solution[i];
for(int i = 0; i < goods; i++)
cout << " " << solution[i];
cout << " value : " << cv << endl;
Best_value = cv;
} else//否则丢下
{
solution[t] = 0;
t++;//保证不能装的情况下不陷入死循环,课以注释掉试一下
}
while(get_best_value(t, cw) + cv <= Best_value)//利用限界函数剪枝,如果之后不会获得更优解则回调到可能获得更优解的结点
{
t--;
while (t >= 0 && solution[t] == 0)//回调到装物品的结点
t--;
if (t < 0)
break;
solution[t] = 0;//不装该物品
cw -= things[t].weight;//更新数据
cv -= things[t].value;
}
}
}
void Get_Choose()
{
vector<int> pos;
for(int i = 0; i < goods; i++)
{
if(Best_solution[i] == 1)
pos.push_back(things[i].index);
}
sort(pos.begin(), pos.end());
cout << "装入背包的编号: " << endl;
for(int i = 0; i < pos.size(); i++)
cout << " " << pos[i] + 1;
cout << endl << endl;
}
int main()
{
things = new Thing[goods];
for(int i = 0; i < goods; i++)
{
things[i].weight = information[0][i];
things[i].value = information[1][i];
things[i].index = i;
}
sort(things, things + goods, cmp);
cout << "递归运行结果: " << endl;
Best_value = 0;
RecursiveBacktrack(0, 0,Max_Weigth);
Get_Choose();
Best_value = 0;
cout << "迭代运行结果:" << endl;
IterativeBacktrack(0, 0, Max_Weigth);
Get_Choose();
}
2020-12-21
最新推荐文章于 2020-12-30 16:44:00 发布