把一个数随机分成n份,随机数字和等于总数 PHP代码
例如:100随机分成5份,5个数字的和等于100;
一、100个数随机分成10份:
说明:
1、此算法money_total值可大于 personal_num 也可以小于personal_num;
2、得出来的结果是保留两位小数点;
3、相加和等于100;可用于发红包,精准到小数;
4、值类型结果是string(字符串);
$money_total=100;
$personal_num=10;
$min_money=0.01;
$money_right=$money_total;
$randMoney=[];
for($i=1;$i<=$personal_num;$i++){
if($i== $personal_num){
$money=$money_right;
}else{
$max=$money_right*100 - ($personal_num - $i ) * $min_money *100;
$money= rand($min_money*100,$max) /100;
$money=sprintf("%.2f",$money);
}
$randMoney[]=$money;
$money_right=$money_right - $money;
$money_right=sprintf("%.2f",$money_right);
}
shuffle($randMoney);
var_dump($randMoney);
运行结果
array (size=10)
0 => string '54.91' (length=5)
1 => string '3.02' (length=4)
2 => string '4.59' (length=4)
3 => string '12.76' (length=5)
4 => string '0.02' (length=4)
5 => string '22.83' (length=5)
6 => string '0.01' (length=4)
7 => string '0.01' (length=4)
8 => string '0.01' (length=4)
9 => string '1.84' (length=4)
二、100随机分成5份:
说明:
1、此算法total_money值必须大于total_num;
2、得出来的结果是整数;
3、相加和等于100;
4、值类型结果是int(整型);
<?php
$total_money=100;
$total_num=5;
$total_money=$total_money - $total_num;
for($i=$total_num;$i>0;$i--){
$data[$i]=1;
$ls_money=0;
if($total_money>0){
if($i==1){
$data[$i] +=$total_money;
}else{
$max_money=floor($total_money/$i);
$ls_money=mt_rand(0,$max_money);
$data[$i]+=$ls_money;
}
}
$total_money -= $ls_money;
}
var_dump($data);
运行结果
<?php
$total_money=100;
$total_num=5;
$total_money=$total_money - $total_num;
for($i=$total_num;$i>0;$i--){
$data[$i]=1;
$ls_money=0;
if($total_money>0){
if($i==1){
$data[$i] +=$total_money;
}else{
$max_money=floor($total_money/$i);
$ls_money=mt_rand(0,$max_money);
$data[$i]+=$ls_money;
}
}
$total_money -= $ls_money;
}
var_dump($data);
三、6人随机分成3组
<?php
$div=3; //分成几组
$total=6; //总数
$a=range(0,$div-1);
$base=($total-array_sum($a))/$div;
for($len=count($a),$i=0; $i<$len; $i++){
$a[$i]+=$base;
}
shuffle($a); //打乱排序
var_dump($a);//$a中便是分的不等数
运行结果
array (size=3)
0 => int 2
1 => int 3
2 => int 1
四、100随机分成9份
此php算法有点特殊,它的结果可以是int整型,也可以是float浮点型;我们再看另一种写法:当我们把100这个数随机分成9份的时候,结果就不一样喽,如下:
<?php
$div=9;
$total=100;
$a=range(0,$div-1);
$base=($total-array_sum($a))/$div;
for($len=count($a),$i=0; $i<$len; $i++){
$a[$i]+=$base;
}
shuffle($a); //打乱排序
var_dump($a);//$a中便是分的不等数
运行结果
array (size=9)
0 => float 14.111111111111
1 => float 12.111111111111
2 => float 13.111111111111
3 => float 8.1111111111111
4 => float 11.111111111111
5 => float 10.111111111111
6 => float 15.111111111111
7 => float 9.1111111111111
8 => float 7.1111111111111
从上面结果我们可以看,当不能整除的时候,得出来的结果不是整型,而且,得出来的结果相加它的值是不等于100的,只会无限的接近100;不信的话你可以把上面9个值相加,它的结果一定会小于100;
具体你想实现什么样的效果?请根据你的场景来采用不同的算法;
以下是来自网友的算法,经过我的整理发到此文章中来,欢迎大家点评!
五、100随机分成9份
我也自己写了一个,但是没有大家写得好,希望大家不要笑,我写的这个算法呢,结果都是浮点型float,而且相加的和也是小于100,但是它接近不了100,经常相加的和等于99;这就很尴尬了!
<?php
$total = 100; //待划分的数字
$div = 9; //分成的份数
$area = 10; //各份数间允许的最大差值
$average = round($total / $div);
$sum = 0;
$result = array_fill( 1, $div, 0 );
for( $i = 1; $i < $div; $i++ ){
//根据已产生的随机数情况,调整新随机数范围,以保证各份间差值在指定范围内
if( $sum > 0 ){
$max = 0;
$min = 0 - round( $area / 2 );
}elseif( $sum < 0 ){
$min = 0;
$max = round( $area / 2 );
}else{
$max = round( $area / 2 );
$min = 0 - round( $area / 2 );
}
//产生各份的份额
$random = rand( $min, $max );
$sum += $random;
$result[$i] = $average + $random;
}
//最后一份的份额由前面的结果决定,以保证各份的总和为指定值
$result[$div] = $average - $sum;
//结果呈现
var_dump($result);
echo '总和:', array_sum( $result );
运行结果
array(9) {
[1]=>
float(11)
[2]=>
float(16)
[3]=>
float(10)
[4]=>
float(6)
[5]=>
float(15)
[6]=>
float(9)
[7]=>
float(11)
[8]=>
float(10)
[9]=>
float(11)
}
总和:99
六、100随机分成5份
下面是我自己写的一个PHP算法,看看有没有大家需要的;得出来的结果都是整型,就算把100这个数随机分成9份,相加总和还会等于100;我示例代码是把100分成5份的。
<?php
//随机整型利用“不同”就有顺序的原理,
function randomDivInt($div,$total){
$remain=$total;
$max_sum=($div-1)*$div/2;
$p=$div; $min=0;
$a=array();
for($i=0; $i<$div-1; $i++){
$max=($remain-$max_sum)/($div-$i);
$e=rand($min,$max);
$min=$e+1; $max_sum-=--$p;
$remain-=$e;
$a[$e]=true;
}
$a=array_keys($a);
$a[]=$remain;
return $a;
}
for($i=0; $i<3; $i++){
$a=randomDivInt(5,100);
var_dump($a);//$a中便是分的不等数
var_dump(array_sum($a));
}
运行结果
array(5) {
[0]=>
int(0)
[1]=>
int(13)
[2]=>
int(15)
[3]=>
int(22)
[4]=>
int(50)
}
int(100)
array(5) {
[0]=>
int(9)
[1]=>
int(13)
[2]=>
int(15)
[3]=>
int(27)
[4]=>
int(36)
}
int(100)
array(5) {
[0]=>
int(13)
[1]=>
int(16)
[2]=>
int(22)
[3]=>
int(23)
[4]=>
int(26)
}
int(100)