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.
Get
the MATLAB code
Published with MATLAB® 7.4



Am I missing something, or is the duplication in your calculations of handsr and handff a mistake? Did you mean to write the following?
tic
handsr = rot90(hands3t,2)
toc
Steve-
Good catch and sorry about that. I have updated the blog to show the right version now.
–Loren
Hi Loren,
I’m mightily confused as to how using rot90 is sorting the array so that the cards with the lowest high value are coming up first. Doesn’t rot90(X,2) just flip the array by 180 degrees, preserving the order of the rows? Likewise the flip-flip method seems to do the same thing. Where is the re-ordering occurring?
-Dan
Dan-
Flipping IS reordering. It’s not deeper than that.
–Loren
Loren,
To make sure I am understanding. This analysis will then only work in the specific case where the rows are already in order, just backwards. These approaches don’t act to order the data in terms of lowest high value first, that was already done (albeit backwards) by nchoosek. Is this correct?
Dan
Dan-
The flipping will work if the data came from nchoosek. It won’t always work. I’m just trying to point people to various tools.
–Loren
Loren,
I’m trying to run a simulation in which a vector needs to be reordered randomly during each iteration of the simulation. I’ve looked up MATLAB’s help documentation, and can’t seem to find anything.
To give you an example:
A = [1.2 3.8 5.7 90 63.7 88.65] and I need to pick 3 numbers from the array randomly without replacement. I’d like to randomly reorder the array and pick the first 3 each time. Is there a built-in function to accomplish the randomising part? Also, is this the most efficient way to do it?
Navaneethan
Navaneethan-
Take a look at the function randperm. I think it will do what you need. Something like this:
and repeat the last 2 lines as often as you need.
–Loren
Loren,
Thank you for the prompt response! I tried your idea out. However, randperm works only on integers, and consequently all values in the vector n are approximated to the nearest integer. Any other thoughts?
Navaneethan
Use the values as indices into A.
–Loren
Thanks a lot, Loren! That worked perfectly.