洗牌演算法shuffle

2021-09-26 16:11:44 字數 1520 閱讀 9411

原文:

一、fisher–yates shuffle

演算法思想就是從原始陣列中隨機抽取乙個新的數字到新陣列中

#fisher–yates shuffle

''' 1. 從還沒處理的陣列(假如還剩k個)中,隨機產生乙個[0, k]之間的數字p(假設陣列從0開始);

2. 從剩下的k個數中把第p個數取出;

3. 重複步驟2和3直到數字全部取完;

4. 從步驟3取出的數字序列便是乙個打亂了的數列。

'''import random

def shuffle(lis):

result =

while lis:

p = random.randrange(0, len(lis))

lis.pop(p)

return result

r = shuffle([1, 2, 2, 3, 3, 4, 5, 10])

print(r)

二、knuth-durstenfeld shuffle(random.shuffle)

每次從未處理的資料中隨機取出乙個數字,然後把該數字放在陣列的尾部,即陣列尾部存放的是已經處理過的數字。這是乙個原地打亂順序的演算法,演算法時間複雜度也從fisher演算法的o(n2)提公升到了o(n)。

#knuth-durstenfeld shuffle

def shuffle(lis):

for i in range(len(lis) - 1, 0, -1):

p = random.randrange(0, i + 1)

lis[i], lis[p] = lis[p], lis[i]

return lis

r = shuffle([1, 2, 2, 3, 3, 4, 5, 10])

print(r)

三、inside-out algorithm

inside-out algorithm 演算法的基本思想是設一游標i從前向後掃瞄原始資料的拷貝,在[0, i]之間隨機乙個下標j,然後用位置j的元素替換掉位置i的數字,再用原始資料位置i的元素替換掉拷貝資料位置j的元素。其作用相當於在拷貝資料中交換i與j位置處的值。

#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)

01揹包及空間優化:

洗牌演算法shuffle

對這個問題的研究始於一次在群裡看到朋友發的洗牌面試題。當時也不知道具體的解法如何,於是隨口回了一句 每次從剩下的數字中隨機乙個。過後找相關資料了解了下,洗牌演算法大致有3種,按發明時間先後順序如下 一 fisher yates shuffle 演算法思想就是從原始陣列中隨機抽取乙個新的數字到新陣列中...

三種洗牌演算法shuffle

由抽牌 換牌和插牌衍生出三種洗牌演算法,其中抽牌和換牌分別對應fisher yates shuffle和knuth durstenfeld shhuffle演算法。最早提出這個洗牌方法的是 ronald a.fisher 和 frank yates,即 fisher yates shuffle,其基...

go實現陣列切片洗牌函式Shuffle

在深度學習 機器學習中,我們經常會使用到乙個叫shuffle函式,我一般叫打亂函式,也有人叫洗牌函式,就是聽著高階點,它可以幫助我們打亂資料集,那麼在go中我們如何實現乙個呢?大家可以直接使用我寫的乙個工具庫 lodago,有點lodash的味道。對於打亂函式有很多演算法實現,由於我的場景並不需要實...