出于自我教育的目的,我想实现马尔可夫链生成器,使用尽可能多的Redis,以及尽可能少的应用程序级逻辑。
假设我想根据历史深度为N的频率表(比如2)构建一个字生成器。
作为一个不是很有趣的例子,对于两个单词bar
和baz
的字典,频率表如下(“。”是终结符,数字是权重):
. . -> b x2 . b -> a x2 b a -> r x1 b a -> z x1 a r -> . x1 a z -> . x1
当我生成单词时,我从两个终止符. .
前两个字母b a
只有一种可能的结果。
第三个字母可以是r
或z
,具有相同的概率,因为它们的权重相等。
第四封信总是终结者。
(在字典中用较长的单词会更有趣。)
无论如何,如何优雅地使用Redis?
Redis集合有SRANDMEMBER
,但没有权重。
Redis排序集具有权重,但没有随机成员检索。
Redis列表允许将权重表示为条目副本,但如何与它们进行集合交叉?
看起来应用程序代码注定要做一些数据处理......
答案 0 :(得分:1)
根据到目前为止所考虑的集合成员的累积概率,您可以通过为每个成员分配0到1之间的分数来完成带有redis排序集的加权随机选择。 em>包括当前成员 您使用的订单无关紧要;您可以选择任何方便的订单。然后通过生成在0和1之间均匀分布的随机浮点数 r 来完成随机选择,并调用
ZRANGEBYSCORE zset r 1 LIMIT 0 1,
将返回分数大于或等于 r 的第一个元素。 一点点推理应该说服你选择一个成员的概率因此得到正确加权。
不幸的是,分配给元素的分数需要与累积概率成比例这一事实似乎使得难以以保留的方式使用有序集合联合或交集运算随机选择元素的分数的意义。那部分 似乎需要一些重要的应用程序逻辑。