Jump to content

Help me to randomize simple algorithm


Recommended Posts

Anyone want to help me randomize this algorithm?

Right now, despite a series of randomizations, all numbers are drawn almost the same. The difference is slight.

Func GenerateNumbers()
    Local $aResult[0]

    For $i = 1 To 12
        $r = Random(1, 49, 1)
        $r2 = Random(1, 4)
        Switch($r2)
            Case 1
                If $r>=1 And $r<=15 Then $r = Abs(Random(-$r, 25, 1))
            Case 2
                If $r>=16 And $r<=31 Then $r = Abs(Random(-$r, 15, 1))
            Case 3
                If $r>=32 And $r<=49 Then $r = Abs(Random(-$r, 0, 1))
            case 4
        EndSwitch
        _ArrayAdd($aResult, $r)
    Next

    $aResult = _ArrayUnique($aResult, 0, 0, 0, $ARRAYUNIQUE_NOCOUNT)
    $aResult = _ArrayExtract($aResult, 0, 5)
    Return $aResult
EndFunc

Thanks in advance.

 

Link to comment
Share on other sites

Actually, I've never used it, this is my very first time, but it does not change my results too much.

Func GenerateNumbers()
    Local $aResult[49]
    Local $iTotalNumbers = 0
    Local $r = 1
    Local $iSeed = 1
    Do
        $iSeed = Random(1, 14000000, 1)
        SRandom($iSeed)
        $r = Int(Random()*100)
        If $r >= 1 And $r <= 49 Then
            ConsoleWrite($r & @CRLF)
            $aResult[$iTotalNumbers] = $r
            $iTotalNumbers += 1
        EndIf
    Until $iTotalNumbers = 12

    $aResult = _ArrayUnique($aResult, 0, 0, 0, $ARRAYUNIQUE_NOCOUNT)
    $aResult = _ArrayExtract($aResult, 0, 5)
    Return $aResult
EndFunc

1647183617_srandomresults.thumb.PNG.44953b8a859096a26e2eba03a2a2361c.PNG

Edited by DesireDenied
Link to comment
Share on other sites

Link to comment
Share on other sites

Thanks. Nothing really much has changed.

Func GenerateNumbers()
    Local $aResult[12]
    Local $iTotalNumbers = 0
    Local $r = 1
    Local $iSeed = Random(1, 28000000, 1)
    SRandom($iSeed)
    Do
        $r = String(Random())
        $r = StringMid($r, Random(2, 12, 1), 2)
        $r = Int($r)
        If $r >= 1 And $r <= 49 Then
            ConsoleWrite($r & @CRLF)
            $aResult[$iTotalNumbers] = $r
            $iTotalNumbers += 1
        EndIf
    Until $iTotalNumbers = 12

    $aResult = _ArrayUnique($aResult, 0, 0, 0, $ARRAYUNIQUE_NOCOUNT)
    $aResult = _ArrayExtract($aResult, 0, 5)
    Return $aResult
EndFunc

I have also started to experiment with Sin() but it does make bigger difference.

Func GenerateNumbers()
    Local $aResult[12]
    Local $iTotalNumbers = 0
    Local $r = 1
    Do
        $r = Int(Sin(Random(1, 14000000))*100)

        If $r >= 1 And $r <= 49 Then
            ConsoleWrite($r & @CRLF)
            $aResult[$iTotalNumbers] = $r
            $iTotalNumbers += 1
        EndIf
    Until $iTotalNumbers = 12

    $aResult = _ArrayUnique($aResult, 0, 0, 0, $ARRAYUNIQUE_NOCOUNT)
    $aResult = _ArrayExtract($aResult, 0, 5)
    Return $aResult
EndFunc

Do you have any other ideas how to make draws more chaotic?

srandom results.PNG

Link to comment
Share on other sites

3 minutes ago, DesireDenied said:

    Local $iSeed = Random(1, 28000000, 1)  

  SRandom($iSeed)

This still produces the same sequence every time you run it. You need to use an external seed when calling SRandom, for example @AutoitPID or @MSEC (or a combination thereof) BEFORE ever calling Random.

Link to comment
Share on other sites

Oh yeah! It works!

I made to separate functions with totally different seeds, and now the difference is huge.

Func GenerateCoupon()
    Local $aResult[12]
    Local $iTotalNumbers = 0
    Local $r = 1
    Local $iSeed = @MSEC + TimerInit()
    SRandom($iSeed)
    Do
        $r = String(Random())
        $r = StringMid($r, Random(2, 12, 1), 2)
        $r = Int($r)
        If $r >= 1 And $r <= 49 Then
            ConsoleWrite($r & @CRLF)
            $aResult[$iTotalNumbers] = $r
            $iTotalNumbers += 1
        EndIf
    Until $iTotalNumbers = 12

    $aResult = _ArrayUnique($aResult, 0, 0, 0, $ARRAYUNIQUE_NOCOUNT)
    $aResult = _ArrayExtract($aResult, 0, 5)
    Return $aResult
EndFunc

Func GenerateDraw()
    Local $aResult[12]
    Local $iTotalNumbers = 0
    Local $r = 1
    Local $iSeed = @AutoItPID + @MSEC
    SRandom($iSeed)
    Do
        $r = String(Random())
        $r = StringMid($r, Random(2, 12, 1), 2)
        $r = Int($r)
        If $r >= 1 And $r <= 49 Then
            ConsoleWrite($r & @CRLF)
            $aResult[$iTotalNumbers] = $r
            $iTotalNumbers += 1
        EndIf
    Until $iTotalNumbers = 12

    $aResult = _ArrayUnique($aResult, 0, 0, 0, $ARRAYUNIQUE_NOCOUNT)
    $aResult = _ArrayExtract($aResult, 0, 5)
    Return $aResult
EndFunc

 

srandom results.PNG

Link to comment
Share on other sites

  • Moderators

DesireDenied,

If that is all you need then I suggest simply using _ArrayShuffle:

#include <Array.au3>

Global $aArray[50]

For $i = 1 To 49
    $aArray[$i] = $i
Next

_ArrayShuffle($aArray, 1, 49)

_ArrayDisplay($aArray, "", Default, 8)

The function uses the Fisher-Yates shuffle algorithm, so should be properly random.

M23

Edited by Melba23
Added link

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

DesireDenied,

You appear to be confusing "truly random" with what you perceive as "random". It is quite likely that successive numbers in a truly random sequence will be close neighbours - just look at any lottery draw. So trying to avoid such occurrences is in fact making the series less random, not more.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Try this :

#include <Constants.au3>
#include <Array.au3>

Const $MAX = 49
Local $aArray[$MAX]

For $i = 1 to 500
  GenerateNumber(20)
Next

_ArrayDisplay($aArray)

Func GenerateNumber($iNum)
  SRandom(Int(@MSEC))
  For $i = 1 to $iNum
    $aArray[Random(1,$MAX,1)-1] += 1
  Next
  Sleep(Random(5,15,1))
EndFunc

Looks to me quite random...

Link to comment
Share on other sites

@Melba23

You're completely right. 
Idea to make draws more chaotic would only damage final results of my simulations.
Thanks a lot.

Also thanks for your code, its not is twice faster than generating array of 5 element and using random, it is almost that good as statistics from the game I am trying to simulate.

Screenshot_2021-02-01 Lotto, Kaskada, Multi Multi, Mini Lotto, Zdrapki - lotto pl.png

Link to comment
Share on other sites

6 minutes ago, Nine said:

Try this :

#include <Constants.au3>
#include <Array.au3>

Const $MAX = 49
Local $aArray[$MAX]

For $i = 1 to 500
  GenerateNumber(20)
Next

_ArrayDisplay($aArray)

Func GenerateNumber($iNum)
  SRandom(Int(@MSEC))
  For $i = 1 to $iNum
    $aArray[Random(1,$MAX,1)-1] += 1
  Next
  Sleep(Random(5,15,1))
EndFunc

Looks to me quite random...

@Nine Thanks, it works, but its very slow. But it is a good lesson to me :)

Link to comment
Share on other sites

Semi-ontopic,...

I needed a "FairRandom" function once and used nested randoms...

Random(0, Random(0, Random(0, Random(0, Random(0, Random(0, Random(0, Random(0, 99999999), 1), 1), 1), 1), 1), 1), 1

This way a fair amount of each "Block" of numbers gets picked, like, an equal amount of numbers between 0 and 10000, and 10000 to 20000, 20000 to 30000 and so on.

Like a lottery with numbers from 1 to 1 million, most numbers picked would be way above 100000, with very few numbers between 1 100000 being picked, with nested randoms the drawing is more fair.

 

This is probably very slow though, but works fine and fair if it was a lottery drawing. :)

Some guy's script + some other guy's script = my script!

Link to comment
Share on other sites

Here my attempt with fast performance criteria in :

#include <Constants.au3>
#include <Array.au3>

Const $MAX = 49
Local $aArray[$MAX]

For $i = 1 to 500
  GenerateNumber(20)
Next

_ArrayDisplay($aArray)

Func GenerateNumber($iNum)
  SRandom(Mod(DllCall ("kernel32.dll", "bool", "QueryPerformanceCounter", "uint64*", 0)[1],111))
  For $i = 1 to $iNum
    $aArray[Random(1,$MAX,1)-1] += 1
  Next
EndFunc

:)

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...