Today I used the python’s API shuffle(random.shuffle) to resort a list and I am wondering the related algorithm so I find some materials。
Fisher-Yates shuffle
- Write down the numbers from 1 through N.
- Pick a random number k between one and the number of unstruck numbers remaining (inclusive).
- Counting from the low end, strike out the kth number not yet struck out, and write it down elsewhere.
- Repeat from step 2 until all the numbers have been struck out.
- The sequence of numbers written down in step 3 is now a random permutation of the original numbers.
import random
def my_shuffle(sorted_list):
result = []
while sorted_list:
index = random.randrange(0,len(sorted_list))
result.append(sorted_list[index])
del(sorted_list[index])
return result
if __name__ == '__main__':
a = [1,2,3,4,5]
print(my_shuffle(a))
Knuth-Durstenfeld Shuffle
traverse the list, for each index i choose another one in the range(i+1,len(list)) and exchange the value
def knuth_shuffle(sorted_list):
for i in range(0,len(sorted_list)-1):
index = random.randrange(i+1,len(sorted_list))
sorted_list[i],sorted_list[index] = sorted_list[index],sorted_list[i]
return sorted_list
if __name__ == '__main__':
a = [1,2,3,4,5]
print(knuth_shuffle(a))
Inside-Out Algorithm
similar to Knuth-Durstenfeld Shuffle
#Inside-Out Algorithm
def shuffle(lis):
result = lis[:]
for i in range(1, len(lis)):
j = random.randrange(0, i)
result[i] = result[j]
result[j] = lis[i]
return result
r = shuffle([1, 2, 2, 3, 3, 4, 5, 10])
print(r)
The python’s random.shuffle:
def shuffle(self, x, random=None):
"""Shuffle list x in place, and return None.
Optional argument random is a 0-argument function returning a
random float in [0.0, 1.0); if it is the default None, the
standard random.random will be used.
"""
if random is None:
randbelow = self._randbelow
for i in reversed(range(1, len(x))):
# pick an element in x[:i+1] with which to exchange x[i]
j = randbelow(i+1)
x[i], x[j] = x[j], x[i]
else:
_int = int
for i in reversed(range(1, len(x))):
# pick an element in x[:i+1] with which to exchange x[i]
j = _int(random() * (i+1))
x[i], x[j] = x[j], x[i]