小马马说MapReduce算法案例(1):二度人脉好友推荐

二度人脉好友推荐运用非常广泛,比如在一些主流的社交产品中就有可能认识的人这样的功能,一般来说可能认识的人是通过二度人脉搜索得到的,在传统的关系型数据库中,可以通过图的广度优先遍历算法实现,而且深度限定为2,然而在海量的数据中,这样的遍历成本太大,所以有必要利用MapReduce编程模型来并行化,本篇文章是二度好友推荐的mapreduce简单实现,难免会有不足和缺陷,希望大家能够指出,共同进步。

假如A和B是好友关系,B和C是好友关系,然而C和A不是好友关系,那么A和C是二度好友关系,他们可以通过B认识,B是中间人。我们定义一个符号“>”来代表follow,上面的例子可以这样表示

A>B
B>C

在社交网络任何一个活跃的用户U都存在对应的两个集合,一个是粉丝集合,一个是关注集合,以用户U作为中间联系的2度人脉对,是粉丝集合和关注集合的笛卡尔积。
于是在Map阶段,我们可以这样输出Map结果

key:“A ”value:“>B”;
key:“B ”value:“<A”;
key:“B ”value:“>C”;
key:“C ”value:“<B”;

在shuffle阶段,会自动合并相同key值的value
于是上面通过shuffle阶段,reduce的输入变成

"A":[">B"]
"B":["<A",">C"]
"C":["<B"]

所以在reduce阶段我们可以得到以Key为中间人的好友集合,其中粉丝集合的元素第一个字母是’<’,关注集合的元素第一个字母是’>’,分离这两个集合,并求他们的笛卡尔积,就可以得到二度人脉的关系对。
以下是Map和Reduce函数的核心代码:

测试输入:

liujia  qian
qian    sha
sha     yuan

测试输出:

liujia sha
qian yuan

Map核心代码

protected void map(LongWritable key, Text value,
                Mapper<LongWritable, Text, Text, Text>.Context context)
                throws IOException, InterruptedException {


            String[] vaString=value.toString().split("\t");


            context.write(new Text(vaString[0]), new Text(">"+vaString[1]));
            context.write(new Text(vaString[1]), new Text("<"+vaString[0]));
        }

Reduce核心代码

protected void reduce(Text arg0, Iterable<Text> arg1,
                Reducer<Text, Text, Text, Text>.Context arg2)
                throws IOException, InterruptedException {

            List<String> fuser= new ArrayList<String>();
            List<String> buser= new ArrayList<String>();


            Iterator<Text> it=  arg1.iterator();

            while (it.hasNext()) {
                String item=it.next().toString();

                 if(item.charAt(0)=='>')
                 {
                     fuser.add(item.toString().substring(1));
                 }
                 else {
                     buser.add(item.toString().substring(1));
                }
            }
        for(int i=0;i<buser.size();i++)
        {
            for(int j=0;j<fuser.size();j++)
            {
                arg2.write(new Text(buser.get(i)), new Text(fuser.get(j)));
                System.out.println(buser.get(i)+"->"+fuser.get(j));
            }

        }



        }

原创文章,转载请说明出处

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值