Autor Beitrag
Experience1986
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 192

Win XP Pro SP2
Delphi 7
BeitragVerfasst: Mi 18.05.05 11:02 
Hi,

ich mittlerweile das Problem das random() mir, trotz randomize sehr "schlechte" zufallszahlen zurückliefert.

Wie kann ich das verbessern?
WeBsPaCe
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 2322
Erhaltene Danke: 1

FireFox 3, Internet Explorer 6 SP1
D1, D3Prof, D6Pers, D7Pers+Indy, VisualStudio Express
BeitragVerfasst: Mi 18.05.05 11:10 
Wie meinen? :gruebel:
Stefan S.
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 184


D5
BeitragVerfasst: Mi 18.05.05 11:11 
Soweit ich weiss wird eine Zufallszahl bei "Random" immer aus der vorhergehenden Zahl erzeugt, sprich, die Wahrscheinlichkeit, dass immer die selbe oder eine ähnliche Abfolge von Zufallszahlen kommt, ist recht hoch, was ich zum Beispiel bei einem Vokabeltrainer, den ich mal programmiert habe, gemerkt habe, weil die Abfrage immer mit den selben Vokabeln angefangen hat. Verbessern könnte man es zum Beispiel, indem man die Zufallszahl aus der Uhrzeit erzeugt, denke ich, aber eine wirklich elegante Lösung hab ich auch noch nicht. Interessiert mich selber, die Antwort auf deine Frage.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Mi 18.05.05 11:11 
In welcher Hinsicht ist Random deiner Meinung nach schlecht? Wofür brauchst du es.

user profile iconDaSteve: Dein Problem lässt sich durch einmaliges Aufrufen von Randomize lösen.
Experience1986 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 192

Win XP Pro SP2
Delphi 7
BeitragVerfasst: Do 19.05.05 09:16 
Ich brauche es um einen zufälligen Index meines Arrays anzusteuern.

ausblenden Delphi-Quelltext
1:
2:
3:
randomize;
xy:=random(length(MeinRecordArray));
MeinRecordArray[xy].Irgendwas:='';


Ich nutze bereits randomize und dennoch passiert es öfters das ich einen vorherigen Index generiert bekomme. Da es sich bei meinem Programm um ein Musik Programm handelt ist es extrem nervig wenn man ein bereits zuvor wiedergegebenes Lied erneut hören muss.

Ich hatte bereits versucht ein Integer Array, mit bisher abgespielten Index(en), mitlaufen zu lassen.

Jedes mal wenn ein zufälliger Index generiert wird, der bereits in meinem mitlaufenden Integer Array vorhanden ist, rufe ich die Prozedur erneut auf, in der Hoffnung das ein bislang nicht generierter Index generiert wird.

Nun gibt es an dieser Stelle ein Haken, und zwar wenn ich nur wenige Datensätze (in meinem Fall Songs) in meinem RecordArray habe (1,2,3...) kann es durchaus vorkommen, dass ein neuer Index eher selten getroffen wird, somit passiert es dann, dass das Programm eine CPU Auslaustung von 100% verursacht, was nicht besonders schön ist.


Also, gibt es nun eine andere Möglichkeit Zufallszahlen zu generieren als mit random() bzw. kennt ihr eine Möglichkeit random() weiterhin zu verfeinern, auser randomize?
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 481

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Do 19.05.05 09:53 
Ich denke, dass du das Problem von der falschen Seite her angehst. Solange einen zufälligen Song auszuwählen, bis man einen findet, der noch nciht abgespielt wurde, ist eher ungünstig.
Wie wäre es, wenn du zu Beginn eine Liste erzeugst, in der Verweise auf deine Record-Struktur gegeben sind. Aus dieser Liste suchst du nun ein zufälliges Element aus, fängst an, es abzuspielen, und entfernst es aus der Liste. Damit wird es beim nächsten Mal bestimmt nicht abgespielt.

btw.: Es zeugt nicht von einem schlechten Zufallsgenerator, wenn öfter mal dieselbe Zufallszahl ermittelt wird.

_________________
We are, we were and will not be.
Experience1986 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 192

Win XP Pro SP2
Delphi 7
BeitragVerfasst: Do 19.05.05 10:05 
Das ist ne Super Idee...

Danke... Das hilf mir bestimmt weiter, muss nur noch schauen wo ich eine solche liste anlege, da ich an X verschiedenen Stelllen mein RecordArray erweitere, sauber müsste man coden :(
Tobias1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 454

Win 98, XP Prof
D3 Prof, D2005 Prof
BeitragVerfasst: Do 19.05.05 10:08 
Hier gabs schon man ein Thema über den Delphi-Zufallsgenerator:
www.delphi-forum.de/...41856&highlight=

_________________
Auch das schlechteste Buch hat seine gute Seite: die letzte. (John Osborne)
OneOfTen
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 19.05.05 10:32 
du könntest auch, wenn du es bei deinem unsauberen Code nicht schaffst, eine Liste einzufügen, folgendes machen: :wink:

Immer, wenn der zufällige Index einen bereits gewählten Song ausgewählt hat, nicht einfach einen neuen zufälligen berechnen, sondern einfach den Index solange um 1 erhöhen, bis ein noch nicht gehörter Song ausgewählt ist.
aXiEd
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Sa 21.05.05 16:23 
Du musst darauf achten dass Randomize nur einmal aufgerufen wird (und nicht vor jedem Random). Am besten machst du das beim Erstellen der Form.
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 28

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Sa 21.05.05 16:36 
ausblenden Delphi-Quelltext
1:
Verbessern könnte man es zum Beispiel, indem man die Zufallszahl aus der Uhrzeit erzeugt, denke ich					


ich glaube random(ize) macht das glaube ich auch so :roll:
Tilo
ontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 1098
Erhaltene Danke: 13

Win7 geg. WInXP oder sogar Win98
Rad2007
BeitragVerfasst: So 22.05.05 18:42 
user profile iconF34r0fTh3D4rk hat folgendes geschrieben:
ausblenden Delphi-Quelltext
1:
Verbessern könnte man es zum Beispiel, indem man die Zufallszahl aus der Uhrzeit erzeugt, denke ich					


ich glaube random(ize) macht das glaube ich auch so :roll:

mir randomize(Timer) schon, kannst aber auch andere Werte nehmen
Stefan S.
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 184


D5
BeitragVerfasst: Mi 08.06.05 16:17 
user profile iconF34r0fTh3D4rk hat folgendes geschrieben:
ausblenden Delphi-Quelltext
1:
Verbessern könnte man es zum Beispiel, indem man die Zufallszahl aus der Uhrzeit erzeugt, denke ich					


ich glaube random(ize) macht das glaube ich auch so :roll:


Anscheinend nicht, vor dem ersten "Random" mache ich nämlich immer "Randomize" und trotzdem beginnt zum Beispiel bei meinem halbfertigen Vokabel-Trainer zu 90% die Abfrage mit der selben Vokabel. Und ein zweites mal Randomize geht ja dann nicht mehr.
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Mi 08.06.05 16:54 
@Experience: Du erwartest von dem Zufallszahlengenerator, das er Dir perfekt alle Zahlen genau 1x präsentiert. Das ist dann aber kein Zufall mehr. Das ist ja gerade das 'tolle' (bzw. Blöde, wie in deinem Fall) an den Zufallszahlen.

Was Du benötigst, ist eine zufällige Permutation deiner Songs.

Wenn deine Songs also z.B. die Nummern 1,2,3,4,5 und 6 sind, dann wäre eine zufällige Permutation dann z.B.: 265341.
Wie erzeugt man eine zufällige Permutation? Z.B. so wie OneOfTen es vorgeschlagen hat. Das ist IMHO die einfachste und eleganteste Möglichkeit.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Mi 08.06.05 20:16 
user profile iconalzaimar hat folgendes geschrieben:
Wie erzeugt man eine zufällige Permutation? Z.B. so wie OneOfTen es vorgeschlagen hat. Das ist IMHO die einfachste und eleganteste Möglichkeit.
Nur hast du das Problem, dass der Algorithmus immer langsamer wird und man nicht immer einfach den Index erhöhen kann, weil du sonst übers Array hinaus liest. D.h. brauchst du noch eine Modulo-Operation. Und musst dir zusätzlich auch noch merken, welche Zahl schon vorgekommen ist...

Eine zufällige Permutation erzeugt man normalerweise so, in linearer Zeit (nach Fisher-Yates):
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
Const  
 Count = 10;  
Var  
 A : Array[0..Count-1] of Integer;  
 I, J, T : Integer;  
begin  
 For I := 0 to Count-1 do  
  A[I] := I;  
 For I := 0 to Count-1 do  
 begin  
  J := I+random(Count-I);  
  T := A[J];  
  A[J] := A[I];  
  A[I] := T;  
 end;  
end;
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: Mi 08.06.05 20:20 
Just BTW: Wie sieht das denn bei zufälligen Permutationen nach Alphabeth aus?

d.h. ich möchte die 519. Permutation (alphabethisch gesehen) von 'ABCDEFGHIJ'???

_________________
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.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Mi 08.06.05 20:22 
user profile iconBenBE hat folgendes geschrieben:
Just BTW: Wie sieht das denn bei zufälligen Permutationen nach Alphabeth aus?

d.h. ich möchte die 519. Permutation (alphabethisch gesehen) von 'ABCDEFGHIJ'???

Zufällige Permutation oder 519. Permutation? Was jetzt?
Wie definierst du die 519. Permutation?
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Mi 08.06.05 20:50 
Man kann Permutationen aufzählen. Dazu schreibt man alle Permutationen auf. Anschließend schreibt man neben jede Permutation den Inverse-Code: Für jedes Zeichen wird die Anzahl der Zeichen gezählt, die rechts vom Zeichen vorkommen, und größer sind.
Jede Stelle i dieses Codes wird nun mit (i-1)! multipliziert (von rechts zählen). Wir erhalten die Zahlen von 0 bis n!-1 (n=Anzahl der Stellen). Damit haben wir eine Ordnung auf den Permutationen und können auch die 519.te Permutation ermitteln. Allerdings nicht alphabetisch gesehen. Tschuldigung.

    321 000 0
    312 010 1
    231 100 2
    213 110 3
    132 200 4
    123 210 5

Hier der Algorithmus:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
Function NthPermutation (aString : String; aCount : Integer) : String;
Var
  d : Array Of Integer;
  g, i, n : Integer;

Begin
  n := Length (aString);
  setlength (d, n);
  d[1] := 1;
  For i := 2 to n - 1 do d[i] := i * d[i-1];
  Result := '';
  for i := n-1 downto 1 do begin
    g := (aCount div d[i]) + 1;
    Result  := Result  + aString[g];
    delete (aString, g, 1);
    aCount := aCount mod d[i];
    End;
  Result := Result  + aString;
End;

Kann man bestimmt verbessern. Aber danach wäre die 519.te Permutation (graycodisch gesehen :wink: ) von 'ABCDEFGHIJ' = 'ABCDIFHGJE'. So gesehen vermutlich auch alphabetisch korrekt :mrgreen:
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 08.06.05 22:18 
user profile iconExperience1986 hat folgendes geschrieben:
ausblenden Delphi-Quelltext
1:
2:
3:
randomize;
xy:=random(length(MeinRecordArray));
MeinRecordArray[xy].Irgendwas:='';


Du darfst Randomize nur einmal aufrufen! Steht auch in der Hilfe.
Maweki
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 197

Ubuntu Linux
Lazarus
BeitragVerfasst: Do 09.06.05 06:24 
also ich habe mein Randomize in der System.pas etwas veraendert.
Damit sollte RandSeed besser verteilt sein. Denke ich zumindest...

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure Randomize; inline;
{$IFDEF MSWINDOWS}
var
  Counter, Ticks: Int64;
begin
  if QueryPerformanceCounter(Counter) then
    RandSeed := Counter
  else
  begin
    Ticks := GetTickCount;
    RandSeed := Ticks * 2 - (Ticks and 1);
  end;
end;