本文實例介紹了python實現紅包裂變算法,分享給大家供大家參考,具體內容如下
Python語言庫函數
安裝:
pip install redpackets
使用:
import redpackets redpackets.split(total, num, min=0.01)
1、前情提要
過年期間支付寶紅包、微信紅包成了全民焦點,雖然大多數的紅包就一塊八角的樣子,還是搞得大家樂此不疲。作為一名程序猿,自然會想了解下紅包的實現細節,微信目前是沒有公布紅包的實現細節的,所以這里就綜合網上的討論
通過 Python 來實現紅包裂變。
2、紅包規則
紅包領了不少,據觀察紅包主要有以下幾個限制條件:
所有人都能分到紅包,也就是不會出現紅包數值為 0 的情況
所有人的紅包數值加起來等于支付的金額
紅包波動范圍比較大,約 5%~8% 的紅包數值在平均值的兩倍以上,同時數額 0.01 出現的概率比較高
紅包的數值是隨機的,并且數值的分布近似于正態分布
其中,前兩條是最基本的限制條件,如果要求不是特別高,可以完全只考慮前兩個限制條件即可。
3、裂變方式一
3.1、簡單實現
def weixin_divide_hongbao(money, n): divide_table = [random.randint(1, 10000) for x in xrange(0, n)] sum_ = sum(divide_table) return [x*money/sum_ for x in divide_table]
3.2、相關問題
如使用該方式,需要自己去添加相關代碼邏輯去處理如下問題
浮點數精度問題
邊界值的處理
4、裂變方式二
4.1、完整實現
# -*- coding: utf-8 -*- from decimal import Decimal, InvalidOperation import random def money_val(min, max): return min if min > max else Decimal(str(random.randint(min, max))) def money_random(total, num, min=0.01): """ :param total=10; # 紅包總額 10 元 :param num=8; # 分成 8 個紅包,支持 8 人隨機領取 :param min=0.01; # 每個人最少能收到 0.01 元 """ money_list = [] try: total = Decimal(str(total)) except InvalidOperation as e: return money_list, e.message try: if isinstance(num, float) and int(num) != num: raise ValueError(u'Invalid value for Num: \'{0}\''.format(num)) num = Decimal(str(int(num))) except ValueError as e: return money_list, e.message try: min = Decimal(str(min)) except InvalidOperation as e: return money_list, e.message if total < num * min: return money_list, u'Invalid value for Total-{0}, Num-{1}, Min-{2}'.format(total, num, min) for i in xrange(1, num): safe_total = (total - (num - i) * min) / (num - i) # 隨機安全上限 money = money_val(min * 100, int(safe_total * 100)) / 100 total -= money money_list.append(money) money_list.append(total) random.shuffle(money_list) # 隨機打亂 return money_list, u'Success' if __name__ == '__main__': print money_random(1, 10) print money_random(0.1, 10) print money_random(0.11, 10) print money_random(0.12, 10)
4.2、函數使用
4.2.1、使用 money_random 預先將紅包裂變,存放在 memcache 或者 redis 中
- total ―― 紅包總額
- num ―― 裂變個數
-
min ―― 非必須,紅包最小面額,默認 0.01
4.2.2、當用戶搶紅包的時候,直接 pop 出來一個,直到將所有紅包 pop 完
4.3、庫使用說明
因為涉及到浮點運算,所以使用了 Decimal
5、源碼示例
5.1、運行
python algorithm_utils.py
5.2、效果
5.2.1、對于如下幾個示例
if __name__ == '__main__': print money_random(1, 10) print print money_random(0.1, 10) print print money_random(0.11, 10) print print money_random(0.12, 10) print
5.2.2、裂變后的紅包列表如下
以上就是本文的全部內容,希望對大家學習python程序設計有所幫助。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
