Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

395 commentaire(s) de Forman sur des sources sur tout CodeS-SourceS

Le : 03/07/2009 20:37:44
Source : CALCULATRICE POUR POËTES
A mon avis la calculette de windows calcule en valeur exacte jusqu'à un certain point, puis décide de passer en flottants lorsque le résultat dépasse un certain seuil. Ce qui explique la durée du calcul.

Ce que je voulais dire c'est que si ta calculette utilise le type extended alors ça ne doit pas être triste non plus lorsque tu lui demandes 100000! vu que la mantisse des extended va jusqu'à un peu moins de 10^5000      :-)

Au fait lorsque tu parles de préparer les banderilles, j'espère que tu n'envisages pas que l'un de nous fasse le taureau?


Le : 03/07/2009 16:55:40
Source : GÉNÉRATEUR DE NOMBRES PSEUDO-ALÉATOIRES
Oui c'est bien ça. Mais si ta fonction Random entre dans une boucle d'une taille à peu près égale au bout d'un certain nombre d'utilisations, ça revient au même.

L'avantage c'est que lire un élément du tableau peut être plus rapide que de calculer un random avec un algo sophistiqué.


Le : 03/07/2009 16:45:01
Source : GÉNÉRATEUR DE NOMBRES PSEUDO-ALÉATOIRES
Non, pas si tu fais un Randomize avant de remplir le tableau au lancement du jeu par exemple (lui-même étant basé sur l'horloge interne).


Le : 03/07/2009 16:14:17
Source : GÉNÉRATEUR DE NOMBRES PSEUDO-ALÉATOIRES
Je n'ai pas regardé l'algo de hash mais à mon avis ça n'a rien à voir.

Tout générateur déterministe (entendre par là dont le prochain état est codable un certains nombre de bits) est forcément périodique. Dans ton cas je peux t'affirmer sans faire aucun test qu'il y a au moins une boucle de longueur au plus 2^32 (soit 4 milliard environ :-) ... Tout simplement parce que ta graine est stockée sur 32 bits.

Dans ton exemple avec 54 cartes, effectivement un tel générateur serait raisonnablement efficace.

Mais je pense que dans ce cas, il faut précalculer une séquence: faire un tableau d'environ 54 entiers, stoker une séquence aléatoire dedans au lancement du programme (avec randomize avant) puis définir une nouvelle fonction random qui renvoie successivement tous les éléments du tableau en revenant au début quand la fin est atteinte.

Pourquoi? Tout simplement parce que ça prend moins de temps de renvoyer le n-ième élément d'un tableau que de calculer un hash, faire des xor, etc... pour un résultat "statistiquement équivalent".


Le : 03/07/2009 15:48:04
Source : GÉNÉRATEUR DE NOMBRES PSEUDO-ALÉATOIRES
J'ai détecté une boucle de 8668 éléments avec le ou exclusif (elle commence à 305295269). Mais évidemment je n'ai pas fait de recherche exhaustive.

Effectivement si tu sais qu'une période de longueur N est acceptable alors si ton code fait au moins aussi bien c'est OK. Après il faut aussi regarder la répartition statistique des éléments des boucles (vérifier que c'est en gros uniforme dans l'intervalle).

Ce qui fait la difficulté de trouver des bons générateurs, c'est que pour une longueur de boucle minimale imposée, il doit aussi être très rapide à calculer. En ce sens les générateurs arithmétiques avec des modulo (comme celui de Borland) est un bon compromis...


Le : 03/07/2009 15:39:33
Source : GÉNÉRATEUR DE NOMBRES PSEUDO-ALÉATOIRES
Oui c'est ça.

Mais au-delà de 16 répétitions ça prend un temps monstrueux.

Le problème pour chercher les boucles c'est qu'il faut faire un compromis entre mémoire et vitesse. Il est possible d'aller un plus vite pour chercher une longue boucle en fixant une grande quantité de mémoire.


Le : 03/07/2009 15:11:17
Source : GÉNÉRATEUR DE NOMBRES PSEUDO-ALÉATOIRES
oups une petite erreur dans mon code plus haut (il trouvait bien les boucles mais affichait toujours qu'elles avaient une longueur de 2). Voici la nouvelle procédure:

--------------------------------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
  a,p:LongWord;
  b,c,d:Integer;
begin
  if Started then
    Exit;
  Stopped:=False;
  Started:=True;
  try
    p:=$1000000 div ((MAX_TAB+1)*(MAX_TAB+2));
    a:=Seed0 mod p;
    repeat
      Inc(a);
      if a=p then begin
        a:=0;
        Caption:=Format('Initial seed = %u',[Seed0]);
        Application.ProcessMessages;
        if Stopped then
          Break;
      end;
      Seed:=Seed0;
      Inc(Seed0);
      b:=1;
      Tab[0]:=Seed;
      repeat
        Random;
        c:=0;
        while (Tab[c]<Seed) and (c<b) do
          Inc(c);
        if Tab[c]=Seed then begin
          b:=0;
          repeat
            Tab[b]:=Seed;
            Random;
            Inc(b);
          until (Seed=Tab[0]) and (b>1);
          Tab[b]:=Seed;
          Memo1.Lines.Add(Format('Loop detected (Length = %u):',[b]));
          for c:=0 to b do
            Memo1.Lines.Add(Format('Seed(%u)=%u',[c,Tab[c]]));
          Memo1.Lines.Add('');
          Break;
        end;
        for d:=b downto c do
          Tab[d]:=Tab[d-1];
        Tab[c]:=Seed;
        Inc(b);
      until b>MAX_TAB;
    until Seed0=High(LongWord);
  finally
    Started:=False;
  end;
end;
--------------------------------------------------------------------------------

Et quelques résultats:

Loop detected (Length = 11):
Seed(0)=1576860536
Seed(1)=1243888324
Seed(2)=133932042
Seed(3)=3917576848
Seed(4)=1486399104
Seed(5)=1549541129
Seed(6)=1460177290
Seed(7)=4272665070
Seed(8)=1426530670
Seed(9)=1949176323
Seed(10)=3781238255
Seed(11)=1576860536

Loop detected (Length = 10):
Seed(0)=357440169
Seed(1)=2637825466
Seed(2)=826517477
Seed(3)=1427081938
Seed(4)=1610603249
Seed(5)=1231174083
Seed(6)=3321287677
Seed(7)=252121279
Seed(8)=1190741914
Seed(9)=1231279339
Seed(10)=357440169

Loop detected (Length = 3):
Seed(0)=1108601366
Seed(1)=563960130
Seed(2)=2017111036
Seed(3)=1108601366




Le : 03/07/2009 14:47:22
Source : GÉNÉRATEUR DE NOMBRES PSEUDO-ALÉATOIRES
Ca n'est pas suffisant. Par exemple, la fonction identité (F(x)=x) est elle aussi une bijection (l'image d'un nombre est unique puisque c'est lui-même :-) or si tu l'utilises sur ta graine tu obtiens une suite stationnaire (toujours la même valeur) qui est la pire fonction random qu'on puisse imaginer.

J'ai fait des essais avec la fonction que tu as postée en recherchant des boucles de longueur au plus 16 et j'ai trouvé plusieurs boucles de longueur 2 (j'ai fait varier la seed initiale entre 0 et un milliard et j'ai calculé les 8 permières valeurs):

Loop detected (Length = 2):
Seed(1)=1576860536
Seed(2)=1243888324

Loop detected (Length = 2):
Seed(1)=1460177290
Seed(2)=4272665070

Loop detected (Length = 2):
Seed(1)=357440169
Seed(2)=2637825466

Loop detected (Length = 2):
Seed(1)=1610603249
Seed(2)=1231174083

Loop detected (Length = 2):
Seed(1)=1190741914
Seed(2)=1231279339

Ca signifie que si jamais la graine atteint l'une de ces valeurs ton générateur va osciller entre les 2 valeurs.

Si tu veux tester voici le source qui recherche les boucles. Il faut 2 boutons sur une fiche, l'un "start" l'autre "stop" et un mémo pour l'affichage des résultats.

Pour chercher des boucles plus longues il faut augmenter la valeur de MAX_TAB.

--------------------------------------------------------------------------------
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, LEA_hash, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
    Started,Stopped:Boolean;
  end;

var
  Form1: TForm1;

implementation

const
  MAX_TAB=$F;

var
Seed: Longword;
Seed0: LongWord=0;
Tab:array[0..MAX_TAB] of Longword;

procedure randomize;
begin
Seed := GetTickCount; { On se base sur le temps machine }
end;

procedure Random;
Var
H: THash;
begin
H := Hash(Seed, 4);            { On récupère le hash de la valeur actuelle du générateur       }
Seed := H.A + H.B + H.C + H.D; { On attribue à la valeur actuelle la somme des entiers du hash }
end;


{$R *.dfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
  a,p:LongWord;
  b,c,d:Integer;
begin
  if Started then
    Exit;
  Stopped:=False;
  Started:=True;
  p:=$1000000 div ((MAX_TAB+1)*(MAX_TAB+2));
  a:=Seed0 mod p;
  try
    repeat
      Inc(a);
      if a=p then begin
        a:=0;
        Caption:=Format('Initial seed = %u',[Seed0]);
        Application.ProcessMessages;
        if Stopped then
          Break;
      end;
      Seed:=Seed0;
      Inc(Seed0);
      b:=1;
      Tab[0]:=Seed;
      repeat
        Random;
        c:=0;
        while (Tab[c]<Seed) and (c<b) do
          Inc(c);
        if Tab[c]=Seed then begin
          b:=0;
          repeat
            Tab[b]:=Seed;
            Random;
            Inc(b);
          until (Seed<>Tab[0]) and (b>1);
          Memo1.Lines.Add(Format('Loop detected (Length = %u):',[b]));
          for c:=0 to b-1 do
            Memo1.Lines.Add(Format('Seed(%u)=%u',[c+1,Tab[c]]));
          Memo1.Lines.Add('');
          Break;
        end;
        for d:=b downto c do
          Tab[d]:=Tab[d-1];
        Tab[c]:=Seed;
        Inc(b);
      until b>MAX_TAB;
    until Seed0=High(LongWord);
  finally
    Started:=False;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Stopped:=True;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Stopped:=True;
end;

end.

--------------------------------------------------------------------------------



Le : 03/07/2009 13:51:43
Source : GÉNÉRATEUR DE NOMBRES PSEUDO-ALÉATOIRES
Si tu fais disparaitre une boucle spécifique quelque part, rien ne te garantis que tu ne vas pas en créer une ailleurs...

Le mieux c'est peut-être de faire des tests (calculer la plus petite longueur de boucle) et si tu as de la chance tu auras peut-être une valeur élevée.


Le : 03/07/2009 12:40:30
Source : GÉNÉRATEUR DE NOMBRES PSEUDO-ALÉATOIRES
Oui c'est ça





Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Comparez les prix Nouvelle version


LG KP501

Entre 9€ et 159€


Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,156 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.