1. 程式人生 > >幾種抽獎概率演算法

幾種抽獎概率演算法

演算法一

複製程式碼程式碼如下:
/**
 * 全概率計算
 *
 * @param array $p array('a'=>0.5,'b'=>0.2,'c'=>0.4)
 * @return string 返回上面陣列的key
 */
function random($ps){
    static $arr = array();
    $key = md5(serialize($ps));

    if (!isset($arr[$key])) {
        $max = array_sum($ps);
        foreach ($ps as $k=>$v) {
            $v = $v / $max * 10000;
            for ($i=0; $i<$v; $i++) $arr[$key][] = $k;
        }
    }
    return $arr[$key][mt_rand(0,count($arr[$key])-1)];


演算法二
複製程式碼程式碼如下: function get_rand($proArr) {
    $result = '';

    //概率陣列的總概率精度
    $proSum = array_sum($proArr);

    //概率陣列迴圈
    foreach ($proArr as $key => $proCur) {
        $randNum = mt_rand(1, $proSum);
        if ($randNum <= $proCur) {
            $result = $key;
            break;
        } else {
            $proSum -= $proCur;
        }
    }
    unset ($proArr);

    return $result;
}


上述程式碼是一段經典的概率演算法,$proArr是一個預先設定的陣列,假設陣列為:array(100,200,300,400),開始是從1,1000這個概率範圍內篩選第一個數是否在他的出現概率範圍之內, 如果不在,則將概率空減,也就是k的值減去剛剛的那個數字的概率空間,在本例當中就是減去100,也就是說第二個數是在1,900這個範圍內篩選的。這樣篩選到最終,總會有一個數滿足要求。就相當於去一個箱子裡摸東西,第一個不是,第二個不是,第三個還不是,那最後一個一定是。這個演算法簡單,而且效率非常高,關鍵是這個演算法已在我們以前的專案中有應用,尤其是大資料量的專案中效率非常棒。
接下來我們通過PHP配置獎項。

複製程式碼程式碼如下:
$prize_arr = array(
    '0' => array('id'=>1,'prize'=>'平板電腦','v'=>1),
    '1' => array('id'=>2,'prize'=>'數碼相機','v'=>5),
    '2' => array('id'=>3,'prize'=>'音箱裝置','v'=>10),
    '3' => array('id'=>4,'prize'=>'4G優盤','v'=>12),
    '4' => array('id'=>5,'prize'=>'10Q幣','v'=>22),
    '5' => array('id'=>6,'prize'=>'下次沒準就能中哦','v'=>50),
);
中是一個二維陣列,記錄了所有本次抽獎的獎項資訊,其中id表示中獎等級,prize表示獎品,v表示中獎概率。注意其中的v必須為整數,你可以將對應的獎項的v設定成0,即意味著該獎項抽中的機率是0,陣列中v的總和(基數),基數越大越能體現概率的準確性。本例中v的總和為100,那麼平板電腦對應的中獎概率就是1%,如果v的總和是10000,那中獎概率就是萬分之一了。
每次前端頁面的請求,PHP迴圈獎項設定陣列,通過概率計算函式get_rand獲取抽中的獎項id。將中獎獎品儲存在陣列$res['yes']中,而剩下的未中獎的資訊儲存在$res['no']中,最後輸出json個數資料給前端頁面。
複製程式碼程式碼如下: //如果中獎資料是放在資料庫裡,這裡就需要進行判斷中獎數量
//在中1、2、3等獎的,如果達到最大數量的則unset相應的獎項,避免重複中大獎
//code here eg:unset($prize_arr['0'])
foreach ($prize_arr as $key => $val) {
    $arr[$val['id']] = $val['v'];
}

$rid = get_rand($arr); //根據概率獲取獎項id

$res['yes'] = $prize_arr[$rid-1]['prize']; //中獎項
//將中獎項從陣列中剔除,剩下未中獎項,如果是資料庫驗證,這裡可以省掉
unset($prize_arr[$rid-1]);
shuffle($prize_arr); //打亂陣列順序
for($i=0;$i<count($prize_arr);$i++){
    $pr[] = $prize_arr[$i]['prize'];
}
$res['no'] = $pr;
echo json_encode($res);

相關推薦

抽獎概率演算法

演算法一 複製程式碼程式碼如下: /**  * 全概率計算  *  * @param array $p array('a'=>0.5,'b'=>0.2,'c'=>0.4)  * @return string 返回上面陣列的key  */ function

負載均衡演算法簡介

首先我們來看一下什麼是負載均衡? 隨著業務的發展,單臺web伺服器已經承載不了系統現在流量的時候,我們就需要部署多臺伺服器,將流量分散在不同的伺服器上,這樣可以提高系統的可用性。 我們可以對web請求進行負載均衡,很大的一部分原因是由於HTTP協議的無狀態性,同樣的請求響應是一樣的,所以哪個

JVM的垃圾收集演算法

       在我以前學習C++語言時,很頭疼的一個問題就是記憶體的分配,C++需要我們自己分配記憶體,用完的時候還需要自己釋放,當我們開發人員一旦出現疏忽忘記釋放資源的時候,累積起來就很容易丟擲OutOfMemoryError異常。 &n

python中排序的演算法思想

1.氣泡排序法 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。 對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。在這一點,最後的元素應該 會是最大的數。 針對所有的元素重複以上的步驟,除了最後一個。 持續每次對越來越少的元素重複上面的步驟,直

常用排序演算法的思路和複雜度對比

1、插入排序——直接插入排序、希爾排序 (1)直接插入排序思路:從第1號元素開始,每個元素依次與前面的元素做比較,小的排前面,這樣當比較到最後一 個元 素完即完成排序。 (2)希爾排序思路:     

初級排序演算法的總結

@TOC 幾種初級排序演算法的總結 排序就是將一組物件按照某種邏輯順序重新排列的過程。 在本文中我們使用的操作: 遍歷陣列 比較兩個物件(本文中所有程式碼示例中的less方法) 交換兩個物件 (本文中所有程式碼示例中的

Java 垃圾回收機制與垃圾回收演算法

一、如何確定某個物件是“垃圾”? 這一小節先了解一個最基本的問題:如果確定某個物件是“垃圾”?既然垃圾收集器的任務是回收垃圾物件所佔的空間供新的物件使用,那麼垃圾收集器如何確定某個物件是“垃圾”?通過什麼方法判斷一個物件可以被回收了。 在java中是通過引用來和物件進行關

常見的負載均衡演算法

1、輪詢將所有請求,依次分發到每臺伺服器上,適合伺服器硬體相同的場景。優點:伺服器請求數目相同; 缺點:伺服器壓力不一樣,不適合伺服器配置不同的情況; 2、隨機請求隨機分配到各臺伺服器上。優點:使用簡單; 缺點:不適合機器配置不同的場景 3、最少連結將請求分配到連線數最少的伺服器上(目前處理請求最少的

資料結構(一):常見排序演算法比較

排序 0. 常見排序演算法效率比較 時間複雜度及穩定性比較 排序方法 平均方法 最優複雜度 最壞複雜度 輔助空間 穩定性 氣泡排序 O(

經典搜尋演算法以及應用

目錄 二、 窮舉 分支定界: A* 一、 評估你的複雜度 簡單的判斷演算法是否能滿足執行時間限制的要求 密切關注題中的給出的資料規模,選擇相應的演算法 一起試一下這個題目吧! 樣例: 輸入: 3

磁碟排程演算法的講解

一、磁碟排程主要思想 裝置的動態分配演算法與程序排程相似,也是基於一定的分配策略的。常用的分配策略有先請求先分配、優先順序高者先分配等策略。在多道程式系統中,低效率通常是由於磁碟類旋轉裝置使用不當造成的。作業系統中,對磁碟的訪問要求來自多方面,常常需要排隊。這時,對眾多的訪問要求按一定的次序響應,會直接影響

程序排程演算法模擬C++實現

先到先服務(FCFS)最短作業優先排程演算法(SJF)#include <iostream> #include <queue> #include <algorithm> #include <cstdio> #include &l

分頁演算法。翻頁必備

1.“俄羅斯儲存過程”的改良版CREATEprocedure pagination1(@pagesize int,  --頁面大小,如每頁儲存20條記錄@pageindex int--當前頁碼)asset nocount onbegindeclare @indextable 

快取記憶體演算法

快取是在CPU和記憶體之間的一塊存取速度極快的儲存單元,CPU在處理資料時,如果在暫存器中找不到目標資料,則優先從快取中尋找。而快取的容量遠遠小於記憶體的容量,當快取已滿而又要繼續往其中新增新的資料的時候,如何替換快取中已有的資料就是快取記憶體演算法要解決的問題。假設CPU

經典抽獎概率演算法

php中獎概率演算法,可用於刮刮卡,大轉盤等抽獎演算法。用法很簡單,程式碼裡有詳細註釋說明,一看就懂 &lt;?php /* * 經典的概率演算法, * $proArr是一個預先設定的陣列, * 假設陣列為:array(100,200,300,400), * 開始是從1,1000 這個概

php 抽獎概率演算法

lottery.php &lt;?php //轉自https://segmentfault.com/a/1190000007431893 /* * 不同概率的抽獎原理就是把0到*(比重總數)的區間分塊 * 分塊的依據是物品佔整個的比重,再根據隨機數種子來產生0-* 中的某個數 * 判斷這

常用的機器學習演算法迴歸模型python程式碼實現

       由於在論文實驗過程中一直使用的是python語言完成的論文實驗,所以在論文需要使用機器學習方法時就考慮使用了scikit-learn。        scikit-learn是一款很好的Python機器學習庫,它包含以下的特點:        (1)簡單高效的資

常用迴歸演算法的比較

# -*- coding:utf-8 -*- import numpy as np import matplotlib.pyplot as plt import random def text2num(string):     str_list = string

常見排序演算法及其效率

介紹了幾種交換排序的演算法 1。氣泡排序(Bubble Sort)是一種簡單的排序演算法。它重複地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個演算法的名字由來是因為越小的元素會經由交換慢慢“浮”到數列

常用排序演算法總結

選擇排序、快速排序、希爾排序、堆排序不是穩定的排序演算法,氣泡排序、插入排序、歸併排序和基數排序是穩定的排序演算法。 冒泡法:  這是最原始,也是眾所周知的最慢的演算法了。他的名字的由來因為它的工作看來象是冒泡:  複雜度為O(n*n)。當資料為正序,將不會有交換。複雜度為