El Año Nuevo chino llegará pronto. Los sobres rojos de WeChat son muy populares durante el Año Nuevo chino. Recientemente, un proyecto también quería obtener sobres rojos, así que escribí un algoritmo de generación de sobre rojo.
Requisitos para el algoritmo de generación de envolventes rojos
Pre-cree todos los sobres rojos o genere aleatoriamente un sobre rojo si se solicita una solicitud
En pocas palabras, es el proceso de descomponerse un entero grande M (directamente en unidades de "dividir" en unidades, como 1 yuan, es decir, 100) en n enteros pequeños. El rango de enteros pequeños es [min, max].
La idea más simple es garantizar primero el resultado final, cada sobre rojo pequeño tiene min, y luego cada solicitud genera aleatoriamente un entero que varía de 0 a (max-min), y luego agregue min al dinero del sobre rojo.
Aunque este algoritmo es simple, tiene una desventaja: los sobres rojos generados al final pueden ser todo dinero. En otras palabras, el último sobre rojo puede ser 0.01 yuan.
Otra forma es pre-crear todos los sobres rojos, para que sea más fácil de controlar. Elegí pre-crear todos los sobres rojos.
Algoritmo ideal de generación de sobre rojo
El resultado ideal de la generación de envolventes rojos es que hay más sobres rojos cerca del valor promedio, y hay relativamente pocos sobres rojos grandes y pequeños sobres rojos.
Como puede imaginar, la distribución del número de paquetes rojos generados es un poco como una distribución normal.
Entonces, ¿cómo lograr este requisito de más valores cerca de la línea promedio?
Es encontrar un algoritmo que pueda aumentar la probabilidad en torno al promedio. Luego use un método de "expansión" y "contracción" para lograr este efecto.
Si primero se cuadra, genere números aleatorios en el rango cuadrado y luego cuadrado, entonces la probabilidad ya no será promedio.
Algoritmo específico:
clase pública Hongbaoalgorithm {static random aleatory = new Random (); static {aleattetSetSeed (SystemCurrentTimemillis ()); } public static void main (string [] args) {long max = 200; largo min = 1; Long [] resultado = HongbaoalgorithmGenerate (100_0000, 10_000, máx, min); Total largo = 0; for (int i = 0; i <resultLength; i ++) {// systemoutPrintln ("resultado [" + i + "]:" + resultado [i]); // SystememoutPrintln (resultado [i]); total += resultado [i]; } // verifique si la cantidad total de paquetes rojos generados es correcto SystemEMoTPrintln ("Total:" + Total); // Calcule el número de paquetes rojos para cada dinero y verifique si está cerca de la distribución normal int count [] = new int [(int) max + 1]; for (int i = 0; i <resultLength; i ++) {count [(int) resultado [i]]+= 1; } para (int i = 0; i <countLength; i ++) {SystemEmOutPrintln ("" + i + "" + Count [i]); }} /*** Produce números aleatorios entre Min y Max, pero la probabilidad no es promedio, y la probabilidad de la dirección min a máxima aumenta gradualmente. * Primero cuadrado, luego genere un número aleatorio dentro del rango de valor cuadrado y luego lo cuadrados, lo que produce un efecto de "expansión" y "contracción". * * @param min * @param max * @return */ static long xrandom (long min, long max) {return sqrt (nextLong (sqr (max - min))); } / **** @param Total* Cantidad total del sobre rojo* @param Count* Número de sobres rojos* @param max* cantidad máxima de cada sobre pequeño rojo* @param min* cantidad mínima de cada envoltura roja pequeña* @return matriz de valores de cada pequeño de cada pequeño envolvente generado* / público largo [] generado (largo largo, intento, largo, largo, largo, minuto largo) —cutin = resulte '] promedio largo = total / recuento; largo a = promedio - min; largo B = max - min; // // La probabilidad de dicho número aleatorio realmente ha cambiado, y la posibilidad de generar un número grande es menor que la probabilidad de generar un número decimal. // Esto logra que la mayoría de los sobres rojos tienen el valor alrededor del promedio. Hay menos sobres rojos grandes y pequeños sobres rojos. largo rango1 = sqr (promedio - min); largo rango2 = sqr (max - promedio); para (int i = 0; i <resultLength; i ++) {// porque el número de pequeños sobres rojos suele ser más alto que el número de sobres rojos grandes, porque la probabilidad aquí debe cambiarse. // Cuando el número aleatorio> valor promedio, se genera un pequeño sobre rojo // Cuando el número aleatorio <valor promedio, se genera un sobre grande rojo si (NextLong (Min, Max)> promedio) {// reduce el dinero en la línea promedio // Long Temp = Min + SQRT (NextLong (Range1)); Long temp = min + xrandom (min, promedio); resultado [i] = temp; Total -= temp; } else {// Agregar dinero en la línea promedio // Long temp = max - sqrt (nextLong (range2)); Long temp = max - xrandom (promedio, max); resultado [i] = temp; Total -= temp; }} // Si todavía queda dinero, intente agregarlo al pequeño sobre rojo. Si no se puede agregar, intente el siguiente. while (total> 0) {for (int i = 0; i <resultLength; i ++) {if (total> 0 && result [i] <max) {resultado [i] ++; total--; }}} // Si el dinero es negativo, debe retirarse del sobre pequeño rojo generado mientras (total <0) {para (int i = 0; i <resultLength; i ++) {if (total <0 && result [i]> min) {resultado [i]-; total ++; }}} Resultado de retorno; } static long sqrt (long n) {// ¿mejorado a la búsqueda de tabla? return (long) mathsqrt (n); } static long sqr (long n) {// ¿La búsqueda de la tabla es rápida o se calcula directamente? regresar n * n; } static long nextLong (long n) {return randomNextInt ((int) n); } static long nextlong (largo min, largo max) {return randomNextInt ((int) (max - min + 1)) + min; }}Después de contar los resultados generados, están bastante en línea con los requisitos.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.