我想按排序顺序生成随机数。 我在下面写了代码:
void CreateSortedNode(pNode head)
{
int size = 10, last = 0;
pNode temp;
while(size-- > 0) {
temp = (pnode)malloc(sizeof(struct node));
last += (rand()%10);
temp->data = last;//randomly generate number in sorted order
list_add(temp);
}
}
[编辑:] 期望数量将按增加或减少的顺序产生:即{2,5,9,23,45,68}
int main()
{
int size = 10, last = 0;
while(size-- > 0) {
last += (rand()%10);
printf("%4d",last);
}
return 0;
}
有更好的主意吗?
答案 0 :(得分:1)
如果没有关于样本量或样本范围的任何信息,要知道以下内容是否有趣但不相关或解决方案并不容易,但是因为它在任何情况下都很有趣,所以这里就是。
问题:
在O(1)
空格中,从大小为n
S
的有序集合N
生成大小为<S1,S2,…SN>
的无偏序有序随机样本,以便样本中的元素与有序集中的元素的顺序相同。
解决方案:
概率n/|S|
,请执行以下操作:
将S1
添加到示例中。
递减n
从S1
S
重复步骤1和2,每次使用S
的新第一个元素(和大小),直到n
为0,此时样本将具有所需数量的元素
python中的解决方案:
from random import randrange
# select n random integers in order from range(N)
def sample(n, N):
# insist that 0 <= n <= N
for i in range(N):
if randrange(N - i) < n:
yield i
n -= 1
if n <= 0:
break
解决方案的问题:
需要O(N)
次。我们真的想花费O(n)
时间,因为n
可能比N
小得多。另一方面,我们希望保留O(1)
空格,以防n
也非常大。
更好的解决方案(仅限大纲)
(以下内容改编自Jeffrey Scott Visser的1987年论文,“一种有效的顺序随机抽样算法”,由于Visser博士的慷慨,可以从ACM数字图书馆免费获得。见{{3}请阅读论文了解详情。)
如果我们可以根据某些分布生成一个随机数,而不是递增i
并选择一个随机数,就像上面的python代码一样,那将是很酷的{{1将增加而不会产生任何元素。我们所需要的只是分布(显然取决于i
和n
的当前值。)
当然,我们可以从对算法的检查中精确地推导出分布。但这并没有多大帮助,因为生成的公式需要大量时间来准确计算,最终结果仍为N
。
但是,我们并不总是要准确计算它。假设我们有一些易于计算的合理良好的近似值,这些近似值一直低估概率(结果是它有时不会做出预测)。如果这种近似有效,我们就可以使用它;如果没有,我们将需要回退到准确的计算。如果这种情况很少发生,我们平均可能会达到O(N)
。事实上,Visser博士的论文展示了如何做到这一点。 (附代码。)
答案 1 :(得分:0)
假设您只想生成三个随机数x
,y
和z
,以便它们按排序顺序x <= y <= z
生成。您将把它们放在一些C ++容器中,我将其称为D = [x, y, z]
之类的列表,因此我们也可以说x
是D
的组件0,或{{1等等。
对于首先为D_0
绘制随机值的任何顺序算法,假设它出现2.5,然后这会告诉我们一些关于x
必须是什么的信息,即{{1 }}
因此,以y
的值为条件,您所需的随机数算法必须满足y >= 2.5
的属性。如果您正在绘制的分布类似于统一分布,例如统一分布或高斯分布,那么很明显通常x
将是涉及该分布密度的其他表达式。 (事实上,只有像“无限”的狄拉克三角洲这样的病态分布可能是独立的,对你的应用来说是无稽之谈。)
因此,我们可以充满信心地推测,p(y >= x | x) = 1
{em}的各种值的p(y >= x)
不等于 p(y >= t | x)
。这是依赖随机变量的定义。所以现在您知道随机变量t
(最终列表中的第二个)在统计上与p(y >= t)
无关。
另一种说明方式是,在您的输出数据y
中,x
的组件不是统计独立的观察结果。事实上,他们必须正相关,因为如果我们知道D
比我们想象的更大,我们也会自动知道D
大于或等于我们的想法。
从这个意义上讲,提供这种输出的顺序算法就是马尔可夫链的一个例子。序列中给定数字的概率分布有条件地取决于先前的数字。
如果你真的想要像这样的马尔可夫链(我怀疑你没有),那么你可以随意绘制第一个数字(对于x
),然后绘制正增量,你将添加每个连续的数字,如下:
y
绘制一个值,例如2.5 x
绘制严格正值,例如13.7,因此x
为2.5 + 13.7 = 16.2 y-x
绘制严格正值,例如0.001,因此y
为16.201 您只需要承认结果的组件在统计上不是独立的,因此您不能在依赖于统计独立性假设的应用程序中使用它们。
答案 2 :(得分:0)
早在 1979 年就解决了(由 Carnegie-Mellon 的 Bentley 和 Saxe 解决):
https://apps.dtic.mil/dtic/tr/fulltext/u2/a066739.pdf
解决方案在代码方面也非常紧凑!
他们的论文是用 Pascal 写的,我把它转换成 Python,所以它应该适用于任何语言:
from random import random
cur_max=100 #desired maximum random number
n=100 #size of the array to fill
x=[0]*(n) #generate an array x of size n
for i in range(n,0,-1):
cur_max=cur_max*random()**(1/i) #the magic formula
x[i-1]=cur_max
print(x) #the results
享受你排序的随机数...