R 如何在迷宫中找到最短的路线?

R 如何在迷宫中找到最短的路线?,r,algorithm,path-finding,R,Algorithm,Path Finding,我想做一个代码,给出迷宫作为矩阵时的最短路径 在这种情况下,该迷宫的矩阵表示如下 ## [,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 denot

我想做一个代码,给出迷宫作为矩阵时的最短路径

在这种情况下,该迷宫的矩阵表示如下

## [,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.
期望的结果是:
c(4,1,4,4,1,1)
,其中1表示东,2表示北,3表示西,4表示南

我猜一个可能的代码可能是一个函数,当给定迷宫的矩阵表示时,它以向量的形式给出最短路径

除此之外,我想知道是否可以将保险范围扩大到一般情况,尽管这似乎是多余的。 我想知道是否可以制作一个理想的代码,使其覆盖任意的n×m大小的矩阵,尽管只有4×4的情况就足够了。
我想知道起点和终点是否可以位于顶点以外的任意点,尽管顶点的情况已经足够了

一种可能性是在目标位置设置一个值为1的矩阵,并根据曼哈顿距离目的地的函数,以每平方米0.9的速率减小该值。障碍物的值为零,起点是任意的

一旦定义了这样一个矩阵,最短路径就是通过迭代到值增加最大的相邻正方形来获得的

例如,在M.Sugiyama的《统计强化学习》一书的第一章中描述了这种方法

因此,您的矩阵可以如下所示:

     [,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
算法是:

  • 选择一个非零值的起始正方形
  • 移动到距离您一步远的正方形中具有最高值的正方形
  • 重复上一步,直到到达值为1的正方形

请注意,值
[2,4]
实际上是不可访问的,因此应作为可能的起点排除。目的地不需要位于拐角处。

您可以构建一个图形来表示矩阵中位置之间的有效移动:

# 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)))
#从矩阵构造节点和边

(节点我可能会使用包中的函数,在另一个设置中演示:

library(gdistance)##用于“计算地理网格上的距离和路线”的包
##将采样矩阵转换为空间光栅
m=矩阵(c(2,1,0,1,0,1,1,1,0,0,0,1,0,0,3),nrow=4)

R我不确定这是否是一个编程问题——在你开始思考如何编码之前,你需要先准备好搜索算法。我不确定矩阵是否是表示这个问题的合适数据结构。图形会更好。然后,你会遇到ILP/QP问题,你的目标是找到即使是两个顶点之间的距离相等的点。这不是一个正确答案的问题。有很多方法可以找到路径。检查:你需要决定哪种方法最适合你的数据。我想你可能正在寻找Dijkstra算法的实现。尽管我从未见过这样的输出Egraphs@stasg有大量的算法标签专门用于关于编程问题使用什么算法的问题。算法问题不一定是离题的。我也不理解这里“太宽”的接近投票——这可能用igraph在5行或更少的行中实现……算法的第2步是“移动到距离您一步远的正方形中具有最高值的正方形。“如何在具有相同值的相邻单元格之间进行选择?@RobertH无需选择在这种情况下,可以选择任意一个,只要它是最高值。如果两个单元格具有相同的值,则生成的路径将具有相同的长度。”(例如,先向左再向上转弯,而不是先向上再向左转弯)。感谢您的友好回答。在您的建议中,我想问一下,是否有可能将代码操纵为“f=函数(m){……}”形式的代码,其中m是迷宫的给定矩阵,因此每当给定任意4×4大小的矩阵m时,函数f就会以向量形式给出结果。我想问一下,是否可以不使用任何包而使用代码,这样我就可以在不使用任何包的情况下完成自给自足的代码。@kmee您只需添加谢谢你的回答。我觉得很难把所有问题都考虑进去,可能是因为我的经验不足。我会牢记在心。我想我应该花些时间发表问题,以免漏掉任何必要的条件。我可以允许吗?再次发布一个关于这个问题的问题,并附加条件?谢谢。@kmee此时您确实遇到了一个新的编码问题——您希望实现一个最短路径算法,而不是使用库中的算法。请注意,仅仅要求其他人为您实现这个算法可能是一个太宽泛的问题,很可能会被忽略被否决并关闭。最好自己尝试实现一个最短路径算法,如果在实现过程中遇到问题,就发布一个问题。好的,我自己会尝试。但我现在觉得R中的所有内容都非常模糊,我似乎不知道在几乎所有的例子中该做什么,就像一个学生在学习m时感到苦恼一样在大学里第一次做无神论分析。这只是一个孩子气的抱怨,所以别理它。谢谢。
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
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
(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
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)