Loren on the Art of MATLAB

Turn ideas into MATLAB

Note

Loren on the Art of MATLAB has been archived and will not be updated.

Reordering Arrays

There are some cases, particularly simulations, in which we need to choose a few items from a finite list. A friend mentioned to me that he was doing a Monte Carlo simulation for a card game and wanted to deal out some card hands. It was easier for him to look at the hands if the cards were ordered so they were listed with the hands with the smallest high values were first on the list. As you can imagine, there are lots of ways to do this in MATLAB, and some take longer than others. Also, there are some variants on how to order the hands based on the lowest or intermediate cards, once the highest ones are duly sorted. Why does this matter? For my friend, the right ordering reduced his simulation times from 40 hours (so many hands!) to 15 hours, a 60% savings in time.

Contents

Deal Some Cards

Let's find out all the card combinations taking 3 cards at a time and look at the first few.

hands3 = nchoosek(1:52,3);
hands3(1:10,:)
ans =
     1     2     3
     1     2     4
     1     2     5
     1     2     6
     1     2     7
     1     2     8
     1     2     9
     1     2    10
     1     2    11
     1     2    12

Reorder Cards by Lowest High Value

Let's first try 3 different ways to reorder the cards, using

handsr = rot90(hands3,2);
handsr(1:8,:)
ans =
    52    51    50
    52    51    49
    52    50    49
    51    50    49
    52    51    48
    52    50    48
    51    50    48
    52    49    48

These values start with the high ones, so let's transform our deck.

hands3t = 53-hands3;
tic
handsr = rot90(hands3t,2);
toc
handsr(1:8,:)
Elapsed time is 0.000998 seconds.
ans =
     1     2     3
     1     2     4
     1     3     4
     2     3     4
     1     2     5
     1     3     5
     2     3     5
     1     4     5
tic
handsff = flipud(fliplr(hands3t));
toc
handsff(1:8,:)
Elapsed time is 0.002005 seconds.
ans =
     1     2     3
     1     2     4
     1     3     4
     2     3     4
     1     2     5
     1     3     5
     2     3     5
     1     4     5
tic
handsind = hands3t(end:-1:1,end:-1:1);
toc
handsind(1:8,:)
Elapsed time is 0.000973 seconds.
ans =
     1     2     3
     1     2     4
     1     3     4
     2     3     4
     1     2     5
     1     3     5
     2     3     5
     1     4     5
sameOrder = isequal(handsr, handsff, handsind)
sameOrder =
     1

Another Ordering

You can use sortrows to reorder the data as well.

tic
handsort = sortrows(hands3,3);
toc
handsort(1:8,:)
isequal(handsort, handsr)
Elapsed time is 0.013555 seconds.
ans =
     1     2     3
     1     2     4
     1     3     4
     2     3     4
     1     2     5
     1     3     5
     1     4     5
     2     3     5
ans =
     0

Notice in this case that although the last column is sorted the same as the others, the first two columns come in a different ordering. Plus, I didn't have to do the first transformation of 53-cardvalue. It's not until the 7th row that we can see the difference.

[handsr(7:8,1:3) handsort(7:8,1:3)]
ans =
     2     3     5     1     4     5
     1     4     5     2     3     5

How many rows differ?

sum(any(handsr-handsort,2))
ans =
       21832

Lots of them!

Your Ordering Ideas

Do you need to order data for your work? What are some of the tips you can pass along? Add them here.




Published with MATLAB® 7.4


  • print