繁体   English   中英

如何生成没有连续数字的随机整数列表?

[英]How do I generate a list of random integers without consecutive numbers?

在我对随机生成的列表进行排序后,我有连续的数字,例如

[7, 9, 13, 47, 64, 76, 83, 94, 95, 114, 115, 116, 120, 121, 123, 124, 127, 136, 152, 154, 167, 184, 189, 205, 212, 222, 226, 229, 231, 238]

这里连续的数字是(94, 95)(120, 121)(123, 124) 我该如何删除它们?

我的代码是:

while len(set(l)) != 30:
    a = random.randint(1, 240)
    l.append(a)

l = list(set(l))
l = sorted(l)

f.write(str(l))

我不想使用randrangerandom模块中的choice

创建一个随机数a并检查aa±1是否不在集合中:

import random 
l = set()
while len(l) != 30:
    a = random.randint(1, 240)
    if not {a-1,a,a+1} & l: # set intersection: empty == False == no common numbers
        l.add(a)

l = sorted(l) # sorted creates a sorted list from any iterable

print(l) 

输出:

[5, 12, 40, 47, 55, 59, 62, 73, 76, 82, 84, 89, 93, 95, 109, 
 125, 127, 141, 165, 168, 184, 187, 196, 202, 204, 210, 215, 
 218, 229, 231]

直接使用集合可以检查数字(±1)是否已经非常快速地成为随机数的一部分。

数独:


作为功​​能:

import random

def get_random_numbers_no_neighboring_elems(min_num, max_num, amount):
    """Generates amount random numbers in [min_num,..,max_num] that do not
    include neighboring numbers."""

    # this is far from exact - it is best to have about 5+ times the amount 
    # of numbers to choose from - if the margin is too small you might take
    # very long to get all your "fitting numbers" as only about 1/4 of the range
    # is a viable candidate (worst case): 
    #   [1 2 3 4 5 6 7 8 9 10]: draw 2 then 5 then 8 and no more are possible 
    if (max_num-min_num) // 5 < amount:
        raise ValueError(f"Range too small - increase given range.")

    l = set()
    while len(l) != amount:  
        a = random.randint(min_num, max_num)
        if not {a-1,a,a+1} & l: # set intersection: empty == False == no commons
            l.add(a)
    return sorted(l)

print(get_random_numbers_no_neighboring_elems(1,240,80))

我添加了一个解决方案,其中边缘可以选择的概率与其他边缘相同,但它们需要互斥:

def rand2(k,n,edge=False):
    forbid=set()
    l=set()
    while len(l)<k:
        x=random.randint(1,n)
        if x not in forbid : 
            l.add(x)
            forbid.update({x,x-1,x+1})
            if edge and x in {1,n} : forbid.add(n+1-x)
    return l

from collections import Counter    

print(Counter([tuple(rand2(2,5)) for i in range(10000)])) 
#Counter({(2, 4):1943, (1, 4):1720, (3, 5):1711, (2, 5):1652, (1, 3):1637, (1, 5):1337})

print(Counter([tuple(rand2(2,5,edge=True)) for i in range(100000)]))
#Counter({(2, 5): 2060, (3, 5): 2026, (1, 4): 1981, (1, 3): 1975, (2, 4): 1958})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM