|
本帖最后由 小蚂蚁树 于 2016-6-22 22:04 编辑
比如在1到1000的范围内取900个随机数,理论上的平均值应该是500.5,而用这种方法得到的平均值一直是467左右。而1到500每次都是出现的。
我觉得是这段代码的原因:
- For i = 1 To split_place - 1
- my_share = Round(arr(i) / sum * total_share, 0)
- total_share = total_share - my_share
- sum = sum - arr(i)
- arr(i) = arr(i - 1) + 1 + my_share
- loop_count = loop_count + 1
- Next i
复制代码
这句:Round(arr(i) / sum * total_share, 0),其中total_share是100,sum(假如不放大的话)≈450,而arr(i)(假如不放大的话)是在0到1之间。那么,只有当sum减小到<200的时候,才可能使得(arr(i) / sum * total_share)>0.5,即 my_share=1,否则 my_share 一直都是0。
sum从450减少到200,因为arr(i)平均值是0.5左右,所以 i 要到500以后,才可能使得 sum 变成200。 450-500*0.5=200
我添加了测试代码:
- Dim SumEnough As Boolean '本句添加
- For i = 1 To split_place - 1
- my_share = Round(arr(i) / sum * total_share, 0)
- If my_share > 0 And SumEnough = False Then '本句添加
- MsgBox i & "," & arr(i) & "," & sum & "," & total_share & "," & my_share
- SumEnough = True
- End If
- total_share = total_share - my_share
- sum = sum - arr(i)
- arr(i) = arr(i - 1) + 1 + my_share
- loop_count = loop_count + 1
- Next i
复制代码
然后运行发现,每次都是 i 到500以上,才第一次出现 my_share >0。也就是说,此前500多个数是必然出现的。因此导致了随机性受到破坏。
当然,要按比例对应到“空档”,“空档”是整数,而比例是精度有限、“密度”不定的小数,两者之间有矛盾,可能无法避免这样的问题。 |
|