AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Lineares RandomRange für Real

Ein Thema von Alexander Roth · begonnen am 12. Mär 2007 · letzter Beitrag vom 13. Mär 2007
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Alexander Roth
Alexander Roth

Registriert seit: 17. Mai 2004
Ort: Kenn
574 Beiträge
 
Turbo Delphi für Win32
 
#1

Lineares RandomRange für Real

  Alt 12. Mär 2007, 18:12
Hallo,

also ich habe mir gedacht, wieso immer nur das ganz zufällige RandomRange, wo die Zahlen so völlig gleichverteilt sind.
Eine Lineare Zahlenverteilung wäre doch schön.
Also so was wäre toll
Zitat:
0 0
1 100
2 200
3 300
4 400
5 500
6 600
7 700
8 800
9 900
10 1000
Also habe ich mich daran gemacht:

Der Code:

Erstmal für Real Zufallszahlen
Delphi-Quellcode:
{-----------------------------------------------------------------------------
  Description:
  Procedure:    RandomRRange
  Arguments:    min,max:real; nachkomma:integer=5; IncludeMin:boolean=true; IncludeMax:boolean=true
  Result:      real
  Detailed description:
-----------------------------------------------------------------------------}

function RandomRRange(min,max:real; nachkomma:integer=5; IncludeMin:boolean=true; IncludeMax:boolean=true):real;
begin
  min:=min*power(10,nachkomma);
  max:=max*power(10,nachkomma);
  if IncludeMin then
    min:=min-1;
  if IncludeMax then
    max:=max+1;

  result:=randomrange(round(min),round(max))/power(10,nachkomma);
end;
Dann das besondere
Delphi-Quellcode:
{-----------------------------------------------------------------------------
  Description:
  Procedure:    RandomRRange
  Arguments:    min,max:real; IncreaseProbability, DecreaseProbability:boolean; nachkomma:integer=5; IncludeMin:boolean=true; IncludeMax:boolean=true
  Result:      real
  Detailed description:  Falls IncreaseProbability dann kommen die größeren Zahlen linear häufiger vor als die kleineren
                        Falls DecreaseProbability dann kommen die kleineren Zahlen linear häufiger vor als die größeren
                        Falls beide, dann kommen die mittlere Zahlen linear häufiger vor als die größeren und kleineren
-----------------------------------------------------------------------------}

function RandomRRange(min,max:real; IncreaseProbability, DecreaseProbability:boolean; nachkomma:integer=5; IncludeMin:boolean=true; IncludeMax:boolean=true):real;
begin
  result:=RandomRRange(min,max,nachkomma,IncludeMin, IncludeMax);

  if IncreaseProbability and not DecreaseProbability then
    result:=RandomRRange(min+RandomRRange(0,max-min,nachkomma),max,nachkomma,IncludeMin, IncludeMax);

  if not IncreaseProbability and DecreaseProbability then
    result:=RandomRRange(min,max-RandomRRange(0,max-min,nachkomma),nachkomma,IncludeMin, IncludeMax);


  if IncreaseProbability and DecreaseProbability then
    if randombool then
      result:=RandomRRange(min,max/2,true,false,nachkomma) //links
    else
      result:=RandomRRange(min+(max-min)/2,max,false,true,nachkomma); //rechts
end;
Dann die Test Routine
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var s:string;
    i:integer;
    zufall:real;

    ar: array[0..10] of integer;
begin
  randomize;
  FillChar(ar,sizeof(ar),0);


  for i:=0 to 1100000 do
    begin
    zufall:=RandomRRange(0,10,true,true);
    inc(ar[trunc(zufall)]); // WICHTIG, das hier trunc steht!!!!! das macht nämlich klar wieso 10 nur ganz selten vorkommt
    end;

  s:='';
  for i:=0 to length(ar)-1 do
    s:=s+inttostr(i)+' '+inttostr(ar[i])+#13+#10;

  intxtschreiben(s);
  Close;
end;
Und dann natürlich noch intxtschreiben
Delphi-Quellcode:
{-----------------------------------------------------------------------------
  Description:  Schreibt in eine TXT rein
  Procedure:    intxtschreiben
  Arguments:    text:string; pfad:string=''; vorherloschen:boolean=true
  Result:      None
  Detailed description:
-----------------------------------------------------------------------------}

procedure intxtschreiben(text:string; pfad:string=''; const endung:string='.txt'; vorherloschen:boolean=true);
var txt:textfile;
begin
  if pfad='then
// pfad:=ExtractFilePath(Application.ExeName)+dateToStr(now)+' '+inttostr(hourof(now))+' Uhr und '+inttostr(minuteof(now))+' Minuten'+endung
    pfad:=ExtractFilePath(Application.ExeName)+dateToStr(now)+' '+inttostr(hourof(now))+'h '+inttostr(minuteof(now))+'m '+inttostr(secondof(now))+'s '+endung
  else
    DelDubbleExtension(pfad,endung);

  try
    assignfile(txt,pfad);
    if (fileexists(pfad))and(not vorherloschen) then append(txt) else rewrite(txt);
    writeln(txt,text);
    closefile(txt);
  except
    showmessage('Fehler beim schreiben');
  end;
end;

So ich habe mir die Zufallsverteilung mal angeschaut in Excel und es erfüllt auch den groben Verlauf, aber leider steigt der Verlauf der Verteilung fast e Funktionsmäßig an.
Also nicht linear.
Ach ja dazu gleich mal die Daten für steigend, sinkend, beides (auch im Anhang)
Zitat:
0 56799
1 179147
2 316328
3 475035
4 660863
5 880353
6 1159318
7 1531780
8 2107263
9 3632972
10 143
Zitat:
0 3632360
1 2107747
2 1531753
3 1158711
4 880333
5 660495
6 475303
7 317350
8 179262
9 56687
10 0
Zitat:
0 117919
1 396274
2 770052
3 1345257
4 2869959
5 2871358
6 1345788
7 769382
8 395701
9 118311
10 0
Wisst ihr woran das liegen könnte?

Gruß Alexander

PS: Ich hoffe ihr seid nicht in der Datenflut ertrunken.
Angehängte Dateien
Dateityp: xls daten_179.xls (17,5 KB, 1x aufgerufen)
Alexander Roth
Ich bin umgestiegen auf: Lazarus und Ubuntu! Alles OpenSource!

Besuch doch mal: www.roth.us.ms
  Mit Zitat antworten Zitat
Benutzerbild von yörsch
yörsch

Registriert seit: 10. Jan 2007
Ort: Lampertheim
206 Beiträge
 
Delphi XE2 Architect
 
#2

Re: Lineares RandomRange für Real

  Alt 13. Mär 2007, 08:18
Moin Moin
es dürfte an dem ROUND liegen, genau erklären kann isch´s aber auch nicht!
liegt wohl am abrunden!
Versuch mal was anderes... trunc, ....
Jörg
have FUN
  Mit Zitat antworten Zitat
Benutzerbild von Alexander Roth
Alexander Roth

Registriert seit: 17. Mai 2004
Ort: Kenn
574 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: Lineares RandomRange für Real

  Alt 13. Mär 2007, 08:34
Am Round im RandomRRange für Real Zahlen? Also das
Zitat von Alexander Roth:
Erstmal für Real Zufallszahlen
Delphi-Quellcode:
{-----------------------------------------------------------------------------
  Description:
  Procedure:    RandomRRange
  Arguments:    min,max:real; nachkomma:integer=5; IncludeMin:boolean=true; IncludeMax:boolean=true
  Result:      real
  Detailed description:
-----------------------------------------------------------------------------}

function RandomRRange(min,max:real; nachkomma:integer=5; IncludeMin:boolean=true; IncludeMax:boolean=true):real;
begin
  min:=min*power(10,nachkomma);
  max:=max*power(10,nachkomma);
  if IncludeMin then
    min:=min-1;
  if IncludeMax then
    max:=max+1;

  result:=randomrange(round(min),round(max))/power(10,nachkomma);
end;
Aber wenn ich das aufrufe gibt es eine gleichmäßige Zufallsverteilung.

Gruß Alexander
Alexander Roth
Ich bin umgestiegen auf: Lazarus und Ubuntu! Alles OpenSource!

Besuch doch mal: www.roth.us.ms
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: Lineares RandomRange für Real

  Alt 13. Mär 2007, 08:35
Ich sehe zwar, was du machst, aber ich kanns mathematisch nicht fassen.

Vielleicht ein anderer Ansatz:
Du willst also eine Dichtefunktion, welche linear von min bis max ansteigt (oder abfällt). Das würde bedeuten du brauchst eine quadratische Verteilungsfunktion (Integral der Dichtefunktion). Jetzt musst dur dir also eine quadratische Funktion vorstellen in dem Bereich von x=[min;max] und y=[0;1]. Dabei geht dir Funktion durch die zwei Punkte P1=(min;0) und P2=(max;1). Diese Funktion musst du dir erstmal auf dem Papier erstellen.
Und im Prinzip ziehst du jetzt gleichverteilt (also das, was Delphi mit allen random-Funktionen macht) einen y-wert und rechnest auf den x wert zurück. Dann dürftest du eine lineare Dichetfunktion erreichen. um von y auf x zu kommen müsstest du also dann deine quadratische Funktion invertieren (da dürfte also eine Wurzel reinkommen).
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von Alexander Roth
Alexander Roth

Registriert seit: 17. Mai 2004
Ort: Kenn
574 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: Lineares RandomRange für Real

  Alt 13. Mär 2007, 08:42
Ich verstehe. Ich probiere es aus.
Danke

Gruß Alexander
Alexander Roth
Ich bin umgestiegen auf: Lazarus und Ubuntu! Alles OpenSource!

Besuch doch mal: www.roth.us.ms
  Mit Zitat antworten Zitat
Benutzerbild von Alexander Roth
Alexander Roth

Registriert seit: 17. Mai 2004
Ort: Kenn
574 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: Lineares RandomRange für Real

  Alt 13. Mär 2007, 09:01
Jaaa.... also deine Methode glaube ich habe dich doch nicht so ganz verstanden, bzw sie funktioniert nicht so ganz: Weil:
wenn, min=0; max:=1;
dann kann man quadrieren und muss danach NICHT verschieben und kann wieder die wurzel ziehen und es bleibt das selbe.

Deshalb habe ich einfach ein bisschen rumprobiert und so unverständlich es für mich ist, das:
  result:=sqrt(random)*(max-min)+min; funktioniert einwandfrei.
Ich weis nicht wieso.

Quadrieren bringt den linken Ast der Quadratischen Funktion. Das verstehe ich. Quadrat heißt viele Kleine, D.h. bei 0,1,.. sind sehr viele, d.h. linker Ast einer Quadratischen Funktion.

Doch wieso das mit der Wurzel klappt?

Gruß Alexander
Alexander Roth
Ich bin umgestiegen auf: Lazarus und Ubuntu! Alles OpenSource!

Besuch doch mal: www.roth.us.ms
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#7

Re: Lineares RandomRange für Real

  Alt 13. Mär 2007, 10:27
So funktioniert es natürlich. Vielleicht nochmal als Info, wie die Mathematik dahinter ist:
Als Beispiel für Delphi:
Delphi-Quellcode:
type TLinVerteilung=class
       constructor create(min,max:double);
       function getvalue:double;
      private
       a,b,c:double;
end;

unction TLinVerteilung.getvalue:double;
var y:double;
begin
  y:=random; //y-wert
  //quadratische funktion umkehren um aus dem y-Wert den x-Wert zu bestimmen
  //(nur positive "Lösung")
  //x=-b/(2a) + sqrt( b^2/(4a^2) - (c-y)/a )
  result:=-b/(a*2)+sqrt(sqr(b/a)/4-(c-y)/a); //x-->result
end;
constructor TLinVerteilung.create(min,max:double);
begin
  inherited create;
  //Parameter der quadratischen Funktion für eine lineare Verteilung berechnen
  //y=a*x^2 + b*x + c
  //P1=(min,0)
  //P2=(max,1)
  //P1 ist gleichzeitig Scheitelpunkt der quadratischen Funktion
  a:=1/sqr(max-min);
  b:=-2*min*a;
  c:=sqr(min)*a;
end;
Und wenn du jetzt die Variablen a,b,c oben bei getvalue einsetzt, kommst du genau auf deine Gleichung.
(Hey, das ist eine mathematische Herleitung mit Delphi )

Ansonsten ist es schwer zu erklären. du musst dich in Verteilungsfunktionen einarbeiten.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von Alexander Roth
Alexander Roth

Registriert seit: 17. Mai 2004
Ort: Kenn
574 Beiträge
 
Turbo Delphi für Win32
 
#8

Re: Lineares RandomRange für Real

  Alt 13. Mär 2007, 13:55
Da ist das einfache wurzelziehen aber einfacher.

Wieso beim Quadrieren, aber ein linke Parabelast und beim wurzelziehen was lineares rauskommt, ist mir aber jetzt noch nicht klar.

Es müsste doch analog zu Quadrieren der rechte Parabelast rauskommen.

Wieso ist dem nicht so?

Gruß Alexander
Alexander Roth
Ich bin umgestiegen auf: Lazarus und Ubuntu! Alles OpenSource!

Besuch doch mal: www.roth.us.ms
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#9

Re: Lineares RandomRange für Real

  Alt 13. Mär 2007, 14:36
Natürlich ist deins einfacher.
Ist auch exakt dasselbe, nur gekürzt. Das sollte ja nur mal vor Auge führen, was mathematisch dahinter steht (vielleicht willst du ja mal was anders als eine lineare Verteilung)

Wenn du eine Zufallszahl aus einer bestimmten Dichtefunktion haben willst (die bei dir eine lineare Funktion darstellt), dann bildet man erst die Verteilungsfunktion indem man die Dichtefunktion integriert (würde also aus der linearen Funktion eine quadratische Funktion machen), und dann muss man nur eine zufällige Zahl zwischen 0 und 1 ziehen und bestimmt in der Verteilungsfunktion dazu den x-Wert (eine Verteilungsfunktion hat immer den Wertebereich [0;1] oder besser [0%;100%]). Das ist alles. Mathematisch geht das indem du aus der quadratischen Funktion, die Umkehrfunktion also eine Wurzelfunktion bildest.


(Der andere Parabelast kommt heruas, wenn du (meine Lösung durchgehend) die zweite ösung einer quadratischen Gleichung nimmst, also letzenendes ein Minus vor das "sqrt" setzen. Das ist rein mathematisch zwar richtig, aber für die reale Lösung völlig irrelevant.)


Edit und PPS: Du solltest dir mal ein paar mehr stochastische Grundkenntnisse aneignen. Ist ganz sinnvoll wenn man etwas stochastisches programmiert

Edit2: Hab in der Erklärung noch einen Nebensatz ergänzt.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von Alexander Roth
Alexander Roth

Registriert seit: 17. Mai 2004
Ort: Kenn
574 Beiträge
 
Turbo Delphi für Win32
 
#10

Re: Lineares RandomRange für Real

  Alt 13. Mär 2007, 14:59
Zitat von sirius:
Natürlich ist deins einfacher.
Ist auch exakt dasselbe, nur gekürzt. Das sollte ja nur mal vor Auge führen, was mathematisch dahinter steht (vielleicht willst du ja mal was anders als eine lineare Verteilung)

Wenn du eine Zufallszahl aus einer bestimmten Dichtefunktion haben willst (die bei dir eine lineare Funktion darstellt), dann bildet man erst die Verteilungsfunktion indem man die Dichtefunktion integriert (würde also aus der linearen Funktion eine quadratische Funktion machen), und dann muss man nur eine zufällige Zahl zwischen 0 und 1 ziehen und bestimmt in der Verteilungsfunktion dazu den x-Wert. Das ist alles. Mathematisch geht das indem du aus der quadratischen Funktion, die Umkehrfunktion also eine Wurzelfunktion bildest.
Jetzt habe ich es kapiert. Danke für die Erklärung.
Zitat von sirius:
Edit und PPS: Du solltest dir mal ein paar mehr stochastische Grundkenntnisse aneignen. Ist ganz sinnvoll wenn man etwas stochastisches programmiert
Tja, noch war Stochastik nicht dran. Kommt erst in ein paar Monaten.

Gruß Alexander
Alexander Roth
Ich bin umgestiegen auf: Lazarus und Ubuntu! Alles OpenSource!

Besuch doch mal: www.roth.us.ms
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:03 Uhr.
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