如何使用perl处理图论相关问题

时间:2014-11-05 09:40:41

标签: perl graph graph-theory

我想学习如何在不使用任何额外模块的情况下解决perl中的简单图论问题 我可以解释一个简单的问题。

输入格式:
第1行 - 图-N的顶点数。
接下来的N行 - 顶点索引,直接连接到索引为i的顶点。指数从1开始 终点索引(空格)终点索引,找到最长路径。

示例

4  
2 3 4  
1  
1 4  
1 3  
2 4

解决方案:

2 to 4 can be reached in following ways  
- 2-1-4  
- 2-1-3-4  
so longest path is 2-1-3-4

我想学习使用perl解决此类问题的基础知识。任何帮助将受到高度赞赏。给我一个提示,我会尝试编码。

1 个答案:

答案 0 :(得分:3)

我使用散列哈希来表示图形。如果边缘$graph{$v1}{$v2}位于图表中,则v1-v2存在。您可以通过这种方式表示有向图(因为$graph{$v2}{$v1}不必存在)。此外,如果您想要加权边,您可以将权重存储为值。

要解决您的示例问题,请使用以下内容:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

# Check that vertex can be added to the path.
sub already {
    my ($vertex, @vertices) = @_;
    for my $i (1 .. $#vertices) {
        # last-v or v-last might already be present.
        return 1 if ($vertices[ $i - 1 ] == $vertices[-1] and $vertices[$i] == $vertex)
                 or ($vertices[ $i - 1 ] == $vertex and $vertices[$i] == $vertices[-1])
    }
    return
}

sub path {
    my ($graph, $start, $end, %known) = @_;

    my $count = keys %known;
    for my $path (keys %known) {
        my @vertices = split '-', $path;
        next if $vertices[-1] == $end;

        for my $target (keys %{ $graph->{ $vertices[-1] } }) {
            undef $known{"$path-$target"} unless already($target, @vertices);
        }
    }

    if (keys %known > $count) {
        return path($graph, $start, $end, %known)

    } else {
        return keys %known
    }
}


my %graph;

my $size = <>;
for my $node (1 .. $size) {
    my @targets = split ' ', <>;
    undef $graph{$node}{$_} for @targets;
}
my ($start, $end) = split ' ', <>;

say "$start to $end can be reached in the following ways";
my @paths = grep /-$end$/,
            path(\%graph, $start, $end, map {; "$start-$_" => undef }
                                            keys %{ $graph{$start} });

say for @paths;

my $max = 0;
for my $i (1 .. $#paths) {
    $max = $i if ($paths[$i] =~ tr/-//) > ($paths[$max] =~ tr/-//);
}

say "so longest path is $paths[$max]";