Random() génére un nombre répété

Résolu
yasamira Messages postés 15 Date d'inscription   Statut Membre Dernière intervention   -  
yasamira Messages postés 15 Date d'inscription   Statut Membre Dernière intervention   -
Bonjour à tous,

j'ai un programme en java dont une partie doit générer des nombres aléatoires compris entre (1 à 4 ) avec la fonction Random, et je veux que chaque nombre soit répété n fois.
par Ex :
1 répété 8 fois
2 répété 15 fois
3 répété 20 fois
...

J'ai besoin de votre aiiiiiiiiiiiiiiiiiiiiiiiiide!!,

Merci ^^
A voir également:

3 réponses

KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
Si j'ai bien compris le résultat est fixé :

1 répété 8 fois
2 répété 15 fois
3 répété 20 fois
...

Or avec un random simple tu vas avoir en moyenne autant de répétition pour chaque valeur. Donc dans une grille 100x100 ça fait environ 2500 de chaque. On est loin de 8, 15 et 20. Ou alors j'ai mal compris...
1
yasamira Messages postés 15 Date d'inscription   Statut Membre Dernière intervention  
 
j'ai juste donner des exemple avec ces chiffres, ce que je veux comment je peux fixer pour chaque nombre ( de 1 à 4) le nombre de sa répétition ???
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
Le plus simple c'est de partir d'un tableau rempli avec le nombre de valeurs fixées (sans aléatoire), puis tu mélanges le tableau.

Exemple :

public static Integer[] fill(int...nb)
{
    int sz = 0;
    for (int n : nb)
        sz+=n;
    
    Integer[] tab = new Integer[sz];
    
    for (int i=0, j=0; i<nb.length; i++)
        Arrays.fill(tab, j, j+=nb[i], i+1);
    
    return tab;
} 

public static void shuffle(Integer...tab)
{
    List<Integer> list = Arrays.asList(tab);
    Collections.shuffle(list);
    list.toArray(tab);
}

public static void main(String[] args)
{        
    Integer[] tab = fill(1,2,3,4);
    System.out.println(Arrays.toString(tab)); // [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
    shuffle(tab);
    System.out.println(Arrays.toString(tab)); // [4, 1, 3, 4, 3, 4, 3, 2, 2, 4]
}
0
yasamira Messages postés 15 Date d'inscription   Statut Membre Dernière intervention  
 
premièrement je vous remercie beaucoup pour l'intérêt que vous portez à mon problème

c'est une grille remplie d'états (1,2,3,4),dans mon programme chaque état est représenté et affiché par une couleur (comme un damier) le seul problème que j'ai comment je peux l'lorsque je distribue les états sur la grille de fixer le nombre de chaque états, (sachant combien j'ai de 1 et de 2 .. je dois les distribuer d'une façon aléatoire)
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
Une fois que tu as mélangé tes valeurs dans un tableau, il est facile de passer à une grille, il suffit de réordonner les case tab[n*i+j] en mat[i][j]
0
walidovich_85 Messages postés 608 Date d'inscription   Statut Membre Dernière intervention   73
 
bonjour,

pouvez vous nous partager votre ebauche du programme?
0
yasamira Messages postés 15 Date d'inscription   Statut Membre Dernière intervention  
 
voici la partie dans la quelle je doit indiquer le nombre de fois que chaque nombre doit se répéter, mais je sais pas comment ???

Random r = new Random();

public void init(int [][]t){

for(i=0;i<=99;i++){
for(j=0;j<=99;j++){

t[i][j]=r.nextInt(4);
}
}
}
0
walidovich_85 Messages postés 608 Date d'inscription   Statut Membre Dernière intervention   73
 
Bonsoir tt le monde,

J'ai procédé ainsi pour remplir la grille:

Générer un nombre aléatoire entre 1 et 4;
Contrôler si le nombre de répétition est atteint pour le nombre généré.
Affecter le nombre correcte à la case en itération.

Voila le code:

import java.util.Random;

public class Main1
{
    // des variable de controle
    static int     limit_1 = 15, limit_2 = 20, limit_3 = 30, limit_4 = 35;
    static int     nbr_1, nbr_2, nbr_3, nbr_4;
    static int[][] grille  = new int[10][10];
    static Random  rand    = new Random();
    static int     r;

    public static void main(String args[])
    {
	for (int i = 0; i < 10; i++)
	{
	    for (int j = 0; j < 10; j++)
	    {
		// Controle de l'atteinte de limite
		boolean limit = true;
		while (limit)
		{
		    // générer le nombre aléatoire avec Random
		    r = genererNbr();
		    limit = controlLimit(r, limit);
		}
		grille[i][j] = r;
	    }
	}
	int control_1 = 0;
	int control_2 = 0;
	int control_3 = 0;
	int control_4 = 0;

	// Affichage de la grille

	for (int i = 0; i < 10; i++)
	{
	    for (int j = 0; j < 10; j++)
	    {
		// Compteur de répétition
		if (grille[i][j] == 1)
		    control_1++;
		else if (grille[i][j] == 2)
		    control_2++;
		else if (grille[i][j] == 3)
		    control_3++;
		else if (grille[i][j] == 4)
		    control_4++;

		System.out.print(grille[i][j] + " ");
	    }
	    System.out.println();
	}
	System.out.println();

	// Vérification de nombre de répétition

	System.out.println("Nombre de 1: " + control_1);
	System.out.println("Nombre de 2: " + control_2);
	System.out.println("Nombre de 3: " + control_3);
	System.out.println("Nombre de 4: " + control_4);
    }
    static int genererNbr()
    {
	r = rand.nextInt(4) + 1;
	return r;
    }
    static boolean controlLimit(int nbr, boolean limit)
    {
	switch (nbr)
	{
	    case 1:
		if (nbr_1 < limit_1)
		{
		    nbr_1++;
		    limit = false;
		} else
		    limit = true;
		break;
	    case 2:
		if (nbr_2 < limit_2)
		{
		    nbr_2++;
		    limit = false;
		} else
		    limit = true;
		break;
	    case 3:
		if (nbr_3 < limit_3)
		{
		    nbr_3++;
		    limit = false;
		} else
		    limit = true;
		break;
	    case 4:
		if (nbr_4 < limit_4)
		{
		    nbr_4++;
		    limit = false;
		} else
		    limit = true;
		break;
	}
	return limit;
    }
}


et voila un exemple de résultat:

1 4 2 2 4 1 4 4 1 4 
2 2 4 1 3 3 2 2 2 1 
3 2 4 3 3 3 4 3 1 4 
1 2 4 3 4 2 1 3 4 3 
2 3 3 2 2 2 3 3 3 1 
2 3 2 4 2 2 2 3 4 2 
4 1 1 3 4 4 3 1 4 3 
1 3 1 4 3 1 3 3 3 3 
4 4 4 3 3 4 4 4 4 4 
4 4 3 3 4 4 4 4 4 4 

Nombre de 1: 15
Nombre de 2: 20
Nombre de 3: 30
Nombre de 4: 35


Je pense que c'est une méthode directe mais compliquée et elle peut être encore optimisée, car après l'atteinte de la limite pour un certain nombre, ce nombre peut etre encore généré avec la fonction Random; résultat: des boucles inutiles.

PS: si ces nombre sont piqués aléatoirement d'une liste, on peut illiminer une valeur quand on atteint sa limite de répétition, en résultat, éviter des boucles initules.

Bonne chance
0
yasamira Messages postés 15 Date d'inscription   Statut Membre Dernière intervention  
 
merciiiiiiiiiiiiiiiiiiiiiiiiiiiii bien walidovich_85 je vais essayer d'optimiser mon code mais vos idées m'ont beaucoup aider.
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
"Contrôler si le nombre de répétition est atteint pour le nombre généré."
Cela a un inconvénient que l'on voit bien sur ton exemple, c'est que dès qu'une valeur a été totalement placée, les autres s'accumulent sur la fin, du coup la probabilité de trouver plusieurs 4 à la fin est beaucoup plus grande.

On pourrait mathématiquement améliorer le résultat en biaisant l'aléatoire, pour l'instant tu as 25% de chance d'avoir chaque valeur au tirage puisque tu fais un rand.nextInt(4) + 1, si on veux que les valeurs les moins fréquentes ne se retrouvent pas trop vite épuisées, il faut qu'on les tire moins souvent, proportionnellement à leurs représentations finales.

static int limit_t = limit_1 + limit_2 + limit_3 + limit_4;
static double prop_1 = ((double) limit1)/limit_t;
static double prop_2 = ((double) limit2)/limit_t + prop_1;
static double prop_3 = ((double) limit3)/limit_t + prop_2;
//static double prop_4 = ((double) limit4)/limit_t+ prop_3; // == 1.0

static int genererNbr()
{
    double d = rand.nextDouble();
    if (d<prop_1)
        return 1;
    if (d<prop_2)
        return 2;
    if (d<prop_3)
        return 3;
    return 4;
}

Personnellement, je préfère ma méthode (remplir tout le tableau d'abord puis le mélanger), c'est mathématiquement correct et pas vraiment plus compliqué à mettre en place...
0
walidovich_85 Messages postés 608 Date d'inscription   Statut Membre Dernière intervention   73
 
Oui, vous avez raison, j'ai pa pu donner assez de temps pour ça à cause du match en champions league :D
0
yasamira Messages postés 15 Date d'inscription   Statut Membre Dernière intervention  
 
Avant de remplir tout le tableau il faut un nombre exacte pour chaque état et c'est ça effet mon problème avec la fonction Random() il faut que le 1 er nombre qu'elle me génère se répète n fois et le 2eme m fois ainsi de suite.
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
On a bien compris ta question... à toi de comprendre nos réponses maintenant !
0