合并线性列表 - 重建铁路网

时间:2016-04-20 12:18:11

标签: algorithm list merge

我需要从任意站点请求的单次行程序列重建铁路网络中的站点序列。数据中没有给出方向。但是每个请求都会返回一个终点站。单次旅行的顺序可能有差距。 (end-)结果始终是线性列表 - 不允许分叉。

例如:

结果从请求的站点" 4" :

4 - 3 - 2 - 1 4 - 1 4 - 5 - 6 4 - 8 - 9 4 - 6 - 7 - 8 - 9

手动重新排序:

1 - 2 - 3 - 4 1 - 4 - 4 - 5 - 6 - 4 - 8 - 9 - 4 - 6 - 7 - 8 - 9

合并后的结果应为:

1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9

开始/停止:1,9

是否有算法来计算生成的珍珠绳#34;清单?我试图用perls graph-module弄清楚它,但没有运气。我的算法书也没有帮助。

我认为,存在病理情况,根据输入数据,可能存在多种解决方案。

也许有人有想法解决它!

正如您在答案中看到的,有多个解决方案。所以这是一个真实的数据集:

2204236 -> 2200007 -> 2200001
2204236 -> 2203095 -> 2203976 -> 2200225 -> 2200007 -> 2200001
2204236 -> 2204805 -> 2204813 -> 2204401 -> 2219633 -> 2204476 -> 2202024 -> 2202508 -> 2202110 -> 2202026
2204236 -> 2204813 -> 2204401 -> 2219633 -> 2202508 -> 2202110 -> 2202026 -> 3011047 -> 3011048 -> 3011049
2204236 -> 2204813 -> 2204401 -> 2219633 -> 2204476 -> 2202024 -> 2202508 -> 2202110 -> 2202352 -> 2202026
2204236 -> 2204813 -> 2204401 -> 2219633 -> 2204476 -> 2202024 -> 2202508 -> 2209637 -> 2202110

使用perl解决示例数据:

use Graph::Directed;
use Graph::Traversal::DFS;

my $g = Graph::Directed->new;

$g->add_path(1,2,3,4);
$g->add_path(1,4);
$g->add_path(4,5,6);
$g->add_path(4,8,9);
$g->add_path(4,6,7,8,9);

print "The graph is $g\n";
my @topo = $g->toposort;
print "g toposorted = @topo\n";

输出

> The graph is 1-2,1-4,2-3,3-4,4-5,4-6,4-8,5-6,6-7,7-8,8-9
> g toposorted = 1 2 3 4 5 6 7 8 9

使用其他方向

$g->add_path(4,3,2,1);
$g->add_path(4,1);
$g->add_path(4,5,6);
$g->add_path(4,8,9);
$g->add_path(4,6,7,8,9);

揭示第二个解决方案

The graph is 2-1,3-2,4-1,4-3,4-5,4-6,4-8,5-6,6-7,7-8,8-9
g toposorted = 4 3 2 1 5 6 7 8 9

2 个答案:

答案 0 :(得分:0)

处理图表中的列表节点链接。 4-3-2-1应该意味着4必须在3之前,3之前的2和之前的2之前。所以添加4到3,3到2,2到1的弧。 一旦你拥有了所有这些,你就可以在结果图上运行拓扑排序(在维基百科上查找)。这将保证您获得的订单始终尊重您的部分订单。

当您无法找到解决方案时,唯一的情况是数据自相矛盾(如果您有4-3-24-2-3则无法排序。

你是对的,有多种情况。对于您的示例,另一个好的解决方案是4-5-6-7-8-9-3-2-1

答案 1 :(得分:0)

终端站点是关节节点,它将图形分成多个分区:分区内的所有节点可以相互到达,不同分区中的节点只能通过已知的终端站点到达。在您的示例中,分区数为2,但可能更大,例如考虑星形结构1 - 2, 1 - 3, 1 - 4, 1 - 5

首先,您需要枚举分区。您将图形视为无向图,并在每个方向上从停止站运行DFS。首次运行时,您会发现分区#1,第二次运行分区#2,依此类推。

然后按照停止站的指示将图表视为所有分区的根节点,并为每个分区运行拓扑排序(TS)。

可能的结果:

  1. 其中一个分区的TS失败。这意味着没有解决方案。
  2. 分区数为1,TS成功。解决方案是独一无二的。
  3. 分区数量多于一个,TS对所有分区都成功。这意味着有多种解决方案。要获得任何单个有效结果,请选择一些分区并声明它包含另一个终端站。所有其他分区都插入到任意节点对之间的第一个分区中。