Malkey Posted September 25, 2013 Share Posted September 25, 2013 By adding an appropriate number of duplicates of each case to an array, the correct probability for each case will be returned when the elements of the array are randomly selected. (A weighted random selection) #cs the probability that case1 will happen is 20 the probability that case2 will happen is 80 the probability that case3 will happen is 50 #ce ; Instead of an array made up of 20-case1's, 80-case2's, and 50-case3's, do this:- Local $a[15] = [1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]; An array with 2 - 1's(case1), 8- 2's(case2), and 5 - 3's(case3). Local $index, $iCase1 = 0, $iCase2 = 0, $iCase3 = 0 ; Testing if randomly select an element in an array will work. For $i = 1 To 150000 $index = Random(0, 14, 1) Switch $a[$index] ; Randomly selects one of the elements of the array. Case 1 $iCase1 += 1 Case 2 $iCase2 += 1 Case 3 $iCase3 += 1 EndSwitch Next ConsoleWrite("case1 happened an average " & Round($iCase1 / 1000, 0) & " times out of 150" & @CRLF & _ "case2 happened an average " & Round($iCase2 / 1000, 0) & " times out of 150" & @CRLF & _ "case3 happened an average " & Round($iCase3 / 1000, 0) & " times out of 150" & @LF) #cs Returns:- case1 happened an average 20 times out of 150 case2 happened an average 80 times out of 150 case3 happened an average 50 times out of 150 #ce ; So when you have the array, this is all you need MsgBox(0, "Results", 'A weighted random selection is "' & $a[Random(0, UBound($a) - 1, 1)] & '"') By using >Shafayat's RndwithProbablity() function to test with the 150,000 random selections is verified. Returns exacly the same result. expandcollapse popupLocal $rec, $iCase1 = 0, $iCase2 = 0, $iCase3 = 0 ; Testing if RndwithProbablity() function will work. For $i = 1 To 150000 $rec = RndwithProbablity('a=2,b=8,c=5') Switch $rec ; Randomly selects one of the elements of the array. Case 'a' $iCase1 += 1 Case 'b' $iCase2 += 1 Case 'c' $iCase3 += 1 EndSwitch Next ConsoleWrite("case1 happened an average " & Round($iCase1 / 1000, 0) & " times out of 150" & @CRLF & _ "case2 happened an average " & Round($iCase2 / 1000, 0) & " times out of 150" & @CRLF & _ "case3 happened an average " & Round($iCase3 / 1000, 0) & " times out of 150" & @LF) #cs Returns:- case1 happened an average 20 times out of 150 case2 happened an average 80 times out of 150 case3 happened an average 50 times out of 150 #ce Func RndwithProbablity($valarray) Local $name[100], $val[100], $temp, $temp2, $total, $ptot, $ntot, $rnd $temp = StringSplit($valarray, ",") $total = 0 For $i = 1 To $temp[0] $temp2 = StringSplit($temp[$i], "=") $name[$i] = $temp2[1] $val[$i] = $temp2[2] $total = $total + $temp2[2] Next $rnd = Random(1, $total, 1) For $i = 1 To $temp[0] $ntot = 0 For $j = 1 To $i $ntot = $ntot + $val[$j] Next $ptot = 0 If $i = 1 Then $ptot = 0 Else For $j = 1 To ($i - 1) $ptot = $ptot + $val[$j] Next EndIf If ($rnd > $ptot And $rnd <= $ntot) Then Return $name[$i] ExitLoop EndIf Next EndFunc ;==>RndwithProbablity Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now