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}