很多做电商开发的小伙伴会遇到这个需求。
本文来设定一个规则,大家可以根据我的思路扩展即可。
本文用 php代码实现。其他语言一样,改改。
首先我们用小学学到的知识想一下:
之前我把这个需求给了一个小伙伴看。他给出的答案如下:
<?php
$arr=array("red","red","red","blue","blue","blue","blue","blue","blue","blue");
echo $arr[rand(0,9)];
?>
如果第二个人来摸呢? 这里有个注意点,如果第二个人来摸,那么必定要把这10个球补满(依然是3个红球,7个篮球)
然后最重要的,还要继续“胡乱的、随便的"混合一下。这样,第二个人来摸到篮球的几率才会依然是70%.
上面的程序明显忽略了:继续“胡乱的、随便的"混合一下。 如果每个人都按这个 前三个红后七个蓝 来摸球。那么php的rand函数不能保证篮球是70%。
说到这,很多大神要拿出各种高级算法,譬如啥贝叶斯、矩阵之类的字眼出来。如果这么一个电商功能要用这么复杂的运算,我相信你的老板不会同意你花这么多时间来完成这个功能吧。
接下来,我放出一种简单,但也不失精准性的算法。我们的目标是:使用php的简单函数,尽可能的让摸到篮球的几率接近于70%。
第一步:这个东西要有,这就是初始化的三个红球,7个篮球
<?php
$arr=array("red","red","red","blue","blue","blue","blue","blue","blue","blue");
?>
第二步:随意的、胡乱的混合。
<?php
function swap($i,$j,$arr)
{
$tmp=$arr[$i];
$arr[$i]=$arr[$j];
$arr[$j]=$tmp;
return $arr;
}
?>
第三步:优化交换算法。
<?php
function getRange($arr,$v)
{
$ret=array();
for($i=0;$i<count($arr);$i++)
{
if($arr[$i]==$v)
{
$ret[]=$i;
}
}
return $ret[rand(0,count($ret)-1)];
}
?>
<?php
$i=getRange($arr,"red"); //这样可以取出随机一个红球的序号
$j=getRange($arr,"blue"); //这样可以取出随机一个篮球的序号
第四步:比较重要。开始随意的、胡乱的混合
<?php
for($num=0;$num<10;$num++)
{
$i=getRange($arr,"red");
$j=getRange($arr,"blue");
$arr=swap($i,$j,$arr);
// echo implode(",", $arr)."|".$i."|".$j."<br/>"; //这个语句可以看一下输出,混合过后的排列,是否每次都不一样
}
?>
第五步:再次调用 rand函数
<?php
echo $arr[rand(0,9)];