代码如下:

 <?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. hdu 2665 Kth number (poj 2104 K-th Number) 划分树

    划分树的基本功能是,对一个给定的数组,求区间[l,r]内的第k大(小)数. 划分树的基本思想是分治,每次查询复杂度为O(log(n)),n是数组规模. 具体原理见http://baike.baidu. ...

  2. map简单用法

    let familyNames = []; familyNames = res.Data.map(item=> { return item.ArgText });

  3. objc_setAssociatedObject 关联对象

    使用场景:在分类中,不允许创建实例变量,这里就解决了此问题 参考: https://www.cnblogs.com/someonelikeyou/p/7162613.html 属性的实质:就是实例变量 ...

  4. 【BZOJ3756】Pty的字符串(广义后缀自动机)

    题意: 思路:论文题 建立Trie树的后缀自动机需要换这个长的板子 #include<bits/stdc++.h> using namespace std; typedef long lo ...

  5. 第七周编程总结&&实验报告五

    实验四 类的继承 实验目的 理解抽象类与接口的使用: 了解包的作用,掌握包的设计方法 实验要求 掌握使用抽象类的方法. 掌握使用系统接口的技术和创建自定义接口的方法. 了解 Java 系统包的结构. ...

  6. 高并发大流量专题---10、MySQL数据库层的优化

    高并发大流量专题---10.MySQL数据库层的优化 一.总结 一句话总结: mysql先考虑做分布式缓存,过了缓存后就做mysql数据库层面的优化 1.mysql数据库层的优化的前面一层是什么? 数 ...

  7. JetBrains CLion

    JetBrains CLion 2017.2.4 ①.激活时选择License server: http://idea.irfen.me/ http://idea.imsxm.com/

  8. Topshelf 秒建 Windows 服务

    https://www.jianshu.com/p/f2365e7b439c 在服务器上,可cmd cd 进入bin目录下执行

  9. MVC 入门

    MVC是什么? MVC是一个框架模式,它用于把应用程序的输入.处理和输出进行强制性的分开.使用MVC应用程序被分成三个核心部件:模型.视图.控制器.它们各自处理自己的任务.最典型的MVC就是JSP+S ...

  10. vue搭建项目之设置axios

    首先要下载axios: npm install axios -S 要注意的是,axios不支持Vue.use();这种方式,可以改写原型链. 第二步就是新建axios存放位置: 在项目中src中单独建 ...