2016-10-03 118 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();