数据库中有几百个图书记录,每个记录都有一个发布时间。在网站的主页上,我需要写一些代码,随机挑选10本书放在那里。要求是新书需要有更高的展示机会。
因为时间是一个整数,所以我是这样计算每本书的概率的:
Probability of a book to be drawn = (current time - publish time of the book) / ((current time - publish time of the book1) + (current time - publish time of the book1) + ... (current time - publish time of the bookn))在抽取一本书之后,下一轮循环将从分母中减去(当前时间-该书的出版时间),并重新计算剩余每本书的概率,该循环继续进行,直到抽取了10本书。
这个算法是正确的吗?
顺便说一下,这个网站是用PHP编写的。
如果你脑海中有更好的算法,请随意推荐一些PHP代码。
非常感谢大家。
发布于 2010-06-03 00:50:53
这里有一个非常类似的问题可能会有帮助:Random weighted choice解决方案是用C#编写的,但是代码非常易读,而且非常接近PHP语法,所以它应该很容易适应。
例如,下面是如何在MySQL中做到这一点的:
首先计算所有书籍的总年龄,并将其存储在MySQL用户变量中:
SELECT SUM(TO_DAYS(CURDATE())-TO_DAYS(publish_date)) FROM books INTO @total;然后随机选择书籍,按年龄加权:
SELECT book_id FROM (
SELECT book_id, TO_DAYS(CURDATE())-TO_DAYS(publish_date) AS age FROM books
) b
WHERE book_id NOT IN (...list of book_ids chosen so far...)
AND RAND()*@total < b.age AND (@total:=@total-b.age)
ORDER BY b.publish_date DESC
LIMIT 10;请注意,由于AND表达式的短路,只有当一本书通过了随机选择测试时,@total才会降低。
这不能保证在一次通过中选择10本书--甚至不能保证在给定的一次通过中选择任何一本书。所以你必须重新运行第二步,直到你找到10本书。@total变量保留其减去的值,因此您不必重新计算它。
发布于 2010-06-03 00:24:06
首先,我认为你的公式将保证更早的书被挑选出来。尝试根据以下条件设置初始概率:
年龄-自发布以来的天数
Max(Age) -示例中最早的书
图书年代(I)-图书I的年代
..。Prob (i) = Max (年龄)+电子书年龄(i) /所有i的总和Max (年龄)+电子书年龄(I)
值e确保最旧的书具有一定的被选择的概率。现在已经完成了,您可以随时重新计算任何样本的prob。
现在你必须找到一种不偏不倚的选书方式。也许最好的方法是使用上面的公式计算累积分布,然后选择一个均匀的(0,1) r.v。找到那辆房车在哪。在累积分布中,并挑选离它最近的书。
在编码上帮不了你。讲得通?
https://stackoverflow.com/questions/2959403
复制相似问题