1用EXCEL生成随机数
- rand() 是 [0,1),随机到的是小数
- randbetween(a,b) 是 [a,b] ,但是只能是整数
如果想在EXCEL公式用randbetween()随机小数呢?
- 随机,randbetween() 只能随机整数,如果是要小数,那就先乘100,随机完之后再除100这样处理
- randbetween(a,b) 是 [a,b]
- RANDBETWEEN(1000*G49,1000*H49)/1000
1.1 rand() 用法
- rand() 随机范围是 [0,1) ,系统定义位 左闭右开区间
- rand() = [0,1) 0-1之间的所有小数
- 100*rand() = [0,100) 所有整数和小数
- int(100*rand()) = [0,100) =[0,99] 所有整数
- int((100-1)*rand()+1) = int([0,99) +1) =[1,100)=[1,99] 所有整数
- int(100*rand()) +1= [0,100)+1 =[1,101)=[1,100] 所有整数
- int(1+(100-1+1)*rand()) =int(1+100*rand()) =[1,101) =[1,100] 所有整数
2 RANDBETWEEN
只随机整数
正确写法
RANDBETWEEN(1000*G49,1000*H49)/1000
错误写法
RANDBETWEEN(G49,H49)*1000/1000
可以间接实现if的效果
if p<随机区间1 取对应结果*计算得最终结果
elseif p<随机区间1+随机区间2 取对应结果*计算得最终结果
else 取对应结果
=IF(RANDBETWEEN(1,100)<100*LOOKUP(MIN(BY15,BZ15),CG:CG,CK:CK),MIN(BY15,BZ15),IF(AND(RANDBETWEEN(1,100)>=100*LOOKUP(MIN(BY15,BZ15),CG:CG,CK:CK),RANDBETWEEN(1,100)<100*LOOKUP(MIN(BY15,BZ15),CG:CG,CL:CL)),RANDBETWEEN(MIN(BY15*100,BZ15*100),MIN(MIN(BY15,BZ15)*(1+LOOKUP(MIN(BY15,BZ15),CG:CG,CO:CO)),$D$20)*100)/100,RANDBETWEEN(MIN(BY15*100,BZ15*100),MIN(MIN(BY15,BZ15)*(1+LOOKUP(MIN(BY15,BZ15),CG:CG,CN:CN)),$D$20)*100)/100))
使用函数:
- if 分支判断
- 随机和区间随机,rand() randbetween()
- 查找 lookup() match() index()
- 组合起来
2 用VBA生成随机数
在VBA里
- rnd是[0,1)之间随机
- 左闭右开区间
方法
- 整数[a,b]随机正确写法为 int(a+(b-a+1)*rnd())
- 小数的随机[a,b) 随机正确写法为 (a+(b-a)*rnd() ’但是右边还是不是闭区间有瑕疵
- 这样来说,小数随机,如果要求两边是闭区间,不如用整数随机方法,把小数*1000等变大为整数,最后再除,也是一样得把。
int(1+[0,1)*(6-1+1))
= int(1+[0,1)*6)
=int(1+[0,6))
=int([1,7))
=[1,6]
0.1+[0,1)*(0.6-0.1)
=0.1+ [0,1)*0.5
=0.1+[0,0.5)
=[0.1,0.6)
官方解释
为了生成某个范围内的随机整数,可使用以下公式:
Int((upperbound - lowerbound + 1) * Rnd + lowerbound)
这里,upperbound 是随机数范围的上限,而 lowerbound 则是随机数范围的下限。
注意 若想得到重复的随机数序列,在使用具有数值参数的 Randomize 之前直接调用具有负参数值的 Rnd。使用具有同样 number 值的 Randomize 是不会得到重复的随机数序列的。
- rnd 是左闭右开区间 [0,1)
- 如果要生成 a~b之间的随机数,一般是int(a+ (b-a+1)*rnd)
- 因为一般都是要在整数之间随机 要用 int()
2.1 例子
生成1-10的随机数
- p1 = Int(1 + 10* Rnd()) ---这里正确,刚好10=10-1+1
- p1 = Int(1 + (10-1+1) * Rnd()) --总是正确
如果生成 2-9之间的随机数
- p2 = Int( 2 + 9* Rnd() ) --错误的
- p2 = Int(2 + (9-2+1) * Rnd()) ----正确
2.2 还玩了下其他的
rnd(-1)
- 用永远生成相同的随机数
- 相当于固定随机数种子了?这样的应用情景是?
rnd(0)
- 虽然随机序列都一样,但和rnd(-1) 不同
- 每次连续随机,也是一样的随机数种子,总是用上次的
- 但是如果先停止,再重新开始,就是用下一个随机种子,会和以前的不同
3 下面是测试随机数的代码
测试方法:
- 这个进行了多轮随机
- p1 = Int(1 + (10) * Rnd()) 'Rnd()分别修改为 rnd(-1) rnd(0) rnd(1) rnd(999) 看效果
Private p1
Private s1, s2, s3, s4, s5, s6, s7, s8, s9, s10
Private S
Sub tt1()
Call intial1
S = 10000
For i = 1 To S
Call RR1
Call SS1
' Debug.Print p1
Next
Call SS2
End Sub
Function intial1()
s1 = 0
s2 = 0
s3 = 0
s4 = 0
s5 = 0
s6 = 0
s7 = 0
s8 = 0
s9 = 0
s10 = 0
End Function
Function SS2()
Debug.Print "随到1的平均次数是= " & s1 / S & " s1=" & s1
Debug.Print "随到2的平均次数是= " & s2 / S & " s2=" & s2
Debug.Print "随到3的平均次数是= " & s3 / S & " s3=" & s3
Debug.Print "随到4的平均次数是= " & s4 / S & " s4=" & s4
Debug.Print "随到5的平均次数是= " & s5 / S & " s5=" & s5
Debug.Print "随到6的平均次数是= " & s6 / S & " s6=" & s6
Debug.Print "随到7的平均次数是= " & s7 / S & " s7=" & s7
Debug.Print "随到8的平均次数是= " & s8 / S & " s8=" & s8
Debug.Print "随到9的平均次数是= " & s9 / S & " s9=" & s9
Debug.Print "随到10的平均次数是= " & s10 / S & " s10=" & s10
End Function
Function RR1()
Randomize
p1 = Int(1 + (10) * Rnd()) 'Rnd()分别修改为 rnd(-1) rnd(0) rnd(1) rnd(999) 看效果
'Debug.Print p1
End Function
Function SS1()
Select Case p1
Case Is = 1
s1 = s1 + 1
Case Is = 2
s2 = s2 + 1
Case Is = 3
s3 = s3 + 1
Case Is = 4
s4 = s4 + 1
Case Is = 5
s5 = s5 + 1
Case Is = 6
s6 = s6 + 1
Case Is = 7
s7 = s7 + 1
Case Is = 8
s8 = s8 + 1
Case Is = 9
s9 = s9 + 1
Case Is = 10
s10 = s10 + 1
End Select
End Function
4 如果是不重复的随机数呢,之后再弄
可以
思路很多
比如EXCEL里
一种是先随机,然后用 large() small() 等排序,虽然随机数可能有相同的,尤其是整数,但是排序一定是唯一的,用排序当作随机次序即可。