轮盘赌的弱点在随机数选择
本文关键字:随机数 选择 弱点 | 更新日期: 2023-09-27 18:09:20
我正在研究一个轮盘赌轮盘类,它的功能或多或少像一个普通的轮盘赌轮盘,其中某些数字可以占据轮盘赌轮盘的更大一部分,因此有更高的被选中的可能性。
到目前为止,它已经通过了更基本的单元测试,也就是说,从编程上讲,它可以工作,我可以创建一个轮盘赌轮盘,并用一堆通用值填充它,它就会这样做。
然而,当谈到我的概率测试时,我决定将其作为一个6面骰子进行试验,在1000万次试验后,它应该产生大约3,5的平均骰子掷出不幸的是,它甚至没有接近1000万次试验后的平均骰子掷出大约2,9,所以我猜我的数字选择有弱点?我在下面张贴了单元测试和实际代码:
public class RouletteNumber<T>
{
public readonly T Number;
public readonly int Size;
public RouletteNumber(T number, int size)
{
this.Number = number;
this.Size = size;
}
public static RouletteNumber<T>[] CreateRange(Tuple<T, int>[] entries)
{
var rouletteNumbers = new RouletteNumber<T>[entries.Length];
for (int i = 0; i < entries.Length; i++)
{
rouletteNumbers[i] = new RouletteNumber<T>(entries[i].Item1, entries[i].Item2);
}
return rouletteNumbers;
}
}
public class RouletteWheel<T>
{
private int size;
private RouletteNumber<T>[] numbers;
private Random rng;
public RouletteWheel(params RouletteNumber<T>[] rouletteNumbers)
{
size = rouletteNumbers.Length;
numbers = rouletteNumbers;
rng = new Random();
//Check if the roulette number sizes match the size of the wheel
if (numbers.Sum(n => n.Size) != size)
{
throw new Exception("The roulette number sections are larger or smaller than the size of the wheel!");
}
}
public T Spin()
{
// Keep spinning until we've returned a number
while (true)
{
foreach (var entry in numbers)
{
if (entry.Size > rng.Next(size))
{
return entry.Number;
}
}
}
}
}
[TestMethod]
public void DiceRouletteWheelTest()
{
double expected = 3.50;
var entries = new Tuple<int, int>[]
{
Tuple.Create(1, 1),
Tuple.Create(2, 1),
Tuple.Create(3, 1),
Tuple.Create(4, 1),
Tuple.Create(5, 1),
Tuple.Create(6, 1)
};
var rouletteWheel = new RouletteWheel<int>(RouletteNumber<int>.CreateRange(entries));
var results = new List<int>();
for (int i = 0; i < 10000000; i++)
{
results.Add(rouletteWheel.Spin());
}
double actual = results.Average();
Assert.AreEqual(expected, actual);
}
}
当您调用Random.Next(n)
时,它生成一个介于0和n-1之间的随机数,而不是介于0和n之间。
你解释了吗?
实际上对于一个六面骰子,你会想调用Random.Next(1, 7)
也许我没有正确理解它,但我猜问题在于这里:
while (true)
{
foreach (var entry in numbers)
{
if (entry.Size > rng.Next(size))
{
return entry.Number;
}
}
}
你在计算rng。接下来每次你做if检查。第一个数字被抽中的概率是1/6。第2号(数字中的下一个条目)有2/6的机会被取走(一个新数字在1和6之间呈现)。但是因为你总是从第一个开始,你最终会有更多的低数字。我也不认为在普通的随机生成器中需要while(真的)。我猜这可能会工作,看起来像你当前的代码:
var rndValue = rng.Next(size);
foreach (var entry in numbers)
{
if (entry.Size > rndValue)
{
return entry.Number;
}
}