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

Algorithm 合并线性列表-重建铁路网,algorithm,list,merge,Algorithm,List,Merge,我需要从任意车站请求的单次行程序列重建铁路网络中的车站序列。数据中没有给出方向。但每个请求都返回一个终端停止。单个行程的顺序可能有间隙。 (最终)结果始终是线性列表-不允许分叉 例如: 请求站“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

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

例如:

请求站“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

是否有一个算法来计算得到的“珍珠绳”列表?我试图用perls图形模块来解决这个问题,但没有成功。我关于算法的书也没用

我认为,有些病理病例,根据输入数据,可能有多种解决方案

也许有人有办法解决它

正如你在答案中看到的,有不止一种解决方案。这是一个真实的数据集:

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

处理图中的列表节点链接<代码>4-3-2-1应表示4必须在3之前,3必须在2之前,2必须在1之前。因此,将圆弧从4添加到3,3添加到2,2添加到1。 一旦你有了所有这些,你就可以对结果图进行拓扑排序(在维基百科上查找)。这将保证您得到的订单将始终尊重您得到的部分订单

无法找到解决方案的唯一情况是数据本身矛盾(如果您有
4-3-2
4-2-3
则不可能排序)


你说得对,有很多案例。另一个好的解决方案是
4-5-6-7-8-9-3-2-1
,例如。

终端停止站是铰接节点,它将图形拆分为多个分区:分区内的所有节点都可以彼此访问,不同分区中的节点只能通过已知的终端停止站访问。在示例中,分区的数目是2,但可能大得多,例如考虑星形结构<代码> 1 - 2, 1 - 3, 1 - 4, 1 - 5 < /代码> .< 首先,您需要枚举分区。您将图形视为无向图形,并在每个方向上从停止站运行DFS。第一次运行时发现分区#1,第二次运行时发现分区#2,依此类推

然后,您将图形视为所有分区的根节点,并对每个分区运行拓扑排序(TS)

可能的结果:

  • 其中一个分区的TS失败。这意味着没有解决办法
  • 分区数为1,TS成功。解决方案是独一无二的
  • 分区数不止一个,并且TS对所有分区都成功。这意味着有多种解决方案。要获得任何一个有效的结果,您可以选择某个分区并声明它包含另一个终端站。所有其他分区都插入到任意一对节点之间的第一个分区中

  • 4-5-6-7-8-9-3-2-1也是一个解决方案。为什么这是一个解决方案?9和3之间没有连接。9只与8相连。我对您的问题的理解是,您需要找到这样的电台列表,其中每个给定的列表都是一个子列表。您和我的解决方案都拥有此属性。否则,我不理解“连接”这个词。哦,好吧,现在我有了。所以在这个例子中没有单一的解决方案。如果我在完整的图上运行拓扑搜索,我会得到一个错误,因为图中有循环。@MPH,那么就没有解决方案。除非你在图形构造上有错误。好的,现在它可以工作了!图表必须有方向性。那么,在图中就没有循环,拓扑排序就可以工作了。