0

I have aproblem:

Thread::tdlen: Objects of unequal length in {Null} {} cannot be combined. >>

It seems to occur in the while test which makes no sense at all since I am onlu comparing numbers...?

The program is a program to solve the 0-1 knapsack dynamic programming problem though I use loops, not recursion.

I have put some printouts and i can only think that the problem is in the while loop and it doesnt make sense.

(*  0-1 Knapsack problem
 item = {value, weight} 
  Constraint is maxweight. Objective is to max value. 
 Input on the form:
 Matrix[{value,weight},
       {value,weight},
        ...
      ]
*)

lookup[x_, y_, m_] := m[[x, y]];

generateTable[items_, maxweight_] := {
  nbrofitems = Dimensions[items][[1]];
  keep = values = Table[0, {j, 0, nbrofitems}, {i, 1, maxweight}];
  For[j = 2, j <= nbrofitems + 1, j++,
   itemweight = items[[j - 1, 2]];
   itemvalue = items[[j - 1, 1]];
   For[i = 1, i <= maxweight, i++,
    {
     x = lookup[j - 1, i, values];
     diff = i - itemweight;
     If[diff > 0, y = lookup[j - 1, diff, values], y = 0];
     If[itemweight <= i ,
      {If[x < itemvalue + y,
        {values[[j, i]] = itemvalue + y; keep[[j, i]] = 1;},
        {values[[j, i]] = x; keep[[j, i]] = 0;}]
       },
      y(*y eller x?*)]
     }
    ]
   ];
  {values, keep}
  }

pickItems[keep_, items_, maxweight_] :=
 {
  (*w=remaining weight in knapsack*)
  (*i=current item*)
  w = maxweight;
  knapsack = {};
  nbrofitems = Dimensions[items][[1]];
  i = nbrofitems + 1;
  x = 0;
  While[i > 0 && x < 10,
   {
      Print["lopp round starting"];
      x++;
      Print["i"];
      Print[i];
      Print["w"];
      Print[w];
      Print["keep[i,w]"];
      Print[keep[[i, w]]];
      If[keep[[i, w]] == 1,
       {Append[knapsack, i];
        Print["tjolahej"];
        w -= items[[i - 1, 2]];
        i -= 1;
        Print["tjolahopp"];
        },
       i -= 1;
       ];
      Print[i];
      Print["loop round done"];
      }
     knapsack;
   ]
  }

Clear[keep, v, a, b, c]
maxweight = 5;
nbrofitems = 3;
a = {5, 3};
b = {3, 2};
c = {4, 1};
items = {a, b, c};


MatrixForm[items]
results = generateTable[items, 5];
keep = results[[1]][[2]];
Print["keep:"];
MatrixForm[keep]
Print["------"];
results2 = pickItems[keep, items, 5];
MatrixForm[results2]
olapola
  • 11
  • 1
  • 3
  • I am on an iPad so no Mma here, but a couple of comments on your code. First, `values` definition doesn't need `i` and `j`. Outer `For` loop could be a `FoldList` instead. Also, you are creating global variables in the function. You should put them in a `Module`. It would help to know the input data you are using. – Verbeia Sep 22 '11 at 12:45
  • 1
    If I may give a general recommendation, I'd try to better localize the problematic portion of the code and construct a minimal self - contained example illustrating the problem. That's more work on your side, but you'll learn more and also increase chances for a better answer, since more people will be willing to spend their time looking at your code. This question: http://stackoverflow.com/questions/6167291/how-to-debug-when-writting-small-or-big-codes-using-mathematica-workbench-mma-d/ contains some discussion on debugging of mma code. – Leonid Shifrin Sep 22 '11 at 13:06

2 Answers2

1

This is not really an answer to the specific question being asked, but some hints on general situations when this error occurs. The short answer is that this is a sign of passing lists of unequal lengths to some Listable function, user-defined or built-in.

Many of Mathematica's built-in functions are Listable(have Listable attribute). This basically means that, given lists in place of some or all arguments, Mathematica automatically threads the function over them. What really happens is that Thread is called internally (or, at least, so it appears). This can be illustrated by

In[15]:= 
ClearAll[f];
SetAttributes[f,Listable];
f[{1,2},{3,4,5}]

During evaluation of In[15]:= Thread::tdlen: Objects of unequal length in 
f[{1,2},{3,4,5}] cannot be combined. >>
Out[17]= f[{1,2},{3,4,5}]

You can get the same behavior by using Thread explicitly:

In[19]:= 
ClearAll[ff];
Thread[ff[{1,2},{3,4,5}]]

During evaluation of In[19]:= Thread::tdlen: Objects of unequal length in 
ff[{1,2},{3,4,5}] cannot be combined. >>
Out[20]= ff[{1,2},{3,4,5}]

In case of Listable functions, this is a bit more hidden though. Some typical examples would include things like {1, 2} + {3, 4, 5} or {1, 2}^{3, 4, 5} etc. I discussed this issue in a bit more detail here.

Leonid Shifrin
  • 22,449
  • 4
  • 68
  • 100
0

Try this version:

pickItems[keep_, items_, maxweight_] := Module[{},
  {(*w=remaining weight in knapsack*)(*i=current item*)w = maxweight;
   knapsack = {};
   nbrofitems = Dimensions[items][[1]];
   i = nbrofitems + 1;
   x = 0;
   While[i > 0 && x < 10,
    {
     Print["lopp round starting"];
     x++;
     Print["i"];
     Print[i];
     Print["w"];
     Print[w];
     Print["keep[i,w]"];
     Print[keep[[i, w]]];

     If[keep[[i, w]] == 1,
      {
       Append[knapsack, i];
       Print["tjolahej"];
       w -= items[[i - 1, 2]];
       i -= 1;
       Print["tjolahopp"];
       },
      i -= 1;
      ];

     Print[i];
     Print["loop round done"]
     };
     knapsack
    ]
   }
  ]

no errors now, but I do not know what it does really :)

Nasser
  • 12,849
  • 6
  • 52
  • 104