如何在Python中生成一个总和为给定数字的随机序列?

问题描述 投票:0回答:2

我正在尝试获取随机数以达到我用于 DND 类型游戏的特定总和。 角色可以使用 2-6 点,并用价值 1、2 或 3 点的模块填充。
因此,如果一个角色有 6 点,他们可以拥有任何序列,只要总和为 6。如果有 2 点,他们可以拥有两个 1 点模块或一个 2 点模块。

为此,我正在尝试使用随机生成器来做到这一点。 首先从一个随机数开始,然后从最大点数中减去该数字,然后在该新的最大值下生成一个新的随机数,直到达到 0。这是我的代码,不幸的是它经常生成比限制高一个点的总和。 有什么建议吗?谢谢。

tp = totalPoint
oneMods, twoMods, threeMods = 0, 0, 0
while tp > 0:
  if(tp >= 3):
      var = random.randint(1, 3)
      tp = tp - var
      if var == 3:
          threeMods +=1
      elif var == 2:
          twoMods += 1
      else:
          oneMods += 1
  elif(tp <=2):
      var = random.randint(1,2)
      tp = tp - var
      if var == 2:
          twoMods +=1
      else:
          oneMods += 1
  else:
      var = 1
      tp = tp -1
      oneMods +=1
await ctx.send(f'You have:\nLevel one modules: {oneMods}\nLevel 2 modules: {twoMods}\nLevel three mods: {threeMods}')
python random
2个回答
1
投票

为了避免当您的总和接近目标时出现任何偏差,我会以不同的方式处理这个问题。我不会随机生成构成总和的值,而是生成所有可能的候选值列表并随机选择其中一个。

>>> import itertools
>>> modules = [1, 2, 3]
>>> points = 6
>>> candidates = [module for x in range(points+1)
                         for module in itertools.product(modules, repeat=x) 
                             if sum(module)==points]
>>> candidates
[(3, 3),
 (1, 2, 3),
 (1, 3, 2),
 (2, 1, 3),
 (2, 2, 2),
 (2, 3, 1),
 (3, 1, 2),
 (3, 2, 1),
 (1, 1, 1, 3),
 (1, 1, 2, 2),
 (1, 1, 3, 1),
 (1, 2, 1, 2),
 (1, 2, 2, 1),
 (1, 3, 1, 1),
 (2, 1, 1, 2),
 (2, 1, 2, 1),
 (2, 2, 1, 1),
 (3, 1, 1, 1),
 (1, 1, 1, 1, 2),
 (1, 1, 1, 2, 1),
 (1, 1, 2, 1, 1),
 (1, 2, 1, 1, 1),
 (2, 1, 1, 1, 1),
 (1, 1, 1, 1, 1, 1)]

>>> import random
>>> random.choice(candidates)
(1, 1, 1, 1, 2)

0
投票

这个问题相关,请参阅这个答案

import scipy.stats as sps

def random_split(n,m):
    """ Generate m positive integers summing to n. """
    p = sps.dirichlet.rvs(alpha=[1]*m, size=1)
    return 1+sps.multinomial.rvs(n=n-m, p=p[0], size=1)
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.