Search code examples
arraysmatlabmatrixcellcombinations

How to structure a cell to store values in a specific format in Matlab?


I have a code that looks for the best combination between two arrays that are less than a specific value. The code only uses one value from each row of array B at a time.

B =
       1           2           3
      10          20          30
     100         200         300
    1000        2000        3000

and the code i'm using is :

B=[1 2 3; 10 20 30 ; 100 200 300 ; 1000 2000 3000];
A=[100; 500; 300 ; 425];
SA = sum(A);
V={}; % number of rows for cell V = num of combinations -- column = 1                
n = 1;
for k = 1:length(B)                    
    for idx = nchoosek(1:numel(B), k)'  
       rows = mod(idx, length(B));
       if ~isequal(rows, unique(rows)) %if rows not equal to unique(rows)
           continue  %combination possibility valid      
       end %Ignore the combination if there are two elements from the same row 
       B_subset = B(idx);
       if (SA + sum(B_subset) <= 2000) %if sum of A + (combination) < 2000
           V(n,1) = {B_subset(:)}; %iterate cell V with possible combinations
           n = n + 1;
        end
    end
end

However, I would like to display results differently than how this code stores them in a cell.

Instead of displaying results in cell V such as :

[1]
[10]
[300]
[10;200]
[1000;30]
[1;10;300]

This is preferred : (each row X column takes a specific position in the cell) Here, this means that they should be arranged as cell(1,1)={[B(1,x),B(2,y),B(3,z),B(4,w)]}. Where x y z w are the columns with chosen values. So that the displayed output is :

[1;0;0;0]
[0;10;0;0]
[0;0;300;0]
[0;10;200;0]
[0;30;0;1000]
[1;10;300;0]

In each answer, the combination is determined by choosing a value from the 1st to 4th row of matrix B. Each row has 3 columns, and only one value from each row can be chosen at once. However, if for example B(1,2) cannot be used, it will be replaced with a zero. e.g. if row 1 of B cannot be used, then B(1,1:3) will be a single 0. And the result will be [0;x;y;z].

  • So, if 2 is chosen from the 1st row, and 20 is chosen from the 2nd row, while the 3rd and 4th rows are NOT included, they should show a 0. So the answer would be [2;20;0;0].
  • If only the 4th row is used (such as 1000 for example), the answer should be [0;0;0;1000]

In summary I want to implement the following :

  • Each cell contains length(B) values from every row of B (based on the combination)
  • Each value not used for the combination should be a 0 and printed in the cell

I am currently trying to implement this but my methods are not working .. If you require more info, please let me know.

edit

I have tried to implement the code in the dfb's answer below but having difficulties, please take a look at the answer as it contains half of the solution.


Solution

  • My MATLAB is super rusty, but doesn't something like this do what you need?

    arr =  zeros(1,len(B))
    arr(idx) = B_subset(:)
    V(n,1) = {arr}