Vba 在a和b之间生成“n”个随机数,以达到m行中所需的平均值
假设Z列有200行,是我的最佳平均值Vba 在a和b之间生成“n”个随机数,以达到m行中所需的平均值,vba,excel,random,average,Vba,Excel,Random,Average,假设Z列有200行,是我的最佳平均值 现在我想要一个宏,它在a和b之间生成n个随机整数,包括n,这里有一个命中或不命中的方法,这通常是以无偏方式获得满足附加约束的随机数的唯一可行方法: Function RandIntVect(n As Long, a As Long, b As Long, mean As Double, tol As Double, Optional maxTries As Long = 1000) As Variant 'Uses a hit-or-miss app
现在我想要一个宏,它在a和b之间生成n个随机整数,包括n,这里有一个命中或不命中的方法,这通常是以无偏方式获得满足附加约束的随机数的唯一可行方法:
Function RandIntVect(n As Long, a As Long, b As Long, mean As Double, tol As Double, Optional maxTries As Long = 1000) As Variant
'Uses a hit-or-miss approach to generate a vector of n random ints in a,b inclusive whose mean is
'within the tolerance tol of the given target mean
'The function raises an error if maxTries misses occur without a hit
Dim sum As Long, i As Long, j As Long
Dim lowTarget As Double, highTarget As Double 'targets for *sums*
Dim vect As Variant
lowTarget = n * (mean - tol)
highTarget = n * (mean + tol)
For i = 1 To maxTries
ReDim vect(1 To n)
sum = 0
j = 0
Do While j < n And sum + a * (n - j) <= highTarget And sum + b * (n - j) >= lowTarget
j = j + 1
vect(j) = Application.WorksheetFunction.RandBetween(a, b)
sum = sum + vect(j)
Loop
If j = n And lowTarget <= sum And sum <= highTarget Then
'Debug.Print i 'uncomment this line to see how many tries required
RandIntVect = vect
Exit Function
End If
Next i
'error if we get to here
RandIntVect = CVErr(xlErrValue)
End Function
这是一种命中或未命中的方法,通常是以无偏方式获得满足附加约束的随机数的唯一可行方法:
Function RandIntVect(n As Long, a As Long, b As Long, mean As Double, tol As Double, Optional maxTries As Long = 1000) As Variant
'Uses a hit-or-miss approach to generate a vector of n random ints in a,b inclusive whose mean is
'within the tolerance tol of the given target mean
'The function raises an error if maxTries misses occur without a hit
Dim sum As Long, i As Long, j As Long
Dim lowTarget As Double, highTarget As Double 'targets for *sums*
Dim vect As Variant
lowTarget = n * (mean - tol)
highTarget = n * (mean + tol)
For i = 1 To maxTries
ReDim vect(1 To n)
sum = 0
j = 0
Do While j < n And sum + a * (n - j) <= highTarget And sum + b * (n - j) >= lowTarget
j = j + 1
vect(j) = Application.WorksheetFunction.RandBetween(a, b)
sum = sum + vect(j)
Loop
If j = n And lowTarget <= sum And sum <= highTarget Then
'Debug.Print i 'uncomment this line to see how many tries required
RandIntVect = vect
Exit Function
End If
Next i
'error if we get to here
RandIntVect = CVErr(xlErrValue)
End Function
两种平均值之间的差值不在0.15+、0.15范围内-
两种方法之间的差异不在0.15+,0.15-范围内。您是否可以添加您尝试过的代码并指出存在问题的地方。您是否可以添加您尝试过的代码并指出存在问题的地方。两种方法之间的差异不在+0.15范围内, -0.15@alirezataghizadeh当作为数组公式输入时,该公式可以正常工作。这可能会让人困惑,因为Excel允许您以非数组公式的形式输入公式,其工作方式出乎意料。两种方法之间的差异不在+0.15,-0的范围内。15@alirezataghizadeh当作为数组公式输入时,该公式可以正常工作。这可能会令人困惑,因为Excel允许您以非数组公式的形式输入公式,其工作方式出乎意料。从逻辑上讲,这更多的是一个注释而不是答案,但由于您无法在注释中发布图像,我理解其动机。也许你以后应该删除这个。在任何情况下-您的屏幕截图表明,您没有在应用程序中使用该函数。请注意,在我的屏幕截图中,{=RandIntVect8,1,10,I2,0.15}和周围的大括号,但是{,}在您的屏幕截图中是缺少的。另外:请注意,高于8的目标均值与预期样本均值5.5的标准偏差超过2.5。对于这些值,maxTries=1000次未命中有时会发生大约5%的时间。如果这是您的预期用例,您应该考虑增加最大值,无论是在函数定义本身中还是在调用它时,例如{=RandIntVect8,1,10,I2,0.1510000}。非常感谢您,但我仍然不明白我执行了所有步骤,但仍然不知道我的问题您需要在A2:H2中输入一个数组公式,每个单元格没有单独的公式。1选择整个范围A2:H2。2 type=RandIntVect8,1,10,I2,0.1510000或根据您的区域设置键入的任何内容。不要键入{,}-Excel将自动插入这些。3使用Ctrl+Shift+Enter将公式作为数组公式输入。在任何情况下-如果您只是使用VBA来填充单元格呢?您不需要将RandIntVect用作工作表函数-从VBA调用它。从逻辑上讲,这更多的是一个注释,而不是一个答案,但由于您不能在注释中发布图像,我理解其动机。也许你以后应该删除这个。在任何情况下-您的屏幕截图表明,您没有在应用程序中使用该函数。请注意,在我的屏幕截图中,{=RandIntVect8,1,10,I2,0.15}和周围的大括号,但是{,}在您的屏幕截图中是缺少的。另外:请注意,高于8的目标均值与预期样本均值5.5的标准偏差超过2.5。对于这些值,maxTries=1000次未命中有时会发生大约5%的时间。如果这是您的预期用例,您应该考虑增加最大值,无论是在函数定义本身中还是在调用它时,例如{=RandIntVect8,1,10,I2,0.1510000}。非常感谢您,但我仍然不明白我执行了所有步骤,但仍然不知道我的问题您需要在A2:H2中输入一个数组公式,每个单元格没有单独的公式。1选择整个范围A2:H2。2 type=RandIntVect8,1,10,I2,0.1510000或根据您的区域设置键入的任何内容。不要键入{,}-Excel将自动插入这些。3使用Ctrl+Shift+Enter将公式作为数组公式输入。在任何情况下-如果您只是使用VBA来填充单元格呢?您不需要将RandIntVect用作工作表函数-从VBA调用它。
Sub test()
Dim i As Long
For i = 1 To 3
Range(Cells(i + 1, 1), Cells(i + 1, 8)).Value = RandIntVect(8, 1, 10, Cells(i + 1, 9).Value, 0.15)
Next i
End Sub