我需要一些帮助来识别这个问题并找到解决方案。我不需要有人来编写解决方案,只是说如何解决它。
哈希数组,每个哈希包含一个路径,其ID及其顺序(前向(F)或反向(R))
每条路径都在F位置初始化
my @paths = (
{ id => 1, path => [ A, B ], order => 'F' },
{ id => 2, path => [ C, D, E ], order => 'F' },
{ id => 3, path => [ E, B ], order => 'F' }
);
每个路径的每个节点或顶点也有一个方向(+或 - )
my %plus_minus;
$plus_minus{1}{A} = '+';
$plus_minus{1}{B} = '+';
$plus_minus{2}{C} = '+';
$plus_minus{2}{D} = '-';
$plus_minus{2}{E} = '-';
$plus_minus{3}{E} = '-';
$plus_minus{3}{B} = '-';
您可以反转路径的顺序(例如,[A,B]到[B,A]) 当您从F =>逆转订单时R或R => F您还可以将路径中每个节点的方向从+切换到 - 或 - 到+
方向的路径如下所示:
A +:B +
C +:D-:E -
E-:B-
这是问题输入
对于输出,我想知道是否可以通过反转路径顺序来创建共识路径,以及执行此操作的方式是什么,以确保您找到共识路径。
例如,如果我们颠倒路径1,我们会得到:
和由此产生的共识路径是:
C +:D-:E-:B-:A-
但目前尚不清楚首先反转路径1。例如,如果我们首先反转3怎么办?所以你不能随意进行。
有没有人认识到这个问题或知道如何解决它?
答案 0 :(得分:1)
您所要求的并不容易,而且我对您的要求并不十分清楚
这种局部解决方案采用蛮力方法创建有向图,添加数据及其反转的所有路径,并在结果数据结构中找到最长路径
使用您的示例数据,它会生成您期望的共识路径的 反向 ,但根据您的规则,将始终存在如果有任何两个同样有效的答案,并且由于Perl哈希的随机性,任何一个都可以作为从一次运行到下一次运行的结果呈现
如果我理解正确,那么您还需要确保结果包含原始数据中的所有路径
use strict;
use warnings 'all';
use feature 'say';
use Graph::Directed;
use List::Util 'max';
use List::MoreUtils 'first_index';
my @paths = (
{ id => 1, path => [ qw[ A B ] ], order => 'F' },
{ id => 2, path => [ qw[ C D E ] ], order => 'F' },
{ id => 3, path => [ qw[ E B ] ], order => 'F' },
);
my %plus_minus;
$plus_minus{1}{A} = '+';
$plus_minus{1}{B} = '+';
$plus_minus{2}{C} = '+';
$plus_minus{2}{D} = '-';
$plus_minus{2}{E} = '-';
$plus_minus{3}{E} = '-';
$plus_minus{3}{B} = '-';
# index the array by ID
#
my %paths;
$paths{$_->{id}} = $_ for @paths;
# Incorporate the inexplicably separate plus-minus data
#
for my $id ( keys %plus_minus ) {
my $nodes = $plus_minus{$id};
for my $node ( keys %$nodes ) {
my $sign = $nodes->{$node};
my $nodes = $paths{$id}{path};
my $i = first_index { $_ eq $node } @$nodes;
die sprintf "Node $node not found in path ID $id" if $i < 0;
$nodes->[$i] .= $sign;
}
}
# Add the reverse paths to the hash:
# - Change the `order` field to `R` (original is reliably `F`)
# - Reverse the order of the elements of `path`
# - Reverse the sign of the elements of `path`
#
my $n = max map { $_->{id} } values %paths;
for my $path ( @paths ) {
my $nodes = $path->{path};
my $new_id = ++$n;
$paths{$new_id} = {
id => $new_id,
order => 'R',
path => [
map {
s/([+-])/ $1 eq '+' ? '-' : '+' /er or die;
} reverse @$nodes
],
};
}
# Build the directed graph
#
my $g = Graph::Directed->new;
for my $path ( values %paths ) {
my $nodes = $path->{path};
for my $i ( 0 .. $#$nodes - 1 ) {
$g->add_edge(@{$nodes}[$i, $i+1]);
}
}
# Report the longest path
#
say join ' : ', $g->longest_path;
C+ : D- : E- : B- : A-