【发布时间】:2010-03-30 21:00:35
【问题描述】:
我有一张表,描述了我系统中的各种对象(即雨伞、靴子、挎包等)。这些对象中的每一个都需要具有不同的流行率或发病率。例如,雨伞比靴子更稀有。基于这些因素,我需要根据该发生率值随机选择单个对象(包括空白或“未找到对象”)。
哎呀。有意义吗?
【问题讨论】:
-
没有选择对象的概率应该是多少?这是存储在数据库中还是硬编码常量?
标签: php mysql codeigniter
我有一张表,描述了我系统中的各种对象(即雨伞、靴子、挎包等)。这些对象中的每一个都需要具有不同的流行率或发病率。例如,雨伞比靴子更稀有。基于这些因素,我需要根据该发生率值随机选择单个对象(包括空白或“未找到对象”)。
哎呀。有意义吗?
【问题讨论】:
标签: php mysql codeigniter
SELECT * FROM some_table
WHERE (100*RAND()) > some_table.percent_probability
LIMIT 1
....并且选择的概率存储在 percent_probability 字段中。
C.
【讨论】:
如果您有一个写很少读的场景(即您很少更改对象和概率),您可能需要预先计算概率值,以便如果您有一个随机值,您可以明确地决定哪个要挑选的对象(只需一次挑选,无需排序,无需比较所需的所有记录)。
例如(每磨机的概率)
伞:500‰几率
靴子:250‰ 几率
书包:100‰几率
随便:100‰的机会
“无”:50‰几率
0 到 499 之间的随机数表示“雨伞”已被挑选,500-749 为“靴子”等等。
INSERT INTO foo (name, randmin, randmax) VALUES
('umbrella', 0, 499),
('boots', 500, 749),
('satchel', 750, 849),
('whatever', 850, 949)
每次添加对象或修改概率时都会重新创建此表。
那么你所需要的只是一个查询
SELECT
f.name
FROM
(
SELECT Round(Rand()*1000) as r
) as tmp
JOIN
foo as f
ON
r BETWEEN f.randmin and f.randmax
LIMIT
1
只需生成一个随机值,MySQL 就可以使用 (randmin,randmax) 上的索引快速找到记录。
【讨论】:
我将为此修改 symcbean 的答案,为 symcbean +1。
SELECT * FROM some_table
WHERE (100*RAND()) < some_table.percent_probability
这将返回与您直观地希望分配给它们的概率相匹配的所有结果。例如,概率为 20 的 5 个对象将在 20% 的时间内全部返回。 90% 的时间将返回值为 90 的对象。
因此,您的结果将不止一个对象,但您避免了罕见的对象经常出现。所以现在随便抓一个你的结果。一种简单的方法是将它们全部放在一个数组中,然后:
$items = array(); // assuming you've already filled $items with your
// query results, one item for each array key
$count = count($items);
$chosen_key = rand(1,$count)-1;
$chosen_item = $items[$chosen_key];
【讨论】: