微信随机生成红包金额算法php版_php实例

最近在研究发红包的功能,于是写了个红包的生成算法。

红包生成算法的需求
预先生成所有的红包还是一个请求随机生成一个红包
简单来说,就是把一个大整数m分解(直接以“分为单位,如1元即100)分解成n个小整数的过程,小整数的范围是[min, max]。
最简单的思路,先保底,每个小红包保证有min,然后每个请求都随机生成一个0到(max-min)范围的整数,再加上min就是红包的钱数。
这个算法虽然简单,但是有一个弊端:最后生成的红包可能都是min钱数的。也就是说可能最后的红包都是0.01元的。
另一种方式是预先生成所有红包,这样就比较容易控制了。我选择的是预先生成所有的红包。

理想的红包生成算法
理想的红包生成结果是平均值附近的红包比较多,大红包和小红包的数量比较少。
可以想像下,生成红包的数量的分布有点像正态分布。 

那么如何实现这种平均线附近值比较多的要求呢?
就是要找到一种算法,可以提高平均值附近的概率。那么利用一种”膨胀“再”收缩“的方式来达到这种效果。
先平方,再生成平方范围内的随机数,再开方,那么概率就不再是平均的了。
具体算法:(设置的总钱数,总人数,最大值,最小值要合理)
Php代码

/**
 * 求一个数的平方
 * @param $n
 */
function sqr($n){
  return $n*$n;
} 

/**
* 生产min和max之间的随机数,但是概率不是平均的,从min到max方向概率逐渐加大。
* 先平方,然后产生一个平方值范围内的随机数,再开方,这样就产生了一种“膨胀”再“收缩”的效果。
*/
function xRandom($bonus_min,$bonus_max){
  $sqr = intval(sqr($bonus_max-$bonus_min));
  $rand_num = rand(0, ($sqr-1));
  return intval(sqrt($rand_num));
} 

 /**
 *
 * @param $bonus_total 红包总额
 * @param $bonus_count 红包个数
 * @param $bonus_max 每个小红包的最大额
 * @param $bonus_min 每个小红包的最小额
 * @return 存放生成的每个小红包的值的一维数组
 */
function getBonus($bonus_total, $bonus_count, $bonus_max, $bonus_min) {
  $result = array();  

  $average = $bonus_total / $bonus_count;  

  $a = $average - $bonus_min;
  $b = $bonus_max - $bonus_min;  

  //
  //这样的随机数的概率实际改变了,产生大数的可能性要比产生小数的概率要小。
  //这样就实现了大部分红包的值在平均数附近。大红包和小红包比较少。
  $range1 = sqr($average - $bonus_min);
  $range2 = sqr($bonus_max - $average);  

  for ($i = 0; $i < $bonus_count; $i++) {
    //因为小红包的数量通常是要比大红包的数量要多的,因为这里的概率要调换过来。
    //当随机数>平均值,则产生小红包
    //当随机数<平均值,则产生大红包
    if (rand($bonus_min, $bonus_max) > $average) {
      // 在平均线上减钱
      $temp = $bonus_min + xRandom($bonus_min, $average);
      $result[$i] = $temp;
      $bonus_total -= $temp;
    } else {
      // 在平均线上加钱
      $temp = $bonus_max - xRandom($average, $bonus_max);
      $result[$i] = $temp;
      $bonus_total -= $temp;
    }
  }
  // 如果还有余钱,则尝试加到小红包里,如果加不进去,则尝试下一个。
  while ($bonus_total > 0) {
    for ($i = 0; $i < $bonus_count; $i++) {
      if ($bonus_total > 0 && $result[$i] < $bonus_max) {
        $result[$i]++;
        $bonus_total--;
      }
    }
  }
  // 如果钱是负数了,还得从已生成的小红包中抽取回来
  while ($bonus_total < 0) {
    for ($i = 0; $i < $bonus_count; $i++) {
      if ($bonus_total < 0 && $result[$i] > $bonus_min) {
        $result[$i]--;
        $bonus_total++;
      }
    }
  }
  return $result;
}
$bonus_total = 200;
$bonus_count = 100;
$bonus_max = 10;//此算法要求设置的最大值要大于平均值
$bonus_min = 1;
$result_bonus = getBonus($bonus_total, $bonus_count, $bonus_max, $bonus_min);
$total_money = 0;
$arr = array();
foreach ($result_bonus as $key => $value) {
  $total_money += $value;
  if(isset($arr[$value])){
    $arr[$value] += 1;
  }else{
    $arr[$value] = 1;
  } 

}
//输出总钱数,查看是否与设置的总数相同
echo $total_money;
//输出所有随机红包值
var_dump($result_bonus);
//统计每个钱数的红包数量,检查是否接近正态分布
ksort($arr);
var_dump($arr);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索php随机红包算法
红包金额随机算法、随机红包算法、红包随机分配算法、微信红包的随机算法、微信随机红包算法,以便于您获取更多的相关知识。

时间: 2024-09-30 04:18:59

微信随机生成红包金额算法php版_php实例的相关文章

微信随机生成红包金额算法java版_java

最近几年玩得最疯狂的应该是发红包了,尤其是过年的时候特别受欢迎,下面写了红包的随机算法,其实挺简单的,仅是提供一种思路,希望可以给大家一些启发.  public class WxAlgorithm{ /** * @param moneySum 输入总金额 * @param redNum 输入红包数量 */ private static void wxAlgorithm(double moneySum, int redNum) { // 设置最小的金额 double moneyMin = 0.01

jquery+php随机生成红包金额数量代码分享_jquery

本文实例讲述了jquery+php实现的随机生成红包金额数量特效.分享给大家供大家参考.具体如下: jquery+php实现的随机生成红包金额数量特效是一段实现了可以将一定金额的钱生成多个不同金额的红包的效果代码,红包数量与金钱可以自己设定. 运行效果图:                              -------------------查看效果 下载源码------------------- 小提示:浏览器中如果不能正常运行,可以尝试切换浏览模式. 为大家分享的jquery+ph

微信红包随机生成算法php版_php实例

想了想,自己写写php版的微信红包随机生成算法,能不能实现类似的功能(其实也不敢说是算法).// $bonus_total 红包总金额// $bonus_count 红包个数// $bonus_type 红包类型 1=拼手气红包 0=普通红包 function randBonus($bonus_total=0, $bonus_count=3, $bonus_type=1){ $bonus_items = array(); // 将要瓜分的结果 $bonus_balance = $bonus_to

PHP随机生成唯一HASH值自定义函数_php技巧

网上有很多种方法获取随机唯一的HASH值,但是大同小异: 1.先获取随机的唯一字符串 2.进行MD5或者sha1算HASH值 一个项目要用到hash值,就去网上找了找,却发现PHP有一个函数能直接生成唯一字符串--uniqid(),通过使用这个函数,再加上自己生成的随机数(防止被破解),更具有唯一性且不易被猜解.主要考虑问题如下: 1.随机的效率与随机性:rand和mt_rand函数的选择,首选mt_rand,效率高,随机性好: 2.随机次数:选择5次,本来unniqid就是唯一的,加上随机的可

PHP随机生成信用卡卡号的方法_php技巧

本文实例讲述了PHP随机生成信用卡卡号的方法.分享给大家供大家参考.具体分析如下: 这段PHP代码根据信用卡卡号产生规则随机生成信用卡卡号,是可以通过验证的,仅供学习参考,请不要用于非法用途,否则后果自负. <?php /* PHP credit card number generator Copyright (C) 2006 Graham King graham@darkcoding.net This program is free software; you can redistribute

php微信浏览器分享设置以及回调详解_php实例

在微信中分享给好友/分享到朋友圈这个功能应该是比较常用的了,就拿分享到朋友圈举例,分享出去的内容在朋友圈的展示是以一张小图片+一个简单的介绍的形式来给好友看到的,点击后才是详情,那么这么一来,这张小图片和这段小简介就直接成为了这个被分享后的内容的被点击率的重中之重.在默认情况下,这张图片会载入内容主题部分的第一张大图片,而简介只会加载一个网址.这样的展示方式还是相当不尽如人意的,那我们来看一下这一些内容,是通过什么形式来设置的,拿PHP来做一个举例:  首先我们需要有一个公众号,并且获得appi

php中实现用数组妩媚地生成要执行的sql语句_php实例

会不会碰到这样一种情况呢?每次获取数据将数据和历史版本都有一定的差别,然而用ThinkPHP的addAll()函数,却会将已有的数据删掉再重新写入.这明显不是我们想要的.但自己写sql每次几十个字段也是醉了.如何优雅而又轻松地实现sql的自动生成呢?于是有了下面这个方法. /** * [array_to_sql 根据数组key和value拼接成需要的sql] * @param [type] $array [key, value结构数组] * @param string $type [sql类型i

php版微信自动登录并获取昵称的方法_php实例

本文实例讲述了php版微信自动登录并获取昵称的方法.分享给大家供大家参考,具体如下: 微信自动登录并获取昵称是可以通过api接口来获取的也是通过微信开放的接口来实现了,下面我们一起来看一个例子 仅记录:微信获取昵称自动登录 经过反复几次验证,发现我这个方法有缺陷: 微信内 未关注进入网站,无法获得昵称. 关注后用我这个方法可以获得昵称. 是否是因为第一次生成openid 所以还未生成昵称?待测试. /** * 获取当前页面完整URL地址 */ function get_url() { $sys_

迪菲-赫尔曼密钥交换(Diffie–Hellman)算法原理和PHP实现版_php实例

迪菲-赫尔曼(Diffie–Hellman)是一个可以让双方在不安全的公共信道上建立秘钥的一种算法,双方后期就可以利用这个秘钥加密(如RC4)内容. 迪菲-赫尔曼(Diffie–Hellman)算法原理很简单: 如上原理,最后很容易通过数学原理证明(g^b%p)^a%p = (g^a%p)^b%p,因此它们得到一个相同的密钥. 上面除了a,b和最后得出的公共密钥是秘密的,其它都是可以在公共信道上传递.实际运用中p很大(300位以上),g通常取2或5.那么几乎不可能从p,g和g^a%p算出a(离散