按概率生成随机数
版权声明:可以任意转载,转载时请务必以超链接形式标明如下文章原始出处和作者信息及本声明 作者:xixi 出处:http://blog.csdn.net/slowgrace/archive/2009/03/25/4022632.aspx
1、生成随机数的方法
Function
SetEmpId()
As
String
Dim ref Randomize ref = Int(( 99999 - 10000) * Rnd + 10000) SetEmpId ref End Function This function’s purpose is to assign a unique five-digit number to each new employee. To generate a random integer between two given integers where ending_number = 99999 and beginning_number = 10000,the following formula is used: =Int((ending_number - beginning_number) * Rnd + beginning_number) 2、按概率生成随机整数 以下参考:http://topic.csdn.net/t/20051018/10/4333135.html 如果要随机生成5个数,并控制它们出现的概率. 数字 概率 那就生成0-1的随机数 3、按概率生成随机浮点数 以下来自和Tiger_Zhao的讨论。 如果要控制1个数落在某个区间的概率,比如要求在sngBegin和sngEnd之间生成一个随机数,这个随机数落在sngPB和sngPE之间的概率是P%。有两种方法,以第二种方法为好。 先说第一种方法,要点是: (1)由于sngPB和sngPE将整个区间分成3部分,所以先分别计算随机数落在3部分的概率。落在sngPB和sngPE之间的概率是P%,这是已知的。余下的两个区间的总和概率是(1-p%),分到各个区间的概率按它们的长度分成。 (2)然后根据3个概率得到一个区间划分,落在第一个区间的,就在sngPB和sngPE之间生成一个随机数;落在第二个区间的,就是[sngBegin,sngPB]里生成随机数;落在第3个区间的,就在[sngPE,sngEnd]之间生数。
'create a random number between sngBegin and sngEnd
'with a probability of bytP to lie within sngPB and sngPE Public Function GetRndNumP( sngBegin As Single , sngEnd sngPB sngPE bytP Byte) Single Dim bytP1 Byte bytP2 Byte Debug . Assert( sngPB >= sngBegin) And( sngPE sngPB) sngEnd sngPE) '计算其他区间的概率 bytP1 =(( - sngBegin) /(( -( sngPB))) *( 100 bytP) '[sngBegin,sngPB] bytP2 = bytP '[sngPE,sngEnd] '依据概率投射到相应区间 Select Case GetRandomNum( 1 100) Case To bytP GetRndNumP = GetRandomNum( sngPE) Case( + 1) To( + bytP1) sngPB) bytP1) To 100 sngEnd) End Select Function Public
GetRandomNum(
sngBegin
Single
sngEnd
Single)
Single
GetRandomNum =( sngEnd - sngBegin) + sngBegin Function 这个办法有个问题,就是用了两次随机数,这样实际上影响了它的随机性。Tiger_Zhao建议的第二种方法则没有这个问题,做法是:多个段有不同权重时其实可以映射成相同权重(缩放 [sngPB,sngPE] 区间,相对调整 sngEnd),这样只要一次 Rnd() 就可以完成,代码如下。 'create a random number between sngBegin and sngEnd
'with a probability of bytP to lie within sngPB and sngPE GetRndNumP( sngPB sngPE bytP Byte) sngPLen sngTLen 'total length sngIncreased '需要缩放的长度 sngResult Single sngPLen sngPE sngPB sngTLen sngBegin Debug . Assert( sngPB >= sngBegin) And( sngPB) sngPE) bytP < 100) > 0) Assert <> sngPLen '映射原来的区间为等权重区间 If( / sngTLen) * 100 Then GetRndNumP sngEnd) Exit Function If '((sngPLen + sngIncreased) / (sngTLen + sngIncreased)) * 100 = bytP sngIncreased =(( / 100) sngPLen) /( 1 -( 100)) '缩放回原来区间 sngResult sngIncreased) Select Case sngResult To To( sngIncreased) '等比例缩放 +( sngPB) /( Case( '简单平移 sngIncreased Select Function 另,yesvery说,VB产生的是伪随机数,不是真正的随机数。所以,不能完全满足正态分布。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |