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

Algorithmes et structures de données Discussion :

générer un entier [a, b] avec un RANDOM {0;1}


Sujet :

Algorithmes et structures de données

  1. #1
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut générer un entier [a, b] avec un RANDOM {0;1}
    Bonjour,

    Admettons que j'ai une fonction qui renvoie 0 ou 1, aléatoirement.
    Ca fait partie d'un exo d'un livre, et j'aimerais savoir si la solution que j'ai trouvé est satisfaisante.

    Comment avoir un entier compris entre deux bornes a et b? La solution que j'ai trouvé a une complexité moyenne de (b-a), ce qui ne me semble pas idéal...

    Voilà le principe, avant le pseudo-code:

    Tant que l'écart entre b et a inclus contient un nombre de nombres pair, je divise la poire en deux avec le RANDOM{0; 1}.

    Ensuite, pour chaque entier possible (c'est à dire de a à b), je fait une série d'appels à la fonction RANDOM jusqu'à ce qu'elle m'envoie 0. Soit n ce nombre. Si n est inférieur au n maximum déjà trouvé, j'abandonne le nombre...

    A la fin j'ai une liste beaucoup plus petite (en moyenne deux éléments..), et je peux répéter la procédure.

    Voilà le pseudo-code:

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    procedure RANDOM(a, b)
    //REDUCTION DE L'INTERVALLE
    tant que b-a impair //nombre pair de nombres entre a et b
      si rand(0, 1) = 0
        a + (b-a+1)/2 -> a //on augmente la borne inférieure
      sinon
        b - (b-a+1)/2 -> b //on diminue la borne supérieure
    fin tant que
     
    si a = b RETURN a
     
    //ON PARCOURE TOUS LES NOMBRES
    0 -> max
    0 -> nb_stocké
    tableau A[1..k] //k est ce qu'on veut, on peut agrandir le tableau de toute facon si il y a trop de nombres
    pour i de a à b
       0->essais
       tant que rand(0, 1) = 1
           essais++
       si essais > max
           1 -> nb_stocké
           essais -> max
           i -> A[nb_stocké]
       sinon si essais = max
           nb_stocké++
           i -> A[nb_stocké]
    fin pour
    //A ce stade on n'a qu'un faible nombre de nombres dans A, il est facile d'extraire par la même méthode un nombre unique
    ...
    Voilà, je n'ai pas mis la fin car elle se répète avec la première partie.
    C'est juste que pour générer un nombre entre 0 et 3 millions, je devrais me taper 3 millions de calculs...

    Sinon il m'est venu une autre idée.
    On ne peux pas utiliser la génération aléatoire de bits directement, car si le nombre n'est pas une puissance de 2 alors la méthode sera forcément faussée.
    Mais alors le coût est de lg(n)...

    Donc, si on prend notre intervalle b-a et qu'on utilise la méthode en lg(n) pour génerer un nombre entre 0 et la plus petite puissance de 2 plus grande que b-a?

    On ajoute ce nombre à a, s'il est hors-portée, on réessaye. Là normalement le nombre moyen d'essais est de moins de 2. On a donc un algo en lg(n)!
    _____________________________________________________

    Cependant je me demande si il n'y a pas une erreur quelquepart, et je voudrais avoir votre avis (ainsi que si une solution ou méthode existe, quelle est-elle?)

    Merci beaucoup,
    Coyote508

  2. #2
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut


    pourquoi faire simple quand on peut faire complique

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    nombre  = a + (random{0,1} * (b-a))

  3. #3
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut
    Désolé,
    La fonction me donne que 0 ou 1, pas un flottant entre.

    C'est vrai que ça aurait été plus simple

  4. #4
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut
    Générer un flottant entre 0 et 1 en binaire
    x=0.n0n1n2.........
    Toutes les décimales sont 0 ou 1.
    En n étapes on atteint une précision de l'ordre de 1/2n
    Par la suite si on veut un entier aléatoire entre a et b
    prendre d=b-a
    et n=a+dx
    Reste à déterminer n en fonction de d.
    Il suffit de prendre n suffisamment grand pour que 2^n >d
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  5. #5
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Par défaut
    Bonjour,

    une fonction qui ne donne que des 0 ou 1 !!!!!!
    Quelle horreur !!!!
    Mais en algo il y a presque toujours une solution alors en voilà une :
    - tu génères N nombre aléatoires avec ta fonction que tu stockes dans l'ordre d'apparition.
    - le nombre ainsi formé peut être converti en décimal, puis divisé par 2^N-1.
    - tu obtiens ainsi un nombre aléatoire dans [0,1].
    - ensuite tu utilises la petite fonction que l'on vient de te proposer
    Voilà
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  6. #6
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut
    Ok, mais ca me donne pas une solution totalement totalement aléatoire

    Sinon,
    • si on prend la plus petite puissance de 2 supérieure à b-a,
    • qu'on génère un nombre aléatoire entre 0 et cette puissance de 2 - 1 (en générant chaque bit aléatoirement),
    • et que si le nombre est compris entre 0 et b-a on le garde
    • sinon on reessaye,


    Ca marche pas?

  7. #7
    Membre très actif

    Profil pro
    Étudiant
    Inscrit en
    Décembre 2004
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2004
    Messages : 499
    Par défaut
    comme le dit toto13 si les 0 et les 1 sont totalement aléatoires le nombre compris entre 0 et 2^n-1 sera totalement aléatoire à priori

  8. #8
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut
    Citation Envoyé par acx01b Voir le message
    comme le dit toto13 si les 0 et les 1 sont totalement aléatoires le nombre compris entre 0 et 2^n-1 sera totalement aléatoire à priori
    Ok merci

  9. #9
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Citation Envoyé par coyotte507 Voir le message
    Ok merci
    Il suffit que ton générateur ait une dimension suffisamment grande, comme un Mersenne Twister par exemple (pas un générateur à congruence linéaire comme le rand() du C donc).

  10. #10
    Expert confirmé
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Par défaut
    (pas un générateur à congruence linéaire comme le rand() du C donc).
    Il n'est aléatoire que si tu penses qu'il l'est . L'autre problème avec le rand() du C est qu'il est plus lent que le Mersenne Twister ...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Convertir un entier en caractère avec des 0 devant
    Par Oluha dans le forum Développement
    Réponses: 12
    Dernier message: 28/08/2017, 13h37
  2. Générer n nombres au hasard avec random
    Par fredericbdr dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 05/12/2009, 19h37
  3. Générer une dll 16 bits avec delphi 7
    Par chtiot dans le forum EDI
    Réponses: 4
    Dernier message: 21/02/2006, 18h50
  4. probleme avec le random
    Par Pouyou le caribou dans le forum C++
    Réponses: 10
    Dernier message: 09/06/2005, 20h03
  5. []générer et LIRE du xml avec vb: sélection d'un node
    Par chris21 dans le forum VB 6 et antérieur
    Réponses: 11
    Dernier message: 19/09/2003, 13h14

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