下面摘錄洗牌號碼,並在每執行改變號碼的順序:隨機數和生成數字的相同順序在每個執行
Enumerable.Range(1, 1000).OrderBy(r => Guid.NewGuid()).ToList();
,但我想洗牌的數字和在每次執行生成號碼相同的序列應用?
下面摘錄洗牌號碼,並在每執行改變號碼的順序:隨機數和生成數字的相同順序在每個執行
Enumerable.Range(1, 1000).OrderBy(r => Guid.NewGuid()).ToList();
,但我想洗牌的數字和在每次執行生成號碼相同的序列應用?
使用像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));
不錯!我發誓我在我的小擴展庫中有完全相同的代碼。 – itsme86
這是不是破壞了隨機排列數字的目的? – Amy
生成一次並硬編碼結果。或者使用'Enumerable.Range(1,1000).ToArray()'。這是一個合理的,儘管不太可能的隨機排序。 –
請勿使用GUID進行隨機播放。使用Random對象進行混洗並使用相同的種子初始化對象。 – itsme86