首先,我做了一个小结构来保存数字和重量百分比。
Structure Weights
Public Sub New(num As Integer, per As Integer)
Number = num
Percent = per
End Sub
Public Number As Integer
Public Percent As Integer
End Structure
然后我填写了一个结构列表。接下来,我遍历 lstWeights 并将数字添加到第二个列表中;根据重量百分比将每个数字添加到前 x 次。
Private Sub BuildWeightedList()
lstWeights.Add(New Weights(10, 2))
lstWeights.Add(New Weights(9, 4))
lstWeights.Add(New Weights(8, 5))
lstWeights.Add(New Weights(7, 8))
lstWeights.Add(New Weights(6, 9))
lstWeights.Add(New Weights(5, 11))
lstWeights.Add(New Weights(4, 13))
lstWeights.Add(New Weights(3, 14))
lstWeights.Add(New Weights(2, 16))
lstWeights.Add(New Weights(1, 18))
'Add digits to lst; each digit is added as many times as it weight
For Each item As Weights In lstWeights
For x As Integer = 1 To item.Percent
lst.Add(item.Number)
Next
Next
End Sub
现在获取随机加权数字 (1-10) 记住有 18 个,a16 个二,14 个三等。生成一个随机索引并获取该索引处的数字。出于测试目的,我将结果添加到另一个列表中。
Private Sub WeightedRandom()
Dim ListCount As Integer = lst.Count
Dim index As Integer = R1.Next(0, ListCount)
Dim d1result1 As Integer = lst(index)
lstResult.Add(d1result1)
End Sub
类级变量:
Private lstWeights As New List(Of Weights)
Private lst As New List(Of Integer)
Private lstResult As New List(Of Integer)
Private R1 As New Random
在表单加载构建第一个列表。 lstWeights
BuildWeightedList()
从按钮调用过程。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For x = 0 To 10000
WeightedRandom()
Next
TestWeighted()
MessageBox.Show("Done")
End Sub
然后我就这样测试了:
Private Sub TestWeighted()
Dim c10, c9, c8, c7, c6, c5, c4, c3, c2, c1 As Integer
For Each x As Integer In lstResult
Select Case x
Case 1
c1 += 1
Case 2
c2 += 1
Case 3
c3 += 1
Case 4
c4 += 1
Case 5
c5 += 1
Case 6
c6 += 1
Case 7
c7 += 1
Case 8
c8 += 1
Case 9
c9 += 1
Case 10
c10 += 1
End Select
Next
Dim divisor As Integer = lstResult.Count
Debug.Print($"1 is {c1 / divisor:P00}, 2 is {c2 / divisor:P00}, 3 is {c3 / divisor:P00}, 4 is {c4 / divisor:P00}, 5 is {c5 / divisor:P00}, 6 is {c6 / divisor:P00}, 7 is {c7 / divisor:P00}, 8 is {c8 / divisor:P00}, 9 is {c9 / divisor:P00}, 10 is {c10 / divisor:P00},")
End Sub
即时窗口中的结果:
1 is 18%, 2 is 17%, 3 is 13%, 4 is 13%, 5 is 11%, 6 is 9%, 7 is 8%, 8 is 5%, 9 is 4%, 10 is 2%,
然后测试 John 的扩展
Private Sub Testjmcilhinney()
Dim R1 As New Random 'CORRECTION - moved this to class level
'Dim weightings = {100, 90, 80, 70, 60, 50, 40, 30, 20, 10}
'Took the weights provided by the OP and divided by 550 (total of his percentages) to get weightings totaling 100
Dim weightings = {18, 16, 14, 13, 11, 9, 8, 5, 4, 2} 'Totals 100%
Dim d1result1 As Integer = R1.NextWithWeighting(1, 11, weightings)
lstResult.Add(d1result1)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For x = 0 To 10000
Testjmcilhinney()
Next
TestWeighted()
MessageBox.Show("Done")
End Sub
立即生成窗口
1 is 60%, 2 is 0%, 3 is 21%, 4 is 0%, 5 is 0%, 6 is 19%, 7 is 0%, 8 is 0%, 9 is 0%, 10 is 0%,
第二次尝试
1 is 0%, 2 is 0%, 3 is 0%, 4 is 53%, 5 is 0%, 6 is 3%, 7 is 0%, 8 is 44%, 9 is 0%, 10 is 0%,
我显然做错了什么。
更正后(见评论)
1 is 19%, 2 is 17%, 3 is 14%, 4 is 13%, 5 is 11%, 6 is 9%, 7 is 9%, 8 is 4%, 9 is 4%, 10 is 1%,