Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Zufall Zahlen ?? (Auslosung) (https://www.delphipraxis.net/255-zufall-zahlen-auslosung.html)

Darty 25. Jun 2002 13:36


Zufall Zahlen ?? (Auslosung)
 
Hallo Leutz,

hat jemand einen passenden neutralen Code für einen Zufall-Generator ? Es sollte zum Beispiel der bereich 1 - 32 (Dass wäre die ID-Nummern) aussuchen und es dann neu belegen ... Zum Beispiel ID22 kommt dann in Nr. 3 rein u.s.w. Dabei darf jede ID nur einmal vorkommen.
Für besseres Verständnis, diese code sollte für die "Auslosung und Verteilung" der Spieler auf Turnier-Plänen verwendet werden.

Ich kannte noch von damals im basic die Befehle RND, das problem damals war wenn ich mich noch richtig erinnere, dass beim Programm Start immer die gleichen Zufall-Zahlen generiert wurden. Und dass will ich natürlich verhindern.

Ich bedanke mich schon mal im Vorraus für euer Bemühungen ...

sakura 25. Jun 2002 13:40

Der entsprechende zun RND Befehl in Delphi ist

ID := Random(maxwert); //0..Maxwert-1

Um immer andere Zahlen zu erzeugen, musst Du einmalig vor dem ersten Aufruf von Random den Generator mit
Code:
Randomize;
initialisieren.

Darty 25. Jun 2002 13:47

Huii, dass hilft mir schon etwas weiter ;)

Nur ich überlege wie ich es anstellen könnte so dass keine doppelte Zahlen auftauchen.
Ansonstens müsste ich nach dem Random immer überprüfen ist zum Beispiel die Zahl 30 schon ausgelost, dann gleich wieder von vorne anfangen.. Will irgendwie erreichen, dass zum Beispiel wenn die Zahl 5, 10 und 30 schon gesetzt ist, dass dann nur noch 1-4+6-9+11-29 in Random einbezogen wird. Sonst könnte eventuell zu lange durchziehen wenn nur noch die Zahl 3 fehlen würde und er aber so lange Random mit 32 Zahlen macht bis er endlich mal auf 3 kommt ?? Oder ist mein Gedanke falsch ?

Luckie 25. Jun 2002 13:50

Schreibs in ein Array und nach jeder Ziehung gehst du das Array mit einer Schleif edurch und überprüfst ob die Zahl im Array schon drin steht.

sakura 25. Jun 2002 13:52

Es gibt mehrere Möglichkeiten

1. Du erstellst eine zweite Liste, in der die genutzten Zahlen markiert werden. Wenn eine bereits gezogene Zahl kommt, dann erhöhst Du den Wert, bis eine ungenutzte Zahl erreicht ist.

2. Du erstellst eine zweite Liste, in der die genutzten Zahlen markiert werden. Wenn eine bereits gezogene Zahl kommt, ziehst Du nochmal, bis eine ungenutzte Zahl drankommt. Sollte auch nicht merklich länger dauern - lt. Stochastik, aber wie der Zufall so will.

3. Du erstellst eine zweite Liste, in der die genutzten Zahlen markiert werden. Mit jeder gezogenen Zahl wird der Maximalwert um eins verringert. Für eine gezogene Zahl werden die nicht-genutzten abgezählt, und die entsprechende genutzt.

... und, und, und. Die obigen drei dürften aber die übliichsten sein.

Darty 25. Jun 2002 13:53

@luckie: hmmm kannst du es wenigstens ein wenig code-Ansatz bringen ? Verstehe nicht ganz ? :oops:

sakura 25. Jun 2002 14:05

Für Lösung zwei (ungetestet)

Im Array Zahlen findest Du am Ende alle Zahlen in der gezogenen Reihenfolge.

Code:
const
  Max = 32;
var
  Zahlen: array[0..Max-1] of Integer;

procedure Ziehung;
var
  I, J, Zahl: Integer;
  Gezogen: array[0..Max-1] of Boolean;
begin
  FillChar(Gezogen, SizeOf(Gezogen), #0);
  Randomize;
  for I := 0 to Max-1 do
  begin
    Zahl := Random(Max);
    while Gezogen[Zahl] do
    begin
      Inc(Zahl);
      if Zahl > Max then
        Zahl := 0;
    end;
    Gezogen[Zahl] := True;
    Zahlen[I] := Zahl;
  end;
end;
So, oder so ähnlich...

toms 25. Jun 2002 14:29

Hi,

Schau dir mal "Zufallszahlen ohne Duplikate generieren" von Julian M Bucknall
an:

http://www.swissdelphicenter.ch/de/showcode.php?id=1006
tom

Udontknow 25. Jun 2002 14:31

Hiho!

Bei so einem kleinen Wertebereich ist es natürlich egal, sollten aber irgendwann einmal größere Bereiche auftreten wäre es wohl effektiver, eine Liste zu benutzen:

Man füllt die Liste mit den zu vergebenden Werten.
Anschliessend greift man sich ein zufälliges Element aus der Liste ("Random(List.Count)") und löscht dieses dann aus der Liste raus.

So muss man nicht immer wieder sämtliche Elemente durchgehen, um zu schauen, ob dies schon vergeben ist.

Cu,
Udontknow

sakura 25. Jun 2002 14:33

Zitat:

Zitat von Udontknow
So muss man nicht immer wieder sämtliche Elemente durchgehen, um zu schauen, ob dies schon vergeben ist.

Spannende Frage ist, was schneller ist, andauernd Speicher stückchenweise freizugeben (Elemente aus der Liste enfernen) oder Liste durchlaufen. Ich denke mal, dass das ganze auf den Bereich der auszuwählenden Zahlen drauf ankommt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:04 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz