Page 1 sur 2

Générer des nombres aléatoires différents des précédents

Posté : 11 oct. 2010, 15:31
par b3n
Bonjour à tous,

J'essaie de générer des séries de nombres aléatoires compris dans un certain intervalle. Jusque là, rien de compliqué.
Il faut que j'applique une condition aux nombres générés : il doivent être différents des précédents.

Par exemple (5 nombres compris entre 1 et 50, différents entre eux):

7 - 45 - 21 - 20 - 38 -> bon
12 - 19 - 45 - 12 - 39 -> pas bon

J'ai essayé comme ceci (mais je ne teste la valeur qu'une fois et génère un nouveau nombre le cas échéant; il faudrait générer un nombre jusqu'à en obtenir un qui n'est pas encore dans notre tableau) :
<?php

$suite = array();

for ($i = 1; $i <= 5; $i++)
{
  $number = mt_rand(1, 50);

  if (in_array($number, $suite))
  {
    $newNumber = mt_rand(1, 50);

    if ($newNumber == $number)
    {
      $number = mt_rand(1, 50);
    }
    
    $number = $newNumber;
  }

  $suite[$i] = $number;
  echo "$number <br/>\n";
}
Auriez-vous une idée de solution ?

Merci d'avance.

Re: Générer des nombres aléatoires différents des précédents

Posté : 11 oct. 2010, 15:37
par xTG
$nb_a_tirer = 5;
$val_min = 1;
$val_max = 50;
$tab_result = array();
while($nb_a_tirer != 0 )
{
  $nombre = mt_rand($val_min, $val_max);
  if( !in_array($nombre, $tab_result) )
  {
    $tab_result[] = $nombre;
    $nb_a_tirer--;
  }
}
Ceci devrait faire ce que tu souhaites. :)

Re: Générer des nombres aléatoires différents des précédents

Posté : 11 oct. 2010, 15:38
par stealth35
faut faire une fonction récursive :wink:

EDIT : non oublie celle de xTG est top

Re: Générer des nombres aléatoires différents des précédents

Posté : 11 oct. 2010, 15:55
par b3n
Salut xTG, ça fonctionne impec', un grand merci :P

Re: Générer des nombres aléatoires différents des précédents

Posté : 12 oct. 2010, 13:35
par telnes
hello

il y a la possibilité de faire un tableau avec les chiffres dans l'ordre puis de d'utiliser shuffle() et de dépiller à chaque fois que l'on prend une valeur
évite de faire des test in_array()

Re: Générer des nombres aléatoires différents des précédents

Posté : 12 oct. 2010, 13:39
par xTG
Du fait que in_array() parcourt le tableau dans sa totalité ?

Cela revient au même que ta méthode impliquant le fait de construire le tableau et donc de faire une boucle sur 50 éléments (c'est même pire que ce que j'ai proposé car j'ai moins d'itérations - dans le meilleur des cas - ). De plus tu crois que shuffle fonctionne comment ? Je ne pense pas qu'il puisse reconstruire un tableau sans parcourir la source avant. (donc des itérations supplémentaires)

Re: Générer des nombres aléatoires différents des précédents

Posté : 12 oct. 2010, 14:50
par telnes
pour en avoir le coeur net un petit Bench :)
<?php
set_time_limit(0);


$nb_iterration = 1;
$size = 60;


function MakeRandomNumShuffle($size){
	
	$tab_result = range(1,$size);
	shuffle($tab_result);
	return $tab_result;
}

function MakeRandomNumWhile($size){
	$nb_a_tirer = $size;
	$val_min = 1;
	$val_max = $size+100; // +100 = pour éviter de mouliner 
	$tab_result = array();
	while($nb_a_tirer != 0 )
	{
	  $nombre = mt_rand($val_min, $val_max);
	  if( !in_array($nombre, $tab_result) )
	  {
	    $tab_result[] = $nombre;
	    $nb_a_tirer--;
	  }
	} 
 	
 	return $tab_result;
}
//-----------------------------
$time_startA = microtime(true);
ob_start();

for($i=0;$i<$nb_iterration;$i++){
 
 	MakeRandomNumWhile($size);
 
}
$time_endA = microtime(true);
//-----------------------------

$time_startB = microtime(true);
ob_start();

for($i=0;$i<$nb_iterration;$i++){
 
 	MakeRandomNumShuffle($size);
 
}
$time_endB = microtime(true);
//-----------------------------


$timeA = $time_endA - $time_startA;
$timeB = $time_endB - $time_startB;
$div = $timeA/$timeB;


echo "While size $size ; $nb_iterration fois : $timeA  seconds<br/>\n";
echo "shuffle size $size ; $nb_iterration fois : $timeB  seconds<br/>\n";
echo "while/shuffle $div<br/>\n";
?>
résultat :

While size 10 ; 5 fois : 0.00015497207641602 seconds
shuffle size 10 ; 5 fois : 4.3153762817383E-005 seconds
while/shuffle 3.5911602209945

While size 20 ; 5 fois : 0.00033688545227051 seconds
shuffle size 20 ; 5 fois : 6.5088272094727E-005 seconds
while/shuffle 5.1758241758242

While size 40 ; 5 fois : 0.00076580047607422 seconds
shuffle size 40 ; 5 fois : 0.00010299682617188 seconds
while/shuffle 7.4351851851852

While size 60 ; 5 fois : 0.0018417835235596 seconds
shuffle size 60 ; 5 fois : 0.00014591217041016 seconds
while/shuffle 12.622549019608

de manière générale utiliser les fonctions native est plus rapide. Mais j'ai pu faire une erreur !

++

Re: Générer des nombres aléatoires différents des précédents

Posté : 12 oct. 2010, 15:21
par stealth35
si tu veux faire une liste de 5 nombres entre 0 et 1 milliard avec le suffle ca va prendre de la ressource

Re: Générer des nombres aléatoires différents des précédents

Posté : 12 oct. 2010, 15:28
par telnes
... j'avais pas demandé un Billard , j'avais demandé un Milliard

et moi

tu crois que j'avais demandé une grosse Mite

:mrgreen:
pour 1 milliards le PC il plante ...

Re: Générer des nombres aléatoires différents des précédents

Posté : 12 oct. 2010, 15:31
par stealth35
... j'avais pas demandé un Billard , j'avais demandé un Milliard

et moi

tu crois que j'avais demandé une grosse Mite

:mrgreen:
pour 1 milliards le PC il plante ...
alors qu'avec celle d'xTG ca marche
$nb_a_tirer = 5;
$val_min    = 0;
$val_max    = PHP_INT_MAX;
$tab_result = array();

while($nb_a_tirer)
{
    $nombre = mt_rand($val_min, $val_max);
    if(!in_array($nombre, $tab_result))
    {
        $tab_result[] = $nombre;
        --$nb_a_tirer;
    }
}

var_dump($tab_result);

Re: Générer des nombres aléatoires différents des précédents

Posté : 12 oct. 2010, 15:50
par telnes
bas met $nb_a_tirer = PHP_INT_MAX;

Re: Générer des nombres aléatoires différents des précédents

Posté : 12 oct. 2010, 15:54
par stealth35
bas met $nb_a_tirer = PHP_INT_MAX;
c'est pas le but du topic, avec suffle la liste sera aussi grande le nombre de valeur entre $val_min et $val_max
a moins de faire un array_slice apres mais avec de grandes valeurs c'est pas possible

Re: Générer des nombres aléatoires différents des précédents

Posté : 12 oct. 2010, 16:19
par telnes
de toute façon il y a deux paramètres
  • la taille du tableau de valeur aléatoire unique
    le gap entre min et max
la dessus on gère pas de la même manière si c'est pour des grands ou des petits nombres.

je proposais une autre alternative tout simplement, qui fonctionne bien pour les petits nombre genre 5 nombre entre 1 et 50 !

++

Re: Générer des nombres aléatoires différents des précédents

Posté : 12 oct. 2010, 16:21
par stealth35
de toute façon il y a deux paramètres
  • la taille du tableau de valeur aléatoire unique
    le gap entre min et max
la dessus on gère pas de la même manière si c'est pour des grands ou des petits nombres.

je proposais une autre alternative tout simplement, qui fonctionne bien pour les petits nombre genre 5 nombre entre 1 et 50 !

++
ok montre moi ton code qui fait : 5 nombres entre 1 et 50 avec suffle

Re: Générer des nombres aléatoires différents des précédents

Posté : 12 oct. 2010, 16:34
par telnes
a bas j' en ai fait un autre
function MakeRandomNumIsset($size,$min,$max){
	
	$tab = array();
	while(count($tab) != $size){
	 	$v = rand($min,$max);
	 	if(!isset($tab[$v])){
	 		$tab[$v] = $v;
	 	}
	}

	return $tab;
}
isset() est plus rapide que in_array()

Note : dans le cas ou on veux 50 chiffres aléatoires parmi 1 à 50 faire un truc du genre
$tab_result = range($min,$max);
shuffle($tab_result);

est plus rapide (toute proportion gardé sur la taille du tableau )

apres si il en faut juste 5
$tab_result = array_chunk($tab_result,5); // ou for ??