代码如下:

  1. <?php
  2. /*
  3. * 红包生成随机算法
  4. */
  5. header("Content-type:text/html;charset=utf-8");
  6. date_default_timezone_set('PRC');
  7.  
  8. #红包生成的算法程序
  9. class reward
  10. {
  11. public $rewardMoney; #红包金额、单位元
  12. public $rewardNum; #红包数量
  13. public $scatter; #分散度值1-10000
  14. public $rewardArray; #红包结果集
  15.  
  16. #初始化红包类
  17. public function __construct()
  18. {
  19. $this->rewardArray = array();
  20. }
  21.  
  22. #执行红包生成算法
  23. public function splitReward($rewardMoney, $rewardNum, $scatter = 100)
  24. {
  25. #传入红包金额和数量
  26. $this->rewardMoney = $rewardMoney;
  27. $this->rewardNum = $rewardNum;
  28. $this->scatter = $scatter;
  29. $this->realscatter = $this->scatter / 100;
  30. /*
  31. *前言:今天我突然这样一想,比如要把1个红包分给N个人,实际上就是相当于要得到N个百分比数据
  32. * 条件是这N个百分比之和=100/100。这N个百分比的平均值是1/N。
  33. * 并且这N个百分比数据符合一种正态分布(多数值比较靠近平均值)
  34. *观点:微信红包里很多0.01的红包,我觉得这是微信程序里的人为控制,目的是为了防止总红包数超过总额,先分了几个0.01的红包。
  35. * 不然不管是以随机概率还是正态分布都很难会出现非常多的0.01元红包。
  36. */
  37. #我的思路:正如上面说的,比如:1个红包发给5个人,我要得出5个小数,它们的和是1,他们的平均值是1/5
  38. #计算出发出红包的平均概率值、精确到小数4位。即上面的1/N值。
  39. $avgRand = round(1 / $this->rewardNum, 4);
  40. #红包的向平均数集中的分布正像数学上的抛物线。抛物线y=ax2,|a|越大则抛物线的开口就越小,|a|越小则抛物线的开口就越大,a>0时开口向上,我们这都是正数,就以a>0来考虑吧。
  41. #程序里的$scatter值即为上方的a,此值除以100,当做100为基准,
  42. #通过开方(数学里的抛物线模型,开方可缩小变化值)得出一个小数字较多(小数字多即小红包多)的随机分布,据此生成随机数
  43. $randArr = array();
  44. while (count($randArr) < $rewardNum) {
  45. $t = round(sqrt(mt_rand(1, 10000) / $this->realscatter));
  46. $randArr[] = $t;
  47. }
  48. #计算当前生成的随机数的平均值,保留4位小数
  49. $randAll = round(array_sum($randArr) / count($randArr), 4);
  50. #为将生成的随机数的平均值变成我们要的1/N,计算一下生成的每个随机数都需要除以的值。我们可以在最后一个红包进行单独处理,所以此处可约等于处理。
  51. $mixrand = round($randAll / $avgRand, 4);
  52. #对每一个随机数进行处理,并剩以总金额数来得出这个红包的金额。
  53. $rewardArr = array();
  54. foreach ($randArr as $key => $randVal) {
  55. $randVal = round($randVal / $mixrand, 4);
  56. $rewardArr[] = round($this->rewardMoney * $randVal, 2);
  57. }
  58. #对比红包总数的差异、修正最后一个大红包
  59. sort($rewardArr);
  60. $rewardAll = array_sum($rewardArr);
  61. $rewardArr[$this->rewardNum - 1] = $this->rewardMoney - ($rewardAll - $rewardArr[$this->rewardNum - 1]);
  62. rsort($rewardArr);
  63. #对红包进行排序一下以方便在前台图示展示
  64. foreach ($rewardArr as $k => $value) {
  65. $t = $k % 2;
  66. if ($t) array_push($this->rewardArray, $value);
  67. else array_unshift($this->rewardArray, $value);
  68. }
  69. $rewardArr = NULL;
  70. return $this->rewardArray;
  71. }
  72. }
  73.  
  74. $money = 1000; #总共要发的红包数;
  75. $people = 50; #总共要发的人数
  76. $scatter = 100; #分散度
  77. $reward = new reward();
  78. $rewardArr = $reward->splitReward($money, $people, $scatter);
  79. echo "发放红包个数:{$people},红包总金额{$money}元。下方所有红包总额之和:" . array_sum($reward->rewardArray) . '元。下方用图展示红包的分布';
  80. echo '<hr>';
  81. echo "<table style='font-size:12px;width:600px;border:1px solid #ccc;text-align:left;'><tr><td>红包金额</td><td>图示</td></tr>";
  82. foreach ($rewardArr as $val) {
  83. #线条长度计算
  84. $width = intval($people * $val * 300 / $money);
  85. 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>";
  86. }
  87. echo "</table>";
  88. ?>

在上传的文件里需要改一下:

$t=round(sqrt(mt_rand(1,10000)/$this->realscatter));,要控制值不为能0,我改成了1,没有测试,可能需要改大点,因为开方后的数值会缩小。

也可以对这行的值直接进行ceil处理, 就不会出现红包为0的数了。

对于scatter的值我没有多做研究,不过根据抛物线的数学模型,这个值的意义可以使抛物线的张口放大缩小,即可以让红包的值分散或者集中。

链接:https://www.php.cn/php-weizijiaocheng-393575.html

PHP微信红包生成算法的程序源码(用抛物线的模型实现)的更多相关文章

  1. PHP用抛物线的模型实现微信红包生成算法的程序源码

    <?php /* *Author:Kermit *Time:2015-8-26 *Note:红包生成随机算法 */ header("Content-type:text/html;cha ...

  2. 微信聊天记录查看器(程序+源码) - iOS版

    本文版权归cxun所有,如有转载请注明出处与本文链接,谢谢!原文地址:http://www.cnblogs.com/cxun/p/4338643.html Updates [2016.10.14]感谢 ...

  3. 反编译获取线上任何微信小程序源码(转)

    看到人家上线的小程序的效果,纯靠推测,部分效果在绞尽脑汁后能做出大致的实现,但是有些细节,费劲全力都没能做出来.很想一窥源码?查看究竟?看看大厂的前端大神们是如何规避了小程序的各种奇葩的坑?那么赶紧来 ...

  4. 研究微信红包分配算法之Golang版

    今天来看一下红包的分配,参考几年前流传的微信红包分配算法,今天用Golang实现一版,并测试验证结果. 微信红包的随机算法是怎样实现的?https://www.zhihu.com/question/2 ...

  5. 微信小程序源码推荐

    wx-gesture-lock  微信小程序的手势密码 WXCustomSwitch 微信小程序自定义 Switch 组件模板 WeixinAppBdNovel 微信小程序demo:百度小说搜索 sh ...

  6. 复用微信小程序源码包后仍然有原小程序的版本管理怎么处理

    前言: 复用微信小程序源码包后,重新创建项目导入源码包,会发现开发者工具版本管理中仍然有原来小程序的版本,这样就不太好了.毕竟是一个新的小程序,需要有新的版本控制的.那么这个问题怎么处理呢? 解决方案 ...

  7. 微信小程序源码案例大全

    微信小程序demo:足球,赛事分析 小程序简易导航 小程序demo:办公审批 小程序Demo:电魔方 小程序demo:借阅伴侣 微信小程序demo:投票 微信小程序demo:健康生活 小程序demo: ...

  8. 【转】精选十二款餐饮、快递、票务行业微信小程序源码demo推荐

    微信小程序的初衷是为了线下实体业服务的,必须有实体相结合才能显示小程序的魅力.个人认为微信小程序对于餐饮业和快递业这样业务比较单一的行业比较有市场,故整理推荐12款餐饮业和快递业微信小程序源码demo ...

  9. 【最新】破解微信小程序,获取微信小程序源码,破解微信wxapkg,仅需5秒

    一个后端第一次接触iview,就简单写了个网站. 之前看到有人发解析wx小程序源码包的软件,但是因为微信的升级,之前的办法已经不行了.现在重新改了js文件,适配了最新的版本. 之前微信wxapkg包获 ...

随机推荐

  1. 13.以太坊中web3访问合约账户出现问题——2019年09月29日

    title: 合约交互时发现访问不了地址的bug date: "2019-09-29 10:17:16" tags: Dapp开发 categories: 技术驿站 在编写合约交互 ...

  2. springboot+jsp+mybatis项目实例(后台成功,但是无法跳转jsp页面,没有实体类的注解,看springboot+jsp第二弹相关配置,即可成功配置jsp)

    SpringBoot是用来简化SpringMvc开发的项目,这里自然要整合mybatis等持久化框架! 先看看项目目录: 一.在pom.xml中配置依赖jar包:<project xmlns=& ...

  3. NET Core+win10+Jenkins+Gogs+open ssh持续集成

    背景 阿里云测试环境一台,带宽1M跟不上,Jenkins安装一个插件耗时很长,于是想在本地搭建Jenkins服务,将生成的安装文件同步到目标服务器上. 技术点有: win10:本地环境是win10,测 ...

  4. markdown解析与着色

    markdown解析与着色 简介 最近在调整博客园博客样式,使用markdown发表的博客.这个不要太好用,有道云+markdown简直绝配,可以发在任何支持markdwon的博客网站,样式基本不会走 ...

  5. 4412 linux延时和时间

    基本知识 • linux中延时函数很简单,却经常用到• 在操作系统中和单片机处理延时方式就完全不一样了,不可能是使用for循环浪费系统资源.而是有专门的接口函数• linux系统编程中常用的延时函数: ...

  6. webbench(web性能压力测试工具)

    在运维工作中,压力测试是一项很重要的工作.比如在一个网站上线之前,能承受多大访问量.在大访问量情况下性能怎样,这些数据指标好坏将会直接影响用户体验.但是,在压力测试中存在一个共性,那就是压力测试的结果 ...

  7. nodejs环境安装

    centos7安装nodejs环境 原文地址: https://www.cnblogs.com/MY0101/p/6625344.html 下载地址: https://nodejs.org/dist/ ...

  8. Axure RP 8.0软件安装教程

    Axure8.0(32/64)位下载地址: 链接:https://pan.baidu.com/s/1qYSLkKW 密码:skaw 软件介绍: Axure RP是一个专业的快速原型设计工具,让负责定义 ...

  9. git 忽略提交及已push过得文件忽略提交

    在使用Git的过程中,我们喜欢有的文件比如日志,临时文件,编译的中间文件等不要提交到代码仓库,这时就要设置相应的忽略规则,来忽略这些文件的提交 Git 忽略文件提交的方法 这种方式通过在项目的某个文件 ...

  10. js的几个特殊的运算符略解

    js运算符的一些特殊应用及使用技巧. 1. 是否包含指定字符: ~ ~"str1".indexOf("str2") 含义为:str1 被查找的字符串 str2 ...