在所有示例中,RNG 是从 NET Random 类创建的随机数生成器:
Private RNG = New Random()
灵巧
如果您只需要两个或三个,您可以循环直到当前选择不在结果集中。但是使用一些扩展方法会更简单:
Dim nums = Enumerable.Range(1, 10).
OrderBy(Function(r) RNG.Next).
Take(3).
ToArray()
这从 1 到 10 之间的所有数字开始,将它们按随机顺序排列,取前 3 个并将它们存储在 nums 数组中。我使用了多行形式,在.s 之后打破以说明这些步骤。
只需根据需要更改范围、大小/计数和Take() 元素。例如,对于具有 5 个唯一数字 1-69(精简形式)的彩票:
Dim winners = Enumerable.Range(1, 69).OrderBy(Function(r) RNG.Next()).Take(5).ToArray()
Dim powerball = Enumerable.Range(1, 26).OrderBy(Function(r) RNG.Next()).Take(1).First
由于强力球可以重复第一个数字,它来自自己的池。由于我们只需要一个,因此我们不需要数组,只需 First()。
手动
了解这些事情的逻辑很好,所以这里显示的是手动版本。通过选择并实际检查随机值,这样做的方式不同:
' picked value storage
Dim picks As New List(Of Int32)
Dim pick As Int32 ' current candidate
Do
pick = RNG.Next(1, 11)
If picks.Contains(pick) = False Then
picks.Add(pick)
End If
Loop Until picks.Count = 3
而不是松散的变量,它使用一个列表来保存选择。这样可以很容易地查看当前选择是否已被选中。对于不仅仅是几个值,请使用 HashSet(Of Int32) 而不是 List 以提高性能。
随机对
要创建一个随机的组个数字,每个数字有 2 个,例如对于匹配游戏,只需将基础值池加倍,然后将它们按随机顺序排列:
' create pool of 2 values each for 1-13
Dim nums = Enumerable.Range(1, 13).ToArray()
' concat the set to make 2 of each value, randomize
Dim pool = nums.Concat(nums).OrderBy(Function(r) RNG.Next).ToArray()
对于手动方法,您必须检查循环中每个值的计数。
“用完”精选
另一种变化是当您需要定期使用随机数池时,但您不知道提前需要多少。例如 BINGO 游戏的球或一副纸牌。
Stack(Of T)(或Queue)将根据您的需要“使用”值,而不是指向使用的最后一个插槽(或下一个要使用的插槽)的全局索引器:
' create, randomize pool of 100 ints
Dim nums = Enumerable.Range(1, 100).OrderBy(Function(r) RNG.Next).ToArray
' use array to create Stack<T>
Dim shoe As New Stack(Of Int32)(nums)
' same as:
Dim shoe = New Stack(Of Int32)(Enumerable.Range(1, 100).
OrderBy(Function(r) RNG.Next).ToArray())
这基本上是从 100 个整数开始的,随机化并存储在一个数组中,但是没有 Take(n) 因为我们想要它们全部。然后将它们的值存储在堆栈集合中。使用它:
Console.WriteLine(shoe.Count)
For n As Int32 = 1 To 3
Console.WriteLine("Picked #{0}", shoe.Pop)
Next
Console.WriteLine(shoe.Count)
当您Pop 一个值时,它会自动从集合中删除。如果您使用鞋子中的大量值,则需要检查计数以确保它不为空。
100
选择 #12
已选中 #69
选择 #53
97
绘制3个值后,鞋子只剩下97个值了。
随机笔记
在所有情况下,您的Random 生成器都应该是您创建一次 的表单级对象。切勿在循环中创建它们,否则您可能会一遍又一遍地获得相同的值。
OrderBy(Function(r) RNG.Next) 随机化方法通常对于随意使用来说已经足够了,但它效率低下。如果您将随机化大集合和/或经常使用它,您应该考虑使用适当的随机播放,例如the Fisher-Yates shuffle shown here。