如何使用Excel按顺序生成一系列随机分布的数字
How to generate a series of randomly distributed numbers in sequence using Excel
我有一个号码,我想将其分配到 15 个箱子或单元格中。我希望这 15 个数字按顺序
示例:
要分配的数量 - 340
输出:6 9 12 16 20 24 27 30 32 32 32 30 27 24 20
... 是的,我的系列没有完美分发,但目前我正在这样做,
- 首先创建一个线性数列 1 2 3 4 ... 14 15
- 然后使用 Norm.Dist(x,mean,standard_dev) 生成一系列 z-score 值,其中 x=1, 2, 3 .. 14, 15
- 然后我使用相似的三角形缩放这些值,即。 x1/y1=x2/y2 其中 x1=z 分数; y1=总和(z-分数); x2=我要的数字; y2=340
有更好的方法吗?因为我必须为此生成多个矩阵,但有些地方不太对...
这是一种碰碰运气的方法,它搜索独立正态变量的随机向量,其总和落在目标总和的给定公差范围内,如果是,则重新调整所有数字以等于总和:
Function RandNorm(mu As Double, sigma As Double) As Double
'assumes that Ranomize has been called
Dim r As Double
r = Rnd()
Do While r = 0
r = Rnd()
Loop
RandNorm = Application.WorksheetFunction.Norm_Inv(r, mu, sigma)
End Function
Function RandSemiNormVect(target As Double, n As Long, mu As Double, sigma As Double, Optional tol As Double = 1) As Variant
Dim sum As Double
Dim rescale As Double
Dim v As Variant
Dim i As Long, j As Long
Randomize
ReDim v(1 To n)
For j = 1 To 10000 'for safety -- can increase if wanted
sum = 0
For i = 1 To n
v(i) = RandNorm(mu, sigma)
sum = sum + v(i)
Next i
If Abs(sum - target) < tol Then
rescale = target / sum
For i = 1 To n
v(i) = rescale * v(i)
Next i
RandSemiNormVect = v
Exit Function
End If
Next j
RandSemiNormVect = CVErr(xlErrValue)
End Function
这样测试的:
Sub test()
On Error Resume Next
Range("A1:A15").Value = Application.WorksheetFunction.Transpose(RandSemiNormVect(340, 15, 20, 3))
If Err.Number > 0 Then MsgBox "No Solution Found"
End Sub
具有这些参数的典型输出:
另一方面,如果我将标准偏差更改为 1,我只会收到消息说没有找到解决方案,因为这样在目标总和的指定公差范围内获得解决方案的概率就会微乎其微。
我有一个号码,我想将其分配到 15 个箱子或单元格中。我希望这 15 个数字按顺序
示例:
要分配的数量 - 340 输出:6 9 12 16 20 24 27 30 32 32 32 30 27 24 20
... 是的,我的系列没有完美分发,但目前我正在这样做,
- 首先创建一个线性数列 1 2 3 4 ... 14 15
- 然后使用 Norm.Dist(x,mean,standard_dev) 生成一系列 z-score 值,其中 x=1, 2, 3 .. 14, 15
- 然后我使用相似的三角形缩放这些值,即。 x1/y1=x2/y2 其中 x1=z 分数; y1=总和(z-分数); x2=我要的数字; y2=340
有更好的方法吗?因为我必须为此生成多个矩阵,但有些地方不太对...
这是一种碰碰运气的方法,它搜索独立正态变量的随机向量,其总和落在目标总和的给定公差范围内,如果是,则重新调整所有数字以等于总和:
Function RandNorm(mu As Double, sigma As Double) As Double
'assumes that Ranomize has been called
Dim r As Double
r = Rnd()
Do While r = 0
r = Rnd()
Loop
RandNorm = Application.WorksheetFunction.Norm_Inv(r, mu, sigma)
End Function
Function RandSemiNormVect(target As Double, n As Long, mu As Double, sigma As Double, Optional tol As Double = 1) As Variant
Dim sum As Double
Dim rescale As Double
Dim v As Variant
Dim i As Long, j As Long
Randomize
ReDim v(1 To n)
For j = 1 To 10000 'for safety -- can increase if wanted
sum = 0
For i = 1 To n
v(i) = RandNorm(mu, sigma)
sum = sum + v(i)
Next i
If Abs(sum - target) < tol Then
rescale = target / sum
For i = 1 To n
v(i) = rescale * v(i)
Next i
RandSemiNormVect = v
Exit Function
End If
Next j
RandSemiNormVect = CVErr(xlErrValue)
End Function
这样测试的:
Sub test()
On Error Resume Next
Range("A1:A15").Value = Application.WorksheetFunction.Transpose(RandSemiNormVect(340, 15, 20, 3))
If Err.Number > 0 Then MsgBox "No Solution Found"
End Sub
具有这些参数的典型输出:
另一方面,如果我将标准偏差更改为 1,我只会收到消息说没有找到解决方案,因为这样在目标总和的指定公差范围内获得解决方案的概率就会微乎其微。