Path Flink Gelly路径/轨迹用例

Path Flink Gelly路径/轨迹用例,path,apache-flink,gelly,Path,Apache Flink,Gelly,我们的团队是Gelly api的新手。我们希望实现一个简单的用例,该用例将列出源自初始vertice的所有路径,例如 输入边缘csv文件为 1,2\n2,3\n3,4\n1,5\n5,6 所需输出为(从1开始的完整路径) 1,2,3,4\n1,5,6 请有人帮忙。您可以使用其中一种,例如顶点中心迭代。从源顶点开始,可以迭代地扩展路径,每超步一跳。接收到路径后,顶点将其ID附加到路径,并将其传播到其传出邻居。如果顶点没有传出邻居,则它将打印/存储路径,并且不会进一步传播路径。为了避免循环,顶点还可

我们的团队是Gelly api的新手。我们希望实现一个简单的用例,该用例将列出源自初始vertice的所有路径,例如

输入边缘csv文件为 1,2\n2,3\n3,4\n1,5\n5,6

所需输出为(从1开始的完整路径) 1,2,3,4\n1,5,6

请有人帮忙。

您可以使用其中一种,例如顶点中心迭代。从源顶点开始,可以迭代地扩展路径,每超步一跳。接收到路径后,顶点将其ID附加到路径,并将其传播到其传出邻居。如果顶点没有传出邻居,则它将打印/存储路径,并且不会进一步传播路径。为了避免循环,顶点还可以在传播之前检查其ID是否存在于路径中。计算函数可以如下所示:

public static final class ComputePaths extends ComputeFunction<Integer, Boolean, NullValue, ArrayList<Integer>> {

    @Override
    public void compute(Vertex<Integer, Boolean> vertex, MessageIterator<ArrayList<Integer>> paths) {
        if (getSuperstepNumber() == 1) {
            // the source propagates its ID
            if (vertex.getId().equals(1)) {
                ArrayList<Integer> msg = new ArrayList<>();
                msg.add(1);
                sendMessageToAllNeighbors(msg);
            }
        }
        else {
            // go through received messages
            for (ArrayList<Integer> p : paths) {
                if (!p.contains(vertex.getId())) {
                    // if no cycle => append ID and forward to neighbors
                    p.add(vertex.getId());
                    if (!vertex.getValue()) {
                        sendMessageToAllNeighbors(p);
                    }
                    else {
                        // no out-neighbors: print p
                        System.out.println(p);
                    }
                }
                else {
                    // found a cycle => print the path and don't propagate further
                    System.out.println(p);
                }
            }
        }
    }
}
公共静态最终类ComputePath扩展了ComputeFunction{
@凌驾
公共void计算(顶点、消息迭代器路径){
如果(GetSuperSepNumber()==1){
//源传播其ID
if(vertex.getId()等于(1)){
ArrayList msg=新的ArrayList();
味精添加(1);
向所有邻居发送消息(msg);
}
}
否则{
//浏览收到的信息
对于(ArrayList p:路径){
如果(!p.contains(vertex.getId())){
//如果没有循环=>追加ID并转发到邻居
p、 添加(vertex.getId());
如果(!vertex.getValue()){
向所有邻居发送消息(p);
}
否则{
//无输出邻居:打印p
系统输出println(p);
}
}
否则{
//找到一个循环=>打印路径,不进一步传播
系统输出println(p);
}
}
}
}
}
在这段代码中,我假设您已经对顶点进行了预处理,以使用“true”值标记没有out邻居的顶点。例如,您可以使用
graph.outDegrees()
查找这些

请记住,枚举大型密集图中的所有路径的计算代价很高。中间路径状态可能会很快爆发。您可以考虑使用比使用int的ArrayList更紧凑的方式来表示路径,但是如果您有一个大直径的稠密图,请注意成本。 如果您不需要路径本身,但只对可达性或最短路径感兴趣,则存在更有效的算法。

您可以使用其中一种,例如以顶点为中心的迭代。从源顶点开始,可以迭代地扩展路径,每超步一跳。接收到路径后,顶点将其ID附加到路径,并将其传播到其传出邻居。如果顶点没有传出邻居,则它将打印/存储路径,并且不会进一步传播路径。为了避免循环,顶点还可以在传播之前检查其ID是否存在于路径中。计算函数可以如下所示:

public static final class ComputePaths extends ComputeFunction<Integer, Boolean, NullValue, ArrayList<Integer>> {

    @Override
    public void compute(Vertex<Integer, Boolean> vertex, MessageIterator<ArrayList<Integer>> paths) {
        if (getSuperstepNumber() == 1) {
            // the source propagates its ID
            if (vertex.getId().equals(1)) {
                ArrayList<Integer> msg = new ArrayList<>();
                msg.add(1);
                sendMessageToAllNeighbors(msg);
            }
        }
        else {
            // go through received messages
            for (ArrayList<Integer> p : paths) {
                if (!p.contains(vertex.getId())) {
                    // if no cycle => append ID and forward to neighbors
                    p.add(vertex.getId());
                    if (!vertex.getValue()) {
                        sendMessageToAllNeighbors(p);
                    }
                    else {
                        // no out-neighbors: print p
                        System.out.println(p);
                    }
                }
                else {
                    // found a cycle => print the path and don't propagate further
                    System.out.println(p);
                }
            }
        }
    }
}
公共静态最终类ComputePath扩展了ComputeFunction{
@凌驾
公共void计算(顶点、消息迭代器路径){
如果(GetSuperSepNumber()==1){
//源传播其ID
if(vertex.getId()等于(1)){
ArrayList msg=新的ArrayList();
味精添加(1);
向所有邻居发送消息(msg);
}
}
否则{
//浏览收到的信息
对于(ArrayList p:路径){
如果(!p.contains(vertex.getId())){
//如果没有循环=>追加ID并转发到邻居
p、 添加(vertex.getId());
如果(!vertex.getValue()){
向所有邻居发送消息(p);
}
否则{
//无输出邻居:打印p
系统输出println(p);
}
}
否则{
//找到一个循环=>打印路径,不进一步传播
系统输出println(p);
}
}
}
}
}
在这段代码中,我假设您已经对顶点进行了预处理,以使用“true”值标记没有out邻居的顶点。例如,您可以使用
graph.outDegrees()
查找这些

请记住,枚举大型密集图中的所有路径的计算代价很高。中间路径状态可能会很快爆发。您可以考虑使用比使用int的ArrayList更紧凑的方式来表示路径,但是如果您有一个大直径的稠密图,请注意成本。 如果您不需要路径本身,但只对可达性或最短路径感兴趣,那么存在更高效的算法