2016-09-01 9 views
0

Этот код заимствован из книги «Практическая аналитика графа с помощью Apache Giraph».Apache Giraph: не удается изменить значение края через setEdgeValue()

Целью моего кода является преобразование графика с использованием только одного направления в использование двухсторонних ребер.

Мои данные табуляцией текстовый файл TextDoubleDoubleAdjacencyListVertexInputFormat:

A 0 B 0 
B 0 
C 0 A 0 D 0 
D 0 B 0 G 0 
E 0 A 0 B 0 D 0 
F 0 C 0 D 0 
G 0 C 0 E 0 

Моя минимальная нерабочим пример:

import org.apache.giraph.GiraphRunner; 
    import org.apache.giraph.graph.*; 
    import org.apache.hadoop.io.*; 
    import org.apache.hadoop.util.ToolRunner; 
    import org.apache.giraph.edge.EdgeFactory; 

    public class DigraphToGraph extends BasicComputation<Text,DoubleWritable,DoubleWritable,Text> 
    { 
    static final DoubleWritable ORIG_E = new DoubleWritable (1), 
           NEW_E = new DoubleWritable (2); 

    @Override 
    public void compute(Vertex <Text,DoubleWritable, DoubleWritable> vertex, Iterable<Text> messages) { 
    if (getSuperstep() == 0) 
     sendMessageToAllEdges (vertex, vertex.getId()); 
    else { 
     for (Text m:messages) { 
     DoubleWritable edgeValue = vertex.getEdgeValue (m); 
     if (edgeValue == null) 
      vertex.addEdge (EdgeFactory.create (m, NEW_E)); 
     else 
      // problem HERE: try to relabel edge 
      vertex.setEdgeValue (m, ORIG_E); 
     } 
    } 

    vertex.voteToHalt(); 
    } 
} 

После выполнения этого кода я ожидал края, чтобы иметь только 1 или 2 значения. Тем не менее, я получаю:

G 0.0 C 0.0 E 0.0 D 2.0 
E 0.0 A 0.0 B 0.0 D 0.0 G 2.0 
F 0.0 C 0.0 D 0.0 
D 0.0 B 0.0 G 0.0 E 2.0 B 2.0 C 2.0 
B 0.0 E 2.0 D 2.0 A 2.0 
C 0.0 A 0.0 D 0.0 G 2.0 B 2.0 
A 0.0 B 0.0 E 2.0 C 2.0 

Почему мой код не изменяет ранее существовавшие края?

+0

Я также попытался использовать: 'removeEdgesRequest (vertex.getId(), m); addEdgeRequest (vertex.getId(), EdgeFactory.create (m, ORIG_E)) ;, но это не сработало. –

ответ

0

Ваш выход правильный. Предположим, что существует ребро от v1 до v2 со значением 0. Ваш код работает следующим образом: 1- если есть ребро от v2 до v1, то значение этого ребра будет обновлено до 1. 2- в противном случае a новый ребро будет создан из v2 в v1 со значением 2. В обоих случаях значение исходного края не будет изменено.

Поскольку в ваших входных данных нет двунаправленного края, первый случай не выполняется. В результате на вашем выходе нет значения 1.