把一个数随机分成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);

运行结果:

  1. array (size=10)
  2.   0 => string '54.91' (length=5)
  3.   1 => string '3.02' (length=4)
  4.   2 => string '4.59' (length=4)
  5.   3 => string '12.76' (length=5)
  6.   4 => string '0.02' (length=4)
  7.   5 => string '22.83' (length=5)
  8.   6 => string '0.01' (length=4)
  9.   7 => string '0.01' (length=4)
  10.   8 => string '0.01' (length=4)
  11.   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);

运算结果:

  1. array (size=5)
  2.   5 => int 5
  3.   4 => int 17
  4.   3 => int 23
  5.   2 => int 9
  6.   1 => int 46

 

三、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中便是分的不等数

运行结果:

  1. array (size=3)
  2.   0 => int 2
  3.   1 => int 3
  4.   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中便是分的不等数

运行结果:

  1. array (size=9)
  2.   0 => float 14.111111111111
  3.   1 => float 12.111111111111
  4.   2 => float 13.111111111111
  5.   3 => float 8.1111111111111
  6.   4 => float 11.111111111111
  7.   5 => float 10.111111111111
  8.   6 => float 15.111111111111
  9.   7 => float 9.1111111111111
  10.   8 => float 7.1111111111111

 

从上面结果我们可以看,当不能整除的时候,得出来的结果不是整型,而且,得出来的结果相加它的值是不等于100的,只会无限的接近100;不信的话你可以把上面9个值相加,它的结果一定会小于100;

php算法

 

具体你想实现什么样的效果?请根据你的场景来采用不同的算法;

 

以下是来自网友的算法,经过我的整理发到此文章中来,欢迎大家点评!

 

五、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 );

运行结果:

  1. array(9) {
  2.   [1]=>
  3.   float(11)
  4.   [2]=>
  5.   float(16)
  6.   [3]=>
  7.   float(10)
  8.   [4]=>
  9.   float(6)
  10.   [5]=>
  11.   float(15)
  12.   [6]=>
  13.   float(9)
  14.   [7]=>
  15.   float(11)
  16.   [8]=>
  17.   float(10)
  18.   [9]=>
  19.   float(11)
  20. }
  21. 总和: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));
}

运行结果:

  1. array(5) {
  2.   [0]=>
  3.   int(0)
  4.   [1]=>
  5.   int(13)
  6.   [2]=>
  7.   int(15)
  8.   [3]=>
  9.   int(22)
  10.   [4]=>
  11.   int(50)
  12. }
  13. int(100)
  14. array(5) {
  15.   [0]=>
  16.   int(9)
  17.   [1]=>
  18.   int(13)
  19.   [2]=>
  20.   int(15)
  21.   [3]=>
  22.   int(27)
  23.   [4]=>
  24.   int(36)
  25. }
  26. int(100)
  27. array(5) {
  28.   [0]=>
  29.   int(13)
  30.   [1]=>
  31.   int(16)
  32.   [2]=>
  33.   int(22)
  34.   [3]=>
  35.   int(23)
  36.   [4]=>
  37.   int(26)
  38. }
  39. int(100)
    A+
发布日期:2017年05月12日 18:57:08  所属分类:PHP算法
最后更新时间:2017-12-15 21:01:31
评分: (3 票;平均数5.00 ;最高评分 5 ;用户总数3;总得分 15;百分比100.00)
付杰
花牛苹果 甘肃天水 李宏恩家自种 1斤 包邮
花牛苹果 甘肃天水 李宏恩家自种 1斤 包邮
  • ¥ 6.8元
  • 市场价:8.8元
服务器管理面板/主机控制面板“安装”服务
服务器管理面板/主机控制面板“安装”服务
  • ¥ 9.9元
  • 市场价:49.9元
SEO顾问服务 中小型网站 单站/最低99.9元 全方位优化
SEO顾问服务 中小型网站 单站/最低99.9元 全方位优化
  • ¥ 99.9元
  • 市场价:5000元
PHP运行环境 wamp lamp lnmp 安装 配置 搭建服务
PHP运行环境 wamp lamp lnmp 安装 配置 搭建服务
  • ¥ 9.9元
  • 市场价:49.9元

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

目前评论:6   其中:访客  5   博主  1

  1. 头像 小桥流水 1

    这个应该也可以理解为:PHP从p个数字中选出m个数,使其和等于n 吧!

  2. 头像 飞龙在天 1

    算法东西看不懂,也不想懂,太伤脑筋了。

  3. 头像 PHP算法吹牛大师 1

    我也自己写了一个,(此文章第五个就是我写的,博主已经把它整理到文章去了!)但是没有大家写得好,希望大家不要笑,我写的这个算法呢,结果都是浮点型float,而且相加的和也是小于100,但是它接近不了100,经常相加的和等于99;这就很尴尬了!

    • 头像 php算法排序研究 1

      @PHP算法吹牛大师 其实你的代码也没什么问题,只能说结果会和博客文章中所讲的算法第三种一样,都会无限接近100;你之所以相加和经常等于99;那是因为你用了四舍五入函数:round();因此才会造成这样!

  4. 头像 PHP算法爱好者 2

    下面是我自己写的一个PHP算法(算法已经被博主整理到此文章去了,此文章第6个算法就是我写的。),看看有没有大家需要的;得出来的结果都是整型!
    例如:把100这个数随机分成9份,相加总和还等于100;
    运行结果如下:

    1. F:\wamp64\www\1.php:41:  
    2. array (size=9)  
    3.   0 => int 3  
    4.   1 => int 8  
    5.   2 => int 9  
    6.   3 => int 10  
    7.   4 => int 12  
    8.   5 => int 13  
    9.   6 => int 14  
    10.   7 => int 15  
    11.   8 => int 16  
    12. F:\wamp64\www\1.php:42:int 100  
    13.   
    14. F:\wamp64\www\1.php:41:  
    15. array (size=9)  
    16.   0 => int 1  
    17.   1 => int 6  
    18.   2 => int 9  
    19.   3 => int 11  
    20.   4 => int 12  
    21.   5 => int 13  
    22.   6 => int 14  
    23.   7 => int 15  
    24.   8 => int 19  
    25. F:\wamp64\www\1.php:42:int 100  
    26.   
    27. F:\wamp64\www\1.php:41:  
    28. array (size=9)  
    29.   0 => int 4  
    30.   1 => int 8  
    31.   2 => int 9  
    32.   3 => int 10  
    33.   4 => int 11  
    34.   5 => int 12  
    35.   6 => int 13  
    36.   7 => int 15  
    37.   8 => int 18  
    38. F:\wamp64\www\1.php:42:int 100