Excel中的随机数数组

时间:2016-11-17 11:03:41

标签: excel vba excel-vba excel-formula

如何使用RANDRANDBETWEEN函数创建随机数组?

我试图在一个公式中模拟10卷六面模(例如)的平均结果?

我过去曾尝试过以下操作,但它只会创建一个随机数并重复它。

=SUMPRODUCT((ROW(A1:A10)^0)*(INT(RAND()*6)+1))/10

5 个答案:

答案 0 :(得分:7)

RANDBETWEEN函数可以处理数组输入。所以

=RANDBETWEEN(ROW(1:10)^0,6)

有效地创造:

=RANDBETWEEN({1;1;1;1;1;1;1;1;1;1},{6;6;6;6;6;6;6;6;6;6})

返回1到6之间的10个不同随机数的数组。通过将A1:A10更改为A1:A100,可以很容易地将其更改为100(或多个)随机数。

因此,平均10个独立骰子卷的单一公式可能是:

=SUMPRODUCT(RANDBETWEEN(ROW(A1:A10)^0,6)/10

或等效的CSE公式

{=AVERAGE(RANDBETWEEN(ROW(A1:A10)^0,6))}

答案 1 :(得分:2)

三种可能的解决方案:

1)您可以通过使用正态近似来模拟单个单元格中10个卷的平均值。在目标单元格中​​输入:

=ROUND(NORM.INV(RAND(),3.5,SQRT(35/(12*10))),1)

我明确地离开了10,如果你想改变滚动的数量,你可以展示你需要修改的内容。 35为3.5 * 10的事实是巧合,即使有100卷,35号也会保持不变。如果从10开始变化,则可能需要调整舍入。对于10,标准偏差约为0.54,将1和6放在约4.6的标准偏差处,平均值为3.5。平均而言,该公式将为您提供超过每270,000次1-6 1的范围内的值。 10个卷的平均骰子直方图形成一个相当不错的钟形曲线,所以这种方法当然是合理的,可能适用于您的目的。

2)一个VBA sub ,它使用精确的电子表格公式填充选定的单元格,从而减轻了繁琐的计数需求。如果要求最终电子表格不含宏,则仍可在开发阶段使用:

Sub DiceAverageFormula()
    'places a formula in the selected cell (or cells)
    'which simulates the average of rolling a die n 10 times

    Dim i As Long, n As Long
    Dim form As String

    n = InputBox("How many times do you want to roll?", "Dice", 10)
    If n < 1 Then Exit Sub
    form = "=Average(Randbetween(1,6)"
    For i = 2 To n
        form = form & ",Randbetween(1,6)"
    Next i
    form = form & ")"
    Selection.Formula = form
End Sub

3)为了完整起见,天真的VBA UDF:

Function RollDice(n As Long, Optional k As Long = 6) As Double
    'simulates the rolling of n k-sided die, returing the average

    Application.Volatile 'can be removed, of course

    Dim i As Long, sum As Long
    With Application.WorksheetFunction
        For i = 1 To n
            sum = sum + .RandBetween(1, k)
        Next i
    End With
     RollDice = sum / n
End Function

为了测试各种方法,我用每种方法填充了30行,并对结果进行了5个数字的总结(看似合理):

enter image description here

毋庸置疑,在屏幕截图中,正常近似值的平均值低于其他两个值并不特别相关。在统计测试可以检测到第一列与另一列之间的任何差异之前,您需要相当多的运行。

在编辑:这是一个公平骰子的10个卷的平均值的精确概率与正常近似的图表。它强调了在这里使用中心极限定理是多么合理。即使n = 10是一个有点小的样本大小,确切的概率是足够对称和单峰的,它已经看起来很正常:

enter image description here

答案 2 :(得分:1)

我能想到的问题的唯一直接答案是定义一个名为(例如)randeval的命名区域,并在其定义中使用隐藏的EVALUATE函数: -

 =EVALUATE(REPT("+RANDBETWEEN(1,6)",Sheet1!A1))

在A1中输入10,在A2中输入以下内容: -

=randeval/a1

每次按Ctrl-Alt-F9,都会产生十个骰子平均值的新估计值。

答案 3 :(得分:1)

我试图在VBA中做类似的事情,但是Evaluate的表现与Excel公式不同:

a = [randbetween(row(1:10)^0,6)]                ' 3

b = [transpose(randbetween(row(1:10)^0,6))]     ' {3,3,6,4,6,4,2,5,1,2}

c = [average(randbetween(row(1:10)^0,6))]       ' 2.9

答案 4 :(得分:0)

这对你有用吗?它每排有一个骰子。
您输入A1中的“投掷”数量,B列将显示结果。

In B1: 
=IF(A$1>=ROW(),RANDBETWEEN(1,6),"")

然后你只需填写以满足你的需要。

enter image description here

UDF怎么样?

Function Throws(c)
    If Range(c).Value > 0 Then
        For i = 1 To Range(c).Value
            Str1 = Str1 & "," & WorksheetFunction.RandBetween(1, 6)
        Next i
        Throws = Mid(Str1, 2)
    End If

End Function

enter image description here

您可以在任何单元格中输入投掷次数,并使用=Throws("CELL")激活它 并且它返回一个单元格中的抛出

EDIT2:

即使是数组,也不确定是否可以使用平均值。

Function Throws(c) As Variant()
    Dim Str1 As Variant
    If Range(c).Value > 0 Then
        For i = 1 To Range(c).Value
            If i = 1 Then Str1 = WorksheetFunction.RandBetween(1, 6)
            Str1 = Str1 & "," & WorksheetFunction.RandBetween(1, 6)
        Next i
        Throws = Application.WorksheetFunction.Transpose(Array(Str1))
    End If

End Function