使用PHP使用特定规则生成数字

使用PHP使用特定规则生成数字,php,random,Php,Random,例如,我得到了这个整数110 设Nx为整数 是否可以使用限制以下规则的PHP生成N1到N8(N1到N8是整数): N1+N2+N3+N4+N5+N6+N7+N8=110 我不知道什么函数(例如rand()、mt_rand()、using loops等)可以让PHP做到这一点。我能想到的解决问题的最短方法是: $m = 110; // desired sum $v = 8; // desired elements $x = []; // result for($i = 1; $i &

例如,我得到了这个整数110

设Nx为整数

是否可以使用限制以下规则的PHP生成N1到N8(N1到N8是整数):

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


我不知道什么函数(例如rand()、mt_rand()、using loops等)可以让PHP做到这一点。

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

$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));
所以万岁,这正是你想要的,尽管它可以优化以获得更好的传播。但让我逐行解释

首先,我刚刚初始化了三个变量
$m
是所有元素所需的总和
$v
是要生成的元素数。并且,
$x
包含一个数组,其中包含计算出的所有N,因此我们感兴趣的结果是:

$m = 110;  // desired sum
$v = 8;    // desired elements
$x = [];   // result
现在,我们通过要计算的元素开始一个循环。请注意,我们从1开始,因为稍后将使用0计算最后一个值:

for($i = 1; $i < $v; $i++)
在最后一步中,我们需要确保最终得到所需的和,因此,我没有随机设置元素,而是将元素设置为所需的最大和减去所有现有元素的和:

$x[0]=$m-array_sum($x);
代码的最后几行只是打印出结果,但正如承诺的那样,让我解释一下我选择的随机函数的“复杂”最大部分

    $m - array_sum($x) - (($v - $i) * $v)
这里真正方便的一个PHP函数是函数,它将数组的所有元素相加。如果我们只对每个元素调用
rand(1110)
,那么我们很容易得到一个大于110的总和,因此我们从最大值中减去所有现有元素的总和,以避免出现这种情况:
$m-array\u 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))
,直到获得所需的结果。

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

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

N1和N2等之间的关系规则是什么?只是随机数,它可以是任何整数,最后可以加成110。然后答案是“是的,你可以在PHP中这样做。”rand()、mt_rand()和循环可能会有效。试着写一些代码,看看会发生什么。这里解释了一个算法:你想要任何约束,比如没有重复项吗?另外,它必须是8个数字,还是最多8个数字?你指的是整数还是正整数?那真的不是一组随机数。这是一组用1填充的随机数。当然是!如果你测试它,你会看到。。。我只是给出了带1的示例,以显示如果避免“软化”最大值会发生什么。这可能会更加完善,但实际上从我的测试运行来看,我每10次迭代不超过7次-唯一的非随机值是最后一次,在我的情况下,它永远不会是“1”,但因为它是max减去一个随机值之和,所以在评论之前请测试代码!如果你在1到100之间挑选8个随机数,那么仅仅是偶然得到7个1的概率是多少?概率是由PHPs rand()函数给出的,因此如果你将最后一个乘法器保持在较低的水平,那么你可以得到类似(103,1,1,1,1,1,1,1,1)的结果,乘法器会减少这种影响,并将随机数在你得到的范围内传播得更多“更好”的结果,如果这不是期望的,那么就不考虑乘法器,所以它只是
$m-array\u sum($x)-($v-$i)”,如果你将min设置为零,那么你可以将max设置为
$m-array\u sum($x)`并且你将有带零的“真实”非优化随机数……我的实现是随机的,但没有使用cosmeticsNo-rand函数(有众所周知的问题)给你随机数。你必须用概率函数来回答我的问题。如果你认为一排7个可能是偶然发生的,我想和你玩一个骰子游戏。随机数是关于每个值的概率相等,而不是关于好。
    $m - array_sum($x) - (($v - $i) * $v)
$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));
Array
(
  [1] => 16
  [2] => 13
  [3] => 15
  [4] => 23
  [5] => 5
  [6] => 7
  [7] => 1
  [8] => 30
)
Elements sum to: 110