一个PHP MYSQL 随机机率问题

aaronwei 2007-10-25 06:48:33
table1 有个字段weight记录0~5的整数,我要从表中虽机select出8条记录,要求weight值越高的,被select出来的机率越高
...全文
438 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
helloyou0 2007-10-27
  • 打赏
  • 举报
回复
上面的其实还有点含义不清....说的出现概率并不是出现在最终结果的概率...还和数据中weight的分布有关..
想想如果weight=1的有1000000000个, weight=5的有10个, 那么最终结果里出现5的概率肯定是非常非常小的...

如果你说的几率是出现在最终结果的几率....和weight的多少无关的话....
那么实际上....选8个....
weight 概率 结果里大概
5 0.3 8*0.3 ~=~ 2.4 个
4 0.25 8*0.25 ~=~ 2 个
3 0.2 8*0.2 ~=~ 1.6 个
2 0.15 8*0.15 ~=~ 1.2 个
1 0.1 8*0.1 ~=~ 0.8 个

你就照这个比例随机取吧.......嘿嘿.......
要逼真的话, 再用rand()让结果个数"晃动"一下,比如weight5的这次取3个,下次取2个,再下次取4个....最终平均下来接近2.4就行.....
helloyou0 2007-10-27
  • 打赏
  • 举报
回复
上面的句子直接简化的结果是:

SELECT *, rand() as ord
from tablename
where
rand() <
CASE weight
WHEN 5 THEN 0.3
WHEN 4 THEN 0.55
WHEN 3 THEN 0.75
WHEN 2 THEN 0.9
WHEN 1 THEN 1
END
order by ord
limit 8

和上面的同样效果

但是,这个语句的效率是很差的,
两个rand()还要过滤和排序.....索引无法用....
如果你数据不大, 要求不高, 思想不复杂, 人品不算好.....
更重要的...老板给钱不多的话,先用...下次改进的时候再要钱


我待会再继续聊








helloyou0 2007-10-27
  • 打赏
  • 举报
回复
上面的要加desc, 谢谢指出~:)

如果你对几率和weight的关系有要求,那么就要更明确一下这个关系~~~
有个比较简单的方法, 你可以列一个表~~
比如:
如果你需要
weight值 出现概率 出现条件
5 30%=0.3 rand()<0.3
4 25%=0.25 rand()<0.55
3 20%=0.2 rand()<0.75
2 15%=0.15 rand()<0.9
1 10%=0.1 rand()<1

可以这么写:
SELECT * from tablename
where
rand()<
CASE weight
WHEN 5 THEN 0.3
WHEN 4 THEN 0.55
WHEN 3 THEN 0.75
WHEN 2 THEN 0.9
WHEN 1 THEN 1
END

这样出来的是按照上面比例几率出现, 但是一般不止8条, 那么再平均随机从里面抽8条

select * from
(
SELECT * from tablename
where
rand()<
CASE weight
WHEN 5 THEN 0.3
WHEN 4 THEN 0.55
WHEN 3 THEN 0.75
WHEN 2 THEN 0.9
WHEN 1 THEN 1
END
) x
order by rand()
limit 8

这样能达到效果,但是这个语句无疑可以简化一下, 我先发了, 等我再看一下

懒得去死 2007-10-26
  • 打赏
  • 举报
回复
rand()*weight desc 和 weight 也不是成正比关系。

rang()*5 不一定几率大的就是5
faisun 2007-10-26
  • 打赏
  • 举报
回复
order by weight - rand()*5 desc 好像不是正比关系吧

rand()*weight desc 中 weight 和几率成正比线性关系。
懒得去死 2007-10-26
  • 打赏
  • 举报
回复

create table lk11(
id int not null auto_increment primary key,
weight int
);
insert into lk11(weight) values
(1),(2),(5),(3),(2),(3),(4),(4),(5),(3),(1),(3),(2),(4),(5);

create index `k_w` on lk11(weight);

懒得去死 2007-10-26
  • 打赏
  • 举报
回复
helloyou0的方法倒一下就可以了。

select * from lk11 order by weight - rand()*5 desc limit 8;
dreambird1983 2007-10-26
  • 打赏
  • 举报
回复
学习了~~~
faisun 2007-10-26
  • 打赏
  • 举报
回复
To helloyou0 :
额... 你那个应该是weight=5的容易排到后面吧
faisun 2007-10-26
  • 打赏
  • 举报
回复
select * from table1 order by rand()*weight desc limit 8;


思路: order by rand() 实际上是在所有的字段后附加一个字段 "rand()",一个随机的值,然后再按这个 "rand()" 字段正向排序。

而 order by rand() desc 则是按 "rand()" 字段的反向排的(尽管得到的效果和前者一样),即 "rand()" 值越大排的越前。

按LZ的要求, weight 越大,rand()*weight 产生的值会越大,加了 desc 后,越容易排到前面。
helloyou0 2007-10-26
  • 打赏
  • 举报
回复
写法很多,因为你没有明确weight和几率的关系,

比如:

select * from table order by weight-rand()*5 limit 8


就可以,
weight=5, weight-rand()*5 => 0~5
weight=4, weight-rand()*5 => -1~4
weight=3, weight-rand()*5 => -2~3
weight=2, weight-rand()*5 => -3~2
weight=1, weight-rand()*5 => -4~1
weight=0, weight-rand()*5 => -5~0
自然weight=5的容易排到前面

dreambird1983 2007-10-26
  • 打赏
  • 举报
回复
我对“几率”的概念有点疑惑,请教一下。

我可不可以对weight降序排序,取前8条,即先取weight为5的,再取weight为4的........

而几率的概念就是数据库里有5条weight为5的,随机选取,我取出4条,或者3条就叫被选出来的几率高?

楼主要的是这样的吗?如果真是这样的,这个需求有点意思~~~~~
懒得去死 2007-10-26
  • 打赏
  • 举报
回复
NND.逼近函数没有找到。
试试这个:

select * from table1 order by floor(1+rand()*5) limit 8;
dreambird1983 2007-10-26
  • 打赏
  • 举报
回复
mark
faisun 2007-10-26
  • 打赏
  • 举报
回复
select * from table1 order by rand()*SQRT(weight) desc limit 8;

可减少差距
aaronwei 2007-10-26
  • 打赏
  • 举报
回复
各位大哥的方法我都试了我limit 8,select出来的结果weight=5 4 3的机率很高,但一直没有select出weight=2 1,还有好的算法马?
Meteorlet 2007-10-26
  • 打赏
  • 举报
回复
上面的公式都不对,概率是可能性,而不是weight=5就一定排在weight=0的前面

select * from table order by (weight * rand() + rand())
weight = 5, 0~6
weight = 4, 0~5
weight = 3, 0~4
weight = 2, 0~3
wegith = 1, 0~2
weight = 0, 0~1
aaronwei 2007-10-26
  • 打赏
  • 举报
回复
我试了了大家的方法,但是都是weight=5 4 3的机率很高,一直没select出weight=2 1,能把weight=2 1的机率略提高点吗
foolbirdflyfirst 2007-10-26
  • 打赏
  • 举报
回复


mysql>select * from table order by floor(weight-1+rand()*2) desc limit 8;
aaronwei 2007-10-26
  • 打赏
  • 举报
回复
非常感谢大家的帮忙
加载更多回复(1)

21,887

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧