我在C#中創建了一個遊戲,並且遊戲的關鍵部分是隨機性。它本質上是一個摔跤模擬器,根據許多因素(如摔跤手屬性和當前動量)在桌面上選擇「移動」。C中的隨機加權#
然後在匹配這個標準的所有移動中,隨機選擇一個使用Random對象和Skip/Take在LINQ中執行,但這實際上還不夠。我想要做的是選擇重量移動概率(我已經在移動表上爲此列設置了一個1到100之間的整數)。我如何將這個權重應用到我的隨機行選擇中?
我在C#中創建了一個遊戲,並且遊戲的關鍵部分是隨機性。它本質上是一個摔跤模擬器,根據許多因素(如摔跤手屬性和當前動量)在桌面上選擇「移動」。C中的隨機加權#
然後在匹配這個標準的所有移動中,隨機選擇一個使用Random對象和Skip/Take在LINQ中執行,但這實際上還不夠。我想要做的是選擇重量移動概率(我已經在移動表上爲此列設置了一個1到100之間的整數)。我如何將這個權重應用到我的隨機行選擇中?
這不是太困難。我沒有任何代碼可以使用,所以我假設你有一個對象Move
,其中一個屬性Weight
在一個數組中,所有權重總和爲100.0(真的不重要)。 現在你按權重降序對數組進行排序,選擇一個介於0到99之間的隨機數,並遍歷所有這些減少你的隨機數。只要它不積極了,那麼你停下來挑當前索引/移動
var value = rnd.NextDouble()*100.0;
foreach(var move in moves.OrderByDescending(m => m.Weight))
{
value -= move.Weight;
if (value <= 0) return move;
}
當然,你可以緩存排序,甚至選秀權成一個大的數組,並使用一個隨機指數這個(性能)但是我希望這個原理應該是清楚的。
正如喬治建議 - 這裏是一個版本,在那裏你可以下降到假設權重之和高達100:
double _weightSum;
...
// initialize the Sum somewhere
_weightSum = moves.SumBy(m => m.Weight);
Move GetRandomMove()
{
var value = rnd.NextDouble()*weightSum;
foreach(var move in moves.OrderByDescending(m => m.Weight))
{
value -= move.Weight;
if (value <= 0) return move;
}
}
某些代碼會對我理解你的需求有幫助,但我建議使用隨機.NET庫函數。有些文檔可以在這裏找到:
http://msdn.microsoft.com/en-us/library/system.random.aspx
這個例子產生5個隨機整數
Random rand = new Random();
Console.WriteLine("Five random integer values:");
for (int ctr = 0; ctr <= 4; ctr++)
Console.Write("{0,15:N0}", rand.Next());
Console.WriteLine();
這將與當前時間播種它,使其「更隨機」。如果你想要可重複的測試,你可以在測試的時候用一個常量進行播種。
加起每個可能移動的總重量。
除以每一個總數,所以你已經將範圍歸一化爲0..1。
獲得該範圍內的隨機數。爲每次移動選擇一致的順序,並選擇隨機數字所在的順序。
我看着基本上是做同樣的事情,卡斯滕,但使用LINQ。
給出的舉動是招式集合每個
public Move PickRandomMove()
{
var allMovesWeight = moves.Sum(m => m.Weight);
// pick a unit of weight at random, then shift it along by the weight of the
// first move so that there will always be an element in the TakeWhile results
var randomPick = new Random().Next(0, allMovesWeight) + moves.First().Weight;
return moves.TakeWhile(move => (randomPick -= move.Weight) > 0).Last();
}
我懷疑有表達TakeWhile是如何工作的更明確的方式,但希望你的想法
他應該重的整數屬性請注意,每次隨着可用移動次數的變化,100將不會相同。 –
請閱讀 - 權重應該總計爲100 - 如果他們不需要按照您的建議進行標準化步驟。 – Carsten
對不起,我沒有讀過,我認爲它可能會改變代碼做2快速的總和,所以它作爲一個工作樣本。 –