【问题标题】:Random amount calculator [duplicate]随机金额计算器[重复]
【发布时间】:2013-11-18 19:55:57
【问题描述】:

我正在尝试找出一个随机数量的计算器,但以稀有性为例:

choices = [10,100,1000,10000]

10 最常见,100 更常见,1000 罕见,10000 极其罕见

我试过了

import random
def getAmmounts():
    choices = [10, 100, 1000, 10000]
    values = [random.choice(choices) for i in range(10)]
    return values

它返回了大量的值,但它们不是随机的10000 经常出现,而当我调用它时它几乎不应该出现,我收到的数据是:

[1000, 10000, 100, 1000, 10000, 10, 1000, 10000, 100, 100]

其中有两个10000's,几乎没有任何10 值,而10s100s 应该是最常见的,然后偶尔出现1000,但几乎没有10000 值。有没有办法设置一个优先类型的函数来做到这一点?在完成后应该返回的一些很好的示例数据是:

[10,10,100,10,10,100,1000]

还有偶尔的10000,但应该非常罕见,知道如何设置吗?

【问题讨论】:

  • 每个数字到底应该有多常见(即,概率是多少)?
  • @jwodder 每个的概率不是一个确切的数量,但10s应该是最常见的,所以在具有 20 个值的数据中,10 应该出现大约 6-10 次,但永远不要精确到 100值可能是 3-5 千次或两次,但几乎不会出现 10000 值
  • @user2925490 jwodder 所问的实际上是对总体解决方案的暗示。您想为这些值分配概率,例如,10 出现 80% 的时间,100 出现 10% 的时间,1000 出现 8% 的时间,10000 出现 2%的时间。但是,在为此分配实际百分比时,请记住getAmounts() 将实时运行多少次,这样如果用户可以在每分钟内运行getAmounts() 1000 次,那么您仍然有@ 987654349@ 是一个罕见的数字(一次或两次)。这将需要概率/统计数学。
  • 还有thisthisthisthisthis,可能还有很多其他问题。
  • @user2925490 除了我刚才说的,你说你想让10出现6 out of 20 times。将其重新调整为统计问题,注意6 of 20 可以表示为百分比((6/20)*100 = 30%!

标签: python probability weighted-average


【解决方案1】:

您的代码没有分配任何概率。您可能希望 1010000 少见,但 Python 不会知道这一点。

您可以使用 random.random 模拟概率以生成 0 到 1 之间的随机数,并根据生成的数字返回适当的数字。

例如

import random

def make_number():
  val = random.random()
  if val < 0.1: #10%
    return 10000
  elif val < 0.3: # 20%
    return 1000
  elif val < 0.6: # 30%
    return 100
  else: # 40%
    return 10

values = [make_number() for i in range(10)]
print (values)

【讨论】:

  • 这很好,但是当你实现它时要小心这里的逻辑,OP。如果您更改操作符符号,您可能会因为堆叠的elif 结构而遇到问题。例如,您不能将标志翻转为&gt;,否则您会遇到问题。
  • 写完之后,看起来也很难维护。我会使用哈希来存储更容易维护的概率。或者像this question 中的答案一样干净,因为您可以轻松添加或删除案例。
  • @Keikoku 稍微修改了一下,效果很好,感谢所有其他给出答案的人,当我修改它以满足我的需要时,他们都提供了帮助。
【解决方案2】:

输入列表中每个项目的概率相等。用你想要的比例给它一个列表。

choices = [10, 10, 10, 100]

10 的可能性是 100 的三倍。

【讨论】:

  • 像这样手动调整概率是一个很好的开始方式,但是当您将实施规模扩大一点时,我会变得一团糟。从长远来看,学习概率/统计(非常基础的版本)对了解如何让计算机按比例生成会更有帮助。
【解决方案3】:

为什么不生成一个数字,然后根据范围分配:

x = randint(1,11)
if x == 10:
    #This is the rarest, occurring only 10% of the time
elif x < 10 and x >= 8:
    #9 or 8 aka 20%
elif x < 8 and x >= 5:
    #7, 6, 5 aka 30%

您可以随心所欲地对其进行调整,或者使范围更长以获得更具体的机会。

【讨论】:

  • 此解决方案比 Jud 或 Triplee 的解决方案更优雅,因为他们让您手动将条目添加到所需的概率,这使用范围为您完成。它不像直接实现那么优雅,但我会选择它而不是我见过的任何其他东西。
  • 如果我理解正确,每个 elif 行的第一部分是多余的,因为如果上面的 if/elif 为真,则不会查看 elif。所以if x == 10, elif x &gt;= 8, elif x &gt;= 5, else我说的对吗?
【解决方案4】:

你可以产生一个随机数

import random
x = random.random() % this produces a random number between 0 and 1

您可以使用随机生成的数字在 10、100、1000 和 10000 之间进行选择:

if x < 0.5:        # x is between 0 and .50, so 50% chance
    choice = 10
else if x < 0.75:  # x is between .50 and .75, so 75-50 = 25% chance
    choice = 100
else if x < 0.9:   # x is between .75 and .90, so 90-75 = 15% chance
    choice = 1000
else:
    choice = 10000 # x is between .90 and 1, so 100-90 = 10% chance (5 times less likely than the first one)

这在 50% 的运行中输出 10,在 25% 的运行中输出 100,在 15% 的运行中输出 1000,在 10% 的运行中输出 10000。您可以将范围自定义为您想要的 [10,100,1000,10000] 上的任何分布!

【讨论】:

  • 从没想过要使用随机十进制数,我现在想编辑我的答案以使用它,但我不想窃取您的想法;)我喜欢使用列出而不是直接分配一个值,因为如果您不使用值列表,则如果您想更改值,则必须更改代码。
【解决方案5】:

一个快速(虽然不一定是最好的)解决方案是粘贴多个您希望在列表中更频繁出现的数字的副本:

import random
def getAmmounts():
    choices = [10] * 80 + [100] * 15 + [1000] * 4 + [10000] * 1
    values = [random.choice(choices) for i in range(10)]
    return values

【讨论】:

  • 这在技术上是一个解决方案,但是一个真的凌乱的解决方案,不能真正扩展到任何应用程序。花时间学习基于统计的答案会更有用。
  • 因此我的“快速但不是最好的”。我不知道 OP 需要多么灵活的解决方案。
  • 完全正确,我正在审查它们,看看我们可以让 OP 使用的直接实现有多接近;越直接,可能(越难)越好。
【解决方案6】:
import random

def getAmounts():
  amount = random.random(1,10)
  if amount == 10:
    return 10000
  elif amount > 8:
    return 1000
  elif amount > 5:
    return 100
  else:
    return 10

或者,如果你想使用一个列表,你可以做类似的事情(我没有打开 IDLE,加载需要很长时间,所以如果我有点跑题了,我很抱歉。)

import random

def getAmounts():
    values = [10, 100, 1000, 10000]
    amount = random.random(1,10)
    if amount == 10:
        return values[3]
    elif amount > 8:
        return values[2]
    elif amount > 5:
    return values [1]
  else:
    return values[0]

使用列表,您可以随时更改返回的实际值,因此,如果您想要返回 50、500、5000 和 50000 而不是 10、100、1000、50000,则只需重新分配值列表,然后代码仍然可以正常工作,无需遍历和更改每一行。

【讨论】:

    猜你喜欢
    • 2023-04-07
    • 2014-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多