思路
如果两个人有一组共同好友,但这两个人本身不是好友,那个就会推荐他们联系,最后都可以归结为查找。用户1的所有好友里两两互为推荐好友,用户1和好友的关系为直接好友。先循环所有用户的所有好友,找出全部推荐好友和直接好友,在全部推荐好友去除直接好友即为推荐好友。所有的推荐好友中会按图论中的路径数对好友有个评分,只显示推荐联系的10个人,即取top 10.
与共同好友的区别
共同好友在于计算两个朋友集合的交集,推荐好友在于计算两个朋友集合的(并集-交集)
A–>B–>C && A<>C ->A–>C 二度好友
A–>B<–C && A<>C -> A–>C C–>A 共同好友
对于单向网络,二度好友和共同好友是两种结构,对于双向网络(无向图),二度好友和共同好友是同一种网络结构。共同好友可以有共同好友数,按共同好友数进行候选的排序,二度好友同理。
输入:
P F1,F2,…Fn
算法:
map(key,friends){
for(friend:friends){
directFriend=Tuple2(friend,-1);
emit(key,directFriend);
}
for(int i=0;j<friends.size();i++){
for(int j=i+1;j<friends.size();j++){
possibleFriend1=Tuple2(friends.get(j),person);
emit(friends.get(i),possibleFriend1);
possibleFriend2=Tuple2(friends.get(i),person);
emit(friends.get(j),possibleFriend2);
}
}
}
reduce(key,values){
Map<Long,List> mutualFriends=new HashMap<Long,List>();
for(Tuple2<toUser,mutualFriend> t2:values){
Long toUser=t2.toUser;
Long mutualFriend=t2.mutualFriend;
boolean alreadyFriend=(mutualFriend==-1);
if(mutualFriends.containsKey(toUser)){
if(alreadyFriend){
mutualFriends.put(toUser,null);
}else if(mutualFriends.get(toUser)!=null){
mutualFriends.get(toUser).add(mutualFriend);
}
}else{
if(alreadyFriend){
mutualFriends.put(toUser,null);
}else{
mutualFriends.put(toUser,List<mutualFriends>)
}
}
}
String reducerOutput=formaterOutput(mutualFriends);
emit(key,reduceOutput);
}
好友关系是对称的,边是偶数的
关注是非对称的,边不一定是偶数的
u1:u2,u3,u4
u2:u5,u6,u1
u3:u7,u8
u4:u1
u5:u2
u6:u2
u7:u3
u8:u3
map:
[u1,u2],[u2,u3,u4]
[u1,u3],[u2,u3,u4]
[u1,u4],[u2,u3,u4]
[u1,u2],[u1,u5,u6]
[u2,u5],[u5,u6]
[u2,u6],[u5,u6]
[u3,u7],[u7,u8]
[u3,u7],[u7,u8]
[u1,u4],[u1]
[u2:u5],[u2]
[u2:u6],[u2]
[u3:u7],[u3]
[u3:u8],[u3]
reduce
[u1,u2],[u1,u5,u6],[u2,u3,u4]
map
[u1],[u3,u4]
[u2],[u5,u6]