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

Contribuez / Téléchargez Sources et Outils PHP Discussion :

Génération de nombres aléatoires


Sujet :

Contribuez / Téléchargez Sources et Outils PHP

  1. #21
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    Ouep bien vu l'optimisation stealth

  2. #22
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    c'est une méthode hyper simple a faire et a comprendre par contre ça peu très vite bouffer de la mémoire si la fourchette est grande.

  3. #23
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    ... effectivement

    Pour des valeurs $offsetMax - $offsetMin relativement raisonnable la méthode avec "range" est le mieux que l'on puisse faire à mon avis.

    Mais il faut bien garder à l'esprit cette contrainte car si l'on veut tirer par exemple 10 nombres uniques au hasard entre 1 et 1 000 000 cette fonction n'est pas du tout optimisée en temps de réponse et l'on risque de saturer la mémoire serveur lors de la création du tableau d'un million d'éléments...


    Une autre méthode bien plus optimisée dans ce cas de figure est de faire un truc dans le genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $nombre_valeur_a_retourner = 10;
     
    $resultat = array();
     
    while (count($resultat) < $nombre_valeur_a_retourner)
    {
    $resultat[] = mt_rand(1,1000000);
    $resultat = array_unique($resultat);
    }
    Par contre cette fois ci il faut bien garder à l'esprit que le nombre de valeurs à retourner doit éviter de se rapprocher de l'interval de la fourchette (surtout si la fourchette est assez grande). D'après mes tests si l'on veut retourner 999 valeurs distinctes dans une fourchette de 1000 éléments on est dans les 25 secondes de temps de réponse et théoriquement on risque une boucle infinie.

    A contrario cette méthode à une réponse instantanée pour tirer 10 nombres différents dans une fourchette de 1000000 alors qu'avec la méthode "range" on a une erreur serveur dû au dépassement de la mémoire disponible.

    Ces méthodes sont donc à utiliser suivant les besoins mais ni l'une ni l'autre n'est universelle

  4. #24
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Je parlais plus haut de tests avec les deux méthodes "range" et "rand".

    Si ça vous tente voici le jeu de test, vous n'avez plus qu'à modifier les trois premières variables :

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    $nb = 15;
    $offsetMin = 0;
    $offsetMax = 1000;
     
     
     
    function nbAleatoires_rand($nb, $offsetMin, $offsetMax)
    {
        if($offsetMax < $offsetMin || abs($offsetMax - $offsetMin) < $nb-1)
        {
            return false;
        }
     
        $resultat = array();
     
    	while (count($resultat) < $nb)
    	{
    		$resultat[] = mt_rand($offsetMin,$offsetMax);
    		$resultat = array_unique($resultat);
    	}
     
        return $resultat;
    }
     
    $time = microtime(true);
     
    $resultat = nbAleatoires_rand($nb, $offsetMin, $offsetMax);
     
    $time_end = microtime(true);
    $time_tot = $time_end - $time;
     
    echo ' durée exécution _rand = ' . $time_tot.'<br />';
     
    echo '<pre>';
    print_r($resultat);
    echo '</pre>';
     
     
     
    function nbAleatoires_range($nb, $offsetMin, $offsetMax)
    {
        if($offsetMax < $offsetMin || abs($offsetMax - $offsetMin) < $nb-1)
        {
            return false;
        }
     
        $range = range($offsetMin, $offsetMax);
     
        shuffle($range);
     
        return array_slice($range, 0, $nb);
    }
     
    $time = microtime(true);
     
    $tab = nbAleatoires_range($nb, $offsetMin, $offsetMax);
     
    $time_end = microtime(true);
    $time_tot = $time_end - $time;
     
    echo ' durée exécution _range = ' . $time_tot.'<br />';
     
    echo '<pre>';
    print_r($tab);
    echo '<pre>';

  5. #25
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Bonsoir,

    Allez ma première contribution
    Voici la fonction que j'utilise en PHP 5.3+
    Elle ne gère pas les bornes min et max mais permet de générer des nombres de grandes tailles.
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    class RandomGenerator {
     
       /**
        * Génère une ou plusieurs chaines numériques aléatoires
        * Si NbValues = 1, renvoie une chaine
        * Si NbValues > 1, renvoie un tableau
        * @param int $pLength Longueur de la chaine à créer
        * @param bool $pUniqueDigits Aucune duplication de chiffres dans un nombre aléatoire, si TRUE alors $pLength max = 10
        * @param int $pNbValues Nombre de valeurs aléatoires à générer
        * @param bool $pUniqueValues Aucun doublons dans le tableau final, applicable ssi $pNbValues > 1
        * @return string|array|FALSE Array([] => rand)
        * @static
        */
       static function numeric($pLength, $pUniqueDigits = FALSE, $pNbValues = 1, $pUniqueValues = TRUE) {
          # cohérence
          if (($pLength < 1) || ($pNbValues < 1)) {
             return FALSE;
          }
     
          if ($pUniqueDigits && ($pLength > 10)) {
             return FALSE;
          }
     
          # closures : générateurs des nombres aléatoires
          $unique = function() use ($pLength) {
                       $base = range(0, 9);
                       shuffle($base);
                       return implode(array_slice($base, 0, $pLength));
                    };
     
          $noUnique = function() use ($pLength) {
                         $result = '';
                         for($i = 0 ; $i < $pLength ; ++$i) {
                            $result .= mt_rand(0, 9);
                         }
                         return $result;
                      };
     
          if ($pNbValues == 1) {
             return ($pUniqueDigits) ? $unique() : $noUnique();
          }
     
          # plusieures itérations, renvoie un tableau
          $aleas = array();
          for($i = 0 ; $i < $pNbValues ; ++$i) {
             $aleas[] = ($pUniqueDigits) ? $unique() : $noUnique();
          }
     
          # en $pUniqueValues == TRUE, on vérifie si le tableau ne contient pas de doublons 
          # et on regénère autant de fois que nécessaire les doublons effacés
          if ($pUniqueValues) {
             while (($toRegen = ($pNbValues - (count(array_unique($aleas))))) > 0) {
                for($i = 0 ; $i < $toRegen ; ++$i) {
                   $aleas[] = ($pUniqueDigits) ? $unique() : $noUnique();
                }
             }
          }
          return $aleas;
       }
    }

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Réponses: 10
    Dernier message: 19/01/2012, 12h56
  2. Génération de nombres aléatoires
    Par nono_31 dans le forum Collection et Stream
    Réponses: 3
    Dernier message: 05/07/2008, 21h06
  3. défaut des fonctions de génération de nombres aléatoire type rand()
    Par Christophe30 dans le forum Langages de programmation
    Réponses: 3
    Dernier message: 17/02/2008, 20h21
  4. Génération de nombre aléatoires
    Par rebaudo dans le forum Smalltalk
    Réponses: 1
    Dernier message: 29/11/2007, 12h54
  5. recherche algo de génération de nombre aléatoire
    Par Pascale38 dans le forum MFC
    Réponses: 2
    Dernier message: 26/01/2004, 14h20

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