使用PHP生成具有特定规则的数字

时间:2015-03-21 14:54:42

标签: php random

例如我得到了这个整数110

设Nx为整数

是否可以使用PHP生成N1到N8(N1到N8是一个整数),它限制了以下规则:

N1 + N2 + N3 + N4 + N5 + N6 + N7 + N8 = 110?

不知道什么函数(例如rand(),mt_rand(),使用循环等)可以PHP做到这一点。

2 个答案:

答案 0 :(得分:0)

我能想到的问题的最短解决方案是:

$m = 110;  // desired sum
$v = 8;    // desired elements
$x = [];   // result

for($i = 1; $i < $v; $i++)
    $x[$i] = rand(1, $m - array_sum($x) - (($v - $i) * $v));
$x[0] = $m-array_sum($x);

// print results
print_r($x);
printf("Elements sum to: %d\n",array_sum($x));

导致

Array
(
    [1] => 16
    [2] => 13
    [3] => 15
    [4] => 23
    [5] => 5
    [6] => 7
    [7] => 1
    [0] => 30
)
Elements sum to: 110

所以欢呼,正是你想要的,尽管它可以针对更好的传播进行优化。但是让我解释一下行。

首先我刚刚初始化了三个变量。 $m是您希望为所有元素提供的所需金额。 $v是您要生成的元素数量(N&#39; s)。并且$x包含一个数组,其中包含计算的所有N,因此我们感兴趣的结果是:

$m = 110;  // desired sum
$v = 8;    // desired elements
$x = [];   // result

现在我们开始循环遍历我们想要计算的元素。注意我们从1开始,因为我们将在后面使用0来计算最后一个值:

for($i = 1; $i < $v; $i++)

现在来了&#34;脑力劳动&#34;我们将当前元素$x[$i]设置为随机值。在PHP中,我们可以将最小值和最大值传递给随机函数,所以我选择1作为min来避免0&#39; s和max我选择i将在最后解释更详细,但显然我们想避免110作为第一个值,其余为零,这就是我们这样做的方式:

    $x[$i] = rand(1, $m - array_sum($x) - (($v - $i) * $v));

在最后一步中我们需要确保我们最终得到所需的总和,所以我只需将元素设置为所需的最大总和减去所有现有元素的总和:

$x[0]=$m-array_sum($x);

代码的最后几行只打印出结果,但正如所承诺的那样,让我解释一下&#34;复杂的&#34;我选择的随机函数的最大部分。

    $m - array_sum($x) - (($v - $i) * $v)

这里真正方便的一个PHP函数是array_sum函数,它将数组的所有元素相加。如果我们只是在每个元素上调用rand(1,110),那么我们很容易就会得到一个高于 110 的和,所以我们从最大值中减去所有现有元素的总和以避免这是第一手资料:$m - array_sum($x)。因此,如果最后三个生成的元素加起来 43 ,则下一个元素不能高于 67 110 - 43 )。我们仍然可以得到像(12,7,24,5,62,0,0,0)这样的结果,我们不会忽略零,所以我们必须减去元素的数量留下$v - $i,这将避免零。

我们仍然可以得到像(12,7,24,5,59,1,1,1)这样的结果并且看起来不太好,所以我做的最后一次优化是将它乘以一个任意数字为更高的值留出更多空间 - 在这种情况下,我只使用$v(元素数量)作为任意数字,但您可以使用此值即(($v - $i) * 12)),直到获得所需结果。

答案 1 :(得分:0)

非常感谢!几乎和我想要的一样。

$m = 110;  // desired sum
$v = 8;    // desired elements
$x = [];   // result

for($i = 1; $i < $v; $i++)
    $x[$i] = mt_rand(1, $m - array_sum($x) - (($v - $i) * $v));
$x[] = $m-array_sum($x);

// print results
print_r($x);
printf("Elements sum to: %d\n",array_sum($x));

我已将 rand()更改为 mt_rand(),这可能会使事情变得更快 $x[0] = $m-array_sum($x); =&gt; $x[] = $m-array_sum($x);

这样Array就可以从1开始,到8结束

Array
(
  [1] => 16
  [2] => 13
  [3] => 15
  [4] => 23
  [5] => 5
  [6] => 7
  [7] => 1
  [8] => 30
)
Elements sum to: 110