Bonjour,
j'aimerais générer disons k nombres réels entre 0 et un entier N, sous la contrainte que les k nombres générés satisfont que leur somme fasse N.
Comment feriez-vous ?
Merci,
Bonjour,
j'aimerais générer disons k nombres réels entre 0 et un entier N, sous la contrainte que les k nombres générés satisfont que leur somme fasse N.
Comment feriez-vous ?
Merci,
Il ne s'agit pas juste de tirer des nombres aléatoires, la somme des nombres tirés doit être égale à N.
Après, je n'ai donné que la classe nécessaire. Ensuite, il suffit d'un peu d'algorithmique (bon, il y a un piège si il reste 1 à la somme).
Soit pour le traitement:
Et pour tester la classe:
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 package com.developpez; import java.util.ArrayList; import java.util.List; import java.util.Random; public class Generation { private Generation() { } public static List<Integer> genereNombres(int total){ List<Integer> lReturn = new ArrayList<>(); int reste = total; int genere; Random random = new Random(); while(reste > 0) { genere = (reste > 1)? random.nextInt(reste):reste; reste -= genere; lReturn.add(genere); } return lReturn; } }
Au pire, ça m'aura fait un exercice...
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 package com.developpez; import java.util.List; public class MainGenere { public static void main(String[] args) { verifie(Generation.genereNombres(10)); verifie(Generation.genereNombres(50)); verifie(Generation.genereNombres(100)); } public static void verifie(List<Integer> list) { Integer somme = list.stream().mapToInt(i -> i).sum(); System.out.println(); System.out.println("Généré : "+list.toString()); System.out.println("Somme = "+somme); System.out.println(); } }
Je ne vois pas comment faire pour que la somme des valeurs générées vaut par N (par exemple 3).
C'est des maths, pas de la programmation.
On pourra remarquer que si k = 1, alors il n'y a pas d'aléatoire possible. Le nombre "choisi" doit être égal à N et puis c'est tout.
De même, si k = 2, quel que soit le premier nombre A qu'on tire, le deuxième nombre n'est pas aléatoire, il doit être égal à N - A. Du coup il s'agit plutôt de tracer un segment de 0 à N et de tirer au hasard un point sur ce segment. Ensuite, on obtient deux nombres en prenant les longueurs des deux segments de part et d'autre de ce point.
A partir de cette considération, on peut imaginer de nombreuses manières de partitionner au hasard en k sous-segments le segment 0 à N. Tout dépend de ce qu'on veut.
Personnellement je tirerais (k - 1) points au hasard sur le segment, puis je les trierais dans l'ordre, et je prendrais les longueurs des segments de gauche à droite. Ça me semble être le tirage aléatoire le plus uniforme. Mais ce n'est pas forcément ce qu'on veut.
Oui ben tu tires ton nombre aléatoire et tu vérifies la condition après et si elle n'est pas vérifiée tu continues de tirer... bref do { [...] } while (<test>).
Puisque K est connu, un for() fait aussi bien l'affaire et on dispose de conditions d’arrêt supplémentaire.
A chaque fois que tu tires un nombre, tu déduis ce nombre que tu viens de tirer de la valeur max (reste0 = N, reste1 = reste0 - tirage0, etc.).
Le nombre généré le plus récent est stockée dans une liste/un tableau.
A partir du moment ou ton reste vaut 0, tous les autres nombres a tirer valent 0.
Si tu arrives au Keme nombre (indice K-1) sans que la somme vaut N/le resteK-1 vaut 0, du coup le dernier nombre est pas aléatoire mais vaut resteK-1.
Rien de bien complique.
Merci de penser au tagquand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.
suivez mon blog sur Développez.
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook
J'ai oublié de dire que je voulais une loi uniforme et avec ta méthode je ne suis pas bien sûr que ça le soit.
Bon je suis un peu a cote de la plaque en maths et en stats depuis le temps mais en faisant un grand nombre de série et en moyennant les résultats ça devrait pas retourner une valeur proche de N/K ?
Peut-etre une grosse c*** de ma part : faire K tirages aleatoires sur une valeur de N/K puis repartir ce qu'il reste de N - Somme(tirages) aléatoirement sur les valeurs tirées ?
Merci de penser au tagquand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.
suivez mon blog sur Développez.
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook
Partager