Math 生成排序后的随机整数而不进行排序?O(n)

Math 生成排序后的随机整数而不进行排序?O(n),math,sorting,random,Math,Sorting,Random,我只是在看一个关于高尔夫的问题。然而,我突然想到的是,你可以生成一个正增量列表,然后继续将它们添加到一个运行总数中,因此: deltas: 1 3 2 7 2 ints: 1 4 6 13 15 事实上,您可以使用浮动,然后进行归一化以适应某个上限,然后进行取整,但效果是相同的 虽然它不会使代码更短,但如果没有排序步骤,它肯定会更快。但我没有真正掌握的是:得到的整数分布是否与从均匀分布的概率密度函数生成100个随机整数相同 编辑:示例脚本: import random,sys runn

我只是在看一个关于高尔夫的问题。然而,我突然想到的是,你可以生成一个正增量列表,然后继续将它们添加到一个运行总数中,因此:

deltas: 1 3 2  7  2
ints:   1 4 6 13 15
事实上,您可以使用浮动,然后进行归一化以适应某个上限,然后进行取整,但效果是相同的

虽然它不会使代码更短,但如果没有排序步骤,它肯定会更快。但我没有真正掌握的是:得到的整数分布是否与从均匀分布的概率密度函数生成100个随机整数相同

编辑:示例脚本:

import random,sys
running = 0
max = 1000
deltas = [random.random() for i in range(0,11)]
floats = []
for d in deltas:
    running += d
    floats.append(running)
upper = floats.pop()
ints = [int(round(f/upper*max)) for f in floats]
print(ints)
其输出(公平掷骰)为:

更新:并指出对delta使用an将得到整数的均匀分布。

a有一个上限和一个下限。如果你使用你提出的方法,而你的delta恰好被选得足够大,以至于在你生成所有的数字之前,你会遇到上界,那么你的算法下一步会做什么


话虽如此,您可能想调查,这是以给定平均频率发生的随机事件之间的间隔时间分布。

我认为这将非常相似,但由于标准化,极值将不同。例如,在1和100之间随机选择的100个数字都可以是1。然而,使用您的系统创建的100个数字都可能具有0.01的增量,但是当您对它们进行规格化时,您将把它们放大到1->100的范围内,这意味着您永远不会得到一组非常低的数字的奇怪可能性。

如果您将数字范围设为1到1000,并且必须使用其中的100个数字,增量必须至少为10,否则无法达到1000标记。我们来做些工作,在实践中证明一下吧

在一个均匀分布的随机选择中,任何给定数字的概率为100/1000,例如1/10——没有冲击,以此为基础

假设你开始使用一个增量,这个增量只有10

获得数字1的几率是1/10——看起来不错。 获得数字2的几率为1/10+(1/10*1/10)(因为可以连续命中1的2个增量,或者只命中2作为第一个增量。) 获得数字3的几率是1/10+(1/10*1/10*1/10)+(1/10*1/10)+(1/10*1/10)

第一种情况是增量为3,第二种情况是连续命中3个增量为1,第三种情况是增量为1后接2,第四种情况是增量为2后接1

为了我的手指打字,我们不会生成达到5的组合

很快,前几个数字比直接随机数的概率更大

这可以通过改变delta值来改变,所以分数都是不同的,但我不相信你能找到产生相同几率的delta


给出一个类比,它可能会沉没它,如果你认为你的delta为6,你运行两次它就相当于扔2个骰子-每个三角洲都是独立的,但是你知道7的选择几率比2高。

< P>你可以在两个关卡中完成;p> 在第一个过程中,生成介于0和(MAX_RAND/n)之间的增量

在第二步中,将随机数归一化,使其在边界内


仍然是O(n),具有良好的参考位置。

因此,您要问的是,以这种方式生成的数字是否将均匀分布

您正在生成一个系列:

yj=∑I= 0J(席/A)< /P> <> >代码> > <代码>是所有席的总和。席是(正)三角洲的列表。< / P> <>这是可以做的,IFF席指数分布(用任何固定的平均值)。因此,如果席是均匀分布的,则所得的YJ将不均匀分布。

已经说过,生成指数席值很容易。 一个例子是:

sum := 0
for I = 1 to N do:
    X[I] = sum = sum - ln(RAND)
sum = sum - ln(RAND)
for I = 1 to N do:
    X[I] = X[I]/sum
import random,sys
running = 0
max = 1000
deltas = [random.expovariate(1.0) for i in range(0,11)]
floats = []
for d in deltas:
    running += d
    floats.append(running)
upper = floats.pop()
ints = [int(round(f/upper*max)) for f in floats]
print(ints)
您将在
[0,1)
范围内对随机数进行排序

参考文献:。本文还有其他(更快的)算法


当然,这会生成浮点数。为了使整数均匀分布,您可以在最后一步中将上面的
sum
替换为
sum/RANGE
(即,R.H.S变为
X[i]*RANGE/sum
,然后将数字四舍五入到最接近的整数).

Q:得到的整数分布是否与从均匀分布的概率密度函数生成100个随机整数相同

答:每个增量都是均匀分布的。中心极限定理告诉我们,大量偏差之和的分布(因为它们具有有限的均值和方差)将趋向于正态分布。因此,序列中后面的偏差将不是均匀分布的

因此,简短的回答是“不”。恐怕我不做代数就不能给出简单的解,我今天没有时间做!

并指出,对delta使用an将得到整数的均匀分布

因此,问题中代码示例的新版本将是:

sum := 0
for I = 1 to N do:
    X[I] = sum = sum - ln(RAND)
sum = sum - ln(RAND)
for I = 1 to N do:
    X[I] = X[I]/sum
import random,sys
running = 0
max = 1000
deltas = [random.expovariate(1.0) for i in range(0,11)]
floats = []
for d in deltas:
    running += d
    floats.append(running)
upper = floats.pop()
ints = [int(round(f/upper*max)) for f in floats]
print(ints)
请注意使用了
random.expovariate(1.0)
,a(非常有用!)。在这里,它的平均值为1.0,但由于脚本对序列中的最后一个数字进行了归一化,因此平均值本身并不重要

输出(公平掷骰):

中的(1979)很有趣。它给出了一种算法,用于生成均匀顺序统计信息,该算法不是通过加法而是通过逐次乘法:

max = 1.
for i = N downto 1 do
   out[i] = max = max * RAND^(1/i)
其中RAND在[0,1]上是一致的。这样,您就不必在最后进行规范化,事实上甚至不必将数字存储在数组中;您可以将其用作迭代器


第22页给出了该算法的另一种推导,并将其归功于Malmquist(1950)。

我认为他已经回答了这个问题,不是吗?如果你使用浮点数,你可以设置为cal