生成 N 个具有 X 位数字的随机数,使差值(从上到下减去的数字)为正数

generate N random numbers with X digits such that the difference(the numbers subtracted from top to bottom) is positive

提问人:sourlemonaid 提问时间:1/11/2019 最后编辑:sourlemonaid 更新时间:1/11/2019 访问量:80

问:

我正在尝试生成具有 X 位数的 N 个随机数,以便差异始终为正。

我能想到的最好的方法是生成 N 个数字

10,11,30,49,50然后对它们进行排序,找到差异,如果它是负数,就像在这种情况下一样,我会重新做一遍整个过程。50,49,30,11,10-50

可以想象,这是一种非常蛮力的方式,而且速度很慢。有没有更好的方法可以做到这一点?

如果有帮助,N 和 X 最多为 5。

如果不清楚,

我需要的是生成一组数字。然后,当你减去所有这些数字时,你会得到一个肯定的答案。在我的示例中,我生成的随机数是 10,11,30,49,50。我知道得到正数的最好方法是从最小的数字中减去最大的数字。所以我从大到小订购了它们。50,49,30,11,10 然后减去它们,我得到 -50(负数)所以我必须重新开始,直到我得到类似 90,20,30,10,11 的东西,排序后给我 90,30,20,11,10,这是 19(一个正数),当一切都被减去时,我可以停止

我也不介意我必须做几次,但我想将尝试次数保持在最低限度

换句话说,我试图生成一系列数字,其中最大值减去所有其他值的总和总是正数

语言无关 的随机 差异

评论

1赞 pjs 1/11/2019
也许我特别密集,但我不明白你在问什么。你能明确解释一下你所说的“差异”(什么和其他什么之间的差异?)是什么意思吗?以及你如何计算你的一组数字的-50。另外,排序起了什么作用?从一组有序的值开始,到一个相反有序的集合结束。为什么?
0赞 sourlemonaid 1/11/2019
@pjs我可能只是不够清楚。我需要的是生成一组数字。然后,当你减去所有这些数字时,你会得到一个肯定的答案。在我的示例中,我生成的随机数是 。我知道得到正数的最好方法是从最小的数字中减去最大的数字。所以我从大到小订购了它们。 然后减去它们,我得到 -50(一个负数)所以我必须重新开始,直到我得到类似 19(正数)的东西,当一切都被减去时,我可以停下来。10,11,30,49,5050,49,30,11,1090,30,20,11,10
1赞 pjs 1/11/2019
仍然没有看到一个很好的解释,具体来说,你从什么中减去什么。减法是成对标量运算:A - B = 差值。你的 A 和 B 是多少,它如何产生 -50?此外,在您的扩展解释中,您说“获得正数的最好方法是从最小的数字中减去最大的数字。我已经有一段时间没有学习减法了,但我很确定一个小值中减去一个大值会产生一个负数,而不是一个正数。
0赞 sourlemonaid 1/11/2019
@pjs在本例中,90-30-20-11-10 = 19 和 50-49-30-11-10 = -50。我必须从第一个到最后一个减去所有数字。从大到小对它们进行排序,使我有最好的机会获得正数。我说肯定是因为我试图将所有数字保持在 0 以上。对不起,我的措辞很糟糕
0赞 pjs 1/11/2019
换句话说,您正在寻找最大值减去所有其他值的总和。在这种情况下,顺序无关紧要,因为无论其顺序如何,其他值的总和都是相同的。

答:

1赞 ascoder 1/11/2019 #1

你可以用基于斐波那契数列的随机方法生成一个数字。

在斐波那契数列中,您根据前一个数字生成一个数字。如果你想要一个随机的正数,只需生成一个随机数并将其添加到最后一个随机数中,这将始终满足你的要求。

我在python中做了一个片段

import random

number_list=[]
r_number=0
while(r_number < 100):
    b_number=random.randint(1,10)
    r_number += b_number
    if r_number<100:
        number_list.append(r_number)
print(number_list)

结果如下:

首次执行:

[4, 14, 22, 24, 26, 28, 29, 34, 35, 36, 46, 48, 51, 56, 64, 72, 79, 89, 98]

第二次执行:

[7, 13, 19, 27, 34, 35, 39, 43, 45, 48, 52, 58, 68, 74, 83, 86, 88, 93, 99]

这种方法的优点(如果你对代码进行一些优化,可能会更好)是复杂度是 O(n)(线性),而不是你使用的任何排序算法。

我希望我已经解决了你的疑问 最后,个人观点:排序最好的集合是已经排序的集合。

编辑 1:我看到您需要最大数字大于其他数字的总和,这是一个简单的变化。

import random

number_list = []
r_number = random.randint(1, 10)
LIMIT=1000

while r_number < LIMIT:
    sum_ = sum(number_list)
    r_number = random.randint(sum_, sum_ + 10)
    number_list.append(r_number)

if number_list[-1] > LIMIT:
    del number_list[-1]

print(number_list)
print("Last element minus the rest equals",number_list[-1] - (sum(number_list) - number_list[-1]))

结果

[3, 4, 7, 21, 37, 72]
0

[9, 19, 38, 74]
8

[4, 4, 11, 20, 47, 96]
10

[4, 5, 10, 26, 55]
10

我只是尝试将 LIMIT 设置为 1e99 并计时:

Last element minus the rest equals 7

real    0m0,023s
user    0m0,020s
sys     0m0,000s

从中可以推断出大量的输出

./test.py |wc -c
17109

它计算程序输出给出的字符数。在这种情况下,非常长的整数。

评论

0赞 sourlemonaid 1/11/2019
我不确定这是否完全有效。如果我发现你所有数字的差值,我最终会得到一个负数。目标是将生成的数字从上到下减去,并使结果始终为正数。不过,我将尝试您提供的想法。我认为这是一个好的开始
1赞 sourlemonaid 1/11/2019
这太完美了!正是我需要的
0赞 ascoder 1/11/2019
不错的:D事情只是在每次要附加的下一个元素大于列表的总和时检查。你可以随机化它或其他任何东西。
1赞 sourlemonaid 1/12/2019
@trenixjetix谢谢!这与我所做的非常相似。很好的答案
2赞 Dillon Davis 1/12/2019
只是一个警告 - 如果使用它的人关心任何属性/其随机数的分布(均匀、加密安全等),此方法将破坏您初始 rng 的任何这些属性。与原题中的蛮力方法相比,这更具限制性,更不统一。