如果将游戏地图划分为子图,如何最小化子图之间的边缘?
我有一个问题,我正在尝试在基于网格的游戏(如吃豆人或推箱子)中进行A*搜索,但我需要找到“围栏”。什么是围栏?子图,其顶点数量符合软约束条件的最大值和最小值,且具有尽可能少的割边。
或者你可以说我正在寻找子图之间的桥梁,但这通常是同样的问题。
例子
基于网格的游戏地图示例 http://dl.dropbox.com/u/1029671/map1.jpg
给定一个看起来像这样的游戏,我的目标是找到封闭区域,以便我可以正确地找到它们的入口,从而得到进入这些封闭区域内部顶点的良好启发式。
替代文本 http://dl.dropbox.com/u/1029671/map.jpg
所以我想要在任何给定的地图上找到这些着色区域。
我的动机
我这样做的原因并不仅仅是满足一个简单曼哈顿距离启发式算法的表现,因为一个封闭启发式算法可以给出更优的结果,而且我不必实际进行A*算法来得到一些适当的距离计算。在玩推箱子类型游戏时,还可以添加对手阻塞在这些围栏内的竞争性阻塞。此外,封闭启发式算法可以用于更恰当地找到目标顶点的极小化方法。
可能的解决方案
问题的一个可能解决方案是Kernighan Lin算法:
function Kernighan-Lin(G(V,E)):
determine a balanced initial partition of the nodes into sets A and B
do
A1 := A; B1 := B
compute D values for all a in A1 and b in B1
for (i := 1 to |V|/2)
find a[i] from A1 and b[i] from B1, such that g[i] = D[a[i]] + D[b[i]] - 2*c[a][b] is maximal
move a[i] to B1 and b[i] to A1
remove a[i] and b[i] from further consideration in this pass
update D values for the elements of A1 = A1 / a[i] and B1 = B1 / b[i]
end for
find k which maximizes g_max, the sum of g[1],...,g[k]
if (g_max > 0) then
Exchange a[1],a[2],...,a[k] with b[1],b[2],...,b[k]
until (g_max <= 0)
return G(V,E)
我的问题是这个算法的运行时间为O(n^2 * lg(n)),我正在考虑将A1和B1中的节点限制在每个子图的边界上,以减少工作量。
我也不理解算法中的c[a][b]成本,如果a和b之间没有边,成本是否被假定为0或无穷大,或者应该基于某些启发式方法创建一条边。
当a和b之间没有边时,你知道c[a][b]应该是什么吗? 你认为我的问题适合使用多级方法吗?为什么或为什么不? 你有没有好的想法来减少kernighan-lin算法对我的问题所需的工作量?