2010-08-08 5 views
2

J'ai un code C++ qui dépend fortement de l'échantillonnage (en utilisant rand()), mais je veux qu'il soit reproductible. Donc au début, j'initialise srand() avec une graine aléatoire et j'imprime cette graine. Je veux que les autres puissent utiliser le même code mais en initialisant srand() avec la même graine et obtenir exactement la même réponse que moi.Comment éliminer toutes les sources de hasard afin que le programme donne toujours des réponses identiques?

Mais dans quelles circonstances est-ce garanti? Je suppose que cela ne fonctionne que si les binaires sont compilés avec le même compilateur sur le même système? Quels sont les autres facteurs qui pourraient rendre la réponse différente de celle que j'ai obtenue initialement?

+0

C'est pourquoi j'aime le code pur/la programmation fonctionnelle. – strager

+0

Vraisemblablement, vous n'initialisez pas srand() avec une graine aléatoire? Ou bien vous êtes dans un processus infiniment récursif. –

+0

@Neil Haha, bon point, j'utilise un mélange de clock(), time (NULL) et getpid(). – Frank

Répondre

8

La solution est d'utiliser le même code dans tous les cas - la bibliothèque de nombres aléatoires Boost est infiniment mieux que tout Implémentation de la bibliothèque standard C++, et vous pouvez utiliser le même code sur toutes les plateformes. Jetez un oeil à this question par exemple de son utilisation et des liens vers les documents de la bibliothèque.

+0

Je vois. Donc, si je dis aux autres d'inclure, par exemple, le générateur de nombres aléatoires Boost 1.42 que j'ai utilisé et initialisé avec la même graine que j'ai utilisée, ils obtiendront exactement le même résultat? Même sur d'autres plateformes et en utilisant un autre compilateur? – Frank

+1

@dehmann Oui, c'est correct. –

+2

J'ajouterais que c'est correct seulement si vous prenez les chiffres de la même manière à chaque fois. Comme un autre mentionné dans les commentaires: si vous utilisez le même générateur de nombres pour plusieurs threads, par exemple, le résultat peut ne pas être reproductible. – n1ckp

3

Vous avez raison de dire que les séquences peuvent être différentes si elles sont compilées sur des machines différentes avec des implémentations rand différentes. La meilleure façon de contourner cela est d'écrire votre propre PRNG. La page de manuel Linux pour srand donne l'exemple simple suivant (cité de la norme POSIX):

POSIX.1-2001 donne l'exemple suivant d'une mise en œuvre de rand() et srand(), peut-être utile quand un a besoin de la même séquence sur deux machines différentes .

static unsigned long next = 1; 

/* RAND_MAX assumed to be 32767 */ 
int myrand(void) { 
    next = next * 1103515245 + 12345; 
    return((unsigned)(next/65536) % 32768); 
} 

void mysrand(unsigned seed) { 
    next = seed; 
} 
+7

Écrire votre propre RNG est la dernière alternative possible que vous devriez envisager. Il n'y a probablement aucune autre fonctionnalité, il est si facile de se tromper et si difficile à tester pour l'exactitude. –

0

Pour éviter ce genre de problème, écrivez votre propre implémentation de rand()! Je ne suis pas expert sur les algorithmes de génération de nombres aléatoires, donc je ne dirai pas plus que cela ...

+0

Ouais, il suffit de résoudre à nouveau ce que des milliers ont fait avant. C'est l'approche du programmeur True C. : P –

0

Découvrez implementation of rand(), et utilisez l'un des générateurs de nombres aléatoires à partir de là - ce qui garantit la répétabilité quelle que soit la plate-forme utilisée.