以下问题是否有名称,是否有算法来解决它? : 给定一个图形,无论是有向还是无,找到满足
给出的规范的所有路径e.g。
A -> B -> *? -> D which results in ABXD and ABYD and ABD etc.
或
A -> *{1} -> D -> *? -> E which results in ABXDZE and ABYDZE and ABDZE etc. etc.
感谢
P.S。 有没有人知道在R或perl或C中执行此操作的图形库?
答案 0 :(得分:1)
我不知道任何图书馆,但你必须将其分为两部分:
对于解析,我让你找到你需要做的事情(使用解析库或你自己)
关于算法部分,我建议您定义一个特殊结构(如链表)来表示您的查询,其中每个元素可以表示一个真实节点,x个节点或无限数量的节点。
您算法的唯一问题是使用无限数量或有限数量的中间节点查找从节点A到节点B的所有路径。您可以使用动态编程或搜索算法(如DFS或BFS)来执行此操作。
答案 1 :(得分:1)
我最后做的是:
例如
A->B
A->C
B->D
C->E
E->D
在将所有数据作为'edgelist'读取后,以perl表示法保存输入数据的结果数据结构如下所示:
my %hash = (
'A' => {'B' => 1, 'C' => 1},
'B' => {'D' => 1},
'C' => {'E' => 1},
'E' => {'D' => 1},
);
查找一对节点是否直接连接可以大致完成(perl):
sub search {
my ($from,$to) = @_;
if( $to eq '*' ){ return defined($x=$hash{$from}) ? [keys $hash{$from}] : [] }
return defined($x=$hash{$from}) && defined($x{$to}) ? [$to] : []
}
在上面的函数中,通过将$ to设置为'*',可以返回'from'节点所连接的所有节点。返回是直接连接到$ from参数的节点的数组引用。
搜索两个节点之间的路径需要递归使用上述函数。
e.g。
sub path {
my ($from,$to, $hops, $save_results) = @_;
if( $hops < 0 ){ return 0 }
$results = search($from, '*');
if( "".@$results == 0 ){ return 0 }
$found = 0;
foreach $result (@$results){
$a_node = new Tree::Nary($result);
if( path($result, $to, $hops-1, $a_node) == 1 ){
$save_results->insert($save_results, -1, $a_node);
$found = 1;
}
}
return $found;
}
如果深度不是太多(即$ hops&lt; 6?),由于堆栈溢出[sic],可以使用递归。
最棘手的部分是读取结果并提取每个路径的节点。经过大量的考虑,我决定使用Tree :: Nary(n-ary树)来存储结果。最后我们有以下树:
|-> B -> D
A -> |-> C -> E -> D
为了提取所有路径,请执行以下操作:
以上是使用perl实现的,但也是在C ++中使用boost :: unordered_map进行哈希表。我还没有在C ++代码中添加树结构。
结果:对于3281415个边缘和18601个唯一节点,perl需要3分钟才能找到A->'*' - &gt;'*' - > B。我准备好了C ++代码的更新。