Seite 1 von 2
Zufallsliste bzw. Zufallszahl "ohne zurücklegen"
Verfasst: 07.05.2011 01:24
von Sebastian
Ich benötige eine Zufallzahlenliste, d. h. ich brauche einen Code, bei dem ich Zufallszahlen ermitteln kann, die bei erneutem Aufruf nicht mehr zur Verfügung stehen (also Zufallsauswahl ohne zurücklegen). Der normale random()-Befehl funktioniert demnach nicht mehr. Meine Idee ist folgende, die auch funktioniert:
Code: Alles auswählen
Dim RandomListArray(Elements-1)
Dim RandomListArray_Temp(Elements-1)
Protected NegativeStep
Protected RandomParameter
For i = 0 To Elements-1
RandomListArray_Temp(i) = i
Next
NegativeStep = Elements ; Wird für das "rückwärtige" Zählen benötigt
For i = 0 To Elements-1
NegativeStep = NegativeStep - 1
RandomParameter = Random(NegativeStep)
RandomListArray(i) = RandomListArray_Temp(RandomParameter)
For i2 = RandomParameter To NegativeStep
If i2 < NegativeStep
RandomListArray_Temp(i2) = RandomListArray_Temp(i2+1)
EndIf
Next
Next
Gibt es noch eine einfachere Variante, die vielleicht auch schneller ist? Das ständige Kopieren der Arraydaten könnte sich ja vielleicht auf die Performance auswirken...
Re: Zufallsliste bzw. Zufallszahl "ohne zurücklegen"
Verfasst: 07.05.2011 01:48
von HeX0R
Ich würde das so in der Art angehen:
Code: Alles auswählen
Procedure GetUniqueRandomNumber(InitNumbers = 0)
Static Dim NUMS.i(0)
Static MyNum
Protected i, j, k
If InitNumbers > 1
;Init Array
ReDim NUMS(InitNumbers)
For i = 0 To InitNumbers - 1
NUMS(i) = i
Next i
;Now lets randomize it.
For i = 1 To InitNumbers * 25
Repeat
j = Random(InitNumbers - 1)
k = Random(InitNumbers - 1)
Until j <> k
Swap NUMS(j), NUMS(k)
Next i
MyNum = InitNumbers
Else
MyNum - 1
If MyNum >= 0
ProcedureReturn NUMS(MyNum)
Else
;Finished, recall it to reinit
ProcedureReturn -1
EndIf
EndIf
EndProcedure
GetUniqueRandomNumber(10)
For i = 1 To 10
Debug GetUniqueRandomNumber()
Next i
Debug GetUniqueRandomNumber()
Re: Zufallsliste bzw. Zufallszahl "ohne zurücklegen"
Verfasst: 07.05.2011 01:53
von STARGÅTE
Ich würde den neuen Befehl RandomizeList() verwenden:
Code: Alles auswählen
NewList Integer()
For n = 1 To 10
AddElement(Integer()) : Integer() = n
Next
RandomizeList(Integer())
ForEach Integer()
Debug Integer()
Next
Einfach eine Liste (Urne) mit Zahlen füllen und diese dann durchmischen mit RandomizeList()
Danach einfach nacheinander auslesen ...
Das geht natürlich auch mit einem Array ...
Re: Zufallsliste bzw. Zufallszahl "ohne zurücklegen"
Verfasst: 07.05.2011 11:02
von Nino
STARGÅTE hat geschrieben:Ich würde den neuen Befehl RandomizeList() verwenden:
Ich auch (oder RandomizeArray()).
Und wenn man eine ältere PureBasic-Version benutzt (z.B. weil PB 4.60 momentan erst im Beta-Stadium ist oder warum auch immer), empfehle ich dafür den(?)/die(?)/das(?) sog.
Knuth Shuffle.
Grüße, Nino
Re: Zufallsliste bzw. Zufallszahl "ohne zurücklegen"
Verfasst: 29.05.2011 11:22
von Sebastian
Oh. Sieh an. In der neuen Purebasic-Version gibt es also endlich einen Befehl dafür? Klasse.
Re: Zufallsliste bzw. Zufallszahl "ohne zurücklegen"
Verfasst: 29.05.2011 11:31
von Sebastian
Okay. Ich habe mir den Knuth-Shuffle-Algorithmus angesehen. Das ist super! Schade, dass ich nicht selbst auf so eine elegante Lösung gekommen bin! Danke für den Tipp!
Re: Zufallsliste bzw. Zufallszahl "ohne zurücklegen"
Verfasst: 30.05.2011 12:30
von Zaphod
Ich bin nicht sicher das ich verstehe was du haben möchtest. Eigentlich startet Random() ja bei jedem Programmstart mit einem neuen Seed-wert, wenn du nicht manuell einen Seed vergibst, zumindest ist das bei Version 4.6 beta3 so.
Welche Version benutzt du denn?
Wenn du bei jedem Aufruf von Random einen neuen Seedwert haben willst - und ich verstehe nicht ganz warum du das wollen solltest - dann kannst du das auch deutlich kürzer haben:
Code: Alles auswählen
Procedure.l RandomRandom(max.l)
RandomSeed(GetTickCount_())
ProcedureReturn Random(max)
EndProcedure
Das bringt allerdings auch nicht wirklich viel mehr Entropie in deine Zufallszahlen.
Für welchen Zweck möchtest du das denn verwenden?
Re: Zufallsliste bzw. Zufallszahl "ohne zurücklegen"
Verfasst: 30.05.2011 12:44
von NicTheQuick
@Zaphod:
Du hast ihn falsch verstanden. Auch bei deinem Code kann es vorkommen, dass zwei mal die selbe Zahl nacheinander kommt. Sebastian hingegen möchte eine Liste erstellen, in der jede Zahl nur einmal vorkommt, aber in einer zufälligen Reihenfolge. Also es hat nichts damit zu tun, dass beim Start des Programms immer wieder die selben Zahlen kommen.
Re: Zufallsliste bzw. Zufallszahl "ohne zurücklegen"
Verfasst: 30.05.2011 12:56
von rolaf
Das liegt bestimmt an den Bananen im Ohr.
Da ich ja lange Zeit für Lotto programmiert habe und ich auch verschiedene Zahlen brauchte, lößte ich das Problem immer so:
Code: Alles auswählen
;Beispiel für 24 versch. Zahlen aus 49
Dim Zufall(24)
For A = 1 To 24
Zufall(A) = Random(48) + 1
For B = 1 To A - 1
If Zufall(A) = Zufall(B)
A - 1
Break
EndIf
Next B
Next A
For A = 1 to 24
Debug Zufall(A)
Next A
Re: Zufallsliste bzw. Zufallszahl "ohne zurücklegen"
Verfasst: 30.05.2011 13:14
von Zaphod
Ah okay, jetzt verstehe ich. Dafür kann ich mir Anwendungsfälle vorstellen.
