2016-10-03 153 views
1

我有一個數字列表,例如:{1,2,3,4,5,6}如何比數組中的其他隨機數生成一個隨機數?

我想隨機生成這些數字,我這樣做是這樣的:

void Update(){ 
    float ran = Random.Range(1,6); 
    print(ran); 
} 

如何生成或打印3比其他數字嗎?

+0

我不喜歡沒有你想做的事情。請詳細解釋預期產出會是多少。 –

+2

例如: 隨機。範圍將打印3,1,5,2,4,6,1,3,2,5,2,5,6現在我想打印(3)比其他數字更多像2,3,3,4,3 ,3,3,3,3,4,3,3,5,3,3 – Neman

+0

Unity3D中不需要方法名稱後面的(),如Update()? – Bouke

回答

8

如果你想傾斜分配就可以了,比如說,生成的地圖值所需的分佈

// all 1..6 are equal with exception of 3 which appears more frequently 
// 1..2, 4..6 - 10% each (1 occurence per 10 items) 
// 3   - 50%  (5 occurences per 10 items) 
private static int[] map = new int[1, 2, 3, 4, 5, 6, 3, 3, 3, 3]; 

... 

void Update{ 
    float ran = map[Random.Range(map.Length)]; 
    print(ran); 
} 
+0

謝謝工程:) – Neman

+0

@Dmitry Bychenko但你的答案使用像'集合{1,2​​,3,4,5,6,3,3,3,3}'和問題給出了類似'{1例,2,3,4,5,6}'。 因爲出現的次數較多,所以會打印數字「3」。 我寫了兩個解決方案,它們用'{1,2,3,4,5,6}'形狀列出了一個列表。 –

+0

@Jorge Santos:有很多方法來扭曲最初的分佈,我是最簡單的,我希望很容易維護;確定代碼有一些缺點,例如很難確保'3'出現正好'51.253496%'次。但正如我從問題中看到的那樣 - 「比其他產品更隨機產生一個」 - 事實並非如此。 –

0

這是某種soluton,用概率論,但它的overenginered。它也可以有輕微的語法錯誤,becouse我從現在的Visual Studio(

var data = new float[] {1, 2, 3, 4, 5, 6}; 
var indexToWeight = (index) => { 
    if (index == 3) return 2; 
    return 1; 
}; 
var total = data.Select((value, index) => indexToWeight(index)).Sum(); 
var weightedData = data.Select((value, index) => Tuple.Create(value, indexToWeight(index)/(float)sum)).ToList(); 
var boundedData = new List<Tuple<float, float>>(weightedData.Count); 
float bound = 0.0f; 
for (int i = 0; i < weightedData.Count; i++) { 
    boundedData.Add(Tuple.Create(weightedData[i].Item1, bound)); 
    bound += weightedData[i].Item2; 
} 

var weightedToValue = (List<Tuple<float, float>> wv, float p) => { 
    var pair = wv.FirstOrDefault(item => item.Item2 > p); 
    if (pair != null) return pair.Item1; 
    return vw.Last().Item1; 
}; 
Random random; 
var randomizedData = Enumerable.Range(1, data.Count).Select(index => weightedtoValue(weightedData, random.NextDouble())).ToArray(); 
+0

好的非常感謝:) – Neman

0

設置threeMultiplier爲1的正態分佈,2很遠兩次多個3,3三次以上3的,依此類推。

void Update() { 
    int threeMultiplier = 2; // Twice as much 3's 
    int maxNumber = 6; 
    int num = Random.Range(1, threeMultiplier * maxNumber); 
    if (num > maxNumber) num = 3; 
    print(num); 
} 
0

一個用於 「滾動骰子黑客」 解決方案可以是這樣的: 浮子跑= Random.Range(1,10);

「RAN轉換到int」

switch (ran) 
case 1: 
    return 1 
case 2: 
    return 2 
case 3: 
    return 3 
case 4: 
    return 4 
case 5: 
    return 5 
case 6: 
    return 6 
default: 
    return 3 

所以你將有3爲彼此50分%的機會,和10%,以減少3-S變化10的數量爲較小的值^^

0

檢查這個例子中我在.net小提琴製作。 在這段代碼中你有兩種可能性。我很確定這可以解決你的問題,它是一個非常簡單的解決方案。 當然,在Unity中你可能想使用Random.Range ...改變一些vars yada yada的名字。

1-您可以多次打印列表中的元素,因此具有'n'個元素的列表將始終輸出'n'個數字作爲輸出。

2 - 您可以打印任何ammount的你想要的,只要你改變變量timesToPrint

的代碼將打印基礎上chanceToPrintGoldenNumbergoldenNumber,否則打印列表中的隨機元素(可以是偶然的黃金號碼)。

實例鏈接HERE!

代碼:

public static void Main() 
{ 
    Random rnd = new Random(); 
    var li = new List<int> {1,2,5,3,6,8}; 
    var timesToPrint = 10; 

    var goldenNumber = 3; 

    // this is actually 55% chance, because we generate a number form 0 to 100 and if it is > than 45 we print it... so 55% chance 
    var chanceToPrintGoldenNumber = 45; 


    // Print as many times as there are numbers on the list 

    Console.WriteLine("Printing as many times as there are elements on the list"); 

    foreach(var number in li) 
    {  
     var goldenNumberChance = rnd.Next(0,100); 

     if (goldenNumberChance > chanceToPrintGoldenNumber) // 55% chance to print goldenNumber 
     { 
      Console.WriteLine(goldenNumber);    
     } 
     else 
     {   
      var i = rnd.Next(0,li.Count); 
      Console.WriteLine(li[i]);   
     } 
    } 

    Console.WriteLine("****************** END ***************************"); 

    // Print as many times as the value of your "timesToPrint". 

    Console.WriteLine("Printing as many times as the value on timesToPrint "); 

    for(var i=0; i< timesToPrint; i++) 
    { 
     var goldenNumberChance = rnd.Next(0,100); 

     if (goldenNumberChance > chanceToPrintGoldenNumber) // 55% chance to print goldenNumber 
     { 
      Console.WriteLine(goldenNumber);    
     } 
     else 
     {   
      var n = rnd.Next(0,li.Count); 
      Console.WriteLine(li[n]);   
     } 

    } 

} 
0

我會做這樣的事情的加權分佈:

public class RandomGenerator 
{ 
    Dictionary<Tuple<double, double>, Tuple<int, int>> probability; 
    Random random; 

    public RandomGenerator(Dictionary<double, Tuple<int, int>> weights) 
    { 
     random = new Random(); 

     Dictionary<double, Tuple<int, int>> percent = weights.Select(x => new { Key = x.Key/weights.Keys.Sum(), Value = x.Value }).ToDictionary(t => t.Key, t => t.Value); 
     probability = new Dictionary<Tuple<double, double>, Tuple<int, int>>(); 
     double last = 0; 
     foreach (var item in percent.OrderBy(x => x.Key).Select(x => new { Key = x.Key, Value = x.Value })) 
     { 
      probability.Add(new Tuple<double, double>(last, last + item.Key), item.Value); 
      last += item.Key; 
     } 
    } 

    public double GetRandomNumber() 
    { 
     double w = random.NextDouble(); 

     var range = probability.Where(x => w >= x.Key.Item1 && w <= x.Key.Item2).First().Value; 

     return random.Next(range.Item1, range.Item2); 
    } 
} 

而且你可以使用這樣的:

Dictionary<double, Tuple<int, int>> weights = new Dictionary<double, Tuple<int, int>>(); 
weights.Add(80, new Tuple<int, int>(1, 100)); 
weights.Add(20, new Tuple<int, int>(3,3)); 

var randgen = new RandomGenerator(weights); 
var number = randgen.GetRandomNumber();