【发布时间】:2013-12-25 15:25:10
【问题描述】:
我们被分配了创建 map reduce 函数的任务,该函数将为 google web 图表中的每个节点 n 输出您可以在 3 跳内从节点 n 到达的节点。 (实际数据可以在这里找到:http://snap.stanford.edu/data/web-Google.html) 这是列表中项目的示例:
1 2
1 3
2 4
3 4
3 5
4 1
4 5
4 6
5 6
从上面的示例图表将是这个
在上面的简化示例中,节点 1 的示例路径是 α [1 -> 2 -> 4 -> 1], [1 -> 2 -> 4 -> 5], [1 -> 2 -> 4 -> 6], [1 -> 3 -> 4 -> 1], [1 -> 3 -> 4 -> 5], [1 -> 3 -> 4 -> 6] και [1 -> 3 -> 5 -> 6] 因此 map reduce 将为节点 1 输出顶点 1,5,6 ( (a) 每个顶点只能计算一次,并且 (b) 仅当存在长度为 3 的圆形路径时才包含当前顶点,例如 [1 -> 2 -> 4 -> 1] 和 [1 -> 3 -> 4 -> 1]。 /p>
我很迷茫,因为我认为这需要图论和算法的知识,而我们还没有学到任何与此相关的知识。
如果有人能给我一个正确的开始方向,我将不胜感激。 (我已经研究过最短路径理论等,但我不确定它是否对这个特定的练习有用)
提前致谢,祝您假期愉快。
编辑
我尝试创建附属列表,但是虽然我希望输出是“vertexID”“node1 node2 node3 node4...”,但我看到在输出文件中我的reducer将每个顶点ID的列表拆分为一对三。
例如,如果我有连接到 Z、X、C、V、B、N、M、G、H、J、K、L 的顶点 A,它会将其输出为
A Z,X,C
A V,B,N
A M,G,H
A J,K,L
下面是我的映射器和reducer
public class AdjacentsListDriver extends Configured implements Tool {
@Override
public int run(String[] args) throws Exception {
Configuration conf = getConf();
Job job = Job.getInstance(conf);
job.setJobName("Test driver");
job.setJarByClass(AdjacentsListDriver.class);
String[] arg0 = new GenericOptionsParser(conf, args).getRemainingArgs();
if (arg0.length != 2) {
System.err.println("Usage: hadoop jar <my_jar> <input_dir> <output_dir>");
System.exit(1);
}
Path in = new Path(arg0[0]);
Path out = new Path(arg0[1]);
FileInputFormat.setInputPaths(job, in);
FileOutputFormat.setOutputPath(job, out);
job.setMapperClass(ListMapper.class);
job.setReducerClass(ListReducer.class);
job.setInputFormatClass(TextInputFormat.class);
job.setOutputFormatClass(TextOutputFormat.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
job.waitForCompletion(true);
return 0;
}
public static void main(String[] args) throws Exception {
int res = ToolRunner.run(new Configuration(), new AdjacentsListDriver(), args);
System.exit(res);
}
}
/**
* @author George
* Theoretically this takes a key(vertexID) and maps all nodes that are connected to it in one hop....
*
*/
public class ListMapper extends Mapper<LongWritable, Text, Text, Text> {
private Text vertexID = new Text();
//private LongWritable vertice= new LongWritable(0);
private Text vertice=new Text();
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString();
StringTokenizer itr = new StringTokenizer(line,"\n");
StringTokenizer itrInside;
//vertice=new LongWritable(Long.valueOf(value.toString()).longValue());
while (itr.hasMoreTokens()) {
if(itr.countTokens() > 2){
}//ignore first line ??
else{
itrInside=new StringTokenizer(itr.toString());
vertexID.set(itr.nextToken());
while(itrInside.hasMoreTokens()){
vertice.set(itrInside.nextToken());
context.write(vertexID, value);
}
}
}
}
}
@override
public class ListReducer extends Reducer<Text, Text, Text, Text>{
public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
String vertices="";
for (Text value : values) {
if(vertices=="")
vertices+=value.toString();
else
vertices=vertices+","+value.toString();
}
Text value=new Text();
value.set(vertices);
context.write(key, value);
}
}
【问题讨论】:
标签: java hadoop graph mapreduce