使用MR求解多个矩阵的乘积之后

首先介绍涉及到的知识点,如下:

1)value的类型是IntArrayWritable,将整型数组值取出的方法有两种。

a.其一,就是使用value的toArray()方法,返回值是一个Object obValue,然后使用Array.get(obValue,index),就可以获得数组中的元素(Object类型),其中index是数组索引,然后再利用Integer.parseInt(Array.get(obValue,index).toString())将其转化为int型即可。

b.第二种方法是使用value的get()方法获得数组,不过是Writable[],但是不能直接使用IntWritable[] intArr=(IntWritable[])value.get(),不能完成Writable[]到IntWritable[]的转化。正确的方式是:

for(Writable val:value.get()){
IntWritable intVal=(IntWritable)val;

}

2)利用InputSplit获得分片的文件名,因为待求解的问题如下所示:

X=(B+u(s+b+d+f))*F

矩阵s、b、d、f与F相乘之前,要扩大u倍,而B矩阵则不需要,通过检测文件名来判断是否先扩大u倍然后再与F相乘。获得文件名的代码如下:

InputSplit inputSplit=context.getInputSplit();
String fileName=((FileSplit)inputSplit).getPath().getName();

如果是要获得文件的上级目录名,可以使用以下代码(http://blog.csdn.net/shallowgrave/article/details/7757914):

String dirName = ((FileSplit) inputSplit).getPath().getParent().getName();

矩阵文件如下所示:


map()中实现矩阵乘法的代码如下:
 obValue=value.toArray();
           InputSplit inputSplit=context.getInputSplit();
           String fileName=((FileSplit)inputSplit).getPath().getName();

           if (!(fileName.startsWith("10"))) {
            for (int i=0;i<rightMatrix[0].length;++i){
                sum=0;
                for (int j=0;j<rightMatrix.length;++j){
                      sum+= Integer.parseInt(Array.get(obValue,j).toString())*2*rightMatrix[j][i];
                }
                arraySum[i]=new IntWritable(sum);
            }
             map_value.set(arraySum);
           }
            else{
               for (int i=0;i<rightMatrix[0].length;++i){
                   sum=0;
                   for (int j=0;j<rightMatrix.length;++j){
                       sum+= Integer.parseInt(Array.get(obValue,j).toString())*rightMatrix[j][i];
                   }
                   arraySum[i]=new IntWritable(sum);
               }
               map_value.set(arraySum);
           }
           context.write(key,map_value);
       }

3)第三个知识点就是IntArrayWritable中toString()方法的定义中StringBuilder的使用。

1   public String toString(){
2         StringBuilder sb=new StringBuilder();
3         for (Writable val:get()){
4             IntWritable intWritable=(IntWritable)val;//使用1)中的第二种方法
5             sb.append(intWritable.get());//在sb后追加一个字符
6             sb.append(",");//再追加一个','字符
7         }
8         sb.deleteCharAt(sb.length()-1);//删除最后一个字符,也就是最后一个‘,’
9         return sb.toString();//将sb转化为字符串返回

完整代码如下:

  1 /**
  2  * Created with IntelliJ IDEA.
  3  * User: hadoop
  4  * Date: 16-3-5
  5  * Time: 上午9:24
  6  * To change this template use File | Settings | File Templates.
  7  */
  8 import org.apache.hadoop.conf.Configuration;
  9 import org.apache.hadoop.fs.FileSystem;
 10 import java.io.IOException;
 11 import java.lang.reflect.Array;
 12 import java.net.URI;
 13 import java.util.Arrays;
 14 
 15 import org.apache.hadoop.fs.Path;
 16 import org.apache.hadoop.io.IntWritable;
 17 import org.apache.hadoop.io.ArrayWritable;
 18 import org.apache.hadoop.io.Text;
 19 import org.apache.hadoop.io.Writable;
 20 import org.apache.hadoop.mapreduce.InputSplit;
 21 import org.apache.hadoop.mapreduce.Job;
 22 import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
 23 import org.apache.hadoop.mapreduce.lib.input.FileSplit;
 24 import org.apache.hadoop.mapreduce.lib.input.SequenceFileInputFormat;
 25 import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
 26 import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
 27 import org.apache.hadoop.mapreduce.Reducer;
 28 import org.apache.hadoop.mapreduce.Mapper;
 29 
 30 public class MutiInputMatrixProduct {
 31     public static class MyMapper extends Mapper<IntWritable,IntArrayWritable,IntWritable,IntArrayWritable>{
 32         public IntArrayWritable map_value=new IntArrayWritable();
 33         public static  int[][] rightMatrix=new int[][]{{10,10,10,10,10},{10,10,10,10,10},{10,10,10,10,10},
 34                 {10,10,10,10,10}};
 35         public Object obValue=null;
 36         public IntWritable[] arraySum=new IntWritable[rightMatrix[0].length];
 37         public int sum=0;
 38        public void map(IntWritable key,IntArrayWritable value,Context context) throws IOException, InterruptedException {
 39            obValue=value.toArray();
 40            InputSplit inputSplit=context.getInputSplit();
 41            String fileName=((FileSplit)inputSplit).getPath().getName();
 42 
 43            if (!(fileName.equals("10IntArray"))) {
 44             for (int i=0;i<rightMatrix[0].length;++i){
 45                 sum=0;
 46                 for (int j=0;j<rightMatrix.length;++j){
 47                       sum+= Integer.parseInt(Array.get(obValue,j).toString())*2*rightMatrix[j][i];
 48                 }
 49                 arraySum[i]=new IntWritable(sum);
 50             }
 51              map_value.set(arraySum);
 52            }
 53             else{
 54                for (int i=0;i<rightMatrix[0].length;++i){
 55                    sum=0;
 56                    for (int j=0;j<rightMatrix.length;++j){
 57                        sum+= Integer.parseInt(Array.get(obValue,j).toString())*rightMatrix[j][i];
 58                    }
 59                    arraySum[i]=new IntWritable(sum);
 60                }
 61                map_value.set(arraySum);
 62            }
 63            context.write(key,map_value);
 64        }
 65     }
 66     public static class MyReducer extends Reducer<IntWritable,IntArrayWritable,IntWritable,Text>{
 67         public int[] sum=null;
 68         public Object obValue=null;
 69         public Text resultText=null;
 70 
 71         public void setup(Context context){
 72             sum=new int[Integer.parseInt(context.getConfiguration().get("leftMatrixNum"))];
 73         }
 74 
 75         public void reduce(IntWritable key,Iterable<IntArrayWritable>value,Context context) throws IOException, InterruptedException {
 76           for(IntArrayWritable intValue:value){
 77               obValue=intValue.toArray();
 78               for (int i=0;i<Array.getLength(obValue);++i){
 79                   sum[i]+=Integer.parseInt(Array.get(obValue,i).toString());
 80               }
 81 
 82           }
 83          resultText=new Text(Arrays.toString(sum));
 84             for (int i=0;i<sum.length;++i){
 85                 sum[i]=0;
 86             }
 87           context.write(key,resultText);
 88         }
 89 
 90     }
 91 
 92     public static void main(String[]args) throws IOException, ClassNotFoundException, InterruptedException {
 93         String uri="/home/hadoop/2016Test/Input";
 94         String outUri="/home/hadoop/2016Test/Output";
 95         Configuration conf=new Configuration();
 96         FileSystem fs=FileSystem.get(URI.create(uri),conf);
 97         fs.delete(new Path(outUri),true);
 98         conf.set("leftMatrixNum","5");
 99         Job job=new Job(conf,"MultiMatrix");
100         job.setJarByClass(MutiInputMatrixProduct.class);
101         job.setInputFormatClass(SequenceFileInputFormat.class);
102         job.setOutputFormatClass(TextOutputFormat.class);
103         job.setMapperClass(MyMapper.class);
104         job.setReducerClass(MyReducer.class);
105         job.setMapOutputKeyClass(IntWritable.class);
106         job.setMapOutputValueClass(IntArrayWritable.class);
107         job.setOutputKeyClass(IntWritable.class);
108         job.setOutputValueClass(Text.class);
109         FileInputFormat.setInputPaths(job, new Path(uri));
110         FileOutputFormat.setOutputPath(job,new Path(outUri));
111         System.exit(job.waitForCompletion(true)?0:1);
112     }
113 }
114 class IntArrayWritable extends ArrayWritable {
115     public IntArrayWritable(){
116         super(IntWritable.class);
117     }
118     public String toString(){
119         StringBuilder sb=new StringBuilder();
120         for (Writable val:get()){
121             IntWritable intWritable=(IntWritable)val;
122             sb.append(intWritable.get());
123             sb.append(",");
124         }
125         sb.deleteCharAt(sb.length()-1);
126         return sb.toString();
127     }
128 }

 

posted @ 2016-03-05 20:05  lz3018  阅读(558)  评论(0编辑  收藏  举报