如何比阵列中的其他随机数生成一个随机数?

时间:2016-10-03 12:15:27

标签: c# unity3d

我有一个数字列表,例如:{1,2,3,4,5,6}

我想随机生成这些数字,我这样做是这样的:

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

如何比其他数字生成或打印3个?

6 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:0)

这是使用概率论的某种解决方案,但它是过度工程的。它也可能有轻微的语法错误,因为我现在远离视觉工作室(

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();   

答案 2 :(得分:0)

将3Multiplier设置为1表示正态分布,2表示2次3次,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); 
}

答案 3 :(得分:0)

“滚动骰子黑客”的一个解决方案可能是: float ran = Random.Range(1,10);

“convert ran to 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

所以你将有50%的机会获得3,相互之间有10%的机会将3-s的变化数量减少10变为更小的值^^

答案 4 :(得分:0)

查看我在.Net小提琴中制作的这个例子。 在此代码中,您有两种可能性。 我很确定这可以解决您的问题,这是一个非常简单的解决方案。 当然在Unity中你可能想要使用Random.Range ...更改一些vars yada yada的名字。

1-您可以打印列表中有元素的次数,因此带有'n'个元素的列表将始终打印'n'个数字作为输出。

2-只要更改变量timesToPrint

,就可以打印所需的任何装配

代码将根据goldenNumber打印chanceToPrintGoldenNumber,否则会在列表中打印一个随机元素(可能是偶然的黄金数字)。

示例链接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]);           
        }

    }

}

答案 5 :(得分: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();