寻找Sling Blade Runner拼图中最长的路径

时间:2014-10-05 23:38:37

标签: algorithm scala longest-path

我已经尝试解决一个存档的ITA Software谜题,称为Sling Blade Runner几天了。这个难题的要点如下:

  

"一连串重叠的电影片头,如Sling Blade   赛跑者,你能找到吗?"

     

使用以下电影片段列表:MOVIES.TXT。多字   重叠,如在"杀死一只知更鸟的许可证中,"被允许。相同   标题在解决方案中不得使用多次。启发式   解决方案可能并不总能产生最多的标题   将被接受:寻求合理的效率和权衡   最优性。

     

文件MOVIES.TXT包含6561个按字母顺序排列的电影片段   顺序。

我尝试解决方案有几个部分。

图表构建:

我所做的是将每个电影标题映射到它可以链接到的所有其他电影标题(在它右边)。由于我的图表是Map[String, List[String]],我最终得到的结果。您可以看到使用此流程构建的图表here

图形遍历:

我使用每个节点(地图中的每个键)作为搜索的起始节点进行深度优先搜索。我一直跟踪搜索过程中每个节点的访问深度,并在DFS返回的节点中标记。我最终得到的是List[List[Node]],其中列表中的每个List[Node]都是来自特定搜索的DFS树。

找到最长的链:

我在上一步中获取了所有图遍历的结果,并且对于每个List[Node],我按照深度值对列表进行了排序,我先前按降序标记了节点。然后从列表的头部开始(这给了我在DFS中访问的最深的节点),我回溯了节点以构建链。这给了我一个List[List[String]],其中List中的每个List[String]都是该特定DFS的最长链。按List[List[String]]的大小对List[String]进行排序并抓住头部然后给了我最大的链条。

结果:

我的算法找到的最长链是217个标题长。可以查看输出here

我只能通过谷歌搜索找到其他一些尝试,似乎所有其他尝试都产生了比我能够完成的链更长的链。例如this post表示Eric Burke发现链长245个标题,而a user by the name of icefox on Reddit发现了一个长达312个标题的链。

我无法想到我的算法无法找到最长链的位置,因为其他人发现了更长的链。非常感谢任何帮助/指导。如果您想查看我的代码,可以找到它here(它是用Scala编写的,我刚刚开始学习Scala,如果我犯了一些noob错误,请原谅我。)

更新

我对我的算法进行了一些更改,现在可以找到长度为240+的链。见here

1 个答案:

答案 0 :(得分:1)

问题在于,由于电影图(我假设)有周期,无论你如何为周期的顶点指定深度,都存在一个深度不单调的子路径,因此不予考虑通过您的算法。 Sling Blade Runner是NP难的,因为我们不需要,因此没有已知的多项式时间策略可以在每个输入上产生最佳解决方案。

(Sling Blade Runner不是NP-hard最长路径问题,它指定没有重复顶点而不是没有重复弧的路径,但是从后者到前者有一个简单的多项式时间减少。将顶点v移动到v_in -> v_out,将弧头移动到顶点,将弧线移动到外顶点。从顶点到另一个源顶点创建额外的弧到顶点中的每个顶点,并从每个顶点到顶点接收器顶点到另一个接收器顶点。

要查找图表a->b, b->c, c->a, c->d上的最长路径,Sling Blade Runner的输入将为

s1->s2,
s2->a_in, s2->b_in, s2->c_in, s2->d_in,
a_in->a_out, b_in->b_out, c_in->c_out, d_in->d_out,
a_out->b_in, b_out->c_in, c_out->a_in, c_out->d_in,
a_out->t1, b_out->t1, c_out->t1, d_out->t1,
t1->t2.

最长的路径问题禁止重复顶点,因此最佳解决方案是a->b->c->d而不是c->a->b->c->d。 Sling Blade Runner中的相应链是s1->s2->a_in->a_out->b_in->b_out->c_in->c_out->d_in->d_out->t1->t2。具有重复顶点的路径的相应变换将重复弧c_in->c_out,因此对于Sling Blade Runner是不可行的。)

假设电影标题是

S A
S B
A B
A E
B C
C D
D A
E F

,以便图表看起来像

    F
    ^
    |
    E
    ^
    |
S-->A-->B<--
|   ^   |   \
|   |   v   |
|   D<--C   |
\___________/

我们从S启动DFS并获取以下树(因为我这样说;这不是唯一可能的DFS树)。

S-->A-->B-->C-->D
     \
      ->E-->F

。深度

S 0
A 1
B 2
C 3
D 4
E 2
F 3

,所以最长的单调路径是S A B C D。最长的路径是S B C D A E F。如果您在其他地方启动DFS,那么您甚至不会为S分配深度。

一个更简单的例子是

A B
B C
C D
D A

,无论你从哪里开始,在循环中一直走的最佳路径都不是深度单调:A B C D AB C D A BC D A B C或{ {1}}。