繁体   English   中英

这看起来像是一种在图中找到没有出边的顶点的有效方法(JGrapthT)吗?

[英]Does this look like an efficient way to find vertices which have no outgoing edges in a graph (JGrapthT)?

我正在使用 JGraphT 在内存图中保存大约 150,000 个(或大约)顶点。 这是一个有向图,每个顶点都有 { 0 | 1 } 出边。

我想找到检索没有出边的顶点集。 这是我尝试过的:

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() {
            // ..
        }
    }

这或许,是一种天真的尝试。 我很想知道是否有更好、更惯用和更有效的方法来做到这一点。

我不太确定代码中发生了什么,但以下内容可以正常工作:

Set<Employee> verticesWithoutSucc = myGraph.vertexSet().stream().filter(v -> !Graphs.vertexHasSuccessors(myGraph,v)).collect(Collectors.toSet());

请注意,要获得所有没有出弧的顶点,您必须使用vertexHasSuccessors(.)而不是vertexHasPredecessors(.)

请注意, vertexHasSuccessors方法只是调用.graph.outgoingEdgesOf(vertex);isEmpty();

这种方法应该是有效的,因为它在O(n)时间内运行,其中n是客户的数量。 如果您想要更好的性能,您可以在构建图形期间跟踪所有没有出弧的顶点。 也就是说,在图表中保留一组所有顶点,每次添加弧(i,j)时,从集合中删除顶点i 因此,您始终可以在恒定时间内查询没有输出弧的顶点集。

最后,对于大图,您可以查看jgrapht-opt package 中的优化图实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM