One-Way
爱一人,攀一山,追一梦

MapReduce实现好友推荐:

 

张三的好友有王五、小红、赵六; 同样王五、小红、赵六的共同好友是张三;

在王五和小红不认识的前提下,可以通过张三互相认识,给王五推荐的好友为小红,

给小红推荐的好友是王五,就是王五、小红、赵六互为推荐关系。

 

根据分析就是有相同好友的人物之间为推荐关系,但要排除本来两人就是好友的情况。

计算一个人的好友推荐关系,推荐关系值为1,然后计算所有人的好友推荐关系,最终将推荐关系值相加,计算出最值得推荐的几个好友。

 

简单的说就是两个非好友的人,存在共同好友的人数越多,说明这两个人越值得互相推荐。

数据:

王五    李四    小丽    小玲
小丽    王五    赵六
李四    王五    张三    赵六    小红
小玲    王五    张三    赵六
张三    小玲    李四    赵六
赵六    小丽    小玲    张三    李四    小红
小红    李四    赵六

 

实现代码:

  1 import org.apache.hadoop.conf.Configuration;
  2 import org.apache.hadoop.fs.FileSystem;
  3 import org.apache.hadoop.fs.Path;
  4 import org.apache.hadoop.io.IntWritable;
  5 import org.apache.hadoop.io.LongWritable;
  6 import org.apache.hadoop.io.Text;
  7 import org.apache.hadoop.mapreduce.Job;
  8 import org.apache.hadoop.mapreduce.Mapper;
  9 import org.apache.hadoop.mapreduce.Reducer;
 10 import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
 11 import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
 12 
 13 import java.io.IOException;
 14 
 15 /**
 16  *  好友推荐:
 17  *  计算两个非好友的推荐值,就是两个非好友的共同好友数
 18  *
 19  * Created by Edward on 2016/7/12.
 20  */
 21 public class RunJob {
 22 
 23 
 24     public static void main(String[] args){
 25 
 26         System.setProperty("HADOOP_USER_NAME", "root");
 27 
 28         Configuration conf = new Configuration();
 29 
 30         conf.set("fs.defaultFS", "hdfs://node1:8020");
 31 
 32         try {
 33             FileSystem fs = FileSystem.get(conf);
 34 
 35             Job job = Job.getInstance(conf);
 36             job.setJarByClass(RunJob.class);
 37             job.setMapperClass(MyMapper.class);
 38             job.setReducerClass(MyReducer.class);
 39 
 40             //需要指定 map out 的 key 和 value
 41             job.setOutputKeyClass(Text.class);
 42             job.setOutputValueClass(IntWritable.class);
 43 
 44             FileInputFormat.addInputPath(job, new Path("/test/friend/input"));
 45 
 46             Path path = new Path("/test/friend/output");
 47             if(fs.exists(path))//如果目录存在,则删除目录
 48             {
 49                 fs.delete(path,true);
 50             }
 51             FileOutputFormat.setOutputPath(job, path);
 52 
 53             boolean b = job.waitForCompletion(true);
 54             if(b)
 55             {
 56                 System.out.println("OK");
 57             }
 58 
 59         } catch (Exception e) {
 60             e.printStackTrace();
 61         }
 62 
 63     }
 64 
 65     public static class MyMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
 66 
 67         @Override
 68         protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
 69 
 70             String[] str = value.toString().split("\t");
 71 
 72             for(int i=1; i<str.length; i++) {
 73                 //a 的好友是 b
 74                 context.write(new Text(str[0] + ":" + str[i]), new IntWritable(0));
 75                 //b 的好友是 a
 76                 context.write(new Text(str[i] + ":" + str[0]), new IntWritable(0));
 77                 for (int j = i + 1; j < str.length; j++) {
 78                     // A 的推荐好友是 B
 79                     context.write(new Text(str[i] + ":" + str[j]), new IntWritable(1));
 80                     // B 的推荐好友是 A
 81                     context.write(new Text(str[j] + ":" + str[i]), new IntWritable(1));
 82                 }
 83             }
 84         }
 85     }
 86 
 87     public static class MyReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
 88 
 89         @Override
 90         protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
 91 
 92             int sum = 0;
 93             for(IntWritable i: values)
 94             {
 95                 if(i.get() == 0) {//两个人已经是好朋友的,排除在外
 96                     sum = 0;
 97                     //break;
 98                     return;
 99                 }
100                 sum += i.get();
101             }
102             context.write(key, new IntWritable(sum));
103         }
104     }
105 }

 

计算结果:

小丽:小玲       2
小丽:小红       1
小丽:张三       1
小丽:李四       2
小玲:小丽       2
小玲:小红       1
小玲:李四       3
小红:小丽       1
小红:小玲       1
小红:张三       2
小红:王五       1
张三:小丽       1
张三:小红       2
张三:王五       2
李四:小丽       2
李四:小玲       3
王五:小红       1
王五:张三       2
王五:赵六       3
赵六:王五       3

对结果进行简单的核对,比对图

小丽:小玲       2

小丽和小玲的共同好友数为2,分别为:王五,赵六

 

posted on 2016-07-12 22:14  单行道|  阅读(1251)  评论(0编辑  收藏  举报