Asked by bryan
on 2 Sep 2018

Hi all, I have a problem where I am generating the combinations of people from one group with the people in another group. Each person comes with a name obviously and a Score which is of particular interest. In order to make the combinations fair, the combined scores cannot exceed a maximum value.

NameA='bob'

ScoreA=1000

A={NameA, ScoreA}

NameB='mike'

ScoreB=2000

B={NameB, ScoreB}

GROUP1={'A','B'}

NameC='harry'

ScoreC=500

C={NameC, ScoreC}

NameD='TED'

ScoreD=100

D={NameD, ScoreD}

GROUP2={'C', 'D'}

GROUPS={GROUP1 GROUP2}

[x y] = ndgrid(GROUPS{:})

GROUPScombs = [x(:) y(:)]

GROUPScombs yields 4x2 cell array 4×2 cell array

{'A'} {'C'}

{'B'} {'C'}

{'A'} {'D'}

{'B'} {'D'}

Now at this point I have generated the total combinations but I want to delete the rows where the combined scores are over 2000. So for example Score A + Score C = 1500, so row 1 is good. However, score B+C=2500 which is over 2000 so I would like to delete that row. Not sure how to use MATLAB to easily perform this calculation. Row 3 is good and Row 4 should be eliminated. Thank you.

Answer by Titus Edelhofer
on 3 Sep 2018

Edited by Titus Edelhofer
on 4 Sep 2018

Accepted Answer

Hi,

things get much easier, if you use arrays instead of individual variable names:

% combine names and scores into a table

t = table({'bob'; 'mike'; 'harry'; 'TED'}, [1000 2000 500 100]', ...

'VariableNames', {'Name', 'Score'});

% define your (sub-)groups as you did

groups1 = 1:2;

groups2 = 3:4;

[x,y] = ndgrid(groups1, groups2);

GROUPScombs = [x(:) y(:)]

% now grab from the table the scores as in your combinations:

scores = reshape(t{GROUPScombs, 'Score'}, size(GROUPScombs));

% sum the two columns

scoresSum = sum(scores, 2);

% and select

alledCombs = GROUPScombs(scoresSum<=2000, :)

% and get the corresponding names:

alledNames = reshape(t{alledCombs, 'Name'}, size(alledCombs))

Titus

bryan
on 4 Sep 2018

Titus Edelhofer
on 4 Sep 2018

Added one line to retrieve the names ...

Sign in to comment.

Answer by MF
on 3 Sep 2018

This is definitely not the most optimal solution, but it works. Firstly, create a matrix of scores that correspond to each person in GROUPScombs cell array.

for i = 1:size(GROUPScombs,1)

for j = 1:size(GROUPScombs,2)

if GROUPScombs{i,j}=='A'

RESULTScombs(i,j)=1000;

elseif GROUPScombs{i,j}=='B'

RESULTScombs(i,j)=2000;

elseif GROUPScombs{i,j}=='C'

RESULTScombs(i,j)=500;

else

RESULTScombs(i,j)=100;

end

end

end

Sum the results row-wise.

sumResults=sum(RESULTScombs,2)

Keep only the pairs, whose scores sum is equal to or lower than 1500.

GROUPScombsNew=GROUPScombs(find(sumResults<=1500),:)

Hope this helps.

bryan
on 4 Sep 2018

MF
on 4 Sep 2018

Here is the solution. Again, not optimal, but it works. Loop through all the entries in alledCombs, transform the numbers to the corresponding names and then write them in a cell alledCombs2. Please note that j index refers to columns and index i to the rows of the alledCombs matrix.

k=1

for j=1:size(alledCombs,2)

for i=1:size(alledCombs,1)

alledCombs2{k}=t.Name{alledCombs(i,j)}

k=k+1;

end

end

Please do not forget to accept the answer by Titus/me, if you think that your question was answered properly.

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 1 Comment

## Stephen Cobeldick (view profile)

## Direct link to this comment

https://ch.mathworks.com/matlabcentral/answers/417207-how-to-delete-rows-from-a-cell-array-that-do-not-satisfy-a-certain-condition#comment_605910

Sign in to comment.