竹磬网-邵珠庆の日记 生命只有一次,你可以用它来做些更多伟大的事情–Make the world a little better and easier


171月/170

PHP生成随机红包高级方法

发布在 邵珠庆

/** 传输数字必须为正整数,需要小数通过$bonus_float传值进行换算
* @param $bonus_total (必填) 红包总额
* @param $bonus_count (必填) 红包个数
* @param $bonus_max   (选填) 每个小红包的最大额 最大值要大于平均值
* @param $bonus_min   (选填) 每个小红包的最小额
* @param $bonus_float (选填 Y元J角F分) 红包传入单位
* @return 存放生成的每个小红包的值的一维数组
*/
function getBonus($bonus_total, $bonus_count=20, $bonus_max=0, $bonus_min=1, $bonus_float='Y') {
    $total_money  = 0;
    $arr1         = array();
    $arr2         = array();
    $res          = array();
    // 转换传入金额单位 Y元 J角 F分
    $tmp_float    = $bonus_float;
    if($bonus_float=='Y'){ $bonus_float = 1;   $num_fmt  = 0;}
    if($bonus_float=='J'){ $bonus_float = 10;  $num_fmt  = 1;}
    if($bonus_float=='F'){ $bonus_float = 100; $num_fmt  = 2;}
    // 每人红包平均值
    $average = $bonus_total / $bonus_count;
    // 防止传入参数越界
    if($average > $bonus_max){ echo $bonus_max = round(($bonus_total-$average)/$bonus_count,0)+round($average,0);   }
    if($average < $bonus_min){ echo $bonus_min = 1; }
    $range1  = ($average - $bonus_min)*($average - $bonus_min);
    $range2  = ($bonus_max - $average)*($bonus_max - $average);
    // 生成随机红包逻辑
    for ( $i = 0; $i < $bonus_count; $i++) {         if (rand($bonus_min, $bonus_max) > $average) {
            $temp         = $bonus_min + intval(sqrt(rand(0, (intval($range1)-1))));
            $arr1[$i]   = $temp;
            $bonus_total -= $temp;
        } else {
            $temp         = $bonus_max - intval(sqrt(rand(0, (intval($range2)-1))));
            $arr1[$i]   = $temp;
            $bonus_total -= $temp;
        }
    }
    while ($bonus_total > 0) {
        for ($i = 0; $i < $bonus_count; $i++) {             if ($bonus_total > 0 && $arr1[$i] < $bonus_max) {
                $arr1[$i]++;
                $bonus_total--;
            }
        }
    }
    while ($bonus_total < 0) {
        for ($i = 0; $i < $bonus_count; $i++) {
            if ($bonus_total < 0 && $arr1[$i] > $bonus_min) {
                $arr1[$i]--;
                $bonus_total++;
            }
        }
    }
    // 输出格式化数据结果
    for ($i = 0; $i < $bonus_count; $i++) {
        $arr1[$i]     = number_format($arr1[$i]/$bonus_float,$num_fmt,'.','');
        //统计每个钱数的红包数量,检查是否接近正态分布
        $total_money += $arr1[$i];
        if(isset($arr2[$arr1[$i]])){  $arr2[$arr1[$i]] += 1; }else{ $arr2[$arr1[$i]]  = 1; }
    }
    ksort($arr2);

    $res["total"] = $total_money."(Y)";
    $res["bnmax"] = $bonus_max."(".$tmp_float.")";
    $res["bnmin"] = $bonus_min."(".$tmp_float.")";
    $res["money"] = $arr1;
    $res["count"] = $arr2;

    return $res;
}

$bonus_total  = 2000;
$bonus_count  = 30;
$bonus_max    = 90;  //最大值要大于平均值
$bonus_min    = 1;
$bonus_float  = "Y"; //
$result_bonus = getBonus($bonus_total, $bonus_count,$bonus_max);

echo "

";
print_r($result_bonus);
 
Array
(
    [total] => 2000(Y)
    [bnmax] => 90(Y)
    [bnmin] => 1(Y)
    [money] => Array
        (
            [0] => 74
            [1] => 24
            [2] => 67
            [3] => 73
            [4] => 67
            [5] => 47
            [6] => 69
            [7] => 75
            [8] => 63
            [9] => 44
            [10] => 77
            [11] => 76
            [12] => 70
            [13] => 76
            [14] => 76
            [15] => 72
            [16] => 73
            [17] => 85
            [18] => 68
            [19] => 72
            [20] => 76
            [21] => 68
            [22] => 55
            [23] => 67
            [24] => 65
            [25] => 75
            [26] => 70
            [27] => 71
            [28] => 65
            [29] => 40
        )

    [count] => Array
        (
            [24] => 1
            [40] => 1
            [44] => 1
            [47] => 1
            [55] => 1
            [63] => 1
            [65] => 2
            [67] => 3
            [68] => 2
            [69] => 1
            [70] => 2
            [71] => 1
            [72] => 2
            [73] => 2
            [74] => 1
            [75] => 2
            [76] => 4
            [77] => 1
            [85] => 1
        )

)