From 686962a07fa62a1f1a30ce818d114adffb282f95 Mon Sep 17 00:00:00 2001 From: hekow Date: Wed, 11 Mar 2015 11:30:45 +0100 Subject: [PATCH 1/4] Create iFub --- src/main/java/ml/grafos/okapi/iFub | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/main/java/ml/grafos/okapi/iFub diff --git a/src/main/java/ml/grafos/okapi/iFub b/src/main/java/ml/grafos/okapi/iFub new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/src/main/java/ml/grafos/okapi/iFub @@ -0,0 +1 @@ + From 99bc19d5845e84df339ab72c22dda0fee444e334 Mon Sep 17 00:00:00 2001 From: hekow Date: Wed, 11 Mar 2015 11:31:59 +0100 Subject: [PATCH 2/4] Delete iFub --- src/main/java/ml/grafos/okapi/iFub | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/main/java/ml/grafos/okapi/iFub diff --git a/src/main/java/ml/grafos/okapi/iFub b/src/main/java/ml/grafos/okapi/iFub deleted file mode 100644 index 8b137891..00000000 --- a/src/main/java/ml/grafos/okapi/iFub +++ /dev/null @@ -1 +0,0 @@ - From 23901bcc528c2b8798f5a7ea0ae768704fc1008a Mon Sep 17 00:00:00 2001 From: hekow Date: Wed, 11 Mar 2015 11:34:57 +0100 Subject: [PATCH 3/4] Create iFubAssignLayer.java --- .../ml/grafos/okapi/iFub/iFubAssignLayer.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/main/java/ml/grafos/okapi/iFub/iFubAssignLayer.java diff --git a/src/main/java/ml/grafos/okapi/iFub/iFubAssignLayer.java b/src/main/java/ml/grafos/okapi/iFub/iFubAssignLayer.java new file mode 100644 index 00000000..6b9b47c4 --- /dev/null +++ b/src/main/java/ml/grafos/okapi/iFub/iFubAssignLayer.java @@ -0,0 +1,27 @@ +/** + * Inria Sophia Antipolis - Team COATI - 2015 + * @author Flavian Jacquot + * + */ +package ml.grafos.okapi.iFub; +/* + * This class is used to assign the layer of every vertex and reset the source flag + */ +import java.io.IOException; + +import org.apache.giraph.graph.BasicComputation; +import org.apache.giraph.graph.Vertex; +import org.apache.hadoop.io.IntWritable; +import org.apache.hadoop.io.LongWritable; +import org.apache.hadoop.io.NullWritable; + +public class iFubAssignLayer extends BasicComputation { + + + @Override + public void compute(Vertex vertex, Iterable arg1) throws IOException { + vertex.getValue().setLayer(vertex.getValue().getDistance()); + vertex.getValue().setSource(false); + } + +} From 0ffc75b9f53f19d0c54d06080c6689fe944a9381 Mon Sep 17 00:00:00 2001 From: Flavian Jacquot Date: Wed, 11 Mar 2015 11:59:40 +0100 Subject: [PATCH 4/4] This commit include an implementation of the iFUB algorithm to compute diameter on undirected graphs For more info README --- .../iFub/LongLongEdgesListInputFormat.java | 51 ++++ .../okapi/iFub/MaxDegreeComputation.java | 47 ++++ src/main/java/ml/grafos/okapi/iFub/README | 27 ++ src/main/java/ml/grafos/okapi/iFub/README~ | 22 ++ .../ml/grafos/okapi/iFub/ToUndirected.java | 34 +++ .../ml/grafos/okapi/iFub/iFubBFSCompute.java | 79 ++++++ .../okapi/iFub/iFubInputToUndirected.java | 54 ++++ .../grafos/okapi/iFub/iFubMasterCompute.java | 235 ++++++++++++++++++ .../grafos/okapi/iFub/iFubSelectSource.java | 41 +++ .../ml/grafos/okapi/iFub/iFubVertexValue.java | 73 ++++++ 10 files changed, 663 insertions(+) create mode 100644 src/main/java/ml/grafos/okapi/iFub/LongLongEdgesListInputFormat.java create mode 100644 src/main/java/ml/grafos/okapi/iFub/MaxDegreeComputation.java create mode 100644 src/main/java/ml/grafos/okapi/iFub/README create mode 100644 src/main/java/ml/grafos/okapi/iFub/README~ create mode 100644 src/main/java/ml/grafos/okapi/iFub/ToUndirected.java create mode 100644 src/main/java/ml/grafos/okapi/iFub/iFubBFSCompute.java create mode 100644 src/main/java/ml/grafos/okapi/iFub/iFubInputToUndirected.java create mode 100644 src/main/java/ml/grafos/okapi/iFub/iFubMasterCompute.java create mode 100644 src/main/java/ml/grafos/okapi/iFub/iFubSelectSource.java create mode 100644 src/main/java/ml/grafos/okapi/iFub/iFubVertexValue.java diff --git a/src/main/java/ml/grafos/okapi/iFub/LongLongEdgesListInputFormat.java b/src/main/java/ml/grafos/okapi/iFub/LongLongEdgesListInputFormat.java new file mode 100644 index 00000000..48fdc742 --- /dev/null +++ b/src/main/java/ml/grafos/okapi/iFub/LongLongEdgesListInputFormat.java @@ -0,0 +1,51 @@ +package ml.grafos.okapi.iFub; + +import java.io.IOException; +import java.util.regex.Pattern; + +import org.apache.giraph.io.EdgeReader; +import org.apache.giraph.io.formats.TextEdgeInputFormat; +import org.apache.hadoop.io.LongWritable; +import org.apache.hadoop.io.NullWritable; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mapreduce.InputSplit; +import org.apache.hadoop.mapreduce.TaskAttemptContext; + +public class LongLongEdgesListInputFormat extends + TextEdgeInputFormat { + /** Splitter for endpoints */ + private static final Pattern SEPARATOR = Pattern.compile("[\001\t ]"); + + @Override + public EdgeReader createEdgeReader( + InputSplit split, TaskAttemptContext context) + throws IOException { + return new LongLongEdgesReader(); + } + + public class LongLongEdgesReader extends + TextEdgeReaderFromEachLineProcessed { + @Override + protected String[] preprocessLine(Text line) throws IOException { + return SEPARATOR.split(line.toString()); + } + + @Override + protected LongWritable getSourceVertexId(String[] endpoints) + throws IOException { + return new LongWritable(Long.parseLong(endpoints[0])); + } + + @Override + protected LongWritable getTargetVertexId(String[] endpoints) + throws IOException { + return new LongWritable(Long.parseLong(endpoints[1])); + } + + @Override + protected NullWritable getValue(String[] endpoints) throws IOException { + + return NullWritable.get(); + } + } + } \ No newline at end of file diff --git a/src/main/java/ml/grafos/okapi/iFub/MaxDegreeComputation.java b/src/main/java/ml/grafos/okapi/iFub/MaxDegreeComputation.java new file mode 100644 index 00000000..e8b8668c --- /dev/null +++ b/src/main/java/ml/grafos/okapi/iFub/MaxDegreeComputation.java @@ -0,0 +1,47 @@ +/** + * Inria Sophia Antipolis - Team COATI - 2015 + * @author Flavian Jacquot + * + */ +package ml.grafos.okapi.iFub; + +import java.io.IOException; + +import org.apache.giraph.graph.BasicComputation; +import org.apache.giraph.graph.Vertex; +import org.apache.hadoop.io.IntWritable; +import org.apache.hadoop.io.LongWritable; +import org.apache.hadoop.io.NullWritable; +import org.apache.log4j.Logger; +/* + * This class simply aggregate the degrees with a maxLong aggregator + * and aggregate the id of vertices with maximum degree. + */ +public class MaxDegreeComputation extends BasicComputation{ +private Logger LOG = Logger.getLogger(MaxDegreeComputation.class); + int maxDegree=1; + boolean sourceFound = false; + @Override + public void preSuperstep() { + super.preSuperstep(); + maxDegree=(int)((LongWritable)getAggregatedValue(iFubMasterCompute.MAX_DEGREE)).get(); + } + + @Override + public void compute( + Vertex vertex, + Iterable messages) throws IOException { + if(getSuperstep()==0) + aggregate(iFubMasterCompute.MAX_DEGREE, new LongWritable(vertex.getNumEdges())); + else + { + if(vertex.getNumEdges()==maxDegree&&!sourceFound) + { + sourceFound=true; + LOG.info("Source FOUND ! "+vertex.getId()); + aggregate(iFubMasterCompute.SOURCE_ID, new LongWritable(vertex.getId().get())); + } + } + } + +} diff --git a/src/main/java/ml/grafos/okapi/iFub/README b/src/main/java/ml/grafos/okapi/iFub/README new file mode 100644 index 00000000..b97b1039 --- /dev/null +++ b/src/main/java/ml/grafos/okapi/iFub/README @@ -0,0 +1,27 @@ +Inria Sophia Antipolis - Team COATI - 2015 - Flavian Jacquot + +This folder contains an implementation of the iFub algorithm : an exact algorithm to compute the diameter of undirected graphs. +It's described in an article at http://www.sciencedirect.com/science/article/pii/S0304397512008687 + +I've tried it on several graphs from http://snap.stanford.edu/data/ : +com-amazon ~1M edges +com-Friendster ~2B edges + +In this folder you can found formats to make an undirected graph. +The master compute iFubMasterCompute must be declared in the giraph job command with -mc : + +Example : + +COMPUTE_CLASS="ml.graphos.okapi.iFub.iFubBFSCompute -mc ml.graphos.okapi.iFub.iFubMasterCompute" +EIF=ml.graphos.okapi.iFub.iFubInputToUndirected +EIP=data/com-amazon.ungraph.txt +VOF=org.apache.giraph.io.formats.IdWithValueTextOutputFormat +OP=output/FS30G.UN.txt +WORKER=8 + +$HADOOP_HOME/bin/hadoop jar $GIRAPH_JAR org.apache.giraph.GiraphRunner $COMPUTE_CLASS -eif $EIF -eip $EIP -vof $VOF -op $OP -w $WORKER + +The result is printed as a counter in the job trace. +The number of BFS is also printed. + +For any question you can contact me at tki1.50@gmail.com diff --git a/src/main/java/ml/grafos/okapi/iFub/README~ b/src/main/java/ml/grafos/okapi/iFub/README~ new file mode 100644 index 00000000..573bf86c --- /dev/null +++ b/src/main/java/ml/grafos/okapi/iFub/README~ @@ -0,0 +1,22 @@ +Inria Sophia Antipolis - Team COATI - 2015 - Flavian Jacquot + +This folder contains an implementation of the iFub algorithm : an exact algorithm to compute the diameter of undirected graphs. +It's described in an article at http://www.sciencedirect.com/science/article/pii/S0304397512008687 + +I've tried it on several graphs from http://snap.stanford.edu/data/ : +com-amazon ~1M edges +com-Friendster ~2B edges + +In this folder you can found formats to make an undirected graph. +The master compute iFubMasterCompute must be declared in the giraph job command with -mc : + +Example : + +COMPUTE_CLASS="ml.graphos.okapi.iFub.iFubBFSCompute -mc ml.graphos.okapi.iFub.iFubMasterCompute" +EIF=ml.graphos.okapi.iFub.iFubInputToUndirected +EIP=data/com-amazon.ungraph.txt +VOF=org.apache.giraph.io.formats.IdWithValueTextOutputFormat +OP=output/FS30G.UN.txt +WORKER=8 + +$HADOOP_HOME/bin/hadoop jar $GIRAPH_JAR org.apache.giraph.GiraphRunner $COMPUTE_CLASS -eif $EIF -eip $EIP -vof $VOF -op $OP -w $WORKER diff --git a/src/main/java/ml/grafos/okapi/iFub/ToUndirected.java b/src/main/java/ml/grafos/okapi/iFub/ToUndirected.java new file mode 100644 index 00000000..73dd05dc --- /dev/null +++ b/src/main/java/ml/grafos/okapi/iFub/ToUndirected.java @@ -0,0 +1,34 @@ +package ml.grafos.okapi.iFub; + +import java.io.IOException; + +import org.apache.giraph.edge.EdgeFactory; +import org.apache.giraph.graph.BasicComputation; +import org.apache.giraph.graph.Vertex; +import org.apache.hadoop.io.LongWritable; +import org.apache.hadoop.io.NullWritable; + +public class ToUndirected extends BasicComputation{ + + @Override + public void compute(Vertex vertex, Iterable inbox) throws IOException { + // TODO Auto-generated method stub + if(getSuperstep()==0) + { + sendMessageToAllEdges(vertex, vertex.getId()); + } + else if(getSuperstep()==1) + { + for(LongWritable sourceId : inbox) + { + if(vertex.getEdgeValue(sourceId)==null) + { + vertex.addEdge(EdgeFactory.create(sourceId)); + } + } + } + vertex.voteToHalt(); + + } + +} diff --git a/src/main/java/ml/grafos/okapi/iFub/iFubBFSCompute.java b/src/main/java/ml/grafos/okapi/iFub/iFubBFSCompute.java new file mode 100644 index 00000000..5bb3b621 --- /dev/null +++ b/src/main/java/ml/grafos/okapi/iFub/iFubBFSCompute.java @@ -0,0 +1,79 @@ +/** + * Inria Sophia Antipolis - Team COATI - 2015 + * @author Flavian Jacquot + * + */ +package ml.grafos.okapi.iFub; + +import java.io.IOException; + +import org.apache.giraph.edge.Edge; +import org.apache.giraph.graph.BasicComputation; +import org.apache.giraph.graph.Vertex; +import org.apache.hadoop.io.IntWritable; +import org.apache.hadoop.io.LongWritable; +import org.apache.hadoop.io.NullWritable; +/* + * This class is a version of BFS used in iFub. + * There is a cache for the sourceID and the current BFS step=distance from source + * The method propagateDistance update the aggregators for the iFub Algorithm + */ +public class iFubBFSCompute extends BasicComputation{ + private long Source_ID; + private long bfsStep; + + private boolean isSource( + Vertex vertex) { + return vertex.getId().get() == Source_ID; + } + @Override + public void preSuperstep() { + // TODO Auto-generated method stub + super.preSuperstep(); + this.bfsStep = ((LongWritable)getAggregatedValue(iFubMasterCompute.BFS_STEP)).get(); + if(bfsStep==0) + this.Source_ID = ((LongWritable)getAggregatedValue(iFubMasterCompute.SOURCE_ID)).get(); + } + @Override + public void compute( + Vertex vertex, + Iterable messages) throws IOException { + + if (bfsStep==0) { + if(vertex.getValue()==null) + { + vertex.setValue(new iFubVertexValue()); + } + + vertex.getValue().setDistance(Long.MAX_VALUE); + if (isSource(vertex)) { + vertex.getValue().setSource(true); + propagateDistance(vertex); + } + + } + else + { + if (messages.iterator().hasNext() + && vertex.getValue().getDistance() == Long.MAX_VALUE) { + propagateDistance(vertex); + } + } + } + + private void propagateDistance( + Vertex vertex) + throws IOException { + aggregate(iFubMasterCompute.NUM_ACTIVE_VERTEX, new LongWritable(1)); + + aggregate(iFubMasterCompute.LOWER_B,new LongWritable(bfsStep)); + vertex.getValue().setDistance(bfsStep); + sendMessageToAllEdges(vertex, new IntWritable(0)); + for(Edge arrete : vertex.getEdges()) + { + sendMessage(arrete.getTargetVertexId(), new IntWritable(1)); + } + } + + +} diff --git a/src/main/java/ml/grafos/okapi/iFub/iFubInputToUndirected.java b/src/main/java/ml/grafos/okapi/iFub/iFubInputToUndirected.java new file mode 100644 index 00000000..365d3502 --- /dev/null +++ b/src/main/java/ml/grafos/okapi/iFub/iFubInputToUndirected.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Inria Sophia Antipolis - Team COATI - 2015 + * @author Flavian Jacquot + * + */ +package ml.grafos.okapi.iFub; + +import org.apache.giraph.io.EdgeReader; +import org.apache.giraph.io.ReverseEdgeDuplicator; +import org.apache.hadoop.io.LongWritable; +import org.apache.hadoop.io.NullWritable; +import org.apache.hadoop.mapreduce.InputSplit; +import org.apache.hadoop.mapreduce.TaskAttemptContext; + +import cutGraph.LongLongEdgesListInputFormat; + +import java.io.IOException; + +/** + * Simple text-based {@link org.apache.giraph.io.EdgeInputFormat} for + * unweighted graphs with long ids. + * + * Each line consists of: source_vertex target_vertex + * + * This version also creates the reverse edges. + */ +public class iFubInputToUndirected + extends LongLongEdgesListInputFormat { + @Override + public EdgeReader createEdgeReader( + InputSplit split, TaskAttemptContext context) throws IOException { + EdgeReader edgeReader = + super.createEdgeReader(split, context); + edgeReader.setConf(getConf()); + return new ReverseEdgeDuplicator(edgeReader); + } +} diff --git a/src/main/java/ml/grafos/okapi/iFub/iFubMasterCompute.java b/src/main/java/ml/grafos/okapi/iFub/iFubMasterCompute.java new file mode 100644 index 00000000..34ceefd6 --- /dev/null +++ b/src/main/java/ml/grafos/okapi/iFub/iFubMasterCompute.java @@ -0,0 +1,235 @@ +/** + * Inria Sophia Antipolis - Team COATI - 2015 + * @author Flavian Jacquot + * + */ +package ml.grafos.okapi.iFub; + +import org.apache.giraph.aggregators.LongMaxAggregator; +import org.apache.giraph.aggregators.LongSumAggregator; +import org.apache.giraph.examples.SimpleAggregatorWriter; +import org.apache.giraph.master.DefaultMasterCompute; +import org.apache.hadoop.io.LongWritable; +import org.apache.log4j.Logger; +/* + * This class is used to manage the computation of iFUB algorithm + * It's a bit messy but it works ! + * Severals aggregator are used + */ +public class iFubMasterCompute extends DefaultMasterCompute { + public static String LOWER_B = "Lowerbound"; + public static String LAYER = "Layer"; + public static String SOURCE_ID = "SourceId"; + public static String MAX_DEGREE = "MaxDegree"; + public static String NUM_ACTIVE_VERTEX = "ActiveVertex"; + public static String BFS_STEP = "BFSStep"; + + private static long bfsCounter; + + private Logger LOG = Logger.getLogger(iFubMasterCompute.class); + + + @Override + public void compute() { + printAggregators(); + // select the root vertex for the entire algorithm + + if (getSuperstep() == 0) { + if (LOG.isInfoEnabled()) LOG.info("Computing max degree"); + setComputation(MaxDegreeComputation.class); + } + + else if (getSuperstep() == 1) + { + if (LOG.isInfoEnabled()) LOG.info("Selecting source vertex for 2 sweep"); + } + else + { + // if we tried to select a vertex at the previous step, we start a new BFS + if (getComputation() == iFubSelectSource.class) { + //on vérifie qu'on a bien trouvé une source pour la couche donnée + //we verify that a source have been found, not an error case, it's just mean the layer have been entirely explored + if (((LongWritable)getAggregatedValue(SOURCE_ID)).get() == -1) { + if (LOG.isInfoEnabled()) { + LOG.info("No vertex found for layer : " + ((LongWritable)getAggregatedValue(LAYER)).get()); + } + //we check the halting condition + this.checkHaltingAfterLayer(); + + //on passe à la couche inf + //go to next layer + long previousLayer = ((LongWritable)getAggregatedValue(LAYER)).get(); + setAggregatedValue(LAYER, new LongWritable(previousLayer-1)); + if(previousLayer<0) + { + LOG.info("############################################################# ERROR !"); + haltComputation(); + } + } + else + { + //if we found a source, explore it. + //BFS from the new source + if (LOG.isInfoEnabled()) { + LOG.info("New BFS, source vertex : " + ((LongWritable)getAggregatedValue(SOURCE_ID)).get()); + } + newBFS(); + } + } + else if(getComputation() == iFubAssignLayer.class) + { + //If we just assigned the layers, it's time to select a source and start the exploration + selectSource(); + } + else if((getComputation() == MaxDegreeComputation.class)) + { + //after getting the vertex with the highest degree, we do a 2-sweep = 2BFS + newBFS(); + } + + //if the previous BFS is finished, we select a new source + else if (((LongWritable)getAggregatedValue(NUM_ACTIVE_VERTEX)).get() == 0) { + if(getComputation()==iFubBFSCompute.class) + { + //if 2-sweep isn't done, proceed + if(bfsCounter<3) + { + setAggregatedValue(LAYER, getAggregatedValue(LOWER_B)); + if (bfsCounter==2) + { + //select a source from the center layer + long centerLayer = ((LongWritable)getAggregatedValue(LOWER_B)).get()/2; + + setAggregatedValue(LAYER, new LongWritable( centerLayer)); + } + setComputation(iFubAssignLayer.class); + } + else + { + checkHaltingAfterBFS(); + selectSource(); + } + } + } + else if (((LongWritable)getAggregatedValue(NUM_ACTIVE_VERTEX)).get() > 0) + { + //continue BFS, reset #active vertices and increment BFS_STEP + nextStepBFS(); + } + + } + } + private void selectSource() + { + setAggregatedValue(SOURCE_ID, new LongWritable(-1)); + setComputation(iFubSelectSource.class); + } + + private void newBFS() + { + setAggregatedValue(BFS_STEP, new LongWritable(0)); + iFubMasterCompute.bfsCounter++; + setComputation(iFubBFSCompute.class); + } + + private void nextStepBFS() + { + setAggregatedValue(NUM_ACTIVE_VERTEX, new LongWritable(0)); + setAggregatedValue(BFS_STEP, new LongWritable(((LongWritable)getAggregatedValue(BFS_STEP)).get()+1)); + + } + + private void printAggregators() + { + if(LOG.isInfoEnabled()) + { + LOG.info("printAggregators SUperStep: "+getSuperstep()); + + String value = getAggregatedValue(NUM_ACTIVE_VERTEX).toString(); + LOG.info("NUM_ACTIVE_VERTEX: "+value); + value = getAggregatedValue(LOWER_B).toString(); + LOG.info("LOWER_B: "+value); + + value = getAggregatedValue(LAYER).toString(); + LOG.info("LAYER: "+value); + value = getAggregatedValue(SOURCE_ID).toString(); + LOG.info("SOURCE_ID: "+value); + value = getAggregatedValue(MAX_DEGREE).toString(); + LOG.info("MAX_DEGREE: "+value); + value = getAggregatedValue(BFS_STEP).toString(); + LOG.info("BFS_STEP: "+value); + + LOG.info("BFS_COUNT: "+bfsCounter); + LOG.info("computation class: "+getComputation().toString()); + + } + } + /* + * Check if the halting condition is met after each bfs + * which is maxExentricity==currentLayer*2 + * if not update the new Lower bound + */ + private void checkHaltingAfterBFS() { + long lowerB = ((LongWritable)getAggregatedValue(LOWER_B)).get(); + long currentLayer = ((LongWritable)getAggregatedValue(LAYER)).get(); + + long upperB = currentLayer*2; + if(lowerB==upperB) + { + printResult(lowerB); + } + + } + private void printResult(long diameter) + { + System.out.println("Diameter ="+diameter); + LOG.info("Diameter ="+diameter); + + getContext().getCounter("iFUB stats", "Diameter") + .increment(diameter); + getContext().getCounter("iFUB stats", "BFS") + .increment(bfsCounter); + + this.haltComputation(); + } + /* + * Check if the halting condition is met after exploring all the current layer + * which is lower bound > (currentLayer-1)*2 + */ + private void checkHaltingAfterLayer() { + // TODO Auto-generated method stub + long lowerB = ((LongWritable)getAggregatedValue(LOWER_B)).get(); + long currentLayer = ((LongWritable)getAggregatedValue(LAYER)).get(); + if(lowerB>((currentLayer-1)*2)) + { + printResult(lowerB); + } + } + /* + * register the aggregators used in the algorithm + * and set the default values + */ + @Override + public void initialize() throws InstantiationException, IllegalAccessException { + + registerPersistentAggregator(LOWER_B, LongMaxAggregator.class); + registerPersistentAggregator(LAYER, LongMaxAggregator.class); + registerPersistentAggregator(SOURCE_ID, LongMaxAggregator.class); + registerPersistentAggregator(MAX_DEGREE, LongMaxAggregator.class); + registerPersistentAggregator(NUM_ACTIVE_VERTEX, LongSumAggregator.class); + registerPersistentAggregator(BFS_STEP, LongSumAggregator.class); + + + + setAggregatedValue(NUM_ACTIVE_VERTEX, new LongWritable(1)); + setAggregatedValue(LOWER_B, new LongWritable(-1)); + setAggregatedValue(LAYER, new LongWritable(-1)); + setAggregatedValue(SOURCE_ID, new LongWritable(-1)); + setAggregatedValue(MAX_DEGREE, new LongWritable(-1)); + setAggregatedValue(NUM_ACTIVE_VERTEX, new LongWritable(0)); + + + + } + +} diff --git a/src/main/java/ml/grafos/okapi/iFub/iFubSelectSource.java b/src/main/java/ml/grafos/okapi/iFub/iFubSelectSource.java new file mode 100644 index 00000000..931e497a --- /dev/null +++ b/src/main/java/ml/grafos/okapi/iFub/iFubSelectSource.java @@ -0,0 +1,41 @@ +/** + * Inria Sophia Antipolis - Team COATI - 2015 + * @author Flavian Jacquot + * + */ +package ml.grafos.okapi.iFub; + +import java.io.IOException; + +import org.apache.giraph.graph.BasicComputation; +import org.apache.giraph.graph.Vertex; +import org.apache.hadoop.io.IntWritable; +import org.apache.hadoop.io.LongWritable; +import org.apache.hadoop.io.NullWritable; +/* + * This class is used to select a source before running a BFS + * the current layer is cached before the step + * a vertex is select if it match the currentStep and if it wasn't a source yet + */ +public class iFubSelectSource extends BasicComputation{ + + long currentLayer; + @Override + public void preSuperstep() { + // TODO Auto-generated method stub + super.preSuperstep(); + currentLayer = ((LongWritable)getAggregatedValue(iFubMasterCompute.LAYER)).get(); + } + + @Override + public void compute( + Vertex vertex, + Iterable arg1) throws IOException { + //le sommet est de la couche demandé et il n'as pas été la source + if(vertex.getValue().getLayer()==currentLayer&&!vertex.getValue().wasSource()) + { + aggregate(iFubMasterCompute.SOURCE_ID,vertex.getId()); + } + } + +} diff --git a/src/main/java/ml/grafos/okapi/iFub/iFubVertexValue.java b/src/main/java/ml/grafos/okapi/iFub/iFubVertexValue.java new file mode 100644 index 00000000..259a9a58 --- /dev/null +++ b/src/main/java/ml/grafos/okapi/iFub/iFubVertexValue.java @@ -0,0 +1,73 @@ +/** + * Inria Sophia Antipolis - Team COATI - 2015 + * @author Flavian Jacquot + * + */ +package ml.grafos.okapi.iFub; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +import org.apache.hadoop.io.Writable; +/* + * This class represent the vertex's values used in iFub + * Hold 3 variable : layer, distance from source, was source (=we explored the graph from this vertex) + * + */ +public class iFubVertexValue implements Writable{ + private long layer; + private long distance; + private boolean wasSource=false; + + public iFubVertexValue() { + this.layer = Long.MAX_VALUE; + this.distance = Long.MAX_VALUE; + } + + public iFubVertexValue(long vertexLayer) { + this.layer = vertexLayer; + this.distance = Long.MAX_VALUE; + } + @Override + public void readFields(DataInput in) throws IOException { + + this.distance = in.readLong(); + this.layer = in.readLong(); + this.wasSource = in.readBoolean(); + } + + @Override + public void write(DataOutput out) throws IOException { + out.writeLong(layer); + out.writeLong(distance); + out.writeBoolean(wasSource); + } + + @Override + public String toString() { + return layer +" "+ distance + "" + wasSource; + } + public long getDistance() { + return distance; + } + + public void setDistance(long distance) { + this.distance = distance; + } + + public long getLayer() { + return layer; + } + + public void setLayer(long vertexLayer) { + this.layer = vertexLayer; + } + public boolean wasSource() { + return wasSource; + } + public void setSource(boolean wasSource) { + this.wasSource = wasSource; + } + +}