Recently, sending red envelopes and greetings during the Chinese New Year has become a new trend. As a programmer, he is far more curious about algorithms than about red envelopes. Here we introduce a random red envelope allocation strategy that he thought of. Please give me some advice.
Algorithm introduction
1. Red envelope amount limit
For WeChat red envelopes, we know that no one random minimum red envelope is 1 point and the maximum amount is 200 yuan. Here we also set the range of red envelopes. The following code is the unit of money.
//Minimum red envelope quota private static final int MINMONEY = 1; //Maximum red envelope quota private static final int MAXMONEY = 200 * 100;
2. Determine whether the amount of the red envelope is legal
Note that this step is accompanied by the entire algorithm. We not only need to judge whether the amount is legal before allocating the red envelope, but also need to judge whether the remaining amount is legal after each person tentatively sets the random amount.
private boolean isRight(int money, int count) { double avg = money / count; if (avg < MINMONEY) { return false; } if (avg > MAXMONEY) { return false; } return true; } 3. Randomly generate a red envelope
Here we use a random method to generate a red envelope between MINMONEY and MAXMONEY. After generating the red envelope, we need to determine whether the remaining money is a legal red envelope. If it is not a legal red envelope, we will re-generate the distribution plan. When re-generating the distribution plan, we need to determine whether the red envelope generated is too large or too small. If the red envelope is too large, next time we will randomly reach a small value to a red envelope of this red envelope amount. If the red envelope amount is too small, we will generate a red envelope with a red envelope amount to a large value.
private int random(int money, int minS, int maxS, int count) { //The number of red envelopes is 1, and the amount is returned directly if (count == 1) { return money; } //If the maximum amount and the minimum amount are equal, the amount is returned directly if (minS == maxS) { return minS; } int max = maxS > money ? money : maxS; //Random generate a red envelope int one = ((int)Math.rint(Math.random() * (max - minS) + minS)) % max + 1; int money1 = money - one; //Judge whether this allocation plan is correct if (isRight(money1, count -1)) { return one; } else { double avg = money1 / (count - 1); if (avg < MINMONEY) { //Recursively call, modify the maximum amount of red envelope return random(money, minS, one, count); }else if (avg > MAXMONEY) { //Recursively call, modify the minimum amount of red envelope return random(money, one, maxS, count); } } return one; } 4. Realize red envelope allocation
Here, in order to avoid a certain red envelope occupying a large amount of funds, we need to set the maximum amount of the non-last red envelope, and we set it to N times the average red envelope amount; with the method of one, two, and three, we can realize the allocation of red envelopes.
//The maximum amount of each red envelope is a multiple of the average private static final double TIMES = 2.1; public List<Integer> splitRedPackets(int money, int count) { if (!isRight(money, count)) { return null; } List<Integer> list = new ArrayList<Integer>(); //The maximum amount of the red envelope is TIMES times the average amount int max = (int) (money * TIMES / count); max = max > MAXMONEY ? MAXMONEY : max; for (int i = 0; i < count; i++) { int one = random(money, MINMONEY, max, count - i); list.add(one); money -= one; } return list; }Red envelope allocation plan evaluation
The above introduces the basic algorithm for red envelopes. Let’s verify the algorithm at one time. Suppose there is a red envelope of 200 yuan and 100 copies. Let’s take a look at the final allocation plan.
Complete code
/** *@Description: */ package com.lulei.weixin.util; import java.util.ArrayList; import java.util.List; import com.lulei.util.JsonUtil; public class RedPacketUtil { //Minimum red envelope quota private static final int MINMONEY = 1; //Maximum red envelope quota private static final int MAXMONEY = 200 * 100; //The maximum number of each red envelope is a multiple of the average private static final double TIMES = 2.1; /** * @param money * @param count * @return * @Author:lulei * @Description: Split red envelope*/ public List<Integer> splitRedPackets(int money, int count) { if (!isRight(money, count)) { return null; } List<Integer> list = new ArrayList<Integer>(); //The maximum amount of the red envelope is TIMES times the average amount int max = (int) (money * TIMES / count); max = max > MAXMONEY ? MAXMONEY : max; for (int i = 0; i < count; i++) { int one = random(money, MINMONEY, max, count - i); list.add(one); money -= one; } return list; } /** * @param money * @param minS * @param maxS * @param count * @return * @Author:lulei * @Description: Random red envelope limit*/ private int random(int money, int minS, int maxS, int count) { //The number of red envelopes is 1, and the amount is directly returned if (count == 1) { return money; } //If the maximum amount and the minimum amount are equal, the amount will be returned directly if (minS == maxS) { return minS; } int max = maxS > money ? money : maxS; //Random generate a red envelope int one = ((int)Math.rint(Math.random() * (max - minS) + minS)) % max + 1; int money1 = money - one; //Judge whether this allocation plan is correct if (isRight(money1, count -1)) { return one; } else { double avg = money1 / (count - 1); if (avg < MINMONEY) { //Recursively call, modify the maximum amount of red envelope return random(money, minS, one, count); }else if (avg > MAXMONEY) { //Recursive call, modify the minimum amount of red envelope return random(money, one, maxS, count); } } return one; } /** * @param money * @param count * @return * @Author:lulei * @Description: Is this kind of red envelope legal?*/ private boolean isRight(int money, int count) { double avg = money / count; if (avg < MINMONEY) { return false; } if (avg > MAXMONEY) { return false; } return true; } public static void main(String[] args) { // TODO Auto-generated method stub RedPacketUtil util = new RedPacketUtil(); System.out.println(JsonUtil.parseJson(util.splitRedPackets(20000, 100))); } }For more exciting content, please click "Android WeChat Development Tutorial Summary" and "Java WeChat Development Tutorial Summary" welcome everyone to learn and read.
The above is all about this article, I hope it will be helpful for everyone to learn Java programming.