IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

rand() et srand()


Sujet :

C++

  1. #1
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut rand() et srand()
    Bonjour,

    L'autre jour, j'ai eu un petit soucis avec ces deux fonctions.
    En effet, il me fallait un nombre aléatoire compris entre 0 et 4 (pour un bête test, pas dans un gros programme donc).
    J'ai donc un code du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    srand(time(NULL));
    int i = 4*rand()/((float)RAND_MAX);
    ... et je me retrouve toujours avec la même valeur de i !
    Si par contre j'écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    srand(time(NULL));
    for (int i = 0; i < 20; ++i)
    {
        cout << (int)(4*rand()/((float)RAND_MAX)) << endl;
    }
    ... j'ai toujours le même nombre en premier, mais les autres changent d'une exécution à l'autre.

    Si j'affiche juste rand() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    srand(time(NULL));
    cout << rand() << endl
    return 0;
    ... ça me donne : 14010, 14039, 14066, ... Pas si aléatoire que ça

    Je ne sais pas exactement comment fonctionnent rand() et srand(), mais je crois que srand() définit la première valeur de rand(), qui sert ensuite à calculer la suivante, et ainsi de suite.
    J'aurai cru que la valeur donnée à srand() était un peu comme un indice dans un tableau de nombre aléatoires, mais il semblerai qu'il y ait une relation linéaire entre la valeur donnée à srand() et la première valeur de rand()...

    C'est intentionnel ? (je ne trouve pas ça très malin, m'enfin il doit y avoir une raison)
    Quelle valeur je devrais donner à srand() pour éviter ça ?

    Merci d'avance pour vos conseils.

    Edit : j'utilise gcc.

  2. #2
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Ils sont dans la même fonction srand() et rand()? Si oui alors enléve srand(). Il ne doit être appelé qu'une fois dans le programme car il permet d'initialiser la graine du générateur de nombre pseudo aléatoire qu'est rand().

    Pour plus de détail voir les entrées correspondantes dans la faq. (je crois que c'est dans la faq C)
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  3. #3
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut
    Non non, ce n'est pas le problème. Essaye :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int main()
    {
        srand(time(NULL));
        cout << rand() << endl;
        return 0;
    }
    Même en attendant une ou deux secondes entre deux exécutions, on retrouve presque le même nombre.

    Edit : après quelques tests, on vois que, si on a appelé srand(i), le premier rand() vaut (presque) : round(3.25*i)+38.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 16
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 57
    Points : 65
    Points
    65
    Par défaut
    J'ai aussi la même chose

    Ce qu'il reste à faire, c'est de ne pas prendre en compte la première valeur donnée par rand()... ou alors, vu que c'est seulement entre 1 et 4, tu peux utiliser le modulo:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    srand(time(NULL));
    for (int i = 0; i < 20; ++i)
    {
        cout << (rand()%4)+1 << endl;
    }
    Là tu n'aurais pas les mêmes valeurs de i pour deux exécutions successives (contrairement à la division)

  5. #5
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    C'est normal puisque tu relances le programme presque de suite la graine à peu changer. Quel programme se relancerait comme ça à 1 secondes d'intervalles ?
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 16
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 57
    Points : 65
    Points
    65
    Par défaut
    Citation Envoyé par Goten Voir le message
    C'est normal puisque tu relances le programme presque de suite la graine à peu changer. Quel programme se relancerait comme ça à 1 secondes d'intervalles ?
    La graine change, d'accord, mais ce qui est étonnant c'est que la première valeur donnée par rand() est cette graine et non pas un nombre aléatoire généré à partir de la graine.

  7. #7
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut
    Citation Envoyé par Goten Voir le message
    Quel programme se relancerait comme ça à 1 secondes d'intervalles ?
    Le mien
    C'est juste un programme de test, mais ça reste embêtant...

    @Dreambeliever : Oui, avec le modulo c'est nettement mieu

  8. #8
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Qu'en sait tu que c'est la graine? Moi j'en est aucune idée. (en fait je suis même sur que c'est pas la graine).


    De toute façon si tu as besoin de générateur plus poussé tourne toi vers boost::random.
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 16
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 57
    Points : 65
    Points
    65
    Par défaut
    Citation Envoyé par Goten Voir le message
    Qu'en sait tu que c'est la graine? Moi j'en est aucune idée. (en fait je suis même sur que c'est pas la graine).
    Bah alors il y a un gros problème: avec deux graines légèrement différentes, on obtient deux nombres aléatoires légèrement différents?

    voilà un test:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #include <iostream>
    #include "windows.h"
     
    using namespace std;
     
    int main()
    {
        for (int i = 0; i < 5; i++)
        {
     
            srand(time(NULL));
            cout << rand() << endl;
            Sleep(1000);
        }
     
        return 0;
    }
    1823
    1826
    1829
    1832
    1836
    Si le chiffre ne correspond pas à la graine modulo quelque chose (modulo RAND_MAX?), je ne vois pas comment expliquer des valeurs si rapprochées?

  10. #10
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Kalith Voir le message
    Non non, ce n'est pas le problème. Essaye :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int main()
    {
        srand(time(NULL));
        cout << rand() << endl;
        return 0;
    }
    Même en attendant une ou deux secondes entre deux exécutions, on retrouve presque le même nombre.
    Déjà, rand() renvoie un nombre PSEUDO-aléatoire... En initialisant avec la même valeur, tu retrouveras la même suite de chiffres (ne PAS tenter de l'utiliser en cryptographie, c'est très mauvais, cf. littérature dédiée).

    De plus, "time" renvoie un nombre de SECONDES depuis le 01/01/1970 : il est donc tout à fait normal que tu aie des valeurs "proches" sur deux lancements consécutifs... Essaie plutôt d'initialiser avec le champ microsecondes de "gettimeofday" (Unix), ou de "GetTickCount" (Windows).

    Sinon, voici un lien pour implémenter "gettimeofday" sur Windows, au besoin.
    Dans l'autre sens, un autre lien pour implémenter "GetTickCount" sur Linux...
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  11. #11
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Effectivement, on aurait pu espérer que le générateur aie une plus grande sensibilité à la graine; en gros que le delta entre deux graines successives provoquent des écarts plus importants dans les valeur générées.
    Si tu veux vraiment quelque chose d'aléatoire, alors tournes-toi vers de bibliothèques spécialisées. Et, comme le dit justement Goten, Boost.Random en est une : un tutoriel est d'ailleurs disponible sur le site.

    [EDIT] : comme mentionné plus haut, je te conseille aussi de faire un petit tour sur la FAQ C dans la partie consacrée à rand/srand.

  12. #12
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Citation Envoyé par Dreambeliever Voir le message
    Bah alors il y a un gros problème: avec deux graines légèrement différentes, on obtient deux nombres aléatoires légèrement différents?

    voilà un test:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #include <iostream>
    #include "windows.h"
     
    using namespace std;
     
    int main()
    {
        for (int i = 0; i < 5; i++)
        {
     
            srand(time(NULL));
            cout << rand() << endl;
            Sleep(1000);
        }
     
        return 0;
    }


    Si le chiffre ne correspond pas à la graine modulo quelque chose (modulo RAND_MAX?), je ne vois pas comment expliquer des valeurs si rapprochées?

    Ce que j'infirmais c'est que tu disais que c'est la valeur de la graine qu'on sortait dans le premier rand. Et non c'est la valeur ayant subit plusieurs opérations. (ça dépend de l'implémentation dans ton compilo).
    Si oui c'est normal comme expliqué plus haut, relancé plusieurs fois le programme avec des intervalles très court donnera des nombres très proche. Mais je répéte qui a besoin d'un programme qui se relance toute les x secondes?
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 16
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 57
    Points : 65
    Points
    65
    Par défaut
    Ca me choque quand même...

    En tout cas j'aurais appris qu'il vaut mieux commencer par écarter la première valeur de rand() générée, ce que je ne savais pas

  14. #14
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Goten Voir le message
    Ce que j'infirmais c'est que tu disais que c'est la valeur de la graine qu'on sortait dans le premier rand.
    D'où l'importance d'initialiser la génération avec une valeur elle-même quasi-aléatoire, via l'utilisation de timers à haute résolution... Et non pas l'exemple classique avec "time" qui devrait valoir le bûcher à tous ceux qui l'utilisent !!

    Pour ma part, sur Windows, j'utilise systématiquement QueryPerformanceCounter (résolution de l'ordre de la nanoseconde en général) pour initialiser mes séquences aléatoires... Voire carrément en guise de générateur aléatoire, après application d'un modulo !
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  15. #15
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Mac LAK : Si tu veux du gros aléatoire, utilise carrément CryptGenRandom()...

    Ou bien rand_s() sous Visual 2005, qui wrappe tout ça.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  16. #16
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Mac LAK : Si tu veux du gros aléatoire, utilise carrément CryptGenRandom()...
    C'est plutôt du "petit aléatoire" que je veux en général, d'où l'utilisation du QueryPerformanceCounter modulo N : je veux surtout avoir des valeurs "aléatoires", mais rapidement avec le moins d'overhead possible (génération de valeurs de test habituellement). Je fais donc en général mon modulo sur une puissance de deux via un masque binaire...

    Citation Envoyé par Médinoc Voir le message
    Ou bien rand_s() sous Visual 2005, qui wrappe tout ça.
    Plutôt fan de Delphi, à titre perso...
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  17. #17
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Effectivement, on aurait pu espérer que le générateur aie une plus grande sensibilité à la graine; en gros que le delta entre deux graines successives provoquent des écarts plus importants dans les valeur générées.
    En fait, c'est le cas... à partir du troisième ou du quatrième appel à rand() (et même dans des librairies compliquées d'ailleurs). En général, il est toujours bon, (surtout si on utilise rand() sur plusieurs seed différentes), de l'initialiser avec faire plusieurs appels avant d'en utiliser les résultats, certaines implémentations de la librairie C le font.

    Maintenant, ce n'est pas la bonne façon de faire. Les générateurs de nombres au hasard garantissent un certain niveau de "hasard" entre leurs appels successifs, mais rien du tout sur les corrélations entre deux séries distinctes. En fait deux séries distinctes issues d'un même générateur produiront les mêmes séries, mais avec un point de départ différent...

    Dans le cas précis, le problème a deux origines:

    1-l'implémentation de rand() selon gcc renvoie apparemment la racine passée à srand() lors du premier appel. C'est pas malin, mais il suffit de le savoir...

    2- les racines passées n'étaient pas aléatoires du tout. Si je passe ma date de naissance, ca ne va pas marcher non plus, mais ce ne sera pas la faute de rand()

    Francois
    Dernière modification par Invité ; 17/06/2009 à 16h56.

  18. #18
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par fcharton Voir le message
    En fait, c'est le cas... à partir du troisième ou du quatrième appel à rand() (et même dans des librairies compliquées d'ailleurs).
    On aurait pu espérer avoir une dispersion plus forte dès le premier tirage?

    Citation Envoyé par fcharton Voir le message
    En général, il est toujours bon, si on utilise rand() dans un même programme, et, sur plusieurs seed différentes, de faire plusieurs appels à rand() avant d'en utiliser les résultats.
    Intéressant. En fait, dans les projets où j'ai eu besoin d'aléatoire, celui-ci était toujours généré par du hardware avec tout un tas de traitement pour vérifier les propriétés du nombre tiré. En fait, je n'ai jamais vu rand utilisé dans un projet pro.

  19. #19
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Mais dans un projet où l'aléatoire doit être reproductible, il faut un algorithme pseudo-aléatoire...

    Typiquement, dans ces cas là, j'utilise time() (ou plus précis) pour obtenir la graine si elle n'est pas passée en paramètre, j'affiche ou loggue la graine, puis j'utilise rand().
    Peut s'avérer très utile.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  20. #20
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    En fait, je n'ai jamais vu rand utilisé dans un projet pro.
    Je l'ai souvent vu utiliser dans ma branche (traitement de données), quand on doit "mélanger" des enregistrements. Par exemple, des données d'enquête sont souvent présentées selon un ordre pas aléatoire (en fonction des enquêteurs qui les ont effectués, ou des sous échantillons qui constituent l'étude, ou de leur date de collecte). Pour éviter de "perpetuer" ces biais éventuels on peut vouloir mélanger les données, et rand(), rapide et toujours disponible, est un bon candidat.

    Autre cas, des applis où l'on a besoin de vitesse plus que d'alea "pur". Des algorithmes de recherche, comme les algos génétiques, sont souvent de gros consommateurs de tirages au sort, mais où la parfaite uniformité du générateur n'a aucune importance. Les générateurs congruentiels (en fait, des formes plus simples que rand() même sont souvent des choix raisonnables, en raison de leur vitesse d'exécution.

    En traitement de données, le pseudo aléatoire présente un autre avantage : à seed égale, le programme est parfaitement déterministe. C'est très important pour débuguer, ou pour n'avoir pas à expliquer au client pourquoi le même programme rend des résultats lègèrements différents d'une fois sur l'autre (c'est généralement assez cocasse...).

    Ca dépend carrément du sujet, quoi...

    Francois

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. rand() et srand()
    Par Thosbk dans le forum Débuter
    Réponses: 7
    Dernier message: 03/12/2012, 09h34
  2. [xcode] rand et srand
    Par the_nmy dans le forum XCode
    Réponses: 7
    Dernier message: 07/12/2011, 09h22
  3. [PHP 5.3] Exception avec srand & rand: aucun résultat
    Par max235 dans le forum Langage
    Réponses: 1
    Dernier message: 23/12/2010, 21h25
  4. Problème avec srand() et rand()
    Par rouliane dans le forum C++
    Réponses: 10
    Dernier message: 16/12/2007, 19h35
  5. srand et rand & fonction c++
    Par casafa dans le forum C++
    Réponses: 5
    Dernier message: 27/12/2005, 00h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo