Excel中的随机数组
如何使用RAND
或RANDBETWEEN
函数创build一个随机数组,以便可以在一个公式中模拟10面六面骰子的平均结果?
过去我尝试了以下方法:
=SUMPRODUCT((ROW(A1:A10)^0)*(INT(RAND()*6)+1))/10
但它只产生一次随机数,重复10次,所以平均值等于单个随机输出。 我需要的是一个公式中的10个不同的随机数字。
更新 :我知道这是可能的一个帮手列,但我特别感兴趣的是只使用一个单元格 – 也专门寻找一个解决scheme,只使用工作表函数/而不是VBA
RANDBETWEEN
函数可以处理数组input。 所以
=RANDBETWEEN(ROW(A1:A10)^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)你可以做一个体面的工作,通过使用一个正常的近似来模拟一个单元中的10个卷的平均值。 在目标单元格中input:
=ROUND(NORM.INV(RAND(),3.5,SQRT(35/(12*10))),1)
如果你想改变卷的数量,我明确地留下了10来显示你需要修改的东西。 35是3.5 * 10的事实是巧合,即使有100卷,35也会留在那里。 如果你从10变化,你可能想调整舍入。 10的标准偏差大致为0.54,将1和6放在距3.5的平均值4.6个标准偏差附近。 平均而言,这个公式会给你一个在每270,000次1-6 1的范围之外的值。 10个骰子的骰子平均值的直方graphics成一个相当好的钟形曲线,所以这种方法当然是合理的,并且可能适用于你的目的。
2)一个VBA 子 ,用精确的电子表格公式填充选定的单元格,减轻了您繁琐的计算需求。 如果要求最终的电子表格是无macros观的,那么这仍然可以在开发阶段使用:
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
为了testing各种方法,我用每种方法填充了30行,并对结果进行了5个总结(显得合理):
不用说,在这个屏幕截图中,正常逼近的均值低于另外两个的意思并不特别相关。 在进行统计testing之前,您需要进行相当多的运行才能检测到第一列和第二列之间的差异。
在编辑 :这是一个正确的概率与正常近似的一个公正的10卷的平均值的graphics。 它强调了在这里使用中心极限定理的合理性。 即使n = 10是一个有点小的样本大小,但确切的概率是足够对称和单峰的,它已经看起来相当正常:
对于我能想到的问题,唯一的直接答案是定义一个名为(比如说)randeval的命名范围,并在其定义中使用隐藏的EVALUATE函数: –
=EVALUATE(REPT("+RANDBETWEEN(1,6)",Sheet1!A1))
在A1中input10,在A2中input以下内容: –
=randeval/a1
每次按Ctrl-Alt-F9时,它将产生10个骰子平均值的新估计值。
我试图在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
这对你有用吗? 它有一个骰子在每一行中。
您在A1和B列中input“投掷”的数量将显示结果。
In B1: =IF(A$1>=ROW(),RANDBETWEEN(1,6),"")
然后你只需填写以满足你的需要。
如何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
您在任何单元格中input投掷次数并使用=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