mapreduce编程---寻找图中的三角形

来源:互联网 发布:监理行业发展前景知乎 编辑:程序博客网 时间:2024/06/18 09:10

一. 设计题目
使用mapreduce编程设计一个读取图顶点状态并找出该图中能构成三角形回路的顶点组合,即找出三角形。
二. 设计思路
Map:
1. 读取输入文件,获得图中各顶点与其他顶点的联系(如顶点1与顶点2、4连接等)
2. 枚举包含顶点的所有可能的三角形,输出三角形信息(名)以及其中包含该顶点有效边的数量
Reduce:
1. 统计这个三角形中有效边的数量
2. 假若有3条有效边,该三角形成立,输出该三角形
Input:
规定每行格式为”1 2,3”表示顶点1与顶点2,3相连且顶点2,3的连接关系中必有顶点1(无向图)
三. 程序流程
Redeuce:


这里写图片描述

Map:

这里写图片描述

四. 编译运行
1.设置输入文件路径
这里写图片描述
2.将java文件生成class文件
这里写图片描述
3.将class文件打包成jar文件
这里写图片描述
4.运行
这里写图片描述
5.查看输出
这里写图片描述
测试例子:
1 2,3
2 1,3,4
3 1,2
4 2,5
5 6,7,8
6 5,7
7 5,6,8
8 5,7
所成图:

这里写图片描述
java代码:

import java.io.IOException;import java.util.Arrays;import java.util.Iterator;import java.util.StringTokenizer;import org.apache.hadoop.io.IntWritable;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.conf.Configured;import org.apache.hadoop.fs.Path;import org.apache.hadoop.io.LongWritable;import org.apache.hadoop.io.NullWritable;import org.apache.hadoop.io.Text;import org.apache.hadoop.mapreduce.Job;import org.apache.hadoop.mapreduce.Mapper;import org.apache.hadoop.mapreduce.Reducer;import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;import org.apache.hadoop.util.Tool;import org.apache.hadoop.util.ToolRunner;import org.apache.hadoop.util.GenericOptionsParser;public class TriangleFriendship  {    public static class Map extends Mapper<LongWritable, Text, Text, LongWritable> {        private Text mKey = new Text();        private LongWritable mValue = new LongWritable();        public void map(LongWritable key, Text value, Context context)                throws IOException, InterruptedException {            // 将输入的纯文本文件的数据转化成String            String line = value.toString();            StringTokenizer tokenizer = new StringTokenizer(line);            if(tokenizer.hasMoreTokens()) {                // 输入文本中规定格式为"顶点apex    顶点1,顶点2···"                 // apex顶点                int apex = Integer.parseInt(tokenizer.nextToken());                 //以,来区分收集其他与顶点apex相连的顶点                String[] nodes = tokenizer.nextToken().split(",");                int size = nodes.length;                int[] triangle = new int[3];                //枚举包含顶点的所有可能的三角形。                //从顶点开始的边缘有助于三角形,所以根据关系,输出该三角形中有效边的数量                for(int i = 0; i < size; i++) {                    for(int j = i + 1; j < size; j++) {                        int node1 = Integer.parseInt(nodes[i]);                        int node2 = Integer.parseInt(nodes[j]);                        //这个三角形中的3个顶点                        triangle[0] = apex;                        triangle[1] = node1;                        triangle[2] = node2;                        //计算这些顶点所连成的线,设定只有node>apex时才计数,避免一条边重复算2次                        int count = (apex < node1 ? 1 : 0) + (apex < node2 ? 1 : 0);                        // 排序,使这个三角形在有相关计数时,保存名字不变,保存在同一个三角形中                        Arrays.sort(triangle);                        // 保存三角形信息                        StringBuilder thetriangle = new StringBuilder();                        for(int k = 0; k < 3; k++) {                            thetriangle.append(triangle[k]);                            if(k != 2) {                                thetriangle.append(' ');                            }                        }                        // 输出这个三角形和有效边数量                        mKey.set(thetriangle.toString());                        mValue.set(count);                        context.write(mKey, mValue);                    }                }            }        }    }    public static class Reduce extends Reducer<Text, LongWritable, Text, NullWritable> {        public void reduce(Text key, Iterable<LongWritable> values,                Context context) throws IOException, InterruptedException {            Iterator<LongWritable> iter = values.iterator();            int sum = 0;            while(iter.hasNext()) {                sum += iter.next().get();            }            //有三条有效边,输出该三角形            if(sum == 3) {                 context.write(key, NullWritable.get());            }        }    }    public static void main(String[] args) throws Exception {        Configuration conf = new Configuration();        String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();        if (otherArgs.length < 2) {            System.err.println("Usage: TriangleFriendship <in> [<in>...] <out>");            System.exit(2);        }        Job job = new Job(conf, "TriangleFriendship");        job.setJarByClass(TriangleFriendship.class);        // 设置输出类型        job.setMapOutputKeyClass(Text.class);        job.setMapOutputValueClass(LongWritable.class);        job.setOutputKeyClass(Text.class);        job.setOutputValueClass(NullWritable.class);        // 设置Map和Reduce处理类        job.setMapperClass(Map.class);        job.setReducerClass(Reduce.class);         // 设置输入和输出目录        FileInputFormat.addInputPath(job, new Path(args[0]));        FileOutputFormat.setOutputPath(job, new Path(args[1]));        System.exit(job.waitForCompletion(true) ? 0 : 1);    }}
0 0
原创粉丝点击