Java搶紅包的紅包產生演算法_java

來源:互聯網
上載者:User

馬上過年了。過年微信紅包很火,最近有個項目也要做搶紅包,於是寫了個紅包的產生演算法。

紅包產生演算法的需求

預先產生所有的紅包還是一個請求隨機產生一個紅包

簡單來說,就是把一個大整數m分解(直接以“分為單位,如1元即100)分解成n個小整數的過程,小整數的範圍是[min, max]。

最簡單的思路,先保底,每個小紅包保證有min,然後每個請求都隨機產生一個0到(max-min)範圍的整數,再加上min就是紅包的錢數。

這個演算法雖然簡單,但是有一個弊端:最後產生的紅包可能都是min錢數的。也就是說可能最後的紅包都是0.01元的。

另一種方式是預先產生所有紅包,這樣就比較容易控制了。我選擇的是預先產生所有的紅包。

理想的紅包產生演算法

理想的紅包產生結果是平均值附近的紅包比較多,大紅包和小紅包的數量比較少。

可以想像下,產生紅包的數量的分布有點像常態分佈。

那麼如何?這種平均線附近值比較多的要求呢?

就是要找到一種演算法,可以提高平均值附近的機率。那麼利用一種”膨脹“再”收縮“的方式來達到這種效果。

先平方,再產生平方範圍內的隨機數,再開方,那麼機率就不再是平均的了。

具體演算法:

public class HongBaoAlgorithm {   static Random random = new Random();   static {     randomsetSeed(SystemcurrentTimeMillis());   }      public static void main(String[] args) {     long max = 200;     long min = 1;      long[] result = HongBaoAlgorithmgenerate(100_0000, 10_000, max, min);     long total = 0;     for (int i = 0; i < resultlength; i++) {       // Systemoutprintln("result[" + i + "]:" + result[i]);       // Systemoutprintln(result[i]);       total += result[i];     }     //檢查產生的紅包的總額是否正確     Systemoutprintln("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++) {       Systemoutprintln("" + i + " " + count[i]);     }   }      /**    * 生產min和max之間的隨機數,但是機率不是平均的,從min到max方向機率逐漸加大。    * 先平方,然後產生一個平方值範圍內的隨機數,再開方,這樣就產生了一種“膨脹”再“收縮”的效果。    *    * @param min    * @param max    * @return    */   static long xRandom(long min, long max) {     return sqrt(nextLong(sqr(max - min)));   }    /**    *    * @param total    *      紅包總額    * @param count    *      紅包個數    * @param max    *      每個小紅包的最大額    * @param min    *      每個小紅包的最小額    * @return 存放產生的每個小紅包的值的數組    */   public static long[] generate(long total, int count, long max, long min) {     long[] result = new long[count];      long average = total / count;      long a = average - min;     long b = max - min;      //     //這樣的隨機數的機率實際改變了,產生大數的可能性要比產生小數的機率要小。     //這樣就實現了大部分紅包的值在平均數附近。大紅包和小紅包比較少。     long range1 = sqr(average - min);     long range2 = sqr(max - average);      for (int i = 0; i < resultlength; i++) {       //因為小紅包的數量通常是要比大紅包的數量要多的,因為這裡的機率要調換過來。       //當隨機數>平均值,則產生小紅包       //當隨機數<平均值,則產生大紅包       if (nextLong(min, max) > average) {         // 在平均線上減錢 //       long temp = min + sqrt(nextLong(range1));         long temp = min + xRandom(min, average);         result[i] = temp;         total -= temp;       } else {         // 在平均線上加錢 //       long temp = max - sqrt(nextLong(range2));         long temp = max - xRandom(average, max);         result[i] = temp;         total -= temp;       }     }     // 如果還有餘錢,則嘗試加到小紅包裡,如果加不進去,則嘗試下一個。     while (total > 0) {       for (int i = 0; i < resultlength; i++) {         if (total > 0 && result[i] < max) {           result[i]++;           total--;         }       }     }     // 如果錢是負數了,還得從已產生的小紅包中抽取回來     while (total < 0) {       for (int i = 0; i < resultlength; i++) {         if (total < 0 && result[i] > min) {           result[i]--;           total++;         }       }     }     return result;   }    static long sqrt(long n) {     // 改進為查表?     return (long) Mathsqrt(n);   }    static long sqr(long n) {     // 查錶快,還是直接算快?     return 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;   } } 

統計了下產生的結果,還是比較符合要求的。

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.