[英]Does this look like an efficient way to find vertices which have no outgoing edges in a graph (JGrapthT)?
I am using JGraphT for holding about 150,000 (or thereabouts) vertices in an in-memory graph.我正在使用 JGraphT 在内存图中保存大约 150,000 个(或大约)顶点。 This a directed graph and each vertex is going to have { 0 |
这是一个有向图,每个顶点都有 { 0 | 1 } outgoing edges.
1 } 出边。
I want to find retrieve the set of vertices which have no outgoing edges .我想找到检索没有出边的顶点集。 Here's what I have attempted:
这是我尝试过的:
import io.vavr.Tuple;
import io.vavr.Tuple2;
import io.vavr.Tuple3;
import io.vavr.control.Option;
import org.jgrapht.Graphs;
import org.jgrapht.graph.SimpleDirectedGraph;
import org.jgrapht.graph.concurrent.AsSynchronizedGraph;
public Option<io.vavr.collection.Set<Employee>>
pickEmployeesWithNoSupervisor(Integer companyID) {
// holdingCompany is of type: SimpleDirectedGraph<Employee,String>
// edge is a simple string: "reportingTo"
// Retrieve from a Map, initialized earlier, elsewhere
var holdingCompany = this.allCompanies.get(companyID);
if (holdingCompany == null)
return (Option.none());
else {
var vertices = holdingCompany.vertexSet();
io.vavr.collection.Set<Employee> accumulator = io.vavr.collection.HashSet.empty();
var allNoReportingToEmployees =
io.vavr.collection.HashSet.ofAll(vertices)
.foldLeft(accumulator,(accu,nextEmp) -> {
var hasPredecessors =
Graphs.vertexHasPredecessors(mayBeAKnownCompany,nextEmp);
return (!hasPredecessors ? accu.add(nextEmp) : accu) ;
});
return Option.some(allNoReportingToEmployees);
}
}
public class Employee {
private final Integer empID;
public Employee(Integer empID) {
this.empID = empID;
}
@Override
public boolean equals(Object o) {
// ..
}
@Override
public int hashCode() {
// ..
}
}
This perhaps, is a naive attempt.这或许,是一种天真的尝试。 I am keen to know if there is any better, more idiomatic and more efficient way of doing this.
我很想知道是否有更好、更惯用和更有效的方法来做到这一点。
I'm not quite sure what's going on in the code, but the following would work fine:我不太确定代码中发生了什么,但以下内容可以正常工作:
Set<Employee> verticesWithoutSucc = myGraph.vertexSet().stream().filter(v -> !Graphs.vertexHasSuccessors(myGraph,v)).collect(Collectors.toSet());
Note that, to get all vertices without outgoing arcs, you must use vertexHasSuccessors(.)
as opposed to vertexHasPredecessors(.)
.请注意,要获得所有没有出弧的顶点,您必须使用
vertexHasSuccessors(.)
而不是vertexHasPredecessors(.)
。
Note that the vertexHasSuccessors
method simply invokes .graph.outgoingEdgesOf(vertex);isEmpty();
请注意,
vertexHasSuccessors
方法只是调用.graph.outgoingEdgesOf(vertex);isEmpty();
This approach should be efficient since it runs in O(n)
time, where n
is the number of customers.这种方法应该是有效的,因为它在
O(n)
时间内运行,其中n
是客户的数量。 If you want even better performance, you could keep track of all the vertices without an outgoing arc during the construction of the graph.如果您想要更好的性能,您可以在构建图形期间跟踪所有没有出弧的顶点。 That is, keep a set of all the vertices in your graph, and each time you add an arc
(i,j)
, remove vertex i
from your set.也就是说,在图表中保留一组所有顶点,每次添加弧
(i,j)
时,从集合中删除顶点i
。 As such you can always query the set of vertices without outgoing arcs in constant time.因此,您始终可以在恒定时间内查询没有输出弧的顶点集。
Finally, for large graphs, you could have a look at the optimized graph implementations in the jgrapht-opt
package.最后,对于大图,您可以查看
jgrapht-opt
package 中的优化图实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.