在数组中创建加起来设定数量的数字

时间:2010-05-08 11:03:18

标签: php arrays

我对PHP很新 - 一般编程。基本上我需要完成的是,创建一个 x 数量的数组(随机创建),其值加起来 n

让我们说,我必须创建4个加起来为30的数字。我只需要第一个随机数据集。这里的4和30是将由用户设置的变量。

基本上类似于

x = amount of numbers;
n = sum of all x's combined;

// create x random numbers which all add up to n;

$row = array(5, 7, 10, 8) // these add up to 30

此外,不允许重复,所有数字都必须为正整数。

我需要数组中的值。我有时候一直在乱搞它,但是,我的知识相当有限。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:7)

首先,这是一个非常酷的问题。我几乎可以肯定我的方法甚至不能完美地分配数字,但它应该比其他一些方法更好。

我决定从最低的数字构建数组(并在最后将它们洗牌)。这允许我总是选择一个允许产生有效结果的随机范围。由于数字必须一直在增加,我解决了确保有效解决方案仍然存在的最高可能数量(即,如果n = 4且max = 31,如果第一个数字被选为7,则不会可以选择大于7的数字,使得4个数字的总和等于31)。

$n = 4;
$max = 31;
$array = array();

$current_min = 1;
while( $n > 1 ) {
    //solve for the highest possible number that would allow for $n many random numbers
    $current_max = floor( ($max/$n) - (($n-1)/2) );
    if( $current_max < $current_min ) throw new Exception( "Can't use combination" );
    $new_rand = rand( $current_min, $current_max ); //get a new rand
    $max -= $new_rand; //drop the max
    $current_min = $new_rand + 1; //bump up the new min
    $n--; //drop the n
    $array[] = $new_rand; //add rand to array
}
$array[] = $max; //we know what the last element must be
shuffle( $array );

编辑:对于$n的大值,你最终会在数组末尾有很多分组值,因为很有可能你会得到一个接近最大值的随机值,迫使休息时要非常亲密。可能的解决办法是加权兰特,但这超出了我的范围。

答案 1 :(得分:0)

我不确定我是否理解你,但试试这个:

$n = 4;
$max = 30;
$array = array();

do {
    $random = mt_rand(0, $max);

    if (!in_array($random, $array)) {
        $array[] = $random;
        $n--;
    }
} while (n > 0);

答案 2 :(得分:0)

抱歉,我错过了'没有重复' - 需要加上'重复数据删除器'......我把它放在另一个question

生成一系列具有固定总和的随机数:

  • 制作一系列随机数(最大实际大小以隐藏粒度......)
  • 计算他们的总和
  • 将每个串联乘以desiredsum / sum

(基本上将随机系列缩放到新的大小)

然后有一个舍入错误来调整:

  • 重新计算总和及其差异 来自所需的金额
  • 将sumdiff添加到随机元素 如果不导致a 否定,如果它确实循环到另一个 随机元素,直到罚款。
  • 要超高而不是添加或 将1位减去随机元素 直到sumdiff = 0

这样做会产生一些非随机性,如果源randoms的大小太小会导致结果的粒度。

我没有PHP,但这是一个镜头 -

$n = ;              //size of array
$targsum = ;        //target sum
$ceiling = 0x3fff;  //biggish number for rands
$sizedrands = array();

$firstsum=0;
$finsum=0;

//make rands, sum size
for( $count=$n; $count>0; $count--)
{ $arand=rand( 0, $ceiling );
  $sizedrands($count)=$arand;
  $firstsum+=$arand; }

//resize, sum resize
for( $count=$n; $count>0; $count--)
{ $sizedrands($count)=($sizedrands($count)*$targsum)/$firstsum;
  $finsum+=$sizedrands($count);
  }

//redistribute parts of rounding error randomly until done
$roundup=$targsum-$finsum;

$rounder=1; if($roundup<0){ $rounder=-1; }

while( $roundup!=0 )
{ $arand=rand( 0, $n );
  if( ($rounder+$sizedrands($arand) ) > 0 )
  { $sizedrands($arand)+=$rounder; 
    $roundup-=$rounder; }
  }

答案 3 :(得分:-2)

希望这会对你有所帮助....

方法-1P> {{2P>方法-2P>

$aRandomarray = array();
for($i=0;$i<100;$i++)
{
    $iRandomValue = mt_rand(1000, 999);
    if (!in_array($iRandomValue , $aRandomarray)) {
        $aRandomarray[$i] = $iRandomValue;
    }
}