0

我正在编写一个程序,它必须从数据库中随机选择 10 个项目。标准是它的类型应该基于用户的选择。

所以如果用户选择type 1程序必须10 items选择type 1

如果用户选择type 1 and 2程序必须选择5 itemsfromtype 15 itemsfromtype 2

如果用户选择type 1 , 2 and 4程序,则必须选择3 items其中each type一种类型必须有extra item10 个项目,哪种类型获得额外的问题必须是随机的。

因此,必须对用户可以选择的 N 种类型进行此操作。

关于如何实现这一点的任何建议?

顺便说一句,我正在尝试构建一个随机生成器,因此每次结果都必须是随机的。

Ps:我是用python编码的,但是任何语言代码都可以。

PS:我已经能够使用 SQL WHERE 子句选择项目,这不是真正的问题。

问题是,一旦我获得了每种选定类型的项目,我必须准确选择 10 个具有上述比例的项目,(即):如果选择 4 种类型,每种类型有 2 个项目,并且在任何两个中恰好有 2 个额外项目的类型。

4

3 回答 3

3

一种方法是一次扫描数据库,建立你的十个选择。这是一些伪代码:

  • 查询整个数据库中满足用户条件的记录
  • 建立结果列表中遇到的前十个
  • 如果出现任何其他记录,请随机决定是否包含它(第 n 项应包含的概率为 P(10/n)): if random() < 10.0 / n: ...
  • 如果要包含它,请随机选择先前的选择进行交换: i = randrange(10)

在 Python 中:

result = []
for n, row in enumerate(cursor.execute(user_query), 1):
    if n <= 10:
        result.append(row)
    elif random() < 10.0 / n:
        i = randrange(10)
        result[i] = row

或者,如果数据库不可查询,很大,并且有很大比例的记录预计与用户条件匹配,您可以从整个数据库中随机选择记录,直到找到十个符合条件的唯一记录:

result = set()
while len(result) < 10:
     record = random.choice(entire_db)
     if record not in result and matches(record, user_criteria):
          result.add(record)

后一种算法是 Python 自己的random.sample()函数使用的两种算法之一。

如果您可以运行查询并且匹配记录的数量可以容纳在内存中,那么整个事情可以归结为:

random.sample(list(cursor.execute(user_query)), 10)
于 2011-10-25T04:17:00.950 回答
1

基本上你需要把它变成这种形式:

SELECT item
FROM items
WHERE type = ...
ORDER BY RANDOM()
LIMIT 10

请参阅从 SQLite 表中随机选择这也适用于 PostgreSQL

这很好地让数据库为您完成大部分工作,您需要做的就是弄清楚如何将您的类型作为参数传递,这取决于您的数据库库。

对于多个,我可能只运行几个查询或动态生成一个具有多个联合的查询。

你可以这样做:

SELECT item
FROM items
WHERE type = type1
ORDER BY RANDOM()
LIMIT 5
UNION ALL
SELECT item
FROM items
WHERE type = type2
ORDER BY RANDOM()
LIMIT 5

可以像这样由 Python 生成:

types = ("type1", "type2", "type3")
limit = 10 // len(types) # be careful, for 11 or more types, this will set the limit to 0
sql = """
    SELECT item
    FROM items
    WHERE type = ?
    ORDER BY RANDOM()
    LIMIT %s
""" % (limit)
unioned_sql = " UNION ALL ".join([sql for i in range(len(types))])
result = cursor.execute(unioned_sql, types)

语法可能是错误的——我有一段时间没有使用 DB API。它应该给出这个想法。

您提到一个问题是您需要精确选择 10 个项目,如果比例不能精确到 10,则包括额外项目,因此最好将限制硬编码为 10(最多选择 100 个项目) ,然后在从数据库中获取列表后对其进行修剪。

于 2011-10-25T04:41:29.497 回答
0

您可能会发现一些有用的东西:


Python

随机选择(序列)

Return a random element from the non-empty sequence seq.

随机样本(人口,k)

Return a k length list of unique elements chosen from the population
sequence. Used for random sampling without replacement.

用法:

>>> import random
>>> random.choice([1, 2, 3, 4, 5])  # Choose a random element
3
>>> random.sample([1, 2, 3, 4, 5],  3)  # Choose 3 elements
[4, 1, 5]

SQL

SQL WHERE 子句

WHERE 子句用于仅提取满足指定条件的记录。

用法:

SELECT * FROM Items
WHERE Type=1
于 2011-10-25T04:42:58.387 回答