J essaie de faire generer des nombres aleatoires à X processus venant de
X fork() d'un processus père.
Quand chacun d'eux genere un nombre aleatoire avec random() ou rand(),
meme avec (1+(int) (10.0*rand()/(RAND_MAX+1.0))) , tous me renvoient la
meme valeur exactement.
Comment cela se fait il ?
Et comment avoir X processus générant des valeurs différentes ?
Alexandre Gouraud writes: Ca depend du generateur. Pour certains, utiliser un nombre de la sequence comme graine permet de regenerer la sequence... donc tu n'auras pas l'effet voulu.
Tu peux expliquer un peu plus, parce que je ne suis pas sur de comprendre. Des séquences aléatoires, j'imagine qu'il n'y en a qu'une sur un générateur de bruit. La seul différence, c'est qu'on la démarre à chaque fois à un endroit différent. Donc de toute façon, utiliser un nombre de la séquence ou pas, on en revient toujours à regenérer la séquence, décalée, quelle que soit la méthode utilisée. Est-ce que c'est ce que tu voulais dire ?
Ce qu'il voulait dire je crois, c'est que pour certains générateurs, srand(rand()) fait la même chose que rand(), c'est à dire que si je fais:
Alors on a r1==r2. Ce n'est pas le cas avec le générateur de la glibc: (, 8) ~/tmp $ cc -Wall rand.c -o rand (, 9) ~/tmp $ ./rand 846930886 == 1362961854 ? 0 (et si mes souvenirs sont bons, ce n'est pas le cas plus avec celui de la libc BSD)
Mais pour certains générateur, peut-être. Et dans ce cas, la solution de Jean-Marc n'est pas idéale:
pid_t pid;
int seed = rand(); pid = fork();
if (pid < 0) { ... erreur ... } else if (pid > 0) { .... le père .... } else { srand(seed); .... le fils .... }
Les nombres du père et du fils sont les mêmes avec un générateur qui utilise la valeur du précédent appel à rand()comme graine. Mainteant, je ne sais pas s'il existe réellement des générateurs ayant ce comportement.
Je ne sais pas si j'ai été bien clair, mais j'espère ;)
-- Gael Le Mignot "Kilobug" - - http://kilobug.free.fr GSM : 06.71.47.18.22 (in France) ICQ UIN : 7299959 Fingerprint : 1F2C 9804 7505 79DF 95E6 7323 B66B F67B 7103 C5DA
Member of HurdFr: http://hurdfr.org - The GNU Hurd: http://hurd.gnu.org
Jean-Marc Bourguet wrote:
Alexandre Gouraud <ag@tb.fr> writes:
Ca depend du generateur. Pour certains, utiliser un nombre de la
sequence comme graine permet de regenerer la sequence... donc tu
n'auras pas l'effet voulu.
Tu peux expliquer un peu plus, parce que je ne suis pas sur de
comprendre. Des séquences aléatoires, j'imagine qu'il n'y en a qu'une
sur un générateur de bruit. La seul différence, c'est qu'on la démarre
à chaque fois à un endroit différent. Donc de toute façon, utiliser un
nombre de la séquence ou pas, on en revient toujours à regenérer la
séquence, décalée, quelle que soit la méthode utilisée. Est-ce que
c'est ce que tu voulais dire ?
Ce qu'il voulait dire je crois, c'est que pour certains générateurs,
srand(rand()) fait la même chose que rand(), c'est à dire que si je fais:
Alors on a r1==r2. Ce n'est pas le cas avec le générateur de la glibc:
(gael@pc137082, 8) ~/tmp $ cc -Wall rand.c -o rand
(gael@pc137082, 9) ~/tmp $ ./rand
846930886 == 1362961854 ? 0
(et si mes souvenirs sont bons, ce n'est pas le cas plus avec celui de
la libc BSD)
Mais pour certains générateur, peut-être. Et dans ce cas, la solution
de Jean-Marc n'est pas idéale:
pid_t pid;
int seed = rand();
pid = fork();
if (pid < 0)
{
... erreur ...
}
else if (pid > 0)
{
.... le père ....
}
else
{
srand(seed);
.... le fils ....
}
Les nombres du père et du fils sont les mêmes avec un générateur qui
utilise la valeur du précédent appel à rand()comme graine. Mainteant,
je ne sais pas s'il existe réellement des générateurs ayant ce
comportement.
Je ne sais pas si j'ai été bien clair, mais j'espère ;)
--
Gael Le Mignot "Kilobug" - kilobug@nerim.net - http://kilobug.free.fr
GSM : 06.71.47.18.22 (in France) ICQ UIN : 7299959
Fingerprint : 1F2C 9804 7505 79DF 95E6 7323 B66B F67B 7103 C5DA
Member of HurdFr: http://hurdfr.org - The GNU Hurd: http://hurd.gnu.org
Alexandre Gouraud writes: Ca depend du generateur. Pour certains, utiliser un nombre de la sequence comme graine permet de regenerer la sequence... donc tu n'auras pas l'effet voulu.
Tu peux expliquer un peu plus, parce que je ne suis pas sur de comprendre. Des séquences aléatoires, j'imagine qu'il n'y en a qu'une sur un générateur de bruit. La seul différence, c'est qu'on la démarre à chaque fois à un endroit différent. Donc de toute façon, utiliser un nombre de la séquence ou pas, on en revient toujours à regenérer la séquence, décalée, quelle que soit la méthode utilisée. Est-ce que c'est ce que tu voulais dire ?
Ce qu'il voulait dire je crois, c'est que pour certains générateurs, srand(rand()) fait la même chose que rand(), c'est à dire que si je fais:
Alors on a r1==r2. Ce n'est pas le cas avec le générateur de la glibc: (, 8) ~/tmp $ cc -Wall rand.c -o rand (, 9) ~/tmp $ ./rand 846930886 == 1362961854 ? 0 (et si mes souvenirs sont bons, ce n'est pas le cas plus avec celui de la libc BSD)
Mais pour certains générateur, peut-être. Et dans ce cas, la solution de Jean-Marc n'est pas idéale:
pid_t pid;
int seed = rand(); pid = fork();
if (pid < 0) { ... erreur ... } else if (pid > 0) { .... le père .... } else { srand(seed); .... le fils .... }
Les nombres du père et du fils sont les mêmes avec un générateur qui utilise la valeur du précédent appel à rand()comme graine. Mainteant, je ne sais pas s'il existe réellement des générateurs ayant ce comportement.
Je ne sais pas si j'ai été bien clair, mais j'espère ;)
-- Gael Le Mignot "Kilobug" - - http://kilobug.free.fr GSM : 06.71.47.18.22 (in France) ICQ UIN : 7299959 Fingerprint : 1F2C 9804 7505 79DF 95E6 7323 B66B F67B 7103 C5DA
Member of HurdFr: http://hurdfr.org - The GNU Hurd: http://hurd.gnu.org
Jean-Marc Bourguet
(Gaël Le Mignot) writes:
Jean-Marc Bourguet wrote:
Alexandre Gouraud writes: Ca depend du generateur. Pour certains, utiliser un nombre de la sequence comme graine permet de regenerer la sequence... donc tu n'auras pas l'effet voulu.
Tu peux expliquer un peu plus, parce que je ne suis pas sur de comprendre. Des séquences aléatoires, j'imagine qu'il n'y en a qu'une sur un générateur de bruit. La seul différence, c'est qu'on la démarre à chaque fois à un endroit différent. Donc de toute façon, utiliser un nombre de la séquence ou pas, on en revient toujours à regenérer la séquence, décalée, quelle que soit la méthode utilisée. Est-ce que c'est ce que tu voulais dire ?
Ce qu'il voulait dire je crois, c'est que pour certains générateurs, srand(rand()) fait la même chose que rand(), c'est à dire que si je fais:
Alors on a r1==r2. Ce n'est pas le cas avec le générateur de la glibc:
Ce n'est pas non plus le cas avec les generateurs que je viens d'essayer (qui ont tous RAND_MAX = 32767 sur des machines 32 bits, ce qui explique peut-etre). Je me souviens pourtant m'etre servis de cette propriete (que je savais non portable, c'etait pour debugger un autre probleme) dans le temps.
Tiens, RAND_MAX n'est pas 32767. Si c'est 2^31-1, et que tu as sur une machine 32 bits il y a un risque que le probleme arrive une fois sur deux. Enfin, c'est pas tres complique de l'eviter il suffit de modifier la graine de maniere deterministe dans srand.
(et si mes souvenirs sont bons, ce n'est pas le cas plus avec celui de la libc BSD)
Mais pour certains générateur, peut-être. Et dans ce cas, la solution de Jean-Marc n'est pas idéale:
Ce n'est certainement pas ma solution: j'indiquais le probleme potentiel.
pid_t pid;
int seed = rand();
int seed = rand() ^ 0xDEADBEEF;
et on est bon.
A+
-- Jean-Marc FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc Site de usenet-fr: http://www.usenet-fr.news.eu.org
kilobug@freesurf.fr (Gaël Le Mignot) writes:
Jean-Marc Bourguet wrote:
Alexandre Gouraud <ag@tb.fr> writes:
Ca depend du generateur. Pour certains, utiliser un nombre de la
sequence comme graine permet de regenerer la sequence... donc tu
n'auras pas l'effet voulu.
Tu peux expliquer un peu plus, parce que je ne suis pas sur de
comprendre. Des séquences aléatoires, j'imagine qu'il n'y en a qu'une
sur un générateur de bruit. La seul différence, c'est qu'on la démarre
à chaque fois à un endroit différent. Donc de toute façon, utiliser un
nombre de la séquence ou pas, on en revient toujours à regenérer la
séquence, décalée, quelle que soit la méthode utilisée. Est-ce que
c'est ce que tu voulais dire ?
Ce qu'il voulait dire je crois, c'est que pour certains générateurs,
srand(rand()) fait la même chose que rand(), c'est à dire que si je
fais:
Alors on a r1==r2. Ce n'est pas le cas avec le générateur de la glibc:
Ce n'est pas non plus le cas avec les generateurs que je viens
d'essayer (qui ont tous RAND_MAX = 32767 sur des machines 32 bits, ce
qui explique peut-etre). Je me souviens pourtant m'etre servis de
cette propriete (que je savais non portable, c'etait pour debugger un
autre probleme) dans le temps.
Tiens, RAND_MAX n'est pas 32767. Si c'est 2^31-1, et que tu as sur
une machine 32 bits il y a un risque que le probleme arrive une fois
sur deux. Enfin, c'est pas tres complique de l'eviter il suffit de
modifier la graine de maniere deterministe dans srand.
(et si mes souvenirs sont bons, ce n'est pas le cas plus avec celui de
la libc BSD)
Mais pour certains générateur, peut-être. Et dans ce cas, la solution
de Jean-Marc n'est pas idéale:
Ce n'est certainement pas ma solution: j'indiquais le probleme
potentiel.
pid_t pid;
int seed = rand();
int seed = rand() ^ 0xDEADBEEF;
et on est bon.
A+
--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Alexandre Gouraud writes: Ca depend du generateur. Pour certains, utiliser un nombre de la sequence comme graine permet de regenerer la sequence... donc tu n'auras pas l'effet voulu.
Tu peux expliquer un peu plus, parce que je ne suis pas sur de comprendre. Des séquences aléatoires, j'imagine qu'il n'y en a qu'une sur un générateur de bruit. La seul différence, c'est qu'on la démarre à chaque fois à un endroit différent. Donc de toute façon, utiliser un nombre de la séquence ou pas, on en revient toujours à regenérer la séquence, décalée, quelle que soit la méthode utilisée. Est-ce que c'est ce que tu voulais dire ?
Ce qu'il voulait dire je crois, c'est que pour certains générateurs, srand(rand()) fait la même chose que rand(), c'est à dire que si je fais:
Alors on a r1==r2. Ce n'est pas le cas avec le générateur de la glibc:
Ce n'est pas non plus le cas avec les generateurs que je viens d'essayer (qui ont tous RAND_MAX = 32767 sur des machines 32 bits, ce qui explique peut-etre). Je me souviens pourtant m'etre servis de cette propriete (que je savais non portable, c'etait pour debugger un autre probleme) dans le temps.
Tiens, RAND_MAX n'est pas 32767. Si c'est 2^31-1, et que tu as sur une machine 32 bits il y a un risque que le probleme arrive une fois sur deux. Enfin, c'est pas tres complique de l'eviter il suffit de modifier la graine de maniere deterministe dans srand.
(et si mes souvenirs sont bons, ce n'est pas le cas plus avec celui de la libc BSD)
Mais pour certains générateur, peut-être. Et dans ce cas, la solution de Jean-Marc n'est pas idéale:
Ce n'est certainement pas ma solution: j'indiquais le probleme potentiel.
pid_t pid;
int seed = rand();
int seed = rand() ^ 0xDEADBEEF;
et on est bon.
A+
-- Jean-Marc FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc Site de usenet-fr: http://www.usenet-fr.news.eu.org
Alors on a r1==r2. Ce n'est pas le cas avec le générateur de la glibc:
Ce n'est pas non plus le cas avec les generateurs que je viens d'essayer (qui ont tous RAND_MAX = 32767 sur des machines 32 bits, ce qui explique peut-etre). Je me souviens pourtant m'etre servis de cette propriete (que je savais non portable, c'etait pour debugger un autre probleme) dans le temps.
Tiens, RAND_MAX n'est pas 32767. Si c'est 2^31-1, et que tu as sur une machine 32 bits il y a un risque que le probleme arrive une fois sur deux. Enfin, c'est pas tres complique de l'eviter il suffit de modifier la graine de maniere deterministe dans srand.
Oui, c'est une machine 32-bits et RAND_MAX est de 2^31-1, et la période de 16*(22^31-1) d'après la doc, je ne sais pas exacteemnt comment ils font, mais je crois que le calcul en interne est fait sur plus de bits (et lors d'un srand, certains des bits sont calculés à partir des autres bits du paramètre)
(et si mes souvenirs sont bons, ce n'est pas le cas plus avec celui de la libc BSD)
Mais pour certains générateur, peut-être. Et dans ce cas, la solution de Jean-Marc n'est pas idéale:
Ce n'est certainement pas ma solution: j'indiquais le probleme potentiel.
oulàlà, pardon, oui j'ai confondu celui qui avait proposé la solution à base de "je prends un nombre de la séquence et je m'en sers comme graine" avec ta remarque, je devrai faire plus gaffe, au temps pour moi.
pid_t pid;
int seed = rand();
int seed = rand() ^ 0xDEADBEEF;
et on est bon.
Oui, par exemple :)
-- Gael Le Mignot "Kilobug" - - http://kilobug.free.fr GSM : 06.71.47.18.22 (in France) ICQ UIN : 7299959 Fingerprint : 1F2C 9804 7505 79DF 95E6 7323 B66B F67B 7103 C5DA
Member of HurdFr: http://hurdfr.org - The GNU Hurd: http://hurd.gnu.org
Alors on a r1==r2. Ce n'est pas le cas avec le générateur de la glibc:
Ce n'est pas non plus le cas avec les generateurs que je viens
d'essayer (qui ont tous RAND_MAX = 32767 sur des machines 32 bits, ce
qui explique peut-etre). Je me souviens pourtant m'etre servis de
cette propriete (que je savais non portable, c'etait pour debugger un
autre probleme) dans le temps.
Tiens, RAND_MAX n'est pas 32767. Si c'est 2^31-1, et que tu as sur
une machine 32 bits il y a un risque que le probleme arrive une fois
sur deux. Enfin, c'est pas tres complique de l'eviter il suffit de
modifier la graine de maniere deterministe dans srand.
Oui, c'est une machine 32-bits et RAND_MAX est de 2^31-1, et la
période de 16*(22^31-1) d'après la doc, je ne sais pas exacteemnt
comment ils font, mais je crois que le calcul en interne est fait sur
plus de bits (et lors d'un srand, certains des bits sont calculés à
partir des autres bits du paramètre)
(et si mes souvenirs sont bons, ce n'est pas le cas plus avec celui de
la libc BSD)
Mais pour certains générateur, peut-être. Et dans ce cas, la solution
de Jean-Marc n'est pas idéale:
Ce n'est certainement pas ma solution: j'indiquais le probleme
potentiel.
oulàlà, pardon, oui j'ai confondu celui qui avait proposé la solution
à base de "je prends un nombre de la séquence et je m'en sers comme
graine" avec ta remarque, je devrai faire plus gaffe, au temps pour
moi.
pid_t pid;
int seed = rand();
int seed = rand() ^ 0xDEADBEEF;
et on est bon.
Oui, par exemple :)
--
Gael Le Mignot "Kilobug" - kilobug@nerim.net - http://kilobug.free.fr
GSM : 06.71.47.18.22 (in France) ICQ UIN : 7299959
Fingerprint : 1F2C 9804 7505 79DF 95E6 7323 B66B F67B 7103 C5DA
Member of HurdFr: http://hurdfr.org - The GNU Hurd: http://hurd.gnu.org
Alors on a r1==r2. Ce n'est pas le cas avec le générateur de la glibc:
Ce n'est pas non plus le cas avec les generateurs que je viens d'essayer (qui ont tous RAND_MAX = 32767 sur des machines 32 bits, ce qui explique peut-etre). Je me souviens pourtant m'etre servis de cette propriete (que je savais non portable, c'etait pour debugger un autre probleme) dans le temps.
Tiens, RAND_MAX n'est pas 32767. Si c'est 2^31-1, et que tu as sur une machine 32 bits il y a un risque que le probleme arrive une fois sur deux. Enfin, c'est pas tres complique de l'eviter il suffit de modifier la graine de maniere deterministe dans srand.
Oui, c'est une machine 32-bits et RAND_MAX est de 2^31-1, et la période de 16*(22^31-1) d'après la doc, je ne sais pas exacteemnt comment ils font, mais je crois que le calcul en interne est fait sur plus de bits (et lors d'un srand, certains des bits sont calculés à partir des autres bits du paramètre)
(et si mes souvenirs sont bons, ce n'est pas le cas plus avec celui de la libc BSD)
Mais pour certains générateur, peut-être. Et dans ce cas, la solution de Jean-Marc n'est pas idéale:
Ce n'est certainement pas ma solution: j'indiquais le probleme potentiel.
oulàlà, pardon, oui j'ai confondu celui qui avait proposé la solution à base de "je prends un nombre de la séquence et je m'en sers comme graine" avec ta remarque, je devrai faire plus gaffe, au temps pour moi.
pid_t pid;
int seed = rand();
int seed = rand() ^ 0xDEADBEEF;
et on est bon.
Oui, par exemple :)
-- Gael Le Mignot "Kilobug" - - http://kilobug.free.fr GSM : 06.71.47.18.22 (in France) ICQ UIN : 7299959 Fingerprint : 1F2C 9804 7505 79DF 95E6 7323 B66B F67B 7103 C5DA
Member of HurdFr: http://hurdfr.org - The GNU Hurd: http://hurd.gnu.org
Eric Deveaud
Gaël Le Mignot wrote:
Oui, c'est possible aussi (mais il faut toujours penser à mettre la graine du père avant)
pour qu'il y ait fils il faut en effet que la graine du père ait été mise avant ;-)
-- HB: Quant à Linux [..] trés bon système d'exploitation, mais difficile HB: à implanter en entreprise, pour des raisons non techniques. Dont celle-ci : Le singe préfère la voiture rouge. -+- MB, in Guide du linuxien pervers - "Bien configurer son singe" -+-
Gaël Le Mignot wrote:
Oui, c'est possible aussi (mais il faut toujours penser à mettre la
graine du père avant)
pour qu'il y ait fils il faut en effet que la graine du père ait été
mise avant ;-)
--
HB: Quant à Linux [..] trés bon système d'exploitation, mais difficile
HB: à implanter en entreprise, pour des raisons non techniques.
Dont celle-ci : Le singe préfère la voiture rouge.
-+- MB, in Guide du linuxien pervers - "Bien configurer son singe" -+-
Oui, c'est possible aussi (mais il faut toujours penser à mettre la graine du père avant)
pour qu'il y ait fils il faut en effet que la graine du père ait été mise avant ;-)
-- HB: Quant à Linux [..] trés bon système d'exploitation, mais difficile HB: à implanter en entreprise, pour des raisons non techniques. Dont celle-ci : Le singe préfère la voiture rouge. -+- MB, in Guide du linuxien pervers - "Bien configurer son singe" -+-
un.gabacho.sans.pourrier
Pascal writes:
Emmanuel Delahaye wrote:
Il n'y a pas de 'processus' ou de 'fork()' en langage C. Merci de reposter sur un forum dédié à ton système. Celui-ci a probalement un générateur de random multi-processus. (au hasard : '/dev/random')
Je suis en partie d'accord avec toi, mais une partie de sa question traite du C. Tu as tendance a jouer au modérateur, mais la je trouve que t'exagère. Je ne crois pas que son post pollue le ng, et je pense que t'aurais pu t'abstenir de poster une réponse aussi inutile.
Emmanuel : « si je te gêne, ne me lis plus ». C'est pas ça qu'il a répondu ?
Pascal <fuck@versign.com> writes:
Emmanuel Delahaye wrote:
Il n'y a pas de 'processus' ou de 'fork()' en langage C. Merci de
reposter sur un forum dédié à ton système. Celui-ci a probalement un
générateur de random multi-processus. (au hasard : '/dev/random')
Je suis en partie d'accord avec toi, mais une partie de sa question
traite du C. Tu as tendance a jouer au modérateur, mais la je trouve
que t'exagère. Je ne crois pas que son post pollue le ng, et je pense
que t'aurais pu t'abstenir de poster une réponse aussi inutile.
Emmanuel : « si je te gêne, ne me lis plus ».
C'est pas ça qu'il a répondu ?
Il n'y a pas de 'processus' ou de 'fork()' en langage C. Merci de reposter sur un forum dédié à ton système. Celui-ci a probalement un générateur de random multi-processus. (au hasard : '/dev/random')
Je suis en partie d'accord avec toi, mais une partie de sa question traite du C. Tu as tendance a jouer au modérateur, mais la je trouve que t'exagère. Je ne crois pas que son post pollue le ng, et je pense que t'aurais pu t'abstenir de poster une réponse aussi inutile.
Emmanuel : « si je te gêne, ne me lis plus ». C'est pas ça qu'il a répondu ?
Laurent Wacrenier
Emmanuel Delahaye écrit:
Il n'y a pas de 'processus' ou de 'fork()' en langage C. Merci de reposter sur un forum dédié à ton système. Celui-ci a probalement un générateur de random multi-processus. (au hasard : '/dev/random')
Le standard ne défini pas l'entropie attendue de rand(). Si ça tombe, dans cette implémentation, rand() renvoie toujours la même chose.
Emmanuel Delahaye <emdelYOURBRA@noos.fr> écrit:
Il n'y a pas de 'processus' ou de 'fork()' en langage C. Merci de reposter
sur un forum dédié à ton système. Celui-ci a probalement un générateur de
random multi-processus. (au hasard : '/dev/random')
Le standard ne défini pas l'entropie attendue de rand(). Si ça tombe,
dans cette implémentation, rand() renvoie toujours la même chose.
Il n'y a pas de 'processus' ou de 'fork()' en langage C. Merci de reposter sur un forum dédié à ton système. Celui-ci a probalement un générateur de random multi-processus. (au hasard : '/dev/random')
Le standard ne défini pas l'entropie attendue de rand(). Si ça tombe, dans cette implémentation, rand() renvoie toujours la même chose.