Autor Beitrag
holgerbremen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 120



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 211
Erhaltene Danke: 23



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 174
Erhaltene Danke: 43



BeitragVerfasst: Mo 24.10.11 09:31 
GUID, aber nicht bei 7 Stellen.

msdn.microsoft.com/d...ibrary/bb979128.aspx
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 120



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: 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. :D

_________________
We are, we were and will not be.
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 120



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 211
Erhaltene Danke: 23



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: 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). :nixweiss: 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:
ausblenden Delphi-Quelltext
1:
2:
3:
for i := 1000000 to 9999999 do
   if MyBoolArray[i] then
      MyFileStream.Write(i, SizeOf(Integer));

Auslesen:
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 120



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: 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? :gruebel:

_________________
We are, we were and will not be.
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 211
Erhaltene Danke: 23



BeitragVerfasst: Mo 24.10.11 13:03 
user profile iconGausi hat folgendes geschrieben Zum zitierten Posting springen:
Array[1000000 .. 9999999] of Boolean

Bei einem gewinncode würde doch auch Array[0..9999999of Boolean gehen und die restlichen Stellen mit 0-en auffüllen.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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.