如何将概率添加到随机数生成器

时间:2015-11-19 19:54:11

标签: vb.net

我试图将概率添加到我的随机数生成器中。

这是随机数生成器代码。

'Generate 3 random numbers'
Dim rn As New Random
Dim result1, result2, result3 As Integer
result1 = rn.Next(1, 12)
result2 = rn.Next(1, 12)
result3 = rn.Next(1, 12)

因此,此代码将生成3个随机数并将它们保存到单独的变量中。 我想要发生以下事情。

1 has a 20% chance of being selected
2 has a 28% chance of being selected

值必须介于1到12之间,我需要选择3个数字 沿着那条线的东西。

我找到了this but it seems to be a little off topic?

这可以用于我想要的吗?

2 个答案:

答案 0 :(得分:4)

制作包含100个项目的数组。将值1放入数组中的20个点,将值2放入数组中的28个点,依此类推。然后选择一个随机数组索引。根据您的值和概率,您可以简化或调整数组的大小。

或者,您可以只存储边界对({1,20},{2,48},...),抓取小于最高边界值的随机数,并找到最小对的数字边界值大于或等于随机结果。这是一个例子:

Private rnd As New Random()
Public Function GetValue() As Integer 
    'max value is 100
    Dim boundaries = {
        {20, 48, 56, 60, 69, 74, 77, 82, 84, 88, 92, 100},
        { 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,  12}
    }

    Dim r As Integer = rnd.Next(1, 101) 'upper range is exclusive
    For i As Integer = 0 To boundaries.GetUpperBound(1)
        If boundaries(0, i) >= r Then Return boundaries(1, i)
    Next
    Throw New Exception() 'code should not be able to get here
End Function

Dim result1 As Integer = GetValue()
Dim result2 As Integer = GetValue()
Dim result3 As Integer = GetValue()

答案 1 :(得分:-2)

我不久前在考虑制作一个模仿美国国家人口基数的随机名单;所需的数千个名字模仿了美国人口中的重复使用。为此,我需要一个名字列表以及Sur名称及其使用频率。因此,我从社会保障管理局提取种子数据,以获得前1000名First和Sur名称及其使用频率。

Think of three columns.  The first column is a list of names, the second their frequency seen in the population bases, and the third is the rolling totals of their frequency added row to row:

Marry, 57, 10
John, 40, 60
Lloyd, 2, 62
Zac, 1, 61

Read a seed file of any size into an area, along with the weight value for each name (or number).  This script assigns the rolling total weight values, then generates a random number between 1 and the sum of all weights.  Checks that random number against the rolling sum of weights to locate the number associated with that weight.

Looking at the above example you have a 57% chance to generate Marry, and a 1% chance to generate Zac.

The below script is a more robust example of the general idea.  It will generate random numbers between 1 – 25, based on the probability of their weights.  The portion of the script that generates the random numbers between 1 – 25 loops 128 times to give you 128 numbers based on their probability of being selected.

I basically used something like this to generate thousands of random names to mimic a population bases that mirrored the USA.


Dim iVar001, iVar002, iVar003
Dim iMin, iMax, iRand, iRandN
Dim iRow, iCol
Dim aName
Dim aList()

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' iMin is the lower range of random numbers, iMax is the upper
' range of random numbers being generated
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

iMin = 1
iMax = 25

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Create a dinamic sized 2D area used to generate a random number
' based on weighted Probability.  Array values array(0, 0) threw
' array(x, 0), where “x” is the upper range value of the number
' to be generated, contains the range of random numbers you will
' be generating.  Array values array(0, 1) to array(x, 1) contains
' the weight value for each number.  Array values array(0,2) to 
' array(x,2) contains the rolling sun of the weight values.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''


ReDim aList(iMax - 1, 2)
iVar001 = 0
Do While iVar001 <= (iMax - 1)
  Randomize
  aList(iVar001, 0) = iVar001 + 1
  aList(iVar001, 1) = Int(((20 * iMax) - iMin + 1)* Rnd + iMin)
  If iVar001 = 0 Then
    aList(iVar001, 2) = aList(iVar001, 1)
  Else
    aList(iVar001, 2) = aList(iVar001, 1) + aList(iVar001 - 1, 2)
  End If
  aName = aName & aList(iVar001, 0) & " - " & aList(iVar001, 1) & _
          " - " & aList(iVar001, 2) & vbCrLf
  iVar001 = iVar001 + 1
Loop

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Generate a message box containing the array values.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

MsgBox ("List of numbers," & vbCrLf& "weight values and" & _
        vbCrLf & "totals of weights." & vbCrLf & vbCrLf & aName)


aName = ""
iCount000 = 1
iCount001 = 1
iCol001 = 0

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Generate a randon number between 1 and the total of weight 
' values.  Then step threw the array values until the the random 
' value is nolonger less than or equal to the running wieght value, 
' and record the number associated with that running weight value.
' The count of random =numbers generates is controled by the
' following Do While iCount000 <= 198.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ''

Do While iCount000 <= 198
   Randomize
   iRand = Int((aList(UBound(aList,1),UBound(aList,2)) - iMin + 1)* Rnd + iMin)
   iVar001 = 0
   Do While iRand >= aList(iVar001, 2)
     iVar001 = iVar001 + 1
     iRandN = aList(iVar001, 0)
   Loop
   iCount000 = iCount000 + 1

   If iCount001 = "19" Then
      aName = vbCrLf & aName
      iCount001 = 0
   Else
      iCount001 = iCount001 + 1
   End If

   aName = iRandN & ", " & aName
Loop
MsgBox "List of random numbers in range " & iMin & " to " & iMax & "," & vbCrLf & _
       "based on weighted probability." & vbCrLf & vbCrLf  & aName