从节点对生成节点路径

时间:2015-03-30 22:52:33

标签: perl

我正在尝试生成脚本,该脚本将从不同节点之间的连接列表构建路径(两个节点之间可以有多个直接连接)。此外,我不是要寻找最短路径,而是所有这些路径。虽然每个连接只能在计算中使用一次。 如果您想象计算机网络中的节点(例如a1:1 = router a1, interface 1等),将会更容易解释 例如,假设我们有两条路径(第二条路径,每个节点之间有2条连接):

a1:1 to b1:1| b1:2 to b2:1| b2:4 to a6:1
a1:5 to b5:1| b5:6 to a2:1
a1:7 to b5:2| b5:7 to a2:2

a个节点将始终是终点,但中间可以有任意数量的b节点。

因此我希望获得的输出看起来像:

a1-b1-b2-a6
a1-b5-a2 (in this case there are 2 connections between each of the nodes)

以下是我到目前为止所提出的但是它的效果并不好:

#!/usr/local/bin/perl
use strict;
use warnings;
my %paths;
my %connections =(
'a1:1' => 'b1:1',
'b1:2' => 'b2:1',
'b2:4' => 'a6:1',
'a1:5' => 'b5:1',
'a1:7' => 'b5:2', 
'b5:6' => 'a2:1',
'b5:7' => 'a2:2'
);

my %nodes;
for my $key ( sort keys %connections ){
    my $n1=(split(/:/,$key))[0];
    my $c1=(split(/:/,$key))[1];    
    my $n2=(split(/:/,$nodes{$key}))[0];
    my $c2=(split(/:/,$nodes{$key}))[1];
    $nodes{$n1}{$n2}{n_of_connections}[0]+=1;
    $nodes{$n2}{$n1}{n_of_connections}[0]+=1;
}
my $n=0;
foreach my $node ( sort keys %nodes ){
    $n++;
    foreach my $rnode (keys %{$nodes{$node}}) { # $rnode = "remote node"
        unless ($nodes{$node}{$rnode}{used}==1){
        $paths{$n}[0]=$node."-".$rnode;

    $nodes{$node}{$rnode}{used}[0]=1; #mark that it was used
    $nodes{$rnode}{$node}{used}[0]=1; #mark that it was used
    my $thisnode=$rnode;
    my $nextnode="";
    until ($nextnode =~ /a/){
        foreach my $x (keys %{$nodes{$thisnode}}) {
            unless ($nodes{$thisnode}{$x}{used}==1){
                $nextnode=$x;
                $paths{$n}[0].="-".$x;
                $nodes{$thisnode}{$x}{used}[0]=1; 
                $nodes{$x}{$thisnode}{used}[0]=1; 
                $thisnode=$nextnode;
            }   
        }

    }
}
}

2 个答案:

答案 0 :(得分:0)

以下内容应该从a1生成所有可能的路径。它使用递归子例程path,它只是遍历所有可能的连接。

我还使用了图表的不同表示,即%graph哈希。我在致电%connections之前从path创建了它。

#!/usr/bin/perl
use warnings;
use strict;

sub path {
    my ($start, $graph, $path) = @_;
    my @next = keys %{ $graph->{$start} };
    my $found;
    for my $n (@next) {
        for my $from_i (keys %{ $graph->{$start}{$n} }) {
            for my $to_i (keys %{ $graph->{$start}{$n}{$from_i} }) {
                delete $graph->{$start}{$n}{$from_i}{$to_i};
                path($n, $graph, [ @$path, "$start:$from_i $n:$to_i" ]);
                $found = 1;
                undef $graph->{$start}{$n}{$from_i}{$to_i};
            }
        }
    }
    print "@$path\n" unless $found;
}


my %connections = (
                   'a1:1' => 'b1:1',
                   'b1:2' => 'b2:1',
                   'b2:4' => 'a6:1',
                   'a1:5' => 'b5:1',
                   'a1:7' => 'b5:2',
                   'b5:6' => 'a2:1',
                   'b5:7' => 'a2:2',
                  );

my %graph;
while (my ($from, $to) = each %connections) {
    my ($from_r, $from_i) = split /:/, $from;
    my ($to_r, $to_i)     = split /:/, $to;
    undef $graph{$from_r}{$to_r}{$from_i}{$to_i};
}
path('a1', \%graph, []);

答案 1 :(得分:0)

使用Graph。具体而言,transitive closure