简体   繁体   English

我如何在迷宫中获得最短的路线?

[英]How do I get the shortest route in a labyrinth?

I want to make a code giving the shortest route when given a labyrinth as a matrix. 我想制作一个代码,给出一个迷宫作为矩阵的最短路径。

在此输入图像描述

In this case, the matrix representation of this labyrinth is as follows. 在这种情况下,该迷宫的矩阵表示如下。

## [,1] [,2] [,3] [,4]
## [1,] 2 0 0 0
## [2,] 1 1 0 1
## [3,] 0 1 0 0
## [4,] 1 1 1 3
 , where  0 denotes inaccessible points, 1 denotes accessible points.
          2 denotes the starting point, and 3 denotes the destination.

And, the desired result is this : c(4,1,4,4,1,1) , where 1 denotes East, 2 denotes North, 3 denotes West, and 4 denotes South. 并且,期望的结果是: c(4,1,4,4,1,1) ,其中1表示东,2表示北,3表示西,4表示南。

I guess that one possible code might be a function giving the shortest route as a vector when it is given the matrix representation of a labyrinth. 我猜一个可能的代码可能是一个函数,当给出迷宫的矩阵表示时,它将最短路径作为向量。

In addition to this case, I want to know if the coverage could be extended to general cases, though it seems rather redundant. 除了这种情况,我想知道覆盖范围是否可以扩展到一般情况,尽管它似乎相当多余。 I would like to know whether a desirable code can be made so that it covers arbitrary n by m size matrix, although just 4 by 4 case suffices. 我想知道是否可以制作一个理想的代码,以便它覆盖任意n×m尺寸的矩阵,尽管只有4乘4的情况就足够了。 And I wonder if the start point and the destination could be located at arbitrary points other than vertices, though vertices case is sufficient. 我想知道起点和目的地是否可以位于除顶点之外的任意点,尽管顶点情况就足够了。

You could construct a graph to represent the valid moves between positions in the matrix: 您可以构造一个图表来表示矩阵中位置之间的有效移动:

# Construct nodes and edges from matrix
(nodes <- which(m == 1 | m == 2 | m == 3, arr.ind=TRUE))
#       row col
#  [1,]   1   1
#  [2,]   2   1
#  [3,]   4   1
#  [4,]   2   2
#  [5,]   3   2
#  [6,]   4   2
#  [7,]   4   3
#  [8,]   2   4
#  [9,]   4   4
edges <- which(outer(seq_len(nrow(nodes)),seq_len(nrow(nodes)), function(x, y) abs(nodes[x,"row"] - nodes[y,"row"]) + abs(nodes[x,"col"] - nodes[y,"col"]) == 1), arr.ind=T)
(edges <- edges[edges[,"col"] > edges[,"row"],])
#      row col
# [1,]   1   2
# [2,]   2   4
# [3,]   4   5
# [4,]   3   6
# [5,]   5   6
# [6,]   6   7
# [7,]   7   9

library(igraph)
g <- graph.data.frame(edges, directed=FALSE, vertices=seq_len(nrow(nodes)))

Then you could solve the shortest path problem between the specified start and end location: 然后,您可以解决指定的开始和结束位置之间的最短路径问题:

start.pos <- which(m == 2, arr.ind=TRUE)
start.node <- which(paste(nodes[,"row"], nodes[,"col"]) == paste(start.pos[,"row"], start.pos[,"col"]))
end.pos <- which(m == 3, arr.ind=TRUE)
end.node <- which(paste(nodes[,"row"], nodes[,"col"]) == paste(end.pos[,"row"], end.pos[,"col"]))
(sp <- nodes[get.shortest.paths(g, start.node, end.node)$vpath[[1]],])
#      row col
# [1,]   1   1
# [2,]   2   1
# [3,]   2   2
# [4,]   3   2
# [5,]   4   2
# [6,]   4   3
# [7,]   4   4

Finally, you could determine the direction (1: east; 2: north; 3: west; 4: south) as a simple manipulation of the final set of nodes selected: 最后,您可以确定方向(1:东; 2:北; 3:西; 4:南)作为所选最终节点集的简单操作:

dx <- diff(sp[,"col"])
dy <- -diff(sp[,"row"])
(dirs <- ifelse(dx == 1, 1, ifelse(dy == 1, 2, ifelse(dx == -1, 3, 4))))
# [1] 4 1 4 4 1 1

This code will work for arbitrarily sized input matrices. 此代码适用于任意大小的输入矩阵。

Data: 数据:

(m <- matrix(c(2, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 3), nrow=4))
#      [,1] [,2] [,3] [,4]
# [1,]    2    0    0    0
# [2,]    1    1    0    1
# [3,]    0    1    0    0
# [4,]    1    1    1    3

I'd likely use functions from the gdistance package, demonstrated in another setting here : 我可能会使用功能从gdistance包,在其他设置证实这里

library(gdistance) ## A package to "calculate distances and routes on geographic grids"

## Convert sample matrix to a spatial raster
m = matrix(c(2, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 3), nrow=4)
R <- raster(m)

## Convert start & end points to SpatialPoints objects
startPt <- SpatialPoints(xyFromCell(R, Which(R==2, cells=TRUE)))
endPt   <- SpatialPoints(xyFromCell(R, Which(R==3, cells=TRUE)))

## Find the shortest path between them
## (Note: gdistance requires that you 1st prepare a sparse "transition matrix"
##  whose values give the "conductance" of movement between pairs of cells)
tr1 <- transition(R, transitionFunction=mean, directions=4)
SPath <- shortestPath(tr1, startPt, endPt, output="SpatialLines")

## Extract your direction codes from the steps taken in getting from 
## one point to the other. 
## (Obfuscated, but it works. Use some other method if you prefer.)
steps <- sign(diff(coordinates(SPath)[[1]][[1]]))
(t(-steps)+c(2,3))[t(steps!=0)]
## [1] 4 1 4 4 1 1

## Graphical check that this works
plot(R>0)
plot(rBind(startPt, endPt), col=c("yellow", "orange"), pch=16, cex=2, add=TRUE)
plot(SPath, col="red", lwd=2, add=TRUE)

在此输入图像描述

One possibility consists in setting up a matrix with value 1 at the target and a decrease of the value at the rate of 0.9 for each square, as a function of the Manhattan distance from the destination. 一种可能性在于,在目标处设置值为1的矩阵,并且每个方格的值以0.9的速率减小,作为距离目的地的曼哈顿距离的函数。 The obstacles would have the value zero, the starting point is arbitrary. 障碍物的值为零,起点是任意的。

Once such a matrix is defined, the shortest path is obtained by iteratively going to the neighboring square with the largest increase in value. 一旦定义了这样的矩阵,就通过迭代地去到具有最大值增加的相邻正方形来获得最短路径。

This method is described, eg, in the first chapter of the book "Statistical Reinforcement Learning" by M. Sugiyama. 例如,在M. Sugiyama的书“统计强化学习”的第一章中描述了该方法。

So your matrix could look like this: 所以你的矩阵看起来像这样:

     [,1]  [,2]  [,3] [,4]
[1,] 0.53  0.00  0.0  0.00
[2,] 0.59  0.66  0.0  0.81
[3,] 0.00  0.73  0.0  0.00
[4,] 0.73  0.81  0.9  1.00

And the algorithm would be: 算法将是:

  • Choose a starting square with non-zero value 选择非零值的起始方块
  • Move to the square that has the highest value among those squares that are one step away from you. 移动到距离您一步之遥的广场中具有最高价值的广场。
  • Repeat the previous step until you reach the square with value 1 重复上一步,直到达到值为1的方块

Note that the value [2,4] is de facto not accessible and should therefore be excluded as a possible starting point. 请注意,值[2,4] 事实上是不可访问的,因此应排除作为可能的起点。 The destination does not need to be at a corner. 目的地不需要在拐角处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM