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

Langage Java Discussion :

Utiliser le random en Java


Sujet :

Langage Java

  1. #1
    Nouveau membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 29
    Points : 29
    Points
    29
    Par défaut Utiliser le random en Java
    Salut,

    je veux que la fonction random me génère un ensemble de valeurs de tel que leur "somme" égale à 100, est ce que c'est faisable ?
    voilà comment que je génère mes valeurs actuellement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (int col = 0; col < nbC; ++col)
                    {
                      poid[0][col] = rand.nextInt(100);
                    }
    je sais que cela me génère des valeurs entre 0 et 100, mais moi je veux contrôler la somme des valeurs; Merci d'avance

    Bonne journée.

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Il n'y a pas de méthode qui permet de faire ça. Le plus simple pour le faire à mon avis :

    • tirer n nombres (n le nombre de colonnes)
    • en faire la somme (au fur et à mesure par exemple)
    • calculer le rapport à 100 de la somme
    • diviser tous les nombres tirés par ce rapport (attention : partie entière de la division non entière)
    • corriger l'une des valeurs pour ajuster la somme à 100 pour rattraper l'arrondi.


    Quelque chose comme ça :
    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
    public class Exemple {
     
    	public static void main(String[] args) {
    		int[] values = createRandomValues(20, 100, 100);
    		System.out.println(Arrays.toString(values));
    		System.out.println("Somme : " + Arrays.stream(values).sum());
    	}
     
    	private static int[] createRandomValues(final int nb, final int max, int targetSum) {
    		if ( max*nb<targetSum ) {
    			throw new IllegalArgumentException();
    		}
    		final Random random = new Random();
    		final int[] randomValues = new int[nb];
    		int sum=0;
    		for(int i=0; i<nb; i++) {
    			sum += (randomValues[i] = random.nextInt(max));
    		}
    		final double r = sum/(targetSum*1d);
    		sum=0;
    		for(int i=0; i<nb; i++) {
    			final int value=randomValues[i];
    			sum += (randomValues[i] = (int)(randomValues[i]/r) );
    		}		
    		final int fix = targetSum - sum;
    		// randomValues[random.nextInt(nb)] += fix; // correction due aux arrondis sur une seule des valeurs
    		for(int i=0; i<fix; i++) {
    			randomValues[random.nextInt(nb)]++; // répartition de l'erreur sur diverses valeurs
    		}
    		return randomValues;
    	}
     
    }

  3. #3
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 324
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 324
    Points : 3 768
    Points
    3 768
    Billets dans le blog
    12
    Par défaut
    C'est possible, est-ce que tu as une contrainte :
    • Du nombre de fois où un nombre est présent ? (ex: on a trois "2" dans ton tableau).
    • Du nombre total d'éléments ? (ex: on a cent fois "1" dans ton tableau, la somme fait cent).

  4. #4
    Nouveau membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 29
    Points : 29
    Points
    29
    Par défaut
    Merci pour vos réponses,

    @joel.drigo :
    j'ai compris ton idée mais le programme non c'est compliqué (pour moi)
    j'ai essayé de le faire à ma façon, :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    for (int col = 0; col < nbC; ++col){
                poid[0][col] = rand.nextInt(100);
                sum+=poid[0][col];
                if(((int)sum/100)>1){
                    sum-=poid[0][col];
                    col--; }
                if(col==nbC-1 && ((int)sum/100)<1)
                {sum-=poid[0][col];
                    col--;}
     
            }
    mais ça ne marche pas


    @Gugelhupf:
    une contrainte sur le nombre de fois où un nombre est présent ? : non, mais il est préférable que les valeurs générés seront différents car elles représentent des poids
    une contrainte sur le nombre total d'éléments ? : oui

  5. #5
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    bah c'est normal que ça prend "beaucoup" de temps, puisque :

    • Tu sors une valeur aléatoire inférieure à 100 pour l'indice 0
    • Tu la divise par 100 (division entière), donc ça fait 0 (toujours)
    • Tu testes si 0 est égale à 1 : ce n'est jamais le cas, donc tu recules ton indice de boucle
    • Tu recommences à l'indice 0 (0+1-1=0)


    Je ne dirais pas que ça prend beaucoup de temps, je dirais que ça prend un temps infini !

    On pourrait modifier le test comme ça :
    Ou plus simplement :
    Ce qui montre à l'évidence que cette idée d'algorithme ne peut pas fonctionner. Si par hasard on obtient un total de 100 avant d'arriver à la dernière valeur, et bah c'est trop tard, ou alors il faut mettre 0 dans toutes les colonnes qui restent. On peut arriver à la fin sans atteindre 100, ce qu'on ne veut pas. Ou alors on repasse pour augmenter suffisemment (aléatoirement) pour "consommer" ce qu'il reste, ce qui n'est pas sans poser quelques problèmes.

    Déjà, si on prend un cas extrême, mais avec des nombres pseudo-alétoire, il n'est pas impossible d'obtenir une somme des nombres très supérieure à 100, et ce nettement avant la fin. Surtout avec un grand nombre de valeurs. 5 * 20 = 100 (donc déjà à partir de 5 valeurs on a atteint le max), alors que 20 est nettement inférieur à 100.

    On peut essayer de travailler sur une idée comme la tienne, mais on finit toujours par :
    • soit prendre du temps (faire plusieurs passes)
    • soit avoir une répartition très peu aléatoire, ou non équiprobable en tout cas (plein de zéros, ou alors des valeurs très petites en majorité et 1 ou 2 valeurs très grandes)
    • soit avoir une usine à gaz.


    Ma solution est l'application de Thalès tout simplement. Si c'est un élément de syntaxe Java que tu ne comprends pas, dis lequel et je t'expliquerai ou te donnerait une alternative plus "classique". En revanche Thalès, je vois difficilement comment faire plus simple.

  6. #6
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 324
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 324
    Points : 3 768
    Points
    3 768
    Billets dans le blog
    12
    Par défaut
    Il existe plusieurs façons d'implémenter ton besoin, j'ai créé une implémentation de manière naïve :
    Code Java : 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
    import java.util.*;
    import java.lang.*;
    import java.io.*;
     
    class Test {
        static Integer[] fillRandom(int min, int max){
            Random rand = new Random();
            List<Integer> list = new ArrayList<Integer>();	
            int sum = 0;
            while(sum != max){
                int val = rand.nextInt(max - min + 1) + min;
     
                if(sum + val <= max){
                    list.add(val);
                    sum += val;
                } else if(sum + val > max){
    	        list.add(max - sum);
                    sum = max;
                }
            }
     
            return list.toArray(new Integer[list.size()]);
        }
     
        public static void main (String[] args) {
            try {
                for(int v : fillRandom(0, 100)){
                    System.out.println(v);
                }
            } catch(Exception e){
                e.printStackTrace();
            }
        }
    }

    Lien test.

  7. #7
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    @Gugelhupf: ta méthode ne donne pas un nombre déterminé d'entiers, ni même un nombre fixe.

    @leilusha
    On pourrait faire comme ça aussi :
    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
    public static void main(String[] args) {
    		int[] values = createRandomValues(20, 100);
    		System.out.println(Arrays.toString(values));
    		System.out.println("Somme : " + Arrays.stream(values).sum());
    	}
     
    	private static int[] createRandomValues(int nb, int targetSum) {
    		final int[] randomValues = new int[nb];
    		final Random random = new Random();
    		int max = (int)(targetSum*1d)/nb;
    		for(int i=0; i<nb; i++) {
    			randomValues[i]=max;
    		}
    		randomValues[random.nextInt(nb)]+=targetSum-nb*max;
    		for(int i=0; i<nb; i++) {
    			int j;
    			do {
    				j=random.nextInt(nb);
    			} while(j==i);
    			int value = random.nextInt(randomValues[i]);
    			randomValues[i]-=value;
    			randomValues[j]+=value;
    		}
    		return randomValues;
    	}
    Plus simple, peut-être, mais répartition possiblement non équiprobable. La seconde boucle peut être exécutée plusieurs fois éventuellement.

Discussions similaires

  1. Random en Java
    Par oldscrout dans le forum Collection et Stream
    Réponses: 10
    Dernier message: 26/11/2013, 01h32
  2. Utilisation de MD5 en java
    Par zola dans le forum Sécurité
    Réponses: 9
    Dernier message: 26/02/2011, 14h40
  3. utilisation de random
    Par nelob dans le forum Collection et Stream
    Réponses: 9
    Dernier message: 31/10/2007, 13h51
  4. [Couche réseau]Comment utiliser du CRC en Java?
    Par Yanos dans le forum Langage
    Réponses: 6
    Dernier message: 30/06/2006, 16h23
  5. Réponses: 7
    Dernier message: 21/06/2005, 17h04

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