Как я могу написать цикл for, который создает матрицу евклидовых расстояний между 50 различными точками?р - PullRequest
0 голосов
/ 25 сентября 2019

Я создал матрицу из 50 случайно сгенерированных (x, y) пар, и мне нужно превратить ее в матрицу, которая отображает расстояние от любой точки (в строках) до всех других точек (в столбцах),Это должно привести к диагонали 0 и быть матрицей 50 x 50 .

Я буду рассчитывать расстояния по формуле: enter image description here

Создание матрицы расстояний:

n = 50
x = round(runif(n)*1000)
y = round(runif(n)*1000)
coordinates = cbind(x,y)

head(coordinates)
       x   y
[1,] 266 478
[2,] 372 861
[3,] 573 438
[4,] 908 245
[5,] 202  71
[6,] 898  99

Я пробовал следующее, но, как вы увидите из вывода length(distances), количество элементов в расстояниях равноне 2500, как я ожидал.Кроме того, первый элемент расстояний - 445,4863 вместо 0, как я и надеялся.

distances = c()
for (i in 1:n)
  for (j in 1:n)
    distances[i] = sqrt((coordinates[j,2]-coordinates[i,2])^2 + (coordinates[j,1]-coordinates[i,1])^2)

length(distances)     #This should be 2500 elements long
[1] 50           

distances = matrix(distances, nrow=n, ncol=n)       

1 Ответ

1 голос
/ 25 сентября 2019

Проблема с вашим исходным кодом заключается в том, что вы сохраняете рассчитанное расстояние на каждой итерации до distances[i].Это означает, что для каждого значения i вы перезаписываете одну и ту же позицию для каждого значения j.Это можно исправить, рассчитав индекс, который учитывает как i, так и j:

distances = c()
for (i in 1:n) {
    for (j in 1:n) {
        distances[(i - 1) * n + j] = sqrt((coordinates[j,2]-coordinates[i,2])^2 +
                                          (coordinates[j,1]-coordinates[i,1])^2)
    }
}

Но , я бы не рекомендовал такой подход, как для циклов в Rочень медленные, когда есть векторизованные подходы.По крайней мере, вы должны предварительно выделить вектор расстояний, используя что-то вроде distances = numeric(n * n), потому что изменение вектора несколько раз в R происходит особенно медленно.

...