代码如下:

 <?php
/*
* 红包生成随机算法
*/
header("Content-type:text/html;charset=utf-8");
date_default_timezone_set('PRC'); #红包生成的算法程序
class reward
{
public $rewardMoney; #红包金额、单位元
public $rewardNum; #红包数量
public $scatter; #分散度值1-10000
public $rewardArray; #红包结果集 #初始化红包类
public function __construct()
{
$this->rewardArray = array();
} #执行红包生成算法
public function splitReward($rewardMoney, $rewardNum, $scatter = 100)
{
#传入红包金额和数量
$this->rewardMoney = $rewardMoney;
$this->rewardNum = $rewardNum;
$this->scatter = $scatter;
$this->realscatter = $this->scatter / 100;
/*
*前言:今天我突然这样一想,比如要把1个红包分给N个人,实际上就是相当于要得到N个百分比数据
* 条件是这N个百分比之和=100/100。这N个百分比的平均值是1/N。
* 并且这N个百分比数据符合一种正态分布(多数值比较靠近平均值)
*观点:微信红包里很多0.01的红包,我觉得这是微信程序里的人为控制,目的是为了防止总红包数超过总额,先分了几个0.01的红包。
* 不然不管是以随机概率还是正态分布都很难会出现非常多的0.01元红包。
*/
#我的思路:正如上面说的,比如:1个红包发给5个人,我要得出5个小数,它们的和是1,他们的平均值是1/5
#计算出发出红包的平均概率值、精确到小数4位。即上面的1/N值。
$avgRand = round(1 / $this->rewardNum, 4);
#红包的向平均数集中的分布正像数学上的抛物线。抛物线y=ax2,|a|越大则抛物线的开口就越小,|a|越小则抛物线的开口就越大,a>0时开口向上,我们这都是正数,就以a>0来考虑吧。
#程序里的$scatter值即为上方的a,此值除以100,当做100为基准,
#通过开方(数学里的抛物线模型,开方可缩小变化值)得出一个小数字较多(小数字多即小红包多)的随机分布,据此生成随机数
$randArr = array();
while (count($randArr) < $rewardNum) {
$t = round(sqrt(mt_rand(1, 10000) / $this->realscatter));
$randArr[] = $t;
}
#计算当前生成的随机数的平均值,保留4位小数
$randAll = round(array_sum($randArr) / count($randArr), 4);
#为将生成的随机数的平均值变成我们要的1/N,计算一下生成的每个随机数都需要除以的值。我们可以在最后一个红包进行单独处理,所以此处可约等于处理。
$mixrand = round($randAll / $avgRand, 4);
#对每一个随机数进行处理,并剩以总金额数来得出这个红包的金额。
$rewardArr = array();
foreach ($randArr as $key => $randVal) {
$randVal = round($randVal / $mixrand, 4);
$rewardArr[] = round($this->rewardMoney * $randVal, 2);
}
#对比红包总数的差异、修正最后一个大红包
sort($rewardArr);
$rewardAll = array_sum($rewardArr);
$rewardArr[$this->rewardNum - 1] = $this->rewardMoney - ($rewardAll - $rewardArr[$this->rewardNum - 1]);
rsort($rewardArr);
#对红包进行排序一下以方便在前台图示展示
foreach ($rewardArr as $k => $value) {
$t = $k % 2;
if ($t) array_push($this->rewardArray, $value);
else array_unshift($this->rewardArray, $value);
}
$rewardArr = NULL;
return $this->rewardArray;
}
} $money = 1000; #总共要发的红包数;
$people = 50; #总共要发的人数
$scatter = 100; #分散度
$reward = new reward();
$rewardArr = $reward->splitReward($money, $people, $scatter);
echo "发放红包个数:{$people},红包总金额{$money}元。下方所有红包总额之和:" . array_sum($reward->rewardArray) . '元。下方用图展示红包的分布';
echo '<hr>';
echo "<table style='font-size:12px;width:600px;border:1px solid #ccc;text-align:left;'><tr><td>红包金额</td><td>图示</td></tr>";
foreach ($rewardArr as $val) {
#线条长度计算
$width = intval($people * $val * 300 / $money);
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>";
?>

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

$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. Vue通信的10种方式

    1.10种通信方式 10种:https://juejin.im/post/5bd18c72e51d455e3f6e4334 2.除此之外,还有children和ref. 需要注意 $children  ...

  2. 【leetcode】878. Nth Magical Number

    题目如下: 解题思路:本题求的是第N个Magical Number,我们可以很轻松的知道这个数的取值范围 [min(A,B), N*max(A,B)].对于知道上下界求具体数字的题目,可以考虑用二分查 ...

  3. windows下用VMware虚拟机下安装Linux CentOS6.9图文教程

    首先,请在Windows7下安装VMware虚拟机,这个比较简单,直接从官网下载安装即可,这里不再叙述. 接着,从官网直接下载CentOS6.9的iso镜像文件,地址:https://www.cent ...

  4. 【Linux】批量结束某一脚本的进程

    ps -ef | grep **.sh |grep -v grep | awk '{print $2}' | xargs kill -9

  5. [CSP-S模拟测试]:z(模拟+map+小根堆)

    题目背景 $\frac{1}{4}$遇到了一道水题,$eooooo$完全不会做,于是去请教小$D$.结果小$D$已经去了阿塞拜疆,于是,$\frac{1}{4}$只好来问你,这道题是这样的: 题目描述 ...

  6. [CSP-S模拟测试]:回文串(hash+二分)

    题目描述 $ASDFZ$的机房中不仅有红太阳,还有蓝太阳和原谅色太阳.有一天,太阳们来到机房,发现桌上有不知道哪个蒟蒻放上的问题:令$F(A,B)$表示选择一个串$A$的非空前缀$S$和串$B$的非空 ...

  7. 前端每日实战:38# 视频演示如何用纯 CSS 创作阶梯文字特效

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/MXYBEM 可交互视频教程 此视频 ...

  8. mongodbdriver 的C# 驱动findasync变成列表的方法

    IAsyncCursorExtensions.ToList(返回的Task<IAsyncCursor<T>>实例). 也有他的异步版本.可以参见 https://mongodb ...

  9. html常用代码

    <marquee width="70%" scrollamount="2">大家好</marquee>    // 大家好 字符从左到右 ...

  10. 【HTTP】http请求url参数包含+号,被解析为空格

    项目技术:Angular 6 问题现象:接口传参的时候,使用 httpClient.post 方法提交数据,字段中包含+号被解析成空格,提交数据错误 解决过程: 1.http请求中包含+号,会被自动解 ...