AGB  ·  Datenschutz  ·  Impressum  







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

Zufallszahlengenerator?

Ein Thema von braingrenade · begonnen am 12. Sep 2003 · letzter Beitrag vom 24. Jan 2005
 
null.L.F.

Registriert seit: 26. Nov 2004
Ort: Bensheim
6 Beiträge
 
#18

Re: Zufallszahlengenerator?

  Alt 24. Jan 2005, 06:58
ich hab hier noch eine Mersenne Twister Unit

(für leute, die hier über suchen draufkommen (wie ich))

GetFullRangeRandom ist dabei die eigentliche funktion, die einen (pseudo-)zufallszahlenwert zurückliefert
die anderen habe ich lediglich hinzugefügt, um einfach auf andere datentypen zu kommen bzw. der einfachen bedienung wegen.

Delphi-Quellcode:
unit UnitZufall;

(*******************************************************************************)
(**                                                                           **)
(**  TRNGenerator:                                                            **)
(**             Generiert Zufallszahlen nach dem Mersenne Twister.            **)
(**                                                                           **)
(*******************************************************************************)

{$R-} {range checking off}
{$Q-} {overflow checking off}

interface

const rtsRNGN = 624;

type
  TRNGStateArray = array [0..rtsRNGN-1] of Integer; // the array for the state vector

type TRNGenerator = class
  private
    mt : TRNGStateArray;
    mti: Integer;
    // Generiert eine Zufallszahl von Low(Integer) bis High(Integer)
    function GetFullRangeRandom: Integer;
  public
    constructor Create;
    procedure SetSeed(Seed: Integer); overload;
    procedure SetSeed(const SeedArray: TRNGStateArray); overload;
    procedure Randomize;
    // Liefert eine Zufallszahl im Bereich von 0 bis +Range zurück:
    function GetRandom(Range: Integer): Integer; overload;
    // Liefert eine Zufallszahl im Bereich von 0 bis 1 zurück:
    function GetRandom: Double; overload;
    // Liefert eine Zufallszahl im Bereich von rFrom bis rTo zurück:
    function GetRandomRange(rFrom, rTo: Integer): Integer;
    // Liefert eine Gauss-Verteilte Zufallszahl zurück:
    function Gauss(Mean, Variance: Extended): Extended;
  end;



implementation

const
{ Period parameters }
  rtsRNGM=397;
  rtsRNGMATRIX_A =$9908b0df;
  rtsRNGUPPER_MASK=$80000000;
  rtsRNGLOWER_MASK=$7fffffff;
{ Tempering parameters }
  TEMPERING_MASK_B=$9d2c5680;
  TEMPERING_MASK_C=$efc60000;

constructor TRNGenerator.Create;
begin
  mti := rtsRNGN+1;
  inherited;
end;

procedure TRNGenerator.SetSeed(Seed: Integer);
var i: Integer;
begin
  for i := 0 to rtsRNGN-1 do begin
    mt[i]:= seed and $ffff0000;
    seed := 69069 * seed + 1;
    mt[i]:= mt[i] or ((seed and $ffff0000) shr 16);
    seed := 69069 * seed + 1;
  end;
  mti := rtsRNGN;
end;

procedure TRNGenerator.SetSeed(const SeedArray: TRNGStateArray);
var i: Integer;
begin
  for i := 0 to rtsRNGN-1 do
    mt[i] := SeedArray[i];
  mti := rtsRNGN;
end;

function TRNGenerator.GetFullRangeRandom: Integer;
const mag01 : array [0..1] of Integer =(0, rtsRNGMATRIX_A);
var y, kk: Integer;
begin
  if mti >= rtsRNGN then begin
     if mti = (rtsRNGN+1) then SetSeed(4357);
     for kk := 0 to rtsRNGN-rtsRNGM-1 do begin
        y := (mt[kk] and rtsRNGUPPER_MASK) or (mt[kk+1] and rtsRNGLOWER_MASK);
        mt[kk] := mt[kk+rtsRNGM] xor (y shr 1) xor mag01[y and $00000001];
        end;
     for kk:= rtsRNGN-rtsRNGM to rtsRNGN-2 do begin
       y := (mt[kk] and rtsRNGUPPER_MASK) or (mt[kk+1] and rtsRNGLOWER_MASK);
       mt[kk] := mt[kk+(rtsRNGM-rtsRNGN)] xor (y shr 1) xor mag01[y and $00000001];
       end;
     y := (mt[rtsRNGN-1] and rtsRNGUPPER_MASK) or (mt[0] and rtsRNGLOWER_MASK);
     mt[rtsRNGN-1] := mt[rtsRNGM-1] xor (y shr 1) xor mag01[y and $00000001];
     mti := 0;
    end;
  y := mt[mti]; inc(mti);
  y := y xor (y shr 11);
  y := y xor (y shl 7) and TEMPERING_MASK_B;
  y := y xor (y shl 15) and TEMPERING_MASK_C;
  y := y xor (y shr 18);
  result := y;
end;


procedure TRNGenerator.Randomize;
var alt: Integer;
begin
  alt := System.Randseed;
  System.Randomize;
  SetSeed(System.RandSeed);
  System.RandSeed := alt;
end;

function TRNGenerator.GetRandom(Range: Integer): Integer;
begin
  // 0 <= result < Range
  result := Trunc(Range * GetRandom);
end;

function TRNGenerator.GetRandom: Double;
begin
  result := (Abs(GetFullRangeRandom / High(Integer)))
end;

function TRNGenerator.GetRandomRange(rFrom, rTo: Integer): Integer;
begin
// rFrom <= result <= rTo
  if rFrom > rTo then result := GetRandom(rFrom - rTo + 1) + rTo
  else result := GetRandom(rTo - rFrom + 1) + rFrom;
end;

function TRNGenerator.Gauss(Mean, Variance: Extended): Extended;
{ Marsaglia-Bray algorithm }
var a, b: Extended;
begin
  repeat
    a := 2 * GetRandom - 1;
    b := Sqr(a) + Sqr(2*GetRandom-1);
  until b < 1;
  result := Sqrt(-2*Ln(b)/b) * a * Variance + Mean;
end;

end.
  Mit Zitat antworten Zitat
 


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 09:47 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