生成部分有序的随机数字列表

Posted

技术标签:

【中文标题】生成部分有序的随机数字列表【英文标题】:Generating a partially ordered random list of numbers 【发布时间】:2014-04-22 03:20:52 【问题描述】:

我想生成一个大小为 500 的随机数列表,其中该列表正好 30% 排序(我知道如何生成一个至少 30% 排序的列表),但这不是我想要的,我该怎么做生成一个“正好” 30% 的文件?我卡住了,怎么办?

这里是确切的措辞 “对于排序,您应该构建三个不同大小的文件:有序、逆序的键,最后一个其中 30% 的键是有序的。后一个文件不应包含排序为 30% 的文件完整,而是在其中 30% 的键相对于彼此正确放置但不一定连续的文件中。

【问题讨论】:

30% 排序是什么意思,能举个例子吗? “30% 已排序”是什么意思?如果随机数列表已经按排序顺序出现怎么办? 我创建了一个包含 500 个随机数的列表。我随机取出 150 个数字到另一个数组中并对其进行排序,排序后我将其放回原始数组中。但这不是 Exactly 30%,至少是 30%,我该怎么做才能让它正好 30% 排序? 好的。你认为 500 个随机数的列表会有什么属性? 假设我给了你一个数字列表。您能否列出您将申请的测试,以确定它是否符合您的目的? 【参考方案1】:

对于百分比排序,我可以看到 2 个主要想法:

只是元素数量不合适。

Once 应该能够通过排序获得估计的排序百分比,然后对其进行迭代,并保持每个元素与所需的概率百分比相同,否则将其与随机剩余元素交换(所以,如果我们想要30% 排序后,我们将以 30% 的概率保持元素相同,并以 70% 的概率将其交换)。

如果需要一个确切的数字,可以使用上述结果并(智能)交换随机元素,直到获得所需的百分比。

inversions的数量。

倒置是序列中的一对位置,其中这些位置上的元素不符合其自然顺序。

一个想法是首先对其进行排序,然后交换随机元素,使我们更接近所需的排序百分比,直到我们到达那里。

仅交换使我们更接近预期结果的元素是困难的(至少这样做很有效)。

一种非常暴力的方法是计算每对交换会导致的反转次数的变化,然后随机选择一个使我们更接近目标的次数。

李>

另一个想法是只生成随机对并计算反转的数量,直到我们找到一个让我们更接近的。

第三个选项是选择一个随机元素。如果它大于元素的一半,请尝试将其向左移动(理想情况下增加反转次数)。如果它更小,请尝试将其向右移动。在尝试向左/向右移动时,我们可以(分别)寻找一个更小/更大的元素来交换它并计算反转的变化(我们只需要在计算反转的变化时考虑交换元素之间的元素) .

起初我们可能只是随机交换元素,因为我们可能倾向于更多的反转。

如果百分比高于 50%,我们也可以从一个反向数组开始,即 100% 未排序。

【讨论】:

【参考方案2】:

存在将排列映射到 0 x 0, 1 x 0, 1, 2 x ... x 0, 1, ... n - 1 的一一对应关系,其中 codomain 中元组的第 j 个元素是涉及位置 j 和 i

这里有一个Gibbs sampling 的实例来解决这个问题。初始化一个元组求和到所需的排列数量。重复选择两个不同的索引,并在所有具有相同总和的可能性中均匀随机化。当你厌倦了等待时停下来(分布收敛于均匀但永远不会到达那里;也许明天我会找出一个 Propp--Wilson 风格的精确样本技术)。

在 Python 中(未经测试):

import random

def gibbs(n, target):
    perm = [0] * n
    for i in range(n):
        perm[i] = min(target, i)
        target -= i
    assert target == 0
    while ???:
        i = random.randrange(n)
        j = random.randrange(n)
        if i == j: continue
        total = perm[i] + perm[j]
        perm[i] = random.randrange(max(total - j, 0), i + 1)
        perm[j] = total - perm[i]
    for j in range(n):
        perm[j] = j - perm[j]
        for i in range(j):
            if perm[i] >= perm[j]: perm[i] += 1
    return perm

也可以通过动态规划和条件概率获得精确的样本,但是从这里来看,500 的运行时间看起来有点令人望而却步。

【讨论】:

以上是关于生成部分有序的随机数字列表的主要内容,如果未能解决你的问题,请参考以下文章

44如何生成一个随机数?

python中怎么设置随机产生数字

如何对其中包含随机生成的数字的卡片列表进行排序?

python随机生成一个4位整数,求各个数位上的数字之和

python随机彩票号码生成器游戏

python生成20个随机数列表,前10个升序后10个降序