Algorithm 背包的动态规划矩阵填充
如果我有以下限制:Algorithm 背包的动态规划矩阵填充,algorithm,matrix,language-agnostic,dynamic-programming,Algorithm,Matrix,Language Agnostic,Dynamic Programming,如果我有以下限制: values = {$1,$2,$3,$4} items = {blue,yellow,green,red} weights = {1,2,3,4} capacity = 4 我想用表示项目权重的列和表示所选项目数量的行来填写我的矩阵: 1 2 3 4 1 $1 $1 $1 $1 {1} {1} {1} {1} 2 $1 $1 $3
values = {$1,$2,$3,$4}
items = {blue,yellow,green,red}
weights = {1,2,3,4}
capacity = 4
我想用表示项目权重的列和表示所选项目数量的行来填写我的矩阵:
1 2 3 4
1 $1 $1 $1 $1
{1} {1} {1} {1}
2 $1 $1 $3 $3
{1} {1} {1,2} {1,2}
3 $1 $1 $3 $3
{1} {1} {1,2} {1,2}
4 $1 $1 $3 $3 <--- should be 4?
{1} {1} {1,2} {1,2}
1234
1 $1 $1 $1 $1
{1} {1} {1} {1}
2 $1 $1 $3 $3
{1} {1} {1,2} {1,2}
3 $1 $1 $3 $3
{1} {1} {1,2} {1,2}
4$1$1$3$3解决方案如下
(顺便说一下,考虑在OR的培训)
< P>这个解决方案是这样的
(顺便说一下,考虑在.O.)的训练,
右上/下一个细胞有一个问题,应该说是4 {1,3}。但即使没有,右/底单元格也应该是$4{4},所以它在那里也出了问题。@harold所以在位置(3,3)应该是{1,3}?我的意思是位置(3,4),即你指的单元格正上方右/底单元格上方的单元格有问题,应该是$4{1,3}。但即使没有,右/下单元格也应该是$4{4},所以它在那里也错了。@harold所以在位置(3,3)应该是{1,3}?我的意思是位置(3,4),即你指向的单元格正上方的第一行不应该都是1吗?每个单元格通常表示重量小于或等于当前重量的物品的最佳重量(否则,您的最终检查必须循环某些值以找到最佳值,而不仅仅是返回角单元格)。@Dukeling如果只有一个重量为1的物品,则无法表示2或更多的重量。@polkovnikov.ph我说“小于或等于”。我并不是说这是错的,只是这不是通常的做法(而且稍微慢一点)。为什么第二行不是1230
那么,最后一行2
只表示一个重量2
项目,但重量应该是4
?@Dukeling Yep,当然,有一个bug。谢谢。第一行不应该都是1吗(不是1000
)?每个单元格通常表示重量小于或等于当前重量的物品的最佳重量(否则,您的最终检查必须循环某些值以找到最佳值,而不仅仅是返回角单元格)。@Dukeling您不能表示重量为2或更多的物品,而只有一件物品的重量为1。@polkovnikov.ph我说”小于或等于“。我不是说这是错误的,只是这不是通常的做法(而且速度稍慢)。为什么第二行不是1230
,那么,最后一行2
只表示一个重量2
项目,但重量应该是4
?@Dukeling Yep,当然,有一个bug。谢谢。
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// m[a][b] = NOWAY => There's no way to represent
// weight `b` with first `a` items
const int NOWAY = -1;
typedef vector<vector<int>> vvi;
const int values[] = {1, 2, 3, 4};
const string items[] = {"blue", "yellow", "green", "red"};
const int weights[] = {1, 2, 3, 4};
const int capacity = 4;
const int itemcount = 4;
void rec(vvi const & m, int represent, int mx, vvi & sol);
int main() {
// m[i][j] -- total value
// i -- items 1..i were taken
// j -- total weight of those items
vvi m(itemcount + 1, vector<int>(capacity + 1, NOWAY));
// No items weight nothing. The other values we're yet to build
m[0][0] = 0;
for (int i = 1; i <= itemcount; ++i) {
m[i] = m[i - 1];
int w = weights[i - 1];
// Find new representations
for (int j = capacity - w; j >= 0; --j) {
if (m[i][j] != NOWAY) {
m[i][j + w] = max(m[i][j + w], m[i][j] + values[i - 1]);
}
}
}
// Output table
for (int i = 0; i <= itemcount; ++i) {
for (int j = 0; j <= capacity; ++j)
m[i][j] == NOWAY ? cout << "x " : cout << m[i][j] << ' ';
cout << endl;
}
cout << endl;
// Find the index of the best solution (it's always in the last row)
int mxi = 0;
for (int i = 1; i <= capacity; ++i)
if (m.back()[mxi] < m.back()[i])
mxi = i;
// Recurse to get all the representations
vvi solutions;
rec(m, mxi, itemcount, solutions);
// Output them
for (int i = 0, ilen = solutions.size(); i < ilen; ++i) {
cout << '{';
bool f = true;
for (int j = 0, jlen = solutions[i].size(); j < jlen; ++j) {
if (!f) cout << ", ";
cout << items[solutions[i][j]];
f = false;
}
cout << "}" << endl;
}
}
vector<int> path;
void rec(vvi const & m, int represent, int mx, vvi & sol) {
if (represent == 0) {
sol.push_back(path);
return;
}
if (mx <= 0) return;
for (int i = mx - 1; i >= 0; --i) {
if (represent < weights[i])
continue;
if (m.back()[represent - weights[i]] == m.back()[represent] - values[i]) {
path.push_back(i);
rec(m, represent - weights[i], i, sol);
path.pop_back();
}
}
}
0 x x x x
0 1 x x x
0 1 2 3 x
0 1 2 3 4
0 1 2 3 4
{red}
{blue, green}