当背包允许物品部分装入时,重新设计动态规划策略,满足背包承载最大时价值最高,输出指示向量,并与问题1结果相比较,同时分析算法性能差异。输出c++代码并输出分析及实验心得
时间: 2023-12-26 12:04:42 浏览: 61
当背包允许物品部分装入时,可以使用贪心算法来解决问题。具体来说,我们可以将每个物品按照单位重量的价值从大到小排序,然后依次将单位重量价值最大的物品装入背包,直到背包不能再装入物品为止。如果最后一个物品只能部分装入,则需要计算出它的单位重量价值,从而得到它可以部分装入的重量。
以下是 C++ 代码实现:
```cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Item {
int val;
int wt;
double vpw;
};
bool cmp(Item a, Item b)
{
return a.vpw > b.vpw;
}
vector<double> FractionalKnapsack(int W, vector<int>& wt, vector<int>& val, int n)
{
// 计算每个物品的单位重量价值
vector<Item> items(n);
for (int i = 0; i < n; i++) {
items[i].val = val[i];
items[i].wt = wt[i];
items[i].vpw = (double)val[i] / (double)wt[i];
}
sort(items.begin(), items.end(), cmp);
// 依次装入物品
int cur_wt = 0;
double cur_val = 0.0;
vector<double> selected_items(n, 0.0);
for (int i = 0; i < n; i++) {
if (cur_wt + items[i].wt <= W) {
cur_wt += items[i].wt;
cur_val += items[i].val;
selected_items[i] = 1.0;
}
else {
double remaining_wt = W - cur_wt;
cur_val += remaining_wt * items[i].vpw;
selected_items[i] = remaining_wt / items[i].wt;
break;
}
}
return selected_items;
}
int main()
{
int W = 50;
vector<int> val = {60, 100, 120};
vector<int> wt = {10, 20, 30};
int n = val.size();
vector<double> selected_items = FractionalKnapsack(W, wt, val, n);
// 输出选择的物品
cout << "选择的物品为: ";
for (int i = 0; i < n; i++) {
if (selected_items[i] > 0)
cout << i << "(" << selected_items[i] << ") ";
}
cout << endl;
return 0;
}
```
与第一问的动态规划算法相比,该算法的时间复杂度为 $O(n \log n)$,其中 $n$ 是物品数量。由于该算法不需要对所有子问题进行计算,因此具有较高的效率。但是,该算法无法得到最优解,因为它只考虑了单位重量价值最大的物品。在某些情况下,该算法可能会选择一些单位重量价值较小的物品,从而导致价值不是最大的。
阅读全文