I need to randomize a list.
randomizeList = Function({List}, {Default Local},
//Code goes here
return List;
);
list = {1,2,3,4,5};
randomList = randomizeList(list);
print(randomList); //Expected output something like {2,4,5,1,3}
There are lots of ways to do this and no wrong answer. I appreciate any feedback, thanks!
Yet another way....
// Philip Brown Jul 14, 2016 9:50 AM
phil_randomizeList =Function({aList},{Default Local},
aList[rank( Repeat({random uniform()}, nitems(aList) ) )]
);
The code below compares the four algorithms. Data is stored in a table and then graphed. I'm curious what this looks like in JMP 13?
// pmroz version
pmroz_randomizeList = Function({aList}, {Default Local},
nr = nitems(aList);
dt = New Table( "", private, Add Rows( nr ),
New Column( "Data", Numeric, Continuous, Format( "Best", 12 ),
Set Values( aList ) ),
New Column( "Randomized", Numeric, Continuous, Format( "Best", 12 ),
Formula( Random Uniform() ) )
);
dt << sort(replace table, by(:Randomized));
random_list = dt:Data << get values;
);
// Jeff Perkinson Jul 13, 2016 2:00 PM (in response to Peter Mroz)
jeff_randomizeList =Function({aList},{Default Local},
aList[rank(j(nitems(aList), 1, random uniform()))]
);
// Byron's function
byron_randomizeList = Function({aList},{Default Local},
nr = nitems(alist);
rslist = random shuffle(1::nr);
blist = alist[rslist[1::nr]];
);
// Philip Brown Jul 14, 2016 9:50 AM
phil_randomizeList =Function({aList},{Default Local},
aList[rank( Repeat({random uniform()}, nitems(aList) ) )]
);
nlist = {100, 1000, 10000, 20000, 30000, 40000, 50000, 70000};
dt = new table("Randomize List", Add Rows( nitems(nlist) ),
New Column( "N Items", Numeric, Continuous, Format( "Best", 12 ) ),
New Column( "pmroz", Numeric, Continuous, Format( "Best", 12 ) ),
New Column( "Jeff", Numeric, Continuous, Format( "Best", 12 ) ),
New Column( "Byron", Numeric, Continuous, Format( "Best", 12 ) ),
New Column( "Phil", Numeric, Continuous, Format( "Best", 12 ) )
);
for (i = 1, i <= nitems(nlist), i++,
nm = nlist[i];
dt:N Items[i] = nm;
my_list = (as list(1::nm))[1];
start = tick seconds();
randomList = pmroz_randomizeList(my_list);
elapsed = tick seconds() - start;
dt:pmroz[i] = elapsed;
wait(0);
start = tick seconds();
randomList = jeff_randomizeList(my_list);
elapsed = tick seconds() - start;
dt:Jeff[i] = elapsed;
wait(0);
start = tick seconds();
randomList = byron_randomizeList(my_list);
elapsed = tick seconds() - start;
dt:Byron[i] = elapsed;
wait(0);
start = tick seconds();
randomList = phil_randomizeList(my_list);
elapsed = tick seconds() - start;
dt:Phil[i] = elapsed;
wait(0);
);
dt << Graph Builder( Show Control Panel( 0 ),
Variables( X( :N Items ), Y( :pmroz ), Y( :Jeff, Position( 1 ) ), Y( :Byron, Position( 1 ) ),
Y( :Phil, Position( 1 ) ) ),
Elements( Points( X, Y( 1 ), Y( 2 ), Y( 3 ), Y( 4 ), Legend( 1 ), Jitter( 1 ) ),
Smoother( X, Y( 1 ), Y( 2 ), Y( 3 ), Y( 4 ), Legend( 2 ) ) )
);
I increased the list sizes to help differentiate a little better, although the differences between methods aren't that big. What is surprising is the time differences between the results above and these. Also, it seems weird that pmroz's method is slower with 100 rows than with 10000. Maybe its due to repeating the task of making the table?
JMP 13 beta 8
Mac 2.5 GHz Intel Core i7
16 GB 1600 MHz DDR3
N Items | pmroz | Jeff | Byron | Phil |
100 | 0.1833333333 | 0 | 0 | 0 |
1000 | 0 | 0 | 0 | 0 |
10000 | 0.0166666667 | 0 | 0 | 0 |
50000 | 0.05 | 0.0166666667 | 0 | 0.0166666667 |
100000 | 0.1 | 0.0333333333 | 0.0333333333 | 0.0333333333 |
500000 | 0.6 | 0.2333333333 | 0.1666666667 | 0.2666666667 |
1000000 | 1.3166666667 | 0.5166666667 | 0.3666666667 | 0.5666666667 |
10000000 | 17.633333333 | 6.1833333333 | 4.3 | 7.15 |
love the straight lines; the N^2 behavior for lists is fixed!