![]() |
Lineares RandomRange für Real
Liste der Anhänge anzeigen (Anzahl: 1)
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:
Der Code: Erstmal für Real Zufallszahlen
Delphi-Quellcode:
Dann das besondere
{-----------------------------------------------------------------------------
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;
Delphi-Quellcode:
Dann die Test Routine
{-----------------------------------------------------------------------------
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;
Delphi-Quellcode:
Und dann natürlich noch intxtschreiben
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;
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:
Zitat:
Zitat:
Gruß Alexander PS: Ich hoffe ihr seid nicht in der Datenflut ertrunken. :roteyes: |
Re: Lineares RandomRange für Real
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, .... |
Re: Lineares RandomRange für Real
Am Round im RandomRRange für Real Zahlen? Also das
Zitat:
Gruß Alexander |
Re: Lineares RandomRange für Real
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). |
Re: Lineares RandomRange für Real
Ich verstehe. Ich probiere es aus.
Danke Gruß Alexander |
Re: Lineares RandomRange für Real
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:
Delphi-Quellcode:
funktioniert einwandfrei.
result:=sqrt(random)*(max-min)+min;
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 |
Re: Lineares RandomRange für Real
So funktioniert es natürlich. Vielleicht nochmal als Info, wie die Mathematik dahinter ist:
Als Beispiel für Delphi:
Delphi-Quellcode:
Und wenn du jetzt die Variablen a,b,c oben bei getvalue einsetzt, kommst du genau auf deine Gleichung.
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; (Hey, das ist eine mathematische Herleitung mit Delphi :mrgreen: ) Ansonsten ist es schwer zu erklären. du musst dich in Verteilungsfunktionen einarbeiten. |
Re: Lineares RandomRange für Real
:gruebel: 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 |
Re: Lineares RandomRange für Real
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 ![]() ![]() ![]() ![]() (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 :zwinker: Edit2: Hab in der Erklärung noch einen Nebensatz ergänzt. |
Re: Lineares RandomRange für Real
Zitat:
Zitat:
Gruß Alexander :hi: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:35 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz