Précédent   Forum du club des développeurs et IT Pro > PHP > Langage > Contribuez
Contribuez Proposez vos articles, cours, tutoriels, FAQ, sources, etc. pour PHP
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 17/04/2011, 10h01   #21
Madfrix
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 323
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 323
Points : 2 374
Points : 2 374
Ouep bien vu l'optimisation stealth
__________________
Je ne réponds pas aux questions envoyées par mp
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/04/2011, 15h37   #22
stealth35
Modérateur
 
Inscription : septembre 2010
Messages : 7 958
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 958
Points : 9 508
Points : 9 508
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.
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/04/2011, 20h07   #23
ABCIWEB
Expert Confirmé
 
Homme Alain
Inscription : septembre 2010
Messages : 1 917
Détails du profil
Informations personnelles :
Nom : Homme Alain
Localisation : France, Puy de Dôme (Auvergne)

Informations forums :
Inscription : septembre 2010
Messages : 1 917
Points : 2 852
Points : 2 852
... 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 :
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
__________________
- Réalisations
- Interface graphique : génération en javascript d'objets défilants, texte et/ou images, mode horizontal ou vertical.
ABCIWEB est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/04/2011, 21h09   #24
ABCIWEB
Expert Confirmé
 
Homme Alain
Inscription : septembre 2010
Messages : 1 917
Détails du profil
Informations personnelles :
Nom : Homme Alain
Localisation : France, Puy de Dôme (Auvergne)

Informations forums :
Inscription : septembre 2010
Messages : 1 917
Points : 2 852
Points : 2 852
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 :
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>';
__________________
- Réalisations
- Interface graphique : génération en javascript d'objets défilants, texte et/ou images, mode horizontal ou vertical.
ABCIWEB est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/04/2011, 22h10   #25
rawsrc
Modérateur
 
Avatar de rawsrc
 
Homme Martin
Dev indep
Inscription : mars 2004
Messages : 2 592
Détails du profil
Informations personnelles :
Nom : Homme Martin
Âge : 36
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Dev indep

Informations forums :
Inscription : mars 2004
Messages : 2 592
Points : 6 073
Points : 6 073
Envoyer un message via Skype™ à rawsrc
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 :
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;
   }
}
rawsrc est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 17h02.


 
 
 
 
Partenaires

Hébergement Web