我有一个可以跳跃的迷宫:
0场 1壁 S-启动 E-端
A,B,C - 跳跃的可能性。当你输入带有这个字母的字段时,你会跳到其他具有相同字母的字段(在迷宫中只有两个这样的字段有一个字母(两个As,两个B,两个C)。
当你从A跳到第二个A时 - 你必须总是更进一步(你不能回到跳跃场,而不能移动到至少另一个场)。
示例迷宫:
1 1 E
A 1 0
S 1 A
从开始S到结束E的路径是(kartezian):( 0,0)(0,1)(2,0)(2,1)(2,2)
另一个例子:
A 0 B S
0 1 0 1
0 B 0 1
0 0 A E
输出应为(3,3)(2,3)(1,1)(0,1)(0,2)(0,3)(2,0)(3,0)
我使用BFS algorhitm它适用于正常的迷宫。但是无法想出如何正确添加跳跃可能性。我当前的伪代码(它适用于第一个示例,但在第二个示例中失败):
parents[points]; //array of parents
visited[points]; //array describing whether node was already visited
Que q;
q.put(startPoint);
while(!q.isEmpty)
{
point = q.pop();
if(CanJumpFromThisField(point))
{
jump = getJumpCoordinates(point);
if(parents[point] != jump)
continue;
}
for(allNeighbours(point)) //neighbour is field from left, righ, top, bottom
{
if(neighbour.val != 1)
{
if(!CanJumpFromThisField(neighbour))
{
if(!visited(neighbour))
{
visited(neighbour) = true;
parents(neighbour) = point;
q.put(neighbour);
}
}
else
{
jump = getJumpCoordinates(neighbour);
if(!visited(jump))
{
parents(neighbour) = point;
visited(neighbour)=true;
parents(jump)=neighbour;
visited(jump)=neighbour;
q.put(jump);
}
}
}
}
}
答案 0 :(得分:0)
1)不要从startPoint S到EndPoint E进行BFS,而是从E进行BFS直到你访问所有点。
2)将最短路径的长度从每个点存储到E
3)要找到路径,从S遍历,选择路径长度最小的邻居,并保持遍历直至到达E.
注意:跳跃点也应视为邻居
复杂性:O(sizeof(网格))
答案 1 :(得分:0)
将邻居和邻居视为“目的地”。引入一种新方法,该方法枚举给定点的所有可能目的地(即邻居和跳转目的地)。
有效邻居是不是墙的邻居(即!= 1
)。这将大大简化您的循环。
while(!q.isEmpty)
{
point = q.pop();
for(allDestinations(point)) //neighbours and jump destinations
{
if(!visited(neighbour))
{
visited(neighbour) = true;
parents(neighbour) = point;
q.put(neighbour);
}
}
}
allDestinations(point) returns list of points
{
result = allDestinations(point).where (p=>p.Value != 1);
if(CanJumpFromThisField(point))
{
jump = getJumpCoordinates(point);
if (jump != point)
result.add(jump);
}
}
同样,这是一些有趣的伪代码,但我认为你明白了。不要在一个方法或循环中加入太多逻辑。这让事情很难理解。
答案 2 :(得分:0)
BFS假设到达特定节点是相同的“成功”,尽管路径通向节点 - 这在您的问题中是不正确的。考虑你的4x4迷宫
A 0 B S
0 1 0 1
0 B 0 1
0 0 A E
当分析使B-B跳跃时,它从小区(1,1)向各个方向流动。它很快发现(2,0)并使A-A跳跃。然而,从A(0,3)向南的路径与从B(1,1)向西北方向的路径相遇,它们相互抵消。
问题在于使用迷宫的几何“相邻单元”关系作为BFS图中的过渡关系。在迷宫上面,单元格(2,1)和(1,0)都与(2,0)相邻,你可以制作步骤(1,0)(2,0)和( 2,0)(2,1)。但是,你不能去(1,0)(2,0)(2,1)路径,因为你输入(2,0)后就被迫跳转。
简单的解决方案是:对于每次跳转u-v
,从迷宫中删除单元格u
和v
(使其无法从相邻单元格中访问)以及每个x
相邻u
与y
相邻的每个v
向图表添加x-y
分支。
唉它只适用于没有相邻jupms的迷宫。例如这个修改
A 0 B S
0 1 0 1
0 1 0 1
0 B A E
使分析变得更加复杂。在这种情况下,您必须使用单向分支,例如仅允许x->u
,u->y
,y->v
和v->x
转换。或者从广度优先切换到深度优先搜索...