2010-08-12 5 views

ответ

5

Если у вас нет [] .shuffle, [] .sort_by {рэнд} работает как указал sepp2k. .sort_by временно заменяет каждый элемент чем-то с целью сортировки, в данном случае случайного числа.

[] .sort {rand-0.5} однако не будет правильно перемещаться. Некоторые языки (например, некоторые реализации Javascript) неправильно перетасовывают массивы, если вы делаете случайный сортировку в массиве, причем иногда довольно публичные последствия.

JS Анализ (с графиками!): http://www.robweir.com/blog/2010/02/microsoft-random-browser-ballot.html

рубин ничем не отличается! У этой проблемы есть та же проблема. :)

#sort a bunch of small arrays by rand-0.5 
a=[] 
100000.times{a << [0,1,2,3,4].sort{rand-0.5}} 

#count how many times each number occurs in each position 
b=[] 
a.each do |x| 
    x.each_index do |i| 
     b[i] ||=[] 
     b[i][x[i]] ||= 0 
     b[i][x[i]] += 1 
    end 
end 
p b 

=>

[[22336, 18872, 14814, 21645, 22333], 
[17827, 25005, 20418, 18932, 17818], 
[19665, 15726, 29575, 15522, 19512], 
[18075, 18785, 20283, 24931, 17926], 
[22097, 21612, 14910, 18970, 22411]] 

Каждый элемент должен происходить в каждом положении около 20000 раз. [] .sort_by (rand) дает гораздо лучшие результаты.

#sort with elements first mapped to random numbers 
a=[] 
100000.times{a << [0,1,2,3,4].sort_by{rand}} 

#count how many times each number occurs in each position 
... 

=>

[[19913, 20074, 20148, 19974, 19891], 
[19975, 19918, 20024, 20030, 20053], 
[20028, 20061, 19914, 20088, 19909], 
[20099, 19882, 19871, 19965, 20183], 
[19985, 20065, 20043, 19943, 19964]] 

Аналогично для [] .shuffle (который, вероятно, самый быстрый)

[[20011, 19881, 20222, 19961, 19925], 
[19966, 20199, 20015, 19880, 19940], 
[20062, 19894, 20065, 19965, 20014], 
[19970, 20064, 19851, 20043, 20072], 
[19991, 19962, 19847, 20151, 20049]] 
16

array.shuffle

+0

следует, что работа в 1.8? – BuddyJoe

+0

Кажется, что в массиве 1.8.7, но не 1.8.6 или ранее. [1,2,3,4,5]. Shuffle отлично работает для меня в 1.8.7. –

+1

В 1.8.6 вы можете получить перетасовку из backports или просто использовать '.sort_by {rand}' (если вы можете жить с тем, что это O (n log n)). – sepp2k

1

Что об этом?

Вспомогательные методы для перечисляемого, массива, хэша и строки , которые позволяют вам выбрать случайный элемент или перетасовать порядок элементов.

http://raa.ruby-lang.org/project/rand/