我正在构建一个两方网络生成器,并且正在使用How to filter the result of KNeighborhoodFilter?中的代码,当我的网络较小(5000个节点)时,它可以完美地工作。
现在,我正在使用具有60.000个节点和250.000个链接的网络。为了加快处理速度,我想知道在提取节点的2个距离的邻居时是否可以对节点进行随机抽样,比如说仅50%的2个距离的邻居...
我真的不知道如何实现此目标,也不知道是否可以不对KNeighborhoodFilter类本身进行黑客攻击(我知道我将无法做到这一点……)。
现在,我得到结果并选择一个随机样本,但是我不知道自己是否走对了:
Predicate<Node> onlyUsers = new Predicate<Node>() {
@Override
public boolean apply(Node node) {
return node.getName().startsWith("u");
}
};
// find neighbors of nodes with degree i
Filter<Node, Edge> filter = new KNeighborhoodFilter<Node, Edge>(u, 2, KNeighborhoodFilter.EdgeType.IN_OUT);
// retrieve everything at distance 2 from node u
List<Node> twoDistNei = Lists.newArrayList(filter.transform(zpa).getVertices());
// sample the collection
List<Node> sampledUsers = Lists.newArrayList();
for (int i = 0; i < 2000; i++) {
sampledUsers.add(twoDistNei.get(context.getRNG().nextInt(twoDistNei.size())));
}
Set<Node> sampledNodesHashed = Sets.newHashSet(sampledNodes);
Set<Node> twoDistUsers = Sets.newHashSet(Collections2.filter(sampledNodesHashed, onlyUsers));
我的目标是使此代码运行更快。非常感谢您的宝贵时间。
最好的祝福,
西蒙妮
最佳答案
如果想更快一点,这里有两种可能的方法。它们都涉及一些黑客行为。 :)
(1)修改KNeighborhoodFilter以为您提供一个以概率p遍历边缘的版本。
概括地说,您可以为每个跃点指定一个概率,即为第一跳使用一个概率,为第二跳使用一个概率,依此类推。
进一步的概括可能会根据所涉及的节点/边缘的某些属性为每个边缘使用单独的概率(例如,如果目标具有高度,则可能希望或多或少地跟踪边缘)。
请注意,此解决方案需要认真考虑哪种情况适合您的情况。如果您真正想要的是对完整结果中的节点进行统一的随机采样,那么您基本上需要生成完整结果,然后对其进行过滤。
这可能是最简单的解决方案。真的,这根本不需要太多工作。
(2)创建一个KNeighborhoodFilter的修改版本,该版本将工作分配给不同的处理器。您可能会在具有1个以上核心的计算机上运行此代码,因此您可以创建多个线程,并让Java将它们分配给不同的计算机。如果您真的想加快速度(并且具有适当的设置),则可以将其移植到MapReduce风格的其他计算机上。