Autor |
Beitrag |
holgerbremen
      
Beiträge: 120
|
Verfasst: Mo 24.10.11 08:38
Ich möchte eine 7 stellige Zufallszahl erzeugen. Jede Zahl muss eindeutig sein. Das Problem ist, dass ich mir die bereits erzeugten Zahlen nicht merken möchte. Gibts dafür irgendwelche schlauen Algorithmen?
Es könnte auch notfalls eine alphanumerische "Zahl" erzeugt werden, wenn dies die Sache vereinfacht.
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 24.10.11 09:14
Rein logisch:
Wie soll es eine Möglichkeit geben zufällige Zahlen zu erzeugen, wenn diese dennoch einem bestimmten Gesetz folgen sollen? Das ist ein Widerspruch in sich. (Ja, die Algorithmen, die die Zahlen berechnen, sind natürlich nicht echt zufällig, aber zumindest tun sie so.)
Warum möchtest du dir denn die bereits erzeugten Zahlen nicht merken? Hat das einen bestimmten Grund?
|
|
Teekeks
      
Beiträge: 211
Erhaltene Danke: 23
|
Verfasst: Mo 24.10.11 09:30
Nimm doch die immer Aktuelle Unix-Zeit!
Die musst du dir nicht merken und sie ist immer Einmalig (solange man die Uhr nicht zurück stellt).
Wirklich zufällig ist das zwar nicht, ist aber bei deinen Anforderungen auch nicht wirklich Möglich.
|
|
Blup
      
Beiträge: 174
Erhaltene Danke: 43
|
Verfasst: Mo 24.10.11 09:31
|
|
jasocul
      
Beiträge: 6393
Erhaltene Danke: 147
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Mo 24.10.11 09:41
Du willst 7-stellige Zufallszahlen erzeugen, die eindeutg sind.
Das ist Unsinn. Zufallszahlen werden willkürlich erzeugt (in den Grenzen der Algorithmen) und können dadurch auch mehrfach vorkommen. Das dürfte spätestens klar werden, wenn man mal einen Würfel zum Testen verwendet.
Wären deine Zahlen nur numerisch, würdest spätestens mit Ziehung 10.000.000 ein Problem bekommen. Welche Zahl soll denn kommen, wenn es eindeutig sein soll und nur 7 Stellen existieren?
Vielleicht solltest du erklären, was du unter einer Zufallszahl verstehst. Die mathematische Definition passt jedenfalls nicht auf deine Anforderungen.
|
|
holgerbremen 
      
Beiträge: 120
|
Verfasst: Mo 24.10.11 10:32
Ich brauche ca. 2 Mio. Zahlen (streichen wir den Begriff Zufallszahl) aus max. 9.999.999 Möglichkeiten (7 Stellen). Eine Zahl darf nicht wieder gezogen werden. Es müssen bis zu 100 Zahlen pro Minute erzeugt werden.
Ich möchte die Zahlen nicht speichern, da das den Aufwand erhöht und ich somit diverse Fehler abfangen muss. Deswegen wäre die Möglichkeit die Zahlen aus Datum/Uhrzeit zu erzeugen schon mal gut, aber geht das mit 7 Stellen.
|
|
Gausi
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Mo 24.10.11 10:47
Bei den Werten kannst du es vergessen, mit Zufallszahlen zu arbeiten. Die Wahrscheinlichkeit, dass bei 2 Millionen zufäligen Zahlen aus dem Bereich von 1-10 Millionen eine Zahl doppelt vorkommt, ist sehr hoch.
Also: entweder die Zahlen merken und bei Bedarf neu würfeln, oder ohne Zufall arbeiten.
btw.: Der Aufwand, sich die Zahlen zu merken, dürfte nicht sehr hoch sein. Ich würde da einfach ein Array[1000000 .. 9999999] of Boolean nehmen, das sollte auch gut in den Speicher passen. 
_________________ We are, we were and will not be.
|
|
jasocul
      
Beiträge: 6393
Erhaltene Danke: 147
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Mo 24.10.11 10:48
Da das Datum in Delphi eigentlich ein Float ist, sollte das kein Problem sein. Vor dem Komma steht die Zahl, die das Datum repräsentiert, nach dem Komma die Zeit in Sekunden. Oder vielleicht sogar Millisekunden. Das weiß ich gerade nicht. Sollte aber auf jeden Fall ausreichend sein.
Wenn es nicht wirklich "zufällig" aussehen muss, kannst du dir auch einfach nur immer die aktuelle Zahl merken und diese einfach hochzählen. Aber ich nehme an, du brauchst die Illusion der Zufälligkeit in deinem Programm.
|
|
holgerbremen 
      
Beiträge: 120
|
Verfasst: Mo 24.10.11 10:58
Zitat: | btw.: Der Aufwand, sich die Zahlen zu merken, dürfte nicht sehr hoch sein. Ich würde da einfach ein Array[1000000 .. 9999999] of Boolean nehmen, das sollte auch gut in den Speicher passen. |
Die Zahlen im Speicher merken ist kein Problem. Dazu müßten ich sie auch auf Platte speichern (Wegen Neustart oder Programmabsturz). Was ist, wenn die Datei nicht lesbar ist usw.
Zitat: | Wenn es nicht wirklich "zufällig" aussehen muss, kannst du dir auch einfach nur immer die aktuelle Zahl merken und diese einfach hochzählen. Aber ich nehme an, du brauchst die Illusion der Zufälligkeit in deinem Programm. |
Genauso ist es, man soll nur denken, dass die Zahl zufällig ist. Sie muss aber nicht wirklich sein.
|
|
Teekeks
      
Beiträge: 211
Erhaltene Danke: 23
|
Verfasst: Mo 24.10.11 11:07
Wofür brauchst du dass denn?
Vielleicht gibt es eine andere Lösung dafür?
(hachja, die war das mit dem Wechseln des Leuchtobstes?)
|
|
Gausi
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Mo 24.10.11 11:22
Wenn der User denken soll, dass die Zahl zufällig ist, kommst du mit den Datum/Zeit-Vorschlägen auch nicht weiter. Das ist nicht zufällig.
Du könntest den Wertebereich vergrößern (größere Zahlen erlauben), oder z.B. ein zufälliges Wort mit 7 Zeichen generieren - da hast du dann nicht nur 10 Ziffern, sondern 54 (a..z und A..Z).  Da ist die Kollisionswahrscheinlichkeit schon deutlich geringer.
Ich sehe aber noch nicht dein Problem, was das Speichern der Zahlen angeht:
Speichern der Werte in eine Datei:
Delphi-Quelltext 1: 2: 3:
| for i := 1000000 to 9999999 do if MyBoolArray[i] then MyFileStream.Write(i, SizeOf(Integer)); |
Auslesen:
Delphi-Quelltext 1: 2: 3: 4: 5:
| While MyFileStream.pos < MyFileStream.Size do begin MyFilStream.Read(myNumber, SizeOf(Integer)); myBoolArray[myNumber] := True; end; |
Hilft natürlich nichts, wenn der User die Datei löscht, die Festplatte zwecks Windows-Neuinstallation formatiert oder ein Meteor auf den Rechner fällt. 
_________________ We are, we were and will not be.
|
|
holgerbremen 
      
Beiträge: 120
|
Verfasst: Mo 24.10.11 12:06
Zitat: | Hilft natürlich nichts, wenn der User die Datei löscht, die Festplatte zwecks Windows-Neuinstallation formatiert oder ein Meteor auf den Rechner fällt. |
Und genau von diesem Worst-Case muss ich aber ausgehen (Ausgenommen den Meteor, obwohl hier noch die Größe entscheindent wäre).
Zitat: | Wofür brauchst du dass denn?
Vielleicht gibt es eine andere Lösung dafür? |
Für ändere Lösungen wäre ich dankbar. Gebraucht wir es für einen 7-stelligen Gewinncode. Vorgabe ist es, dass der Code 7-stellig numerisch ist und pseudo zufällig ist. Also ein normal-sterblicher auch mehreren Codes keine Reihe erkennen kann. Speichern alter Codes möchte ich aus den oben genannten Gründen ungern.
|
|
Gausi
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Mo 24.10.11 12:33
Wie willst du denn hinterher die Gültigkeit eines Gewinncodes bestimmen, wenn du die ausgegebenen Codes nicht in irgendweiner Weise speicherst? 
_________________ We are, we were and will not be.
|
|
jfheins
      
Beiträge: 918
Erhaltene Danke: 158
Win 10
VS 2013, VS2015
|
Verfasst: Mo 24.10.11 12:43
Nimm dir einen PRNG mit einer kurzen periode und wirf einfach alle Zahlen weg, die nicht in dem Bereich liegen.
Guck z.B. bei en.wikipedia.org/wik...ters_in_common_usein die Zeile "Microsoft Visual Basic (6 and earlier)[5]"
Das Ding hat eine Periode von 2^24, das passt genau.
Also das teil mit einer bestimmten Zahl initialisieren, und es wird dir immer die gleichen Zahlen ausspucken. Zahlen werden nicht mehrfach gezogen, bevor die Periodenlänge erreicht ist.
Nachteil: Die Zahlen sind nicht perfekt zufällig.
|
|
jasocul
      
Beiträge: 6393
Erhaltene Danke: 147
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Mo 24.10.11 12:52
Oder erzeuge dir erst eine Liste mit eindeutigen Zahlen und mische diese dann.
Ich weiß ja nicht, was alles beim Verteilen der Zahlen passiert, aber du kannst den Zustand ja vielleicht festhalten. Wenn das Programm dann neu gestartet wird, verwirfst du alles, was bis dahin passiert ist.
|
|
Teekeks
      
Beiträge: 211
Erhaltene Danke: 23
|
Verfasst: Mo 24.10.11 13:03
Gausi hat folgendes geschrieben : | Array[1000000 .. 9999999] of Boolean |
Bei einem gewinncode würde doch auch Array[0..9999999] of Boolean gehen und die restlichen Stellen mit 0-en auffüllen.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mo 24.10.11 17:56
Fischer-Yates drauf und gut ist. Und dann einfach das Gesamte Array einmal ausgeben. Sind 4x1000000+8+4 Bytes im RAM und nach nem kleinen Delay hast Du bis zum Aufbrauchen des Puffers deine Ruhe.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|