亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 邏輯算法 > 正文

PHP 生成隨機紅包算法

2020-03-22 16:20:11
字體:
來源:轉載
供稿:網(wǎng)友

基本思路

在隨機數(shù)生成方面,我借鑒了這位博主 @悲慘的大爺 的思路:

原文:比如要把 1 個紅包分給 N 個人,實際上就是相當于要得到 N 個百分比數(shù)據(jù) 條件是這 N 個百分比之和 = 100/100。這 N 個百分比的平均值是 1/N。 并且這 N 個百分比數(shù)據(jù)符合一種正態(tài)分布(多數(shù)值比較靠近平均值)。

解讀:比如我有 1000 塊錢,發(fā) 50 個紅包,就先隨機出 50 個數(shù),然后算出這 50 個數(shù)的均值 avg,用 avg/(1/N),就得到了一個基數(shù) mixrand ,然后用隨機出的那 50 個數(shù)分別去除以 mixrand ,得到每個數(shù)相對基數(shù)的百分比 randVal ,然后用 randVal 乘以 1000 塊錢,就可以得到每個紅包的具體金額了。

算法實現(xiàn)

Talk is cheap, show me your code!

核心生成算法:

<?php/* * Note: 紅包生成隨機算法 */html' target='_blank'>class Reward{    public $rewardMoney;        // 紅包金額、單位元    public $rewardNum;          // 紅包數(shù)量    // 執(zhí)行紅包生成算法    public function splitReward($rewardMoney, $rewardNum, $max, $min)    {        // 傳入紅包金額和數(shù)量,因為小數(shù)在計算過程中會出現(xiàn)很大誤差,所以我們直接把金額放大100倍,后面的計算全部用整數(shù)進行        $min = $min * 100;        $max = $max * 100;        // 預留出一部分錢作為誤差補償,保證每個紅包至少有一個最小值        $this->rewardMoney = $rewardMoney * 100 - $rewardNum * $min;        $this->rewardNum = $rewardNum;        // 計算出發(fā)出紅包的平均概率值、精確到小數(shù)4位。        $avgRand = 1 / $this->rewardNum;        $randArr = [];        // 定義生成的數(shù)據(jù)總合sum        $sum = 0;        $t_count = 0;        while ($t_count < $rewardNum) {            // 隨機產(chǎn)出四個區(qū)間的額度            $c = rand(1, 100);            if ($c < 15) {                $t = round(sqrt(mt_rand(1, 1500)));            } else if ($c < 65) {                $t = round(sqrt(mt_rand(1500, 6500)));            } else if ($c < 95) {                $t = round(sqrt(mt_rand(6500, 9500)));            } else {                $t = round(sqrt(mt_rand(9500, 10000)));            }            ++$t_count;            $sum += $t;            $randArr[] = $t;        }        // 計算當前生成的隨機數(shù)的平均值,保留4位小數(shù)        $randAll = round($sum / $rewardNum, 4);        // 為將生成的隨機數(shù)的平均值變成我們要的1/N,計算一下每個隨機數(shù)要除以的總基數(shù)mixrand。此處可以約等處理,產(chǎn)生的誤差后邊會找齊        // 總基數(shù) = 均值/平均概率        $mixrand = round($randAll / $avgRand, 4);        // 對每一個隨機數(shù)進行處理,并乘以總金額數(shù)來得出這個紅包的金額。        $rewardArr = array();        foreach ($randArr as $key => $randVal) {            // 單個紅包所占比例randVal            $randVal = round($randVal / $mixrand, 4);            // 算出單個紅包金額            $single = floor($this->rewardMoney * $randVal);            // 小于最小值直接給最小值            if ($single < $min) {                $single += $min;            }            // 大于最大值直接給最大值            if ($single > $max) {                $single = $max;            }            // 將紅包放入結果數(shù)組            $rewardArr[] = $single;        }        // 對比紅包總數(shù)的差異、將差值放在第一個紅包上        $rewardAll = array_sum($rewardArr);        // 此處應使用真正的總金額rewardMoney,$rewardArr[0]可能小于0        $rewardArr[0] = $rewardMoney * 100 - ($rewardAll - $rewardArr[0]);        // 第一個紅包小于0時,做修正        if ($rewardArr[0] < 0) {            rsort($rewardArr);            $this->add($rewardArr, $min);        }        rsort($rewardArr);        // 隨機生成的最大值大于指定最大值        if ($rewardArr[0] > $max) {            // 差額            $diff = 0;            foreach ($rewardArr as $k => &$v) {                if ($v > $max) {                    $diff += $v - $max;                    $v = $max;                } else {                    break;                }            }            $transfer = round($diff / ($this->rewardNum - $k + 1));            $this->diff($diff, $rewardArr, $max, $min, $transfer, $k);        }        return $rewardArr;    }    // 處理所有超過最大值的紅包    public function diff($diff, &$rewardArr, $max, $min, $transfer, $k)    {        // 將多余的錢均攤給小于最大值的紅包        for ($i = $k; $i < $this->rewardNum; $i++) {            // 造隨機值            if ($transfer > $min * 20) {                $aa = rand($min, $min * 20);                if ($i % 2) {                    $transfer += $aa;                } else {                    $transfer -= $aa;                }            }            if ($rewardArr[$i] + $transfer > $max) continue;            if ($diff - $transfer < 0) {                $rewardArr[$i] += $diff;                $diff = 0;                break;            }            $rewardArr[$i] += $transfer;            $diff -= $transfer;        }        if ($diff > 0) {            $i++;            $this->diff($diff, $rewardArr, $max, $min, $transfer, $k);        }    }    // 第一個紅包小于0,從大紅包上往下減    public function add(&$rewardArr, $min)    {        foreach ($rewardArr as &$re) {            $dev = floor($re / $min);            if ($dev > 2) {                $transfer = $min * floor($dev / 2);                $re -= $transfer;                $rewardArr[$this->rewardNum - 1] += $transfer;            } elseif ($dev == 2) {                $re -= $min;                $rewardArr[$this->rewardNum - 1] += $min;            } else {                break;            }        }        if ($rewardArr[$this->rewardNum - 1] > $min || $rewardArr[$this->rewardNum - 1] == $min) {            return;        } else {            $this->add($rewardArr, $min);        }    }}

細節(jié)考慮

下邊這段代碼用來控制具體的業(yè)務邏輯,按照具體的需求,留出固定的最大值、最小值紅包的金額等;在代碼中調用生成紅包的方法時 splitReward(total,num,max?0.01,min),我傳入的最大值減了 0.01,這樣就保證了里面生成的紅包最大值絕對不會超過我們設置的最大值。

<?phpclass CreateReward{    /*     * 生成紅包     * @param   int          $total               紅包總金額     * @param   int          $num                 紅包總數(shù)量     * @param   int          $max                 紅包最大值     *     */    public function random_red($total, $num, $max, $min)    {        // 總共要發(fā)的紅包金額,留出一個最大值;        $total = $total - $max;        $reward = new Reward();        $result_merge = $reward->splitReward($total, $num, $max - 0.01, $min);        sort($result_merge);        $result_merge[1] = $result_merge[1] + $result_merge[0];        $result_merge[0] = $max * 100;        foreach ($result_merge as &$v) {            $v = floor($v) / 100;        }        return $result_merge;    }}

實例測試

基礎代碼

先設置好各種初始值。

<?php/** * Created by PhpStorm. * User: lufei * Date: 2017/1/4 * Time: 22:49 */header('content-type:text/html;charset=utf-8');ini_set('memory_limit', '128M');require_once('CreateReward.php');require_once('Reward.php');$total = 50000;$num = 300000;$max = 50;$min = 0.01;$create_reward = new CreateReward();

性能測試

因為 memory_limit 的限制,所以只測了 5 次的均值,結果都在 1.6s 左右。

for ($i=0; $i<5; $i++) {    $time_start = microtime_float();    $reward_arr = $create_reward->random_red($total, $num, $max, $min);    $time_end = microtime_float();    $time[] = $time_end - $time_start;}echo array_sum($time)/5;function microtime_float(){    list($usec, $sec) = explode(" ", microtime());    return ((float)$usec + (float)$sec);}

運行結果:

數(shù)據(jù)檢查

1) 數(shù)值是否有誤

檢測有沒有負值,有沒有最大值,最大值有多少個,有沒有小于最小值的值。

$reward_arr = $create_reward->random_red($total, $num, $max, $min);sort($reward_arr);//正序,最小的在前面$sum = 0;$min_count = 0;$max_count = 0;foreach($reward_arr as $i => $val) {    if ($i<3) {        echo "<br />第".($i+1)."個紅包,金額為:".$val."<br />";    }    if ($val == $max) {          $max_count++;    }    if ($val < $min) {        $min_count++;    }    $val = $val*100;    $sum += $val;}//檢測錢是否全部發(fā)完echo '<hr>已生成紅包總金額為:'.($sum/100).';總個數(shù)為:'.count($reward_arr).'<hr>';//檢測有沒有小于0的值echo "<br />最大值:".($val/100).',共有'.$max_count.'個最大值,共有'.$min_count.'個值比最小值小';

運行結果:

2) 正態(tài)分布情況

注意,出圖的時候,紅包的數(shù)量不要給的太大,不然頁面渲染不出來,會崩 。

$reward_arr = $create_reward->random_red($total, $num, $max, $min);$show = array();rsort($reward_arr);// 為了更直觀的顯示正態(tài)分布效果,需要將數(shù)組重新排序foreach($reward_arr as $k=>$value){    $t=$k%2;    if(!$t) $show[]=$value;;    else array_unshift($show,$value);}echo "設定最大值為:".$max.',最小值為:'.$min.'<hr />';echo "<table style='font-size:12px;width:600px;border:1px solid #ccc;text-align:left;'><tr><td>紅包金額</td><td>圖示</td></tr>";foreach($show as $val){    // 線條長度計算    $width=intval($num*$val*300/$total);    echo "<tr><td> {$val} </td><td width='500px;text-align:left;'><hr style='width:{$width}px;height:3px;border:none;border-top:3px double red;margin:0 auto 0 0px;'></td></tr>";}echo "</table>";

運行結果:

PS:有朋友問我生成的數(shù)據(jù)有沒有通過數(shù)學方法來驗證其是否符合標準正態(tài)分布,因為我的數(shù)學不好,這個還真沒算過,只是看著覺得像,就當他是了。既然遇到了這個問題,就一定要解決嘛,所以我就用 php 內置函數(shù)算了一下,算出來的結果在數(shù)據(jù)量小的時候還是比較接近正態(tài)分布的,但是數(shù)據(jù)量大起來的時候就不能看了,我整不太明白這個,大家感興趣的可以找一下原因喲。

php 的四個函數(shù):stats_standard_deviation(標準差),stats_variance(方差), stats_kurtosis((峰度),stats_skew(偏度)。使用上面的函數(shù)需要安裝 stats 擴展。

以上就是PHP 生成隨機紅包算法的詳細內容,更多請關注電腦知識網(wǎng)其它相關文章!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
欧美成人明星100排名| 亚洲国产无线乱码在线观看| 老牛影视av一区二区在线观看| 美女久久网站| 秋霞电影一区二区| 欧美精品一区二区久久| 黑人极品videos精品欧美裸| 伊人中文字幕在线观看| 2021国产精品久久精品| 色偷偷色偷偷色偷偷在线视频| 久久天天东北熟女毛茸茸| 青青草视频免费在线观看| 国产精品一国产精品最新章节| 国产精品久久999| 午夜在线观看91| 黄色毛片免费看| 国产在线观看中文字幕| 亚洲视频电影图片偷拍一区| 欧美精品一区二区三区国产精品| 精品日韩欧美在线| 女人和拘做爰正片视频| 97高清视频| 国产一区二区三区四区五区加勒比| 99精品国自产在线| 日韩欧美国产1| 免费人成自慰网站| 日韩一卡二卡三卡| 亚洲精品国产偷自在线观看| 91久久久久久久久久久久久久| 日韩午夜电影在线观看| 五月久久久综合一区二区小说| 欧美精品videofree1080p| 三级ai视频| 日韩在线观看免费网站| 伊人久久大香线蕉精品| 91精品国产综合久久精品| 国产精品成人免费一区久久羞羞| 亚洲综合日韩在线| 欧美午夜精品理论片a级大开眼界| 欧美视频免费在线| 成年人在线免费观看视频网站| 日韩精品一区二区三区视频| 在线精品在线| 国产suv精品一区二区三区| 日本孕妇大胆孕交无码| 最新国产精品拍自在线播放| 国产成人精品在线| 色吊丝一区二区| 成人亚洲在线观看| 91福利社在线观看| 国产亚洲成av人片在线观看桃| 国产精品电影一区二区| 日本中文字幕在线2020| 亚洲国产第一区| 亚洲色欲色欲www在线观看| 成熟人妻av无码专区| 六月丁香婷婷色狠狠久久| 亚洲高清视频在线播放| 色视频线观看在线播放| 亚洲无限乱码一二三四麻| 国产精品久久久久久超碰| 亚洲欧美日韩一区二区三区在线观看| 一二三区在线播放| 无码任你躁久久久久久老妇| 久久久综合av| 国产aⅴ精品一区二区四区| 欧美白人猛性xxxxx交69| 激情乱色小说视频| 韩国精品美女www爽爽爽视频| 国产精品免费在线视频| 国产原创av在线| 日韩电影在线观看一区二区| 国产一区视频导航| 亚洲精品极品少妇16p| 久久97久久97精品免视看| 九九热这里有精品视频| 肉丝袜脚交视频一区二区| 免费成人在线电影| 日韩av在线网页| 日韩三级电影网站| 国产精品影视网| 国产精品麻豆va在线播放| 在线观看麻豆视频| 欧洲美女少妇精品| 密臀av一区二区三区| 国产精品嫩草影院一区二区| 久久国产免费视频| 亚洲色图 欧美| 日韩写真福利视频在线| 在线免费观看视频一区| 国产免费视频一区二区三区| 欧美日本啪啪无遮挡网站| 亚州欧美日韩中文视频| 看全色黄大色黄女片18| 中国女人真人一级毛片| 91av免费| 日韩欧美亚洲日产国| 国产免费a级片| 99久久久久久中文字幕一区| 亚洲欧美国产va在线影院| 综合激情五月婷婷| 国产精品午夜久久久久久| 精品av在线播放| 国产欧美一区二区白浆黑人| 69xxxx国产| 另类少妇人与禽zozz0性伦| 麻豆视频在线观看| 国产成年人免费视频| 日韩电影免费网站| 国产精品扒开腿做爽爽爽视频软件| 日韩一区二区三区在线免费观看| 91在线播放视频| 久久五月精品| 操喷在线视频| 色系列之999| 国精产品一区一区三区有限在线| 无套白嫩进入乌克兰美女| 久久久久久久9999| 草草视频在线| 日日操免费视频| 免费h片在线观看| 欧美狂野激情性xxxx在线观| 国产经典一区二区三区| 亚洲综合成人在线| 久久久国产精品亚洲一区| 久久久久国产一区| 亚洲激情自拍偷拍| 91在线看国产| 国产精品乱码一区二区三区软件| 国产精品日韩在线| 成人午夜大片| 国产福利91精品| 亚洲电影一区| 欧洲av一区二区| 青花影视在线观看免费高清| 亚洲午夜久久久久久久久电影院| 狂野欧美性猛交xxxx| 男女做暖暖视频| 亚洲午夜av久久乱码| 久久女同互慰一区二区三区| 99久久免费精品高清特色大片| 亚洲AV无码久久精品国产一区| 久久国产夜色精品鲁鲁99| 91国产视频在线| 中文av免费观看| www.久久久久久久久久久| 日韩黄色免费观看| 色婷婷久久99综合精品jk白丝| 精品三级av在线导航| 亚洲天堂一区二区| 欧美精选一区| 国产乱在线观看视频| 婷婷综合久久中文字幕蜜桃三电影| 国产精品扒开腿做爽爽爽软件| 夜夜夜操操操| 五月激情六月综合| 青春草在线免费视频| 伊人网伊人影院| 国产精品无码白浆高潮| 欧美特黄aaaaaaaa大片| 亚洲高清影视| 一二三区在线| 精品一区二区三区四区五区六区| 日韩激情一二三区| 亚洲第一在线| 欧美日韩一区二区三区四区五区六区| 国语对白永久免费| 天天噜天天色| 亚洲精品成人a8198a| 国产人妖一区二区三区| 大地资源二中文在线影视观看| 午夜影院免费| 婷婷四房综合激情五月| 日本美女一级视频| 欧美日韩亚洲综合一区二区三区激情在线| 91九色91蝌蚪| 亚洲香蕉av在线一区二区三区| 深田えいみ中文字幕99久久| 国产欧洲在线| 欧美a一区二区| 日本www在线观看视频| www.自拍偷拍| 男男h黄动漫啪啪无遮挡软件| 激情久久久久久久| av电影网站在线观看| 亚洲国产精品成人综合久久久| 一区二区视频在线免费| 最新中文字幕一区二区三区| 日韩av高清在线播放| 一本一道波多野毛片中文在线| 日本一区高清在线视频| 欧美精品电影免费在线观看| 九九热视频免费在线观看| 91国内精品久久久| 日韩经典一区| 久久精品首页| 日韩黄色免费电影| 手机亚洲手机国产手机日韩| 欧美成人在线免费视频| 亚洲成a人片77777精品| 熟女少妇a性色生活片毛片| 午夜电影网一区| 欧美视频福利| 在线精品视频一区二区| 91久久嫩草影院一区二区| 成人午夜毛片| 久久久国产亚洲精品| 91国产精品91| 韩日视频在线观看| 免费看污黄网站在线观看| 日本成人黄色网| fc2成人免费人成在线观看播放| 91国在线高清视频| 欧美日韩国产成人高清视频| 16—17女人毛片毛片| 久久久久久99久久久精品网站| 亚洲乱熟女一区二区| 懂色av中文在线| 日本精品性网站在线观看| 亚洲人精选亚洲人成在线| 日韩av.com| 亚洲成av人在线观看| 久久婷婷成人综合色| 在线观看视频你懂得| 污片在线免费观看| 国产主播在线播放| av中文字幕网址| 中文字幕成人av| 亚洲av无一区二区三区| 日本在线免费观看视频| 99精品国产一区二区三区2021| 精品无码三级在线观看视频| 欧美中文在线观看国产| 这里只有久久精品视频| 免费在线黄色电影| 色在线视频播放| 国产精品久久人| 99热这里只有精品在线观看| 国产美女性感在线观看懂色av| 伊人久久久久久久久久久久久| 国产精品欧美激情在线| 欧美日韩精品在线观看视频| 一区在线播放视频| 色狠狠色噜噜噜综合网| 国产欧美va欧美va香蕉在| 欧美日韩免费观看一区=区三区| 三级视频在线| 97av在线影院| 欧美激情中文字幕一区二区| 欧美日韩一区成人| 青青一区二区| 8av国产精品爽爽ⅴa在线观看| www久久99| 国产一区二区精品久| 小小的日本在线观看免费色网| 亚洲久本草在线中文字幕| 一个人在线视频免费观看www| 伊人国产视频| 777午夜精品免费视频| www.久久久久久久| jizzjizzjizz国产| 不卡一区二区在线观看| www日本视频| av网站在线免费| 黄色影视在线观看| 美女写真久久影院| 亚洲第一狼人区| 欧美一区二区在线观看视频| 久久免费看av| 性金发美女69hd大尺寸| 九九热线视频只有这里最精品| 六月丁香在线视频| 国产精品私房写真福利视频| 成人18视频| 亚洲欧美日韩一区二区三区四区| 精品久久久久久久人人人人传媒| 亚洲精品日韩在线观看| 久久久久电影| 手机看片1024久久| 老司机aⅴ毛片免费观看| 不卡的国产精品| 国产在线播放av| 在线观看免费国产小视频| 2019中文字幕在线免费观看| 中文字幕欧美国产| 亚洲伦理精品| a级毛片免费观看在线| www五月婷婷| 一区二区亚洲视频| 老鸭窝毛片一区二区三区| 亚洲码无人客一区二区三区| 裸体在线国模精品偷拍| 激情综合网婷婷| 人妻91麻豆一区二区三区| av片在线免费观看| 中文字幕在线观看高清| 精品一区二区三区日韩| 九色91popny| 亚洲а∨天堂久久精品2021| 成人免费区一区二区三区| 日日噜噜夜夜狠狠视频欧美人| 欧美6一10sex性hd| 成人午夜激情av| 久青青在线观看视频国产| 精品卡一卡二卡三卡四在线| 国产三区在线观看| y111111国产精品久久婷婷| 国产一区二区三区国产| 久久国产麻豆精品| 日韩av一区二区在线影视| 色偷偷av一区二区三区| 国内精品久久久久影院一蜜桃| 欧美jizzhd欧美精品巨大| 另类图片第一页| 日韩成年人视频| 国产在线精品观看| 三大队在线观看| 亚洲三级欧美| 亚洲高潮无码久久| 国产资源第一页| 在线播放精品视频| 天天插天天狠天天透| 亚洲丁香婷深爱综合| 成人观看网址| 亚洲精品成人自拍| 日本不卡一区二区三区四区| va婷婷在线免费观看| 91制片厂在线|