MapReduce:共同好友

本文介绍如何使用MapReduce算法来找出社交网络中任意两个用户之间的共同好友,并详细展示了map和reduce函数的工作流程及输出结果。
社交网站上,在看好友信息时,经常会得到如下一个信息,你和xxx有N位共同好友。
下面是A、B、C、D、E 5个人的好友情况:
A -> B C D
B -> A C D E
C -> A B D E
D -> A B C E
E -> B C D
第一行的意思是A有BCD 3个好友,下面几行的以此类推。
请使用 map reduce 任务,完成共同好友这个功能。
要求:
1. 描述清楚map和reduce函数的的输入,输出
2. (optional)将map 函数、reduce函数的输出逐步演算出来


解答
1.map输入:(偏移量,原始数据)
map输出:([用户1,用户2],用户1和用户2的共同好友)
reduce输入:([用户1,用户2],用户1和用户2的共同好友)
reduce输出:([用户1,用户2],[用户1、用户2的共同好友列表])

2.
map输入:
0 ABCD
4 BACDE
9 CABDE
14 DABCE
19 EBCD

map输出:
BC A
BD A
CD A
AC B
AD B
AE B
CD B
CE B
DE B
AB C
AD C
AE C
BD C
BE C
DE C
AB D
AC D
AE D
BC D
BE D
CE D
BC E
BD E
CD E

reduce输入:
BC A
BD A
CD A
AC B
AD B
AE B
CD B
CE B
DE B
AB C
AD C
AE C
BD C
BE C
DE C
AB D
AC D
AE D
BC D
BE D
CE D
BC E
BD E
CD E

reduce输出:
AB CD
AC BD
AD BC
AE BCD
BC ADE
BD ACE
BE CD
CD ABE
CE BD
DE BC
### 使用MapReduce实现共同好友算法 #### 算法概述 为了找到社交网络中任意两个用户的共同好友,在MapReduce框架内可以设计一种高效的解决方案。该方案主要分为两步:第一步是构建用户及其朋友关系的键值对;第二步是在这些键值对的基础上找出共同好友。 #### 数据准备 假设有一个简单的社交图谱,其中包含若干个用户以及他们之间的友谊连接。数据集可能看起来像这样: ``` Alice Bob Bob Alice Alice Charlie Charlie Alice Bob Dave ... ``` 每一行表示一对互为好友的关系。 #### Mapper阶段 Mapper的任务是从原始的朋友关系记录中提取出所有可能的用户组合,并将其作为键值对输出。对于每一个`(User, Friend)`对,生成所有的`(Friend, User)`对,从而确保每个用户与其他所有已知联系人都能形成配对[^1]。 ```java public class CommonFriendsMapper extends Mapper<LongWritable, Text, Text, IntWritable> { private final static IntWritable one = new IntWritable(1); @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String[] friendsPair = value.toString().split("\\s+"); if(friendsPair.length != 2){ return; } String userA = friendsPair[0]; String userB = friendsPair[1]; // 输出 (friendship pair, 1), e.g., ("Alice_Bob", 1) context.write(new Text(userA + "_" + userB), one); // 反转 friendship pairs 并再次写入以捕捉双向关系 context.write(new Text(userB + "_" + userA), one); } } ``` #### Reducer阶段 Reducer接收来自Mapper的所有`(Friend_Pair, Count)`形式的输入项。如果某个`Friend_Pair`出现了两次,则意味着这两个成员之间存在直接关联之外还有其他公共朋友。此时就可以统计出这对成员共有多少位共同好友[^3]。 ```java import java.util.HashSet; public class CommonFriendsReducer extends Reducer<Text, IntWritable, Text, IntWritable> { HashSet<String> seenPairs = new HashSet<>(); @Override protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int count = 0; boolean isNewPair = false; for(IntWritable val : values){ ++count; // 如果这个pair只出现了一次说明这是首次遇到它或者是自反情况下的重复计数 if(!seenPairs.contains(key)){ isNewPair = true; }else{ // 已经见过一次了,现在又见到了第二次,那么这就是我们要找的那种有共同朋友的情况 break; } } if(isNewPair && count >= 2){ // 记录已经处理过的pairs防止后续重复计算 seenPairs.add(key); context.write(key, new IntWritable(count)); } } } ``` 上述代码片段展示了如何使用MapReduce来识别具有至少一位共同好友的不同用户对。需要注意的是实际应用时还需要考虑更多细节比如去除自我循环等问题[^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kangwq2017

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值