关于依照表取得随机值的问题
本帖最后由 rolaka 于 2010-5-4 17:26 编辑一日 sxd叫儿子去超市打酱油 结账时候拿到一张抽奖卷 到柜台抽奖
柜台前的广告是这么写的:
- 50%拿到 餐巾纸 塑料袋 橡皮筋 中的随机一样
- 12%拿到 糖果 饼干 中的随机一样
- 5%拿到 优惠卷
- 1%拿到 猫粮
- 剩下就是谢谢惠顾了
现需要用au3 来模拟出这个抽奖箱 算法以执行10W次最后统计出来的结果准确度来衡量
(检验方法 算出10W次的结果->统计各类各项奖品在总抽奖次数里的比)
要求:
1.物品列表是可以修改的
2.单次执行时间控制在200ms以内
3.越短越好...!
初级题了...我蛋疼我自重...其实我写的代码太多...想看看有没有更加短的...
200ms的含义:生成一次结果所花费时间...
引起公愤了啊......下面是我自己的...
#include <Array.au3>
$data = StringSplit(StringReplace(FileRead("list.txt"), @CR, ""), @LF, 2)
Dim $list
For $i = 0 To UBound($data)-1
$spilt = StringSplit($data[$i], ",", 2)
$flag = False
For $n = 0 To UBound($list)-1
If $list[$n] == Int($spilt) Then
$flag = True
ExitLoop
EndIf
Next
If $flag Then
$list[$n] = $list[$n] & "," & $spilt
Else
ReDim $list[$n+1]
$list[$n] = Int($spilt)
$list[$n] = $spilt
EndIf
Next
_ArrayDisplay($list)
$time = TimerInit()
$r = luckyBox($list)
MsgBox(0, TimerDiff($time), $r)
;~ For $i = 0 To 100000
;~ FileWriteLine("test",luckyBox($list))
;~ Next
;$list
Func luckyBox(ByRef $list)
$rate = Floor(Random(0, 99999, 1)/1000)
$weighting = 0
While 1
For $i = 1 To UBound($list)-1
If ($rate+$weighting) == $list[$i] Then
Return $list[$i]
EndIf
Next
$weighting += 1
WEnd
EndFunc
list.txt
12,糖果
50,餐巾纸
50,塑料袋
50,橡皮筋
12,饼干
5,优惠卷
1,猫粮
100,谢谢惠顾
测试下来 基本在比例上把(有浮动是很正常的 像p版说的情况是允许少量出现的)... 测试10w次是为了看值的稳定性...
单次平均0.40ms左右... 只来帮项!!!!!$a=6.3;随机值能不能在这里控制呢?
For $b=1 To 10 Step $a
MsgBox(0,"",$b)
Next不知道用这个方法能行通不? 这里只是一个例子,语句还有很多的变通哦 LZ有没有例子?
个人想法,先按比例生成含有10w个元素的数组,再随机不重复的读取这10W个元素 - 50%拿到 餐巾纸 塑料袋 橡皮筋 中的随机一样
- 12%拿到 糖果 饼干 中的随机一样
- 5%拿到 优惠卷
- 1%拿到 猫粮
- 剩下就是谢谢惠顾了
按这个百分比随机存取就可以了 来个笨办法,只是统计没中奖的次数。Local $number
Local $a, $d = "优惠卷", $e = "猫粮"
Local $b = ["餐巾纸", "塑料袋", "橡皮筋"]
Local $c = ["糖果", "饼干"]
;Local
For $i = 1 To 100000
$a = Random(1, 100)
If $a < 50 Then ; Returns a value between 0 and 1.
$msg = $b
If $a < 12 Then
$msg = $c
If $a < 5 Then
$msgbox = $d
If $a < 1 Then
$msg = $e
EndIf
EndIf
EndIf
Else
$msg = "谢谢惠顾"
$number += 1
EndIf
Next
MsgBox(0, 0, "谢谢惠顾次数" & $number) 呵呵,学习了 想到蛋疼,只计算了1万次笨方法。请大家指教#include <array.au3>
Local $arr, $arr3
Local $a, $bb = 0, $d = "优惠卷", $e = "猫粮"
Local $b = ["餐巾纸", "塑料袋", "橡皮筋"]
Local $c = ["糖果", "饼干"]
$begin = TimerInit()
For $m = 0 To 99;这里定义计算次数/100,只计算100次得到 1万次抽奖的数组
Dim $arr2
For $n = 0 To 99
$arr2[$n] = $n
Next
For $i = 0 To 99
$rannumber = UBound($arr2) - 1
$ran = Random(0, $rannumber, 1)
$arr[$i] = $arr2[$ran]
Select
Case $arr[$i] <= 49
$arr[$i] = $b
Case $arr[$i] <= 61 And $arr[$i] > 49
$arr[$i] = $c
Case $arr[$i] <= 66 And $arr[$i] > 61
$arr[$i] = $d
Case $arr[$i] = 67
$arr[$i] = "猫粮"
Case $arr[$i] > 67
$arr[$i] = "未中奖"
EndSelect
_ArrayDelete($arr2, $ran)
Next
_ArrayConcatenate($arr3, $arr)
Next
;_ArraySort($arr3)
_ArrayDelete($arr3,0)
$dif = TimerDiff($begin)
_ArrayDisplay($arr3,$dif)
运行10W次的效率实在是太肉了 3mile 很热心的说,倒是LZ… 3mile 很热心的说,倒是LZ…
afan 发表于 2010-5-3 17:36 http://www.autoitx.com/images/common/back.gif
是啊!撂个问题在这里也不来过问。
前辈最近很忙吧?忙什么呢? 是啊!撂个问题在这里也不来过问。
前辈最近很忙吧?忙什么呢?
水木子 发表于 2010-5-3 17:49 http://www.autoitx.com/images/common/back.gif
忙着睡大觉,天太热,不敢出门,呵呵~
运行10W次的效率实在是太肉了
3mile 发表于 2010-5-3 17:20 http://www.autoitx.com/images/common/back.gif
我想LZ的运行10W次仅是为了检验结果,而实际应用应该只是单次的抽奖,那样应该可以是很快的~ 所以我也在3#提出先按比例生成10W奖池(就不存在再验证了),再每次随机不重复读取奖池的元素 本帖最后由 pusofalse 于 2010-5-3 20:18 编辑
10万次和100次有何区别?——貌似这是涉及到统计学的问题。 - -||
先生成一个100个元素的1维数组。
前50赋值为1,表示餐巾纸;
再12赋值为2,表示糖果;
其次的5赋值为3,为优惠券;
再1赋值为4,为猫粮;
余下的元素全部赋值为5,表示未中奖;
循环100次,取一个介于0-99之间的随机数,作为数组的索引序号,获取数组中该元素的值,并记录获取该值的次数,循环完毕,最后对比1/2/3/4/5各自的获取次数。#include <Array.au3>
$iTimer = TimerInit()
Local $aVar, $aOutput
_AssignVar(0, 499, "餐巾纸")
_AssignVar(500, 619, "糖果")
_AssignVar(620, 669, "优惠券")
_AssignVar(670, 679, "猫粮")
For $i = 0 To 999
$aOutput[$i] = $aVar
Next
_Arraydisplay($aOutput, TimerDiff($iTimer))
Func _AssignVar($iFrom, $iStop, $sVar)
For $i = $iFrom To $iStop
$aVar[$i] = $sVar
Next
EndFunc ;==>_AssignVar
此题可看作编程解生活中的应用题,在想是否应该打乱数组的顺序,更加接近于生活中人的逻辑。
记得很小的时候去抽奖,抽了10次,结果连续10次都中了,用1块钱买来了10块钱的东西,原因在于所有的奖品分布都集中在了一点,只是凭感觉依次从左至右连续抽了个遍。现在想想上面的代码可能会重现那次的情形。 10万次和100次有何区别?
先生成一个100个元素的1维数组。
前50赋值为1,表示餐巾纸;
再12赋值为2,表 ...
pusofalse 发表于 2010-5-3 18:58 http://www.autoitx.com/images/common/back.gif
呵呵,学习了。
我的想法和P大有些雷同。但应该P大的效率更高吧 Dim $arr
$arr = "餐巾纸 塑料袋 橡皮筋 中的随机一样"
$arr = "糖果 饼干 中的随机一样"
$arr = "优惠卷"
$arr = "猫粮"
$arr = "谢谢惠顾了"
$arr = 0
$arr = 0
$arr = 0
$arr = 0
$arr = 0
$begin = TimerInit()
For $i=1 To 100000
$t = Random(1,100)
If $t < 51 Then
$arr += 1
ElseIf $t < 63 Then
$arr += 1
ElseIf $t < 68 Then
$arr += 1
ElseIf $t< 69 Then
$arr += 1
Else
$arr += 1
EndIf
Next
$dif = TimerDiff($begin)
MsgBox(0,"时间差",$dif)
$arr = Round ($arr/1000)
$arr = Round ($arr/1000)
$arr = Round ($arr/1000)
$arr = Round ($arr/1000)
$arr = Round ($arr/1000)
_ArrayDisplay($arr, "各类各项奖品在总抽奖次数里的比")
超200ms 本帖最后由 C.L 于 2010-5-3 21:15 编辑
现需要用au3 来模拟出这个抽奖箱 算法以执行10W次最后统计出来的结果准确度来衡量
(检验方法 算出10W次的结果->统计各类各项奖品在总抽奖次数里的比)
LZ好象是要统计中奖的比率,我也来做个练习,10万次超200MS,修改了下,耗时少了点,但还是离200MS有点远~~
$t = TimerInit()
Dim $zhi=0,$tang=0,$juan=0,$liang=0
For $i=0 To 100000
$s = Random (1,100,1)
Switch $s
Case $s<51
$zhi +=1
Case $s>=51 And $s<63
$tang += 1
Case $s>=63 And $s < 68
$juan += 1
Case $s = 68
$liang += 1
EndSwitch
Next
MsgBox (0,TimerDiff ($t),"餐巾纸中了"&$zhi&"次,中奖比率为:"&$zhi/1000&@CRLF& _
"糖果中了"&$tang&"次,中奖比率为:"&$tang/1000&@CRLF& _
"优惠券"&$juan&"次,中奖比率为:"&$juan/1000&@CRLF& _
"猫粮"&$liang&"次,中奖比率为:"&$liang/1000&@CRLF)
页:
[1]
2