zoukankan      html  css  js  c++  java
  • 怎样高速写出一个陌生人推荐系统

    怎样高速写出一个陌生人推荐系统

     

    在社交游戏中,除了和好友互动,常常还会设计陌生人互动的游戏环节。以下两张图各自是QQ水浒和全民农场的陌生人推荐界面。

    QQ水浒陌生人界面

     

    全民农场陌生人界面

     

    那么,陌生人推荐系统通常是怎么做的呢?以下以全民农场的陌生人推荐系统为例来阐述怎样高速构建一个陌生人推荐系统。因为採用了boost::multi_index库,整个推荐系统代码在400行左右。很简洁。

     

    首先,我们简介一下全民农场的陌生人推荐系统规则:

    1. 等级相近

    2. 城市相近

    3. 性别相反

    4. 活跃用户

     

    一个简单的方法是用列表存储全部最近登录的玩家的数据,查询的时候对遍历每一个玩家,并过滤。然而这样的方式效率比較低下。查询10个玩家平均须要遍历的玩家个数是:

     

    10 * 100 (如果100阶等级) * 50(如果50个城市) * 2 (男女各半)

    = 100000

     

    显然简单地列表方式查询效率低下。所以我们要做索引,这里不得不提到multi_index库,对于这个库的介绍仅仅用一句话:multi_index是一个模拟关系型数据库索引结构的容器( The concept of multi-indexing over the same collection of elements is borrowed from relational database terminology and allows for the specification of complex data structures in the spirit of multiply indexed relational tables where simple sets and maps are not enough),其内部实现相当于多个std::map组合,但比std::map组合更高效,更方便。

     

    考虑到性别字段的值域比較小。我们就不用对它做索引了。我们对等级、城市、和上次登录时间做索引。考虑等级比城市的优先级更高。我们决定对<等级城市>做复合索引(你没听错,就是关系型数据库里的复合索引)。基于上述考虑,我们的陌生人推荐系统的数据结构例如以下图所看到的:

     

        struct stranger_info

        {  

            pod_open_id_t open_id;

            pod_city_t city;

            uint32_t ts;

            uint32_t level;

            uint32_t gender;

    }; 

     

        typedef bmi::multi_index_container<

            stranger_info,

            bmi::indexed_by<

                bmi::ordered_non_unique<bmi::tag<tag_level_city>,

                    bmi::composite_key<stranger_info,

                        bmi::member<stranger_info, uint32_t, &stranger_info::level>,

                        bmi::member<stranger_info, pod_city_t, &stranger_info::city> >

                >,

                bmi::ordered_non_unique<bmi::tag<tag_ts>, bmi::member<stranger_info, uint32_t, &stranger_info::ts> >,

                bmi::ordered_unique<bmi::tag<tag_open_id>, bmi::member<stranger_info, pod_open_id_t, &stranger_info::open_id> >

            >,

            stranger_info_allocator_t

        > stranger_info_db_t;

     

    上述代码定义了两个数据结构stranger_info和stranger_info_db_t。stranger_info描写叙述了玩家的信息,stranger_info_db_t看上去比較复杂,事实上很easy,它定义了一个stranger_info的容器,该容器对stranger_info结构的open_id, city, ts, level这几个字段做索引。

     

    加上索引后。陌生人推荐系统的规则就非常easy满足了:

    1. 等级相近

    2. 城市相近

    tag_level_city这个索引查找到最匹配的玩家,然后以该玩家为基准,前向/后向遍历,找到推荐的陌生人。

    3. 性别相反

    在按tag_level_city遍历过程中,对性别不满足的过滤掉

    4. 活跃用户

    定时按tag_ts从头遍历。删除ts过小的节点。

     

    自此,陌生人推荐系统就介绍到这里,附近里是陌生人推荐系统的实现文件。

    须要注意的是,在真实的系统中,stranger_info有一个handler字段。这个字段相当于一个下标。client请求时把上次的handler传过来。server从该handler往后取数据。实现分页功能。

  • 相关阅读:
    Linux_搭建NFS服务(基础)
    Linux_配置主DNS服务(基础)
    Linux_配置辅助DNS服务(基础)
    Linux_配置本地YUM源(RHEL8)
    9. Mybatis plugins标签 实现分页
    27. SpringBoot 切换内嵌Servlet容器
    8. Mybatis typeHandlers标签
    63. VUEX Getters基本使用
    62. State单一状态树概念
    61 . VUEX state 和 mutations
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/6972511.html
Copyright © 2011-2022 走看看