【问题标题】:I want to select some random numbers but their addition should always be even in Python我想选择一些随机数,但它们的添加应该总是在 Python 中
【发布时间】:2020-10-29 09:04:09
【问题描述】:
import random


for i in range(100):
    a = random.randint(1, 20)
    b = random.randint(1, 20)
    c = random.randint(1, 20)
    if ((a + b + c) % 2) == 0:
        print(str(a) + "," + str(b) + "," + str(c))

我试过了,但没有得到想要的输出。我希望在 1 到 20 之间选择三个随机数,以使它们的总和始终为偶数。在这里,程序只打印输出,即使它没有以这种方式选择数字。 希望你能帮助我。谢谢!

【问题讨论】:

    标签: python python-3.x random


    【解决方案1】:

    检查前两个(a,b)的和是偶数还是奇数,然后相应地设置c?

    import random
    
    
    for i in range(100):
        a = random.randint(1, 20)
        b = random.randint(1, 20)
        if (a + b) % 2 == 0:
          c = random.randint(1, 10) * 2
        else:
          c = random.randint(1, 10) * 2 - 1
        if ((a + b + c) % 2) == 0:
            print(str(a) + "," + str(b) + "," + str(c))
    

    【讨论】:

    • 我认为这段代码永远不会打印c19 的情况。此外,if 条件检查(打印前)似乎是多余的。
    • 关于 if,你是对的,但我保留它以表明这是有效的,c 可以是 19,我刚刚测试了它(将 if 更改为 if c==19 并打印了 3 个输出)。
    • 您是否得到c19 以及同时ab 和@ 的总和987654330@ 加起来等于总数?
    • 是的,(顺便说一句:总和总是偶数)
    【解决方案2】:

    你可以这样做:

    import random
    from itertools import product
    
    # Prepare a list of triplets that add up to an even number
    even_triplets = [x for x in product(range(1,21), range(1,21),range(1,21))
                     if (sum(x)%2)==0]
    
    # Now select 100 of those triplets randomly, allowing
    # duplicates (allowing same triplet to appear multiple times)
    
    result = random.choices(even_triplets, k=100)
    # If you don't want repetitions, un-comment below line instead of above:
    # result = random.sample(even_triplets, 100)
    
    # Print the first and last of the selected 100 triplets, just to verify
    print(result[0])
    print(result[-1])
    

    注意: 目前这个问题的表述方式是自相矛盾:它说abc 将被随机选择,并且它还说他们应该加起来是偶数。如果abc的选择是真正随机的,那么就不能受到加起来是偶数的附加约束。

    【讨论】:

    • 请注意,随机并不意味着均匀分布。它的描述方式,每个随机变量的边际分布确实是均匀的,只是联合分布有一个约束,不包括某些组合。为了证明边缘是统一的,您可以运行,例如,collections.Counter([x[0] for x in even_triplets]) 并查看每个值出现的次数相同
    • @SamMason - 您的意思是输入 for x in result 而不是 for x in even_triplets 吗?
    • 不。我的意思是整个分布的边缘而不是任何特定的样本
    【解决方案3】:

    为了完整起见,使用此分布生成样本的效率较低的方法是使用rejection sampling。这通过拒绝不想要的值来工作,在这种情况下总和不是偶数

    from random import randint
    
    def fn():
      while True:
        x = tuple(randint(1, 20) for _ in range(3))
        if sum(x) & 1 == 0:
          return x
    

    可以用作:

    for i in range(100):
        a, b, c = fn()
        print(f'{a}, {b}, {c}')
    

    拒绝抽样可能会很浪费,但平均而言,我们只希望每接受一个样本就拒绝一个样本,所以这里并不算太糟糕

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-17
      • 1970-01-01
      • 2016-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多