Create numbers within an array that add up to a set amount

后端 未结 4 1975
长情又很酷
长情又很酷 2021-02-07 10:03

I\'m fairly new to PHP - programming in general. So basically what I need to accomplish is, create an array of x amount of numbers (created randomly) whose value add up

4条回答
  •  旧巷少年郎
    2021-02-07 10:29

    sorry i missed 'no duplicates' too
    -so need to tack on a 'deduplicator' ...i put it in the other question

    To generate a series of random numbers with a fixed sum:

    • make a series of random numbers (of largest practical magnitude to hide granularity...)
    • calculate their sum
    • multiply each in series by desiredsum/sum

    (basicaly to scale a random series to its new size)

    Then there is rounding error to adjust for:

    • recalculate sum and its difference from desired sum
    • add the sumdiff to a random element in series if it doesnt result in a negative, if it does loop to another random element until fine.
    • to be ultratight instead add or subtract 1 bit to random elements until sumdiff=0

    Some non-randomness resulting from doing it like this is if the magnitude of the source randoms is too small causing granularity in the result.

    I dont have php, but here's a shot -

    $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; }
      }
    

提交回复
热议问题