구정이 곧 올 것입니다. Wechat Red Envelopes는 구정에 매우 인기가 있습니다. 최근에 프로젝트는 또한 빨간 봉투를 잡고 싶었 기 때문에 빨간 봉투 생성 알고리즘을 썼습니다.
레드 봉투 생성 알고리즘에 대한 요구 사항
한 번의 요청이있는 경우 모든 빨간 봉투를 사전 창조하거나 하나의 빨간 봉투를 무작위로 생성하십시오.
간단히 말해서, 그것은 큰 정수 M (1 위안, 즉 100과 같은 단위로 나누기 단위, 즉 100)을 n 작은 정수로 분해하는 과정입니다. 작은 정수의 범위는 [Min, Max]입니다.
가장 간단한 아이디어는 먼저 결론을 보장하는 것입니다. 각 작은 빨간 봉투에는 최소가 있고 각 요청은 0에서 (max-min) 범위의 정수를 무작위로 생성 한 다음 레드 엔벨로프의 돈에 최소를 추가합니다.
이 알고리즘은 간단하지만 한 가지 단점이 있습니다. 결국 생성 된 빨간 봉투는 모두 최소 돈 일 수 있습니다. 다시 말해, 마지막 빨간 봉투는 0.01 위안 일 수 있습니다.
또 다른 방법은 모든 빨간 봉투를 사전 제작하여 쉽게 제어 할 수 있도록하는 것입니다. 나는 모든 빨간 봉투를 사전 창조하기로 결정했습니다.
이상적인 레드 봉투 생성 알고리즘
이상적인 레드 엔벨로프 생성 결과는 평균값 근처에 더 많은 빨간 봉투가 있으며, 큰 빨간 봉투와 작은 빨간 봉투는 상대적으로 적습니다.
당신이 상상할 수 있듯이, 생성 된 빨간 패킷의 수의 분포는 정규 분포와 비슷합니다.
그렇다면 평균 라인 근처에서 더 많은 값의 요구 사항을 달성하는 방법은 무엇입니까?
평균 주위의 확률을 높일 수있는 알고리즘을 찾는 것입니다. 그런 다음 "확장"및 "수축"방법을 사용 하여이 효과를 달성하십시오.
첫 번째 정사각형이라면 제곱 범위에서 난수를 생성 한 다음 정사각형을 생성하면 확률이 더 이상 평균되지 않습니다.
특정 알고리즘 :
공개 클래스 hongbaoalgorithm {static random = new random (); static {randomsetseed (SystemCurrentTimeMillis ()); } public static void main (String [] args) {long max = 200; 긴 최소 = 1; long [] result = hongbaoalgorithmgenerate (100_0000, 10_000, max, min); 긴 총 = 0; for (int i = 0; i <resultlength; i ++) {// SystemOutPrintln ( "result [" + i + "] :" + result [i]); // SystemEmoutPrintln (result [i]); 총 += 결과 [i]; } // 생성 된 빨간색 패킷의 총량이 올바른 SystemEmoutPrintln인지 확인하십시오 ( "Total :" + Total); // 각 돈에 대한 빨간 패킷 수를 계산하고 정규 분포 int count에 가까운 지 확인하십시오 [] = new int [(int) max + 1]; for (int i = 0; i <resultlength; i ++) {count [(int) result [i]]+= 1; } for (int i = 0; i <countlength; i ++) {SystemEmoutPrintln ( "" + i + "" + count [i]); }} /*** Min과 Max 사이에 임의의 숫자를 생성하지만 확률은 평균이 아니며 Min에서 Max 방향으로의 확률은 점차 증가합니다. * 첫 번째 정사각형은 제곱 값 범위 내에서 난수를 생성 한 다음 제곱 한 다음 "확장"및 "수축"의 영향을줍니다. * * @param min * @param max * @return */ 정적 긴 Xrandom (Long Min, Long Max) {return sqrt (nextLong (sqr (max -min))); } / **** @param 총* 총 빨간 봉투 금액* @param count* @param max* @param max* 각 작은 빨간 봉투의 최대량* @param min* 각 작은 빨간 봉투의 최소 금액* @@return value of small red envelope 생성* / public static long [] 생성 된 {long min, long min). 긴 평균 = 총 / 카운트; 긴 a = 평균 -min; 긴 b = max -min; // // 그러한 임의의 숫자의 확률은 실제로 변경되었으며, 많은 수를 생성 할 가능성은 소수점 숫자를 생성 할 확률보다 작습니다. // 이것은 대부분의 빨간색 봉투가 평균 주위의 값을 가지고 있음을 달성합니다. 큰 빨간 봉투와 작은 빨간 봉투가 적습니다. 긴 범위 1 = SQR (평균 -min); 긴 범위 2 = SQR (최대 - 평균); for (int i = 0; i <resultlength; i ++) {// 작은 빨간 봉투의 수는 일반적으로 큰 빨간 봉투 수보다 높기 때문에 여기서 확률이 변경되어야하기 때문입니다. // 임의의 숫자> 평균 값이있을 때, 작은 빨간 봉투가 생성되면 // 임의의 숫자 <평균 값 <평균 값이 생기면 (NextLong (min, max)> 평균) {// 평균 선에서 돈을 줄인다면 큰 빨간 봉투가 생성됩니다. 긴 온도 = min + xrandom (최소, 평균); 결과 [i] = 온도; 총 -= 온도; } else {// 평균 선에 돈을 추가 // long temp = max -sqrt (nextlong (range2)); 긴 온도 = max -xrandom (평균, 최대); 결과 [i] = 온도; 총 -= 온도; }} // 아직 돈이 남아 있다면 작은 빨간 봉투에 추가하십시오. 추가 할 수 없다면 다음을 시도하십시오. while (total> 0) {for (int i = 0; i <resultlength; i ++) {if (total> 0 && result [i] <max) {result [i] ++; 총--; }}} // 돈이 음수 인 경우, 생성 된 작은 빨간 봉투에서 (총 <0) {for (int i = 0; i <resultlength; i ++) {if (총 <0 && result [i]> min) {result [i]-; 총 ++; }}} 반환 결과; } 정적 긴 sqrt (long n) {// 테이블 조회에 개선 되었습니까? 리턴 (Long) MathSqrt (N); } 정적 긴 SQR (long n) {// 테이블 조회가 빠르거나 직접 계산되어 있습니까? 반환 n * n; } static long nextlong (long n) {return randomnextint ((int) n); } static long nextlong (long min, long max) {return randomnextint ((int) (max -min + 1)) + min; }}생성 된 결과를 계산 한 후에는 요구 사항과 상당히 일치합니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.