Teach you the code to achieve the function of grabbing red envelopes

1. Scene introduction

Grabbing red envelopes is often seen in real scenes. Do you know how to implement it through code?

A common way of thinking is that as long as someone comes to grab a certain amount of red envelopes, the remaining amount will be distributed to him until all the money is spent.

But there is a problem with this. The person who grabs first will have a higher probability of grabbing more money.

For example, if there is 10 yuan, there are three people A, B and C robbing them in order.

A starts to rob. At this time, the amount of the red envelope he grabs ranges from 0 to 10, with an average of 5 yuan. Suppose A grabs 4 yuan.

B starts robbing. At this time, the amount of the red envelope he grabs ranges from 0 to 6 yuan, with an average of 3 yuan. Suppose B robs 4 yuan.

C starts to grab, the amount of the red envelope he grabs ranges from 0 to 2 yuan, with an average of 1, and the remaining money goes to C, 2 yuan.

Look, whoever grabs it first will take advantage of it even more.

Q: Is there a good way to ignore the order of grabbing red packets?

Answer: residual average method

Divide the remaining money by the remaining number of red envelopes, and then multiply by 2 to get a random number within the range. For example, if there is 100 yuan, 10 people grab it,

The range for the first person to grab is 100/10*2 = 20, which is [0,20], and the average is 10. Suppose he grabs 10 yuan

The range for the second person to grab is 90/9*2 = 20, which is [0,20], the average is 10, assuming that he grabs 10 yuan

The range for the third person to grab is 80/8*2 = 20, which is [0,20], and the average is 10

。。。。。。

The probability of them grabbing the red envelopes is the same, so it can be assumed that grabbing the red envelopes is fair to them, and there is no order of precedence!

2. Code implementation

The above principle is understood, and the code is simple to implement. Here, the Player is set up to grab the red envelopes one by one. It is a thread. Whoever grabs it first is completely determined by the machine.

public class HongBao { //Red envelope class (HongBao) to generate the amount of red envelopes and return the remaining amount.
    private AtomicInteger total = new AtomicInteger( 0 ) ;
     private AtomicInteger count = new AtomicInteger() ;
     private static Random random = new Random() ;
     public void setTotal ( int total , int person) {
         this . total .set(total) ;
         this .count _
.set(person);
    }

    public int getPrice () {
         int countDown = count .get() ;
         if (countDown == 1 ) {   //If the last red envelope is left, the remaining money will be given to the last player
 return getRemainPrice() ;
 }
         int rand = ( total .get() / count .get()) * 2 ;
         int price = random .nextInt(rand - 1 ) + 1 ; //value is the average of [1,2)
 total .set ( total .get () - price) ;
 count .decrementAndGet()                                    ;   //I stole one, and the number should be reduced by one
 return price ;   //Return the robbed money
 }            

    public int getRemainPrice() {
        return total.get();
    }
}
public class Player implements Runnable { //Player (Player) is a thread, mainly calling the method of obtaining red envelopes
     private HongBao hongBao ;
     private String name ;
 Player (HongBao hongBao , String name) {
         this . hongBao = hongBao ;
         this . name = name ;
 }        


    @Override
 public void run () {
         int price = hongBao .getPrice () ;   //Start grabbing red packets
 System.out .println ( "Thread[" + name + "]" + "Get <" + price + ">" ) ;
 }                
}
public class Game { //The game class (Game) is responsible for the initialization of red envelopes and setting n players who grab red envelopes
     public static void main (String[] args) throws InterruptedException { start () ;
 }
     public static void start () {
            
        HongBao hongBao = new HongBao();
        int total = 100;
        int count = 5;
initHongBao(hongBao, total, count);  //初始化红包
for (int i = 0; i < count; i++) {                
            Player play = new Player(hongBao, String.valueOf(i));
            new Thread(play).start();
        }
    }

    /**
      * Initialize the red envelope
       * @param hongBao   red envelope class
      * @param total amount
      * @param count how many in total
      */
 private static void initHongBao (HongBao hongBao , int total , int count) {    
        hongBao.setTotal(total, count);
    }
}

3. Summary

At this point, the design of the red envelope algorithm has been completed. When designing the red envelope algorithm, it is necessary to consider that each player has the same probability of getting money when they grab it. Of course, the actual situation is not the same for everyone. As far as this algorithm is concerned, the qps of my computer statistics is 1000, and I hope you have a better solution!


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325644943&siteId=291194637