我有一个对象工厂的接口,它在给定顶点创建Function<Object,Vertex>
和链接BiPredicate<Vertex,Vertex>
的情况下从对象集合创建图形。
这种设计允许通过提供这两种功能来规范任意图形连接算法,但是就我已经能够实现它而言,这需要在所有对象中循环。像这样的输入集合(类Graph
和Vertex
在别处定义):
Function<Object,Vertex> maker; // defined by user.
BiPredicate<Vertex,Vertex> linker; // defined by user.
Graph makeGraph( Collection<Object> input ) {
Graph g = new Graph();
Collection<Vertex> vertices = input.stream.map( ( Objec t ) -> maker.apply( t ) ).collect( Collectors.toList() );
for( Vertex ego : vertices ) {
Collection<Vertex> alters = new ArrayList<>();
alters.addAll( vertices );
alters.remove( ego );
for( Vertex alter : alters ) {
if( linker.test( ego, alter ) ) {
g.makeEdge( ego, alter );
}
}
}
}
我实际上有两个问题:
是否有更优雅的方式迭代集合中所有可能的对(i,j),而不是创建新列表,复制所有内容并从副本中删除i的丑陋解决方案?
< / LI>任何人都可以想到一种优化双重迭代的方法吗?现在,在最好的情况下,执行时间是O(n ^ 2),因为实现需要接受链接函数而不需要了解它,但也许有办法解决这个问题?例如指定某些参数以指示,例如,在共生网络的链接器测试第一次失败后,迭代可能会中断,等等。
当然,如果有人能想出另一种解决方法,我会很高兴听到它。
编辑:
忘记第一个问题,Robert Navado的answer让我意识到我错了。
为了澄清那些:我正在寻找一种方法来告诉实现链接器功能的应用可以在某些条件下进行优化(例如,在上面提到的共现示例中,“按位置排序并在之后中断第一个否定结果“)。
答案 0 :(得分:1)
好吧,直到你可以在图形中的图形中有未链接的顶点并且图形稀疏,我建议存储边而不是顶点。 但是,单链团中的最大边数是V *(V-1)。因此,在更糟糕的情况下,您需要O(V ^ 2)次迭代来链接您的图形,甚至更多的多图形。
至于迭代语法,以下内容也应该有效:
for(Vertex alter : vertices )
for(Vertex ego : vertices ){
//Do the descision
}
查看JUNG库以进行图形操作。它可能已经过时了,但你可以看看他们的数据结构是否有灵感。