6 views (last 30 days)

Show older comments

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.

Titus Edelhofer
on 3 Sep 2018

Edited: Titus Edelhofer
on 4 Sep 2018

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

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.

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.

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!