Le nouvel an chinois arrive bientôt. Les enveloppes rouges WeChat sont très populaires pendant le nouvel an chinois. Récemment, un projet voulait également saisir des enveloppes rouges, j'ai donc écrit un algorithme de génération d'enveloppes rouges.
Exigences pour l'algorithme de génération d'enveloppes rouges
Pré-créer toutes les enveloppes rouges ou générer de manière aléatoire une enveloppe rouge si une demande
En termes simples, c'est le processus de décomposition d'un grand entier M (directement en unités de «division» d'unités, comme 1 yuans, c'est-à-dire 100) en n petits entiers. La gamme de petits entiers est [min, max].
L'idée la plus simple est de garantir la ligne de fond d'abord, chaque petite enveloppe rouge a Min, puis chaque demande génère un entier allant de 0 à (max-min), puis ajouter Min à l'argent de l'enveloppe rouge.
Bien que cet algorithme soit simple, il présente un désavantage: les enveloppes rouges générées à la fin peuvent être tout en argent. En d'autres termes, la dernière enveloppe rouge peut être de 0,01 yuan.
Une autre façon consiste à pré-créer toutes les enveloppes rouges, afin qu'elle soit plus facile à contrôler. J'ai choisi de pré-créer toutes les enveloppes rouges.
Algorithme de génération d'offres rouge idéale
Le résultat idéal de la génération d'enveloppes rouges est qu'il y a plus d'enveloppes rouges près de la valeur moyenne, et il y a relativement peu d'enveloppes rouges et de petites enveloppes rouges.
Comme vous pouvez l'imaginer, la distribution du nombre de paquets rouges générés est un peu comme une distribution normale.
Alors, comment réaliser cette exigence de plus de valeurs près de la ligne moyenne?
C'est pour trouver un algorithme qui peut augmenter la probabilité autour de la moyenne. Ensuite, utilisez une méthode "expansion" et "contraction" pour réaliser cet effet.
Si vous êtes d'abord carré, générez des nombres aléatoires dans la plage carrée, puis carré, la probabilité ne sera plus moyenne.
Algorithme spécifique:
classe publique hongbaoalgorithm {static aléosé aléatoire = new random (); statique {RandomSetSeed (SystemCurrentTimemillis ()); } public static void main (String [] args) {long max = 200; long min = 1; long [] result = hongbaoalgorithmgenerate (100_0000, 10_000, max, min); Total long = 0; for (int i = 0; i <resultLength; i ++) {// systemOutprintln ("result [" + i + "]:" + result [i]); // SystemEmoutPrintln (résultat [i]); Total + = résultat [i]; } // Vérifiez si la quantité totale de paquets rouges générés est correct SystemOutprintln ("Total:" + Total); // Calculez le nombre de paquets rouges pour chaque argent et vérifiez s'il est proche de la distribution normale int count [] = new int [(int) max + 1]; for (int i = 0; i <resultLength; i ++) {count [(int) result [i]] + = 1; } pour (int i = 0; i <countLength; i ++) {SystemEmoutprintln ("" + i + "" + count [i]); }} / ** * produire des nombres aléatoires entre Min et Max, mais la probabilité n'est pas moyenne et la probabilité de la direction min à max augmente progressivement. * Premier carré, puis générer un nombre aléatoire dans la plage de valeur carrée, puis le carré, qui produit un effet de "l'expansion" et du "rétrécissement". * * @param min * @param max * @return * / static long xrandom (long min, long max) {return sqrt (nextLong (sqr (max - min)))); } / ** * * @param total * montant total d'enveloppe rouge * @param count * nombre d'enveloppes rouges * @param max * Montant maximum de chaque petite enveloppe rouge * @param min * Montant minimum de chaque petite enveloppe rouge * @return Array de valeurs de chaque petite envelope rouge générée * / Public Static Long [] Generate (Long Total, int count, long max, long Min) {Long [] Résultat = neuf); Moyenne longue = total / compte; long a = moyen - min; long b = max - min; // // La probabilité d'un tel nombre aléatoire a réellement changé, et la possibilité de générer un grand nombre est plus petite que la probabilité de générer un nombre décimal. // Cela réalise que la plupart des enveloppes rouges ont la valeur autour de la moyenne. Il y a moins de grandes enveloppes rouges et de petites enveloppes rouges. longue plage1 = sqr (moyen - min); longue plage2 = sqr (max - moyenne); pour (int i = 0; i <resultLength; i ++) {// parce que le nombre de petites enveloppes rouges est généralement plus élevé que le nombre de grandes enveloppes rouges, car la probabilité ici doit être modifiée. // Lorsque le nombre aléatoire> valeur moyenne, une petite enveloppe rouge est générée // Lorsque le nombre aléatoire <valeur moyenne, une grande enveloppe rouge est générée si (nextLong (min, max)> moyen) {// réduire l'argent sur la ligne moyenne // long temp = min + sqrt (NextLong (plage1)); Temple long = min + xrandom (min, moyenne); résultat [i] = temp; Total - = temp; } else {// ajouter de l'argent sur la ligne moyenne // long temp = max - sqrt (nextLong (range2)); Temple long = max - xrandom (moyen, max); résultat [i] = temp; Total - = temp; }} // S'il reste encore de l'argent, essayez de l'ajouter à la petite enveloppe rouge. Si cela ne peut pas être ajouté, essayez le suivant. while (total> 0) {for (int i = 0; i <resultLength; i ++) {if (total> 0 && result [i] <max) {result [i] ++; total--; }}} // Si l'argent est négatif, vous devez retirer de la petite enveloppe rouge générée while (total <0) {for (int i = 0; i <resultLength; i ++) {if (total <0 && result [i]> min) {result [i] -; total ++; }}} Retour Résultat; } statique long sqrt (long n) {// amélioré à la recherche de table? retour (long) mathsqrt (n); } SQR long statique (long n) {// La recherche de table est-elle rapide, ou est-elle directement calculée rapidement? retour n * n; } statique long nextLong (long n) {return randomnextint ((int) n); } statique long nextLong (long min, long max) {return randomnextint ((int) (max - min + 1)) + min; }}Après avoir compté les résultats générés, ils sont tout à fait conformes aux exigences.
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.