0

データベースからランダムに 10 個の項目を選択するプログラムを作成しています。基準は、そのタイプがユーザーの選択に基づくべきであるということです。

したがって、ユーザーが選択した場合type 1、プログラムは次のいずれかを選択する必要10 itemsがありますtype 1

ユーザーが選択した場合、type 1 and 2プログラムは選択する必要5 itemstype 1あります5 itemstype 2

ユーザーが選択した場合type 1 , 2 and 4、プログラムは3 itemsforを選択するeach type必要があり、タイプの 1 つが必要であり、extra item10 個のアイテムを取得する必要があり、追加の質問を取得するタイプはランダムでなければなりません。

したがって、これは、ユーザーが選択できる N 個のタイプに対して実行する必要があります。

これを達成する方法について何か提案はありますか?

ちなみに、ランダムジェネレーターを構築しようとしているので、結果は毎回ランダムでなければなりません。

Ps: 私は python でコーディングしていますが、どの言語コードでも問題ありません。

PS: SQL WHERE 句を使用してアイテムを選択できますが、それは本当の問題ではありません。

問題は、選択した各タイプのアイテムを取得したら、上記の比率で正確に 10 アイテムを選択する必要があることです。タイプの。

4

3 に答える 3

3

1 つの方法は、DB を 1 回のパスでスキャンして、10 個の選択を作成することです。ここにいくつかの擬似コードがあります:

  • データベース全体をクエリして、ユーザーの基準を満たすレコードを探します
  • 結果リストで見つかった最初の 10 個を構築します
  • 追加のレコードが発生した場合は、それを含めるかどうかをランダムに決定します (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

または、データベースがクエリ不可能で巨大で、ユーザー基準に一致すると予想されるレコードの割合が高い場合は、基準に一致する一意のレコードが 10 個見つかるまで、DB 全体からランダムにレコードを選択できます。

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()関数で使用される 2 つのアルゴリズムのうちの 1 つです。

ただし、クエリを実行でき、一致するレコードの数がメモリに収まる場合、全体は次のようになります。

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 アイテムを選択します)。 、DBから取得した後にリストをトリムします。

于 2011-10-25T04:41:29.497 に答える
0

役に立つかもしれないいくつかのこと:


パイソン

random.choice(seq)

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

random.sample(母集団, 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 に答える