您可以构建一个图表来表示矩阵中位置之间的有效移动:
# 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)))
然后就可以解决指定起始位置和结束位置之间的最短路径问题:
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
最后,您可以通过对最终选定的节点集进行简单操作来确定方向(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
该代码适用于任意大小的输入矩阵。
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