再问红包算法,之前的有bug,@JXYCYFLM,@
http://bbs.csdn.net/topics/391001579
之前的帖子在此。
两位的算法都是有问题的。
版主给出的修订版,每当红包数量是单数的时候就不对了。加起来不等于总数。
恳请两位大侠帮忙修正。
------解决思路----------------------
$r = distribute(100, 31);<br />echo array_sum($r), PHP_EOL;<br />print_r($r);<br /><br />function distribute($total, $num) {<br /> $avg = $total / $num;<br /> $r = array_fill(0, $num, round($avg, 2));<br /> <br /> for($i=0; $i<$num; $i+=2) {<br /> $t = rand(1, $avg * 100) / 100;<br /> $r[$i] -= round($t, 2);<br /> if($r[$i] <= 0) $r[$i] = 0.01;<br /> if(isset($r[$i+1])) $r[$i+1] += round($t, 2);<br /> }<br /> $r[$num-1] = $total - array_sum(array_slice($r, 0, -1));<br /> return $r;<br />}
$r = distribute(100, 31);<br />echo array_sum($r), PHP_EOL;<br />print_r($r);<br /><br />function distribute($total, $num) {<br /> $avg = round($total / $num, 2);<br /> $r = array_fill(0, $num, $avg);<br /> <br /> for($i=0; $i<$num; $i+=2) {<br /> $t = rand(1, $avg * 100) / 100;<br /> $r[$i] -= $t;<br /> if($r[$i] <= 0) $r[$i] = 0.01;<br /> if(isset($r[$i+1])) $r[$i+1] += $t;<br /> }<br /> $r[$num-1] = $total - array_sum(array_slice($r, 0, -1));<br /> return $r;<br />}
<br />function distribute($total,$num){<br /> return _distribute($total,$num,$total/$num/2,0);<br />}<br />function _ceil($i){<br /> return ((int)($i*100))/100;<br />}<br />function _distribute($total,$num,$pj,$last_c){<br /> if($num==0){<br /> return array();<br /> }<br /> else if($num==1){<br /> return array($total);<br /> }<br /> else { <br /> $cz=_ceil(mt_rand(-$pj*100,$pj*100)/100);<br /> $n=_ceil($pj+$cz+$last_c);<br /> $res[]=$n;<br /> if($num-1>=0)<br /> $res=array_merge($res,_distribute($total-$n,$num-1,$pj,$pj-$cz));<br /> return $res;<br /> }<br />}<br />$ary=distribute(50,12);<br />print_r(array_sum($ary));<br />print_r($ary);<br />
<br />function fn($total, $part, $min = 0.01) {<br /> $res = array_fill(0, $part, $min);<br /> $total -= $part * $min;<br /> for($i=0; $i<$part; $i++) $total -= ($res[$i] += round($i == $part - 1 ? $total : (rand(0, $total * 100)) / 100, 2)) - $min;<br /> return $res;<br />}<br />