Jump to content

I want to do something .. Please help me.


Guest
 Share

Recommended Posts

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.

Local $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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...