如何实现随日期递增返回true概率的PHP随机脚本?
实现随日期线性递增的随机True返回概率脚本
需求明确
- 1月1日(一年第0天)返回True的概率为 1/12
- 12月31日(一年最后一天)返回True的概率为 100%(1/1)
- 概率需逐日平滑递增,无突变
现有代码的问题
- 概率增长非线性:公式
$max = abs($day - 365)/30会让概率增长速度越来越快,并非匀速递增 - 起始概率偏差:1月1日时
$max≈12.17,rand(0,12)返回0的概率是1/13≈7.7%,和需求的1/12≈8.33%存在差距
最优实现方案
方案一:浮点数随机数(推荐,精确线性)
核心逻辑是计算当日的目标概率,生成0-1之间的随机浮点数,若随机数小于等于目标概率则返回True。这种方式能完美实现线性递增,精度最高。
// 获取当日是一年中的第几天(0=1月1日,364=平年12月31日) $dayOfYear = date('z'); // 判断是否为闰年,自动调整全年总天数 $totalDays = date('L') ? 366 : 365; // 计算当日目标概率:从1/12线性增长到1 $startProbability = 1 / 12; $endProbability = 1; $currentProbability = $startProbability + ($endProbability - $startProbability) * ($dayOfYear / ($totalDays - 1)); // 生成0到1之间的安全随机浮点数(PHP 7+可用) $random = random_float(0, 1); // 判定并返回结果 return $random <= $currentProbability;
补充说明:
- 若使用PHP 5,可替换
random_float(0,1)为mt_rand() / mt_getrandmax(),同样能生成均匀分布的0-1浮点数 - 闰年处理逻辑保证了全年概率增长的均匀性,不会因为闰年多一天出现断层
方案二:整数随机数实现(兼容低版本PHP)
通过整数范围的随机数模拟概率,逻辑更直观:
- 设“成功阈值”为1,“随机数总范围”从12(1月1日)线性递减到1(12月31日)
- 生成1到总范围之间的随机数,若等于1则返回True
$dayOfYear = date('z'); $totalDays = date('L') ? 366 : 365; // 计算当日的随机数范围:从12线性减到1 $startRange = 12; $endRange = 1; $currentRange = $startRange - ($startRange - $endRange) * ($dayOfYear / ($totalDays - 1)); // 转为整数,四舍五入保证每日范围合理 $currentRange = round($currentRange); // 生成1到currentRange之间的随机数 $random = mt_rand(1, $currentRange); return $random === 1;
补充说明:
- 用
mt_rand()替代原生rand():前者的随机分布更均匀,性能也更优 - 四舍五入处理能将线性计算得到的小数范围转为整数,保证每日概率接近目标值,偏差极小
内容的提问来源于stack exchange,提问作者shib4life
相关产品推荐
相关产品推荐

