You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何gdistance::shortestPath未生成直线?常数成本下最小成本路径计算异常排查

修正gdistance最短路径计算的问题,得到预期直线路径

我来帮你分析代码里的问题,以及如何调整来得到常数成本下的直线最短路径:

核心错误点

  1. 过渡函数逻辑不符合需求
    你写的speed <- function(x){1/(x[2]+x[1])}并不是真正的"常数通行成本"逻辑。在gdistance的transition函数中,transitionFunction的输入x是当前单元格和相邻单元格的成本值组成的向量。当所有单元格值为1时,这个函数会返回0.5,让所有方向(水平/垂直/对角线)的移动成本完全一致,但实际上对角线移动的距离是水平/垂直的√2倍,若成本为常数,移动成本应该和距离成正比,而非固定值。

  2. 重复地理校正+冗余代码
    你已经对trraster执行了geoCorrection(trraster, scl=FALSE),后续又复制过渡矩阵并再次执行geoCorrection(speed, scl=FALSE),这会让过渡矩阵的权重被错误地二次校正,破坏了原本的距离关系。另外,adj <- adjacent(...)到speed[adj] <-trraster[adj]这段代码完全没用,属于冗余操作,还增加了出错概率。

修正后的代码

如果要模拟"所有单元格通行成本为常数"的场景,我们需要让移动成本和实际地理距离挂钩(此时总成本等价于总距离,最短路径就是直线)。修正后的代码如下:

library(gdistance)

# 创建栅格,所有单元格赋值为1(代表常数通行成本)
raster <- raster(ymn = 35.6, ymx = 35.76, xmx = 139.9, xmn = 139.6, res = 0.001)
raster[] <- 1

# 创建过渡矩阵:用function(x)1表示基础成本为1,directions=8开启8方向移动
trraster <- transition(raster, transitionFunction = function(x) 1, directions = 8)

# 地理校正:将过渡权重调整为实际地理距离,scl=FALSE表示不缩放权重
trraster <- geoCorrection(trraster, scl = FALSE)

# 定义起点和终点(坐标顺序为lon, lat)
origin <- c(139.7761, 35.7136)
goal <- c(139.7582, 35.66639)

# 计算最短路径
path <- shortestPath(trraster, origin, goal, output = "SpatialLines")

# 可视化结果
plot(raster(trraster))
lines(path, col = "darkred", lwd = 2)

代码说明

  • 过渡函数:function(x)1设定每个单元格的基础通行成本为1,后续geoCorrection会自动根据单元格间的距离(水平/垂直是单元格分辨率,对角线是√2倍分辨率)调整过渡权重,保证成本与距离成正比。
  • 单次地理校正:只执行一次geoCorrection,确保权重准确反映真实的移动成本差异。
  • 移除冗余代码:删掉了无意义的过渡矩阵复制和相邻单元格操作,简化代码逻辑。

运行这段代码后,你就能得到预期的直线最短路径了,因为此时路径的总成本等价于总地理距离,最短路径就是欧几里得直线。

内容的提问来源于stack exchange,提问作者junichiyamasaki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 06:47:51