2017-06-12 63 views
0

下面摘錄洗牌號碼,並在每執行改變號碼的順序:隨機數和生成數字的相同順序在每個執行

Enumerable.Range(1, 1000).OrderBy(r => Guid.NewGuid()).ToList(); 

,但我想洗牌的數字和在每次執行生成號碼相同的序列應用?

+5

這是不是破壞了隨機排列數字的目的? – Amy

+0

生成一次並硬編碼結果。或者使用'Enumerable.Range(1,1000).ToArray()'。這是一個合理的,儘管不太可能的隨機排序。 –

+2

請勿使用GUID進行隨機播放。使用Random對象進行混洗並使用相同的種子初始化對象。 – itsme86

回答

5

使用像Fisher-Yates shuffle這樣的算法對項目進行重新排序會更高效。 OrderBy的運行時複雜度爲O(N log N),而Fisher-Yates shuffle爲O(N)

此外,爲了提供隨機數,您應該使用Random類,而不是Guid.NewGuid,它提供了完全不同的用途,並且恰好創建了隨機(成本更高)的東西。

我更願意執行洗牌作爲擴展方法:

public static class ListExtensions 
{ 
    public static IList<T> Shuffle<T>(this IList<T> list, Random random) 
    { 
     for (var i = list.Count; i > 1; i -= 1) 
     { 
      var j = random.Next(i); 
      var temp = list[j]; 
      list[j] = list[i - 1]; 
      list[i - 1] = temp; 
     } 
     return list; 
    } 
} 

可以通過提供一個Random實例與種子特異性(在這種情況下爲0)達到所期望的結果。這將確保每次執行代碼時產生的隨機數序列是相同的:

var shuffledList = Enumerable.Range(0, 1000).ToList().Shuffle(new Random(0)); 
+0

不錯!我發誓我在我的小擴展庫中有完全相同的代碼。 – itsme86

3

而不是使用的O(N log n)的排序重新洗牌(別提產生Guid值的開銷),你應該使用Random和標準爲O(n)Fisher - Yatesshuffle。然後你可以在每次執行時給Random對象一樣的種子。

相關問題