我们的团队是 Gelly api 的新手。我们正在寻求实现一个简单的用例,该用例将列出源自初始顶点的所有路径 - 例如
输入边缘 csv 文件为 1,2\n2,3\n3,4\n1,5\n5,6
所需的输出将是(从 1 开始的完整路径)1,2,3,4\n1,5,6
有人可以帮忙吗。
我们的团队是 Gelly api 的新手。我们正在寻求实现一个简单的用例,该用例将列出源自初始顶点的所有路径 - 例如
输入边缘 csv 文件为 1,2\n2,3\n3,4\n1,5\n5,6
所需的输出将是(从 1 开始的完整路径)1,2,3,4\n1,5,6
有人可以帮忙吗。
您可以使用Gelly 的迭代抽象之一,例如以顶点为中心的迭代。从源顶点开始,您可以迭代地扩展路径,每超步一跳。收到路径后,顶点将其 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);
}
}
}
}
}
在这段代码中,我假设您已经预处理了顶点,以用“真”值标记没有外邻的顶点。例如,您可以使用graph.outDegrees()
来查找那些。
请记住,在一个大而密集的图中枚举所有路径的计算成本很高。中间路径状态可以很快爆发。您可以考虑使用比使用整数的 ArrayList 更紧凑的方式来表示路径,但如果您有一个大直径的密集图,请注意成本。如果您不需要路径本身,但您只对可达性或最短路径感兴趣,那么存在更有效的算法。