我想找到距离为2的所有节点的邻居,以获得一个不那么小的网络(5000个节点和25k个无向边缘)。现在我正在使用:
ArrayList<Node> twoDistNei = new ArrayList<Node>();
Collection<Node> myThreads = g.getNeighbors(u);
for(Node t:myThreads){
Collection<Node> neighbors = g.getNeighbors(t);
for(Node uu:neighbors){
if(!twoDistNei.contains(uu)){
twoDistNei.add(uu);
}
}
}
但它真的很慢,我想知道是否有更有效和快速的方法来实现这一目标。
编辑:我设法使用了KNeighborhoodFilter,这就是我提出的:
KNeighborhoodFilter filter = new KNeighborhoodFilter(u, 2,KNeighborhoodFilter.EdgeType.IN_OUT);
Graph<Node, Edge> transform = filter.transform(zpa);
Collection<Node> vertices = transform.getVertices();
Set<Node> twoDistThreads = new HashSet<Node>();
for (Node v : vertices) {
if(v.getColor().equals("blue")){
twoDistThreads.add((Thread)v);
}
System.out.println("thread " + v.getName() + " has color " + v.getColor());
}
现在我看到过滤器只允许转换()原始网络并引入一个包含所有选定节点的子图(加上链接到所选节点的节点......但为什么?)。 这意味着我必须过滤新的节点集合以仅捕获我感兴趣的2-dist顶点 - 我有一个二分图,其中一组节点是“蓝色”而另一个是“红色”。 我在这里做事,@约书亚?谢谢你的帮助!
祝你好运, 西蒙
答案 0 :(得分:2)
这就是KNeighborhoodFilter的用途: http://jung.sourceforge.net/doc/api/edu/uci/ics/jung/algorithms/filters/KNeighborhoodFilter.html
答案 1 :(得分:1)
你在双循环中获取所有邻居的方法就好了。你是而且应该依靠荣格为你争取所有邻居。如果你对Jung获得所有邻居的方法不满意,你可以1)改进Jung或2)使用别的东西,但我怀疑这实际上是问题:
您正在使用一种非常慢的方法来确保您不使用ArrayList存储两次相同的邻居:
if(!twoDistNei.contains(uu)){
twoDistNei.add(uu);
}
ArrayList.contains
所做的只是遍历所有项目以检查它是否具有特定项目,因此twoDistNei
数组越大,包含方法变得越慢。这称为线性时间算法,因此在这种情况下线性到ArrayList中的项目数量。有一些恒定时间算法可以达到同样的效果,但无论你的数组多大,总是需要相同的时间。
我建议您使用HashSet
而不是ArrayList
,如下所示:
HashSet<Node> twoDistNei = new HashSet<Node>();
Collection<Node> myThreads = g.getNeighbors(u);
for(Node t:myThreads){
twoDistNei.addAll( g.getNeighbors(t) );
}
HashSet的一个定义属性是它不存储重复的条目,所以你可以简单地使用addAll
,一切都会被处理掉。此外,HashSet使用基于hashCode的索引构建内部数组,从而平均实现恒定的时间性能。
希望这有帮助! :)