Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 在a和b之间生成“n”个随机数,以达到m行中所需的平均值_Vba_Excel_Random_Average - Fatal编程技术网

Vba 在a和b之间生成“n”个随机数,以达到m行中所需的平均值

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

假设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 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