确保部分连接的有向图连接牢固

时间:2014-03-11 00:34:54

标签: c# algorithm unity3d procedural-generation

上下文

我正在使用程序生成来构建3D游戏。我试图连接一些预先生成的房间,无论如何,玩家总能到达地图中的任何其他房间。房间有“可能的入口点”,连接走廊必须连接。但是,并非所有入口点都可以从房间内的所有其他入口点到达。例如,可能存在陷阱,因此底部的玩家将无法穿过房间到达顶部,并且必须找到另一种方式。

问题

给定嵌入在3d空间中的一组预先存在的有向图,添加一组最小总长度的(双向)路径,将子图连接成更大的图。如果失败(因为some research表示这是NP-Hard),使路径尽可能短,以便在很短的时间内计算。

到目前为止工作

我最好的解决方案基于this procedural generation post,在那里他创建了所有节点的Delaney三角剖分。我将房间的每个强连通组件(例如,陷阱的顶层和底层)视为单独的节点,并构建MST,但这限制了一些更有趣的可能性(例如,必须通过两条单向路径回到你开始的地方。)


有谁知道解决这个问题的更好方法?

2 个答案:

答案 0 :(得分:1)

也许您可以更好地利用您对3D空间进行建模的事实。这意味着您可以将问题划分为一组平面图,每个图表代表不同的楼层。您可以从建立每个楼层开始强烈连接。然后当你加入地板(可能只有几个楼梯和陷阱)时,通过移除一些边缘扰乱解决方案,同时仍保持整体强连通图。边缘移除的有趣选择将是导致地板本身失去强连通性但在考虑其他楼层时保持性能的选择。这些被称为桥梁,有一个linear algorithm for finding them

如果你只计算边缘而不是它们的长度,孤立地求解平面图(地板)会将其转换为多个Euclidean Steiner tree problems,虽然仍然是NP难的,但可以使用{{3}来解决}。但是,您提到您希望最小化路径的总长度,这使其成为near-optimal polynomial-time approximation scheme。由于其适用于电路设计,已经在这个问题上做了很多rectilinear Steiner tree problem。存在的近似值可以在最佳值的1.5倍之内,这可能对您正在进行的操作更有效:走廊稍长而不是一个地方的所有入口。

答案 1 :(得分:0)

这个问题的嵌入部分使它变得非常糟糕,所以我假设我们估计连接成本以获得有向图,我们想要一个最小成本的强连接弧 - 子图。然后使用贪婪算法找到嵌入。

对于多项式时间的2近似解:选择任意根顶点,然后使用the algorithm due to Chu--Liu and also Edmonds计算最小成本的向北和向向跨越的树状。归还这些的结合。这是一个2近似,因为每个强连通弧 - 子图包含向北和向向跨越的树枝(虽然不一定是最低成本)。我现在从你的一个链接中看到Keith Randall也有这个想法。

您可以实施任何数量的启发式方法。他们可能工作得很好,但他们对我并不感兴趣。如果你担心他们表现得很糟糕,那么你可以"支持"他们使用前面提到的2近似值。

如果您真的想要一个最佳解决方案,那么您最好的选择可能是整数编程。配方为整数程序,这个问题与TSP有一些相似之处。 TSP的程序看起来像这样。

minimize sum_{v -> w} cost(v -> w) x(v -> w)
subject to
(-) for all v, sum_{v -> w} x(v -> w) = 1
(-) for all w, sum_{v -> w} x(v -> w) = 1
for all subsets S of vertices, sum_{v -> w, v in S, w not in S} x(v -> w) >= 1
for all v -> w, x(v -> w) >= 0

对于你的问题的程序,我们放弃标记为(-)的约束,这会强制选择的弧线作为巡视。

minimize sum_{v -> w} cost(v -> w) x(v -> w)
subject to
for all subsets S of vertices, sum_{v -> w, v in S, w not in S} x(v -> w) >= 1
for all v -> w, x(v -> w) >= 0

该计划的双重性如下。

maximize sum_{subsets S of vertices} y(S)
subject to
for all v -> w, sum_{subsets S of vertices, v in S, w not in S} y(S) <= cost(v -> w)
for all subsets S of vertices, y(S) >= 0

现在我们可以调整TSP的分支和绑定解决方案,为此应该有大量的教程资料。你不必从根本上做任何新的事情;实际上,您可以专注于生成子区约束/变量,因为梳子不等式等不适用于此问题。