用最小距离将矩阵中的两个坐标连接起来

9
我正在处理一个基于两个坐标的矩阵完成过程(我不确定术语是否正确),考虑最小距离,让我解释一下。
我有一个nxm(行和列)的矩阵,其中包含NA值和1,如图1所示:

enter image description here

目标是:
  1. 找到由距离等于1(水平和垂直相邻)或1.4142(对角线相邻)连接的连续元素的端点。在示例中,极端坐标由图中的矩形表示。
  2. 确定了极端坐标后,需要完成描述两点之间“最小距离”的坐标。(由图1中的线表示)
假设我已经找到了极端坐标(ab见图2),我试图使用一条线的向量方程式:

enter image description here

我正在尝试创建一个函数,该函数使用极值(a和b)和常数k(见图2)

completa <- function(a, b, k){
  x <- y <- NULL
  resta <- b - a
  u_ba <- resta / sqrt(sum(resta^2))
  for (i in seq(0, 1, k)) {
    posi <- a + i * u_ba
    x <- c(x, posi[1])
    y <- c(y, posi[2])
  }
  coordenadas  <- round(cbind(x, y))
  return(coordenadas)
}

示例矩阵在:

data_mat <- read.csv("https://www.dropbox.com/s/hz42scjuf9uib9y/data_test.csv?dl=1")
a <- c(25, 6)
b <- c(20, 10)

使用具有坐标a、b和k = 0.5的函数(k的值可以在0到1之间变化),将得到以下结果:
completa(a,b,0.5)
#      x y
#[1,] 25 6
#[2,] 25 6
#[3,] 24 7

但是预期输出是:
#      x y
#[1,] 25 6
#[2,] 24 7
#[3,] 23 8
#[4,] 22 9
#[5,] 21 10 # or 21 9,  
#[6,] 20 10

很明显,这条线有不止一种解决方案,因此建议优先考虑最小距离。最后,得到这些坐标后,只需将它们赋值为1即可。主要思路是使该过程递归,并最终将矩阵的所有坐标连接起来。欢迎提出任何建议,谢谢。

2
听起来像是“最短路径问题”,也许igraph包可能会有用。 - zx8754
感谢大家。这三个答案帮助我加入了矩阵的两个坐标的过程。 请问有什么建议可以自动找到矩阵中每组相邻元素的极限坐标(图1中的矩形)吗? 我有一个想法,可以使用距离等于1或*sqrt(2)*将它们聚类,但是当一组坐标有多个极值时,我遇到了问题。 - rral
3个回答

1
据我所见,你遇到了一个数学问题。如果我理解正确的话,你想要“击中”在你的极限坐标之间的方块,以建立你的两个聚类之间的桥梁。你在for循环中犯了错误。在循环末尾,你只添加了ab单位向量1次,因此你只在网格上行进了1的距离。 我已经纠正了你的代码,使它可以完整地行进。希望这解决了你的问题。
completa <- function(a, b, k){
  if(k!=0){
    x <- y <- NULL
    resta <- b - a
    vector_length = sqrt(sum(resta^2))        
    for (i in seq(0, 1, length.out=(vector_length/k))) {
      posi <- a + i * resta
      x <- c(x, posi[1])
      y <- c(y, posi[2])
    }
    coordenadas  <- round(cbind(x, y))
    coordenadas <- unique(coordenadas[,1:2])
  }
if(k==0) coordenadas = a
return(coordenadas)
}

结果是。
 > completa(a,b,0.5)
         x  y
   [1,] 25  6
   [2,] 24  7
   [3,] 23  7
   [4,] 23  8
   [5,] 22  8
   [6,] 22  9
   [7,] 21  9
   [8,] 20 10

1
为什么不直接在确定的极值点之间使用线性逼近,并四舍五入数值...
> x_12 <- c(25, 20)
> y_12 <- c(6, 10)
> do.call(cbind, lapply(approx(x_12, y_12, xout = seq(x_12[1], x_12[2], ifelse(x_12[1]>x_12[2], -1, 1))), round))
     x  y
[1,] 25 6
[2,] 24 7
[3,] 23 8
[4,] 22 8
[5,] 21 9
[6,] 20 10

1
也许你可以尝试像下面这样的东西。
x <- seq(a[1],b[1])
y <- seq(a[2],b[2])
if (length(x) >= length(y)) {
  y <- c(y,rep(tail(y,1),length(x)-length(y)))
} else {
  x <- c(x,rep(tail(x,1),length(y)-length(x)))
}

such that

> cbind(x,y)
      x  y
[1,] 25  6
[2,] 24  7
[3,] 23  8
[4,] 22  9
[5,] 21 10
[6,] 20 10

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接