Ваше разъяснение вопроса указывает на то, что вы хотите, чтобы кластеризация основывалась на фактических отрезках линии , в том смысле, что любые две пары отправления-назначения (OD) следует рассматривать как «близкие», когда оба источника близки, а оба получателя близки. , независимо от того, какой момент считается происхождения или назначения .
Эта формулировка предполагает, что у вас уже есть ощущение расстояния d между двумя точками: это может быть расстояние, когда самолет летит, расстояние на карте, время в пути туда и обратно или любая другая метрика, которая не изменяется, когда O и D переключился. Единственное осложнение состоит в том, что сегменты не имеют уникальных представлений: они соответствуют неупорядоченным парам {O, D}, но должны быть представлены как упорядоченные пары, (O, D) или (D, O). Поэтому мы можем принять расстояние между двумя упорядоченными парами (O1, D1) и (O2, D2) за некоторую симметричную комбинацию расстояний d (O1, O2) и d (D1, D2), например их сумму или квадрат корень суммы их квадратов. Давайте напишем эту комбинацию как
distance((O1,D1), (O2,D2)) = f(d(O1,O2), d(D1,D2)).
Просто определите расстояние между неупорядоченными парами, чтобы оно было меньше из двух возможных расстояний:
distance({O1,D1}, {O2,D2}) = min(f(d(O1,O2)), d(D1,D2)), f(d(O1,D2), d(D1,O2))).
На данный момент вы можете применить любой метод кластеризации на основе матрицы расстояний.
В качестве примера я вычислил все 190 расстояний между двумя точками на карте для 20 самых густонаселенных городов США и запросил восемь кластеров, используя иерархический метод. (Для простоты я использовал евклидовы вычисления расстояний и применил методы по умолчанию в программном обеспечении, которое я использовал: на практике вы захотите выбрать подходящие расстояния и методы кластеризации для вашей задачи). Вот решение, с кластерами, обозначенными цветом каждого отрезка. (Цвета были случайным образом назначены кластерам.)
Вот R
код, который произвел этот пример. Его ввод - текстовый файл с полями «Долгота» и «Широта» для городов. (Для обозначения городов на рисунке также имеется поле «Ключ».)
#
# Obtain an array of point pairs.
#
X <- read.csv("F:/Research/R/Projects/US_cities.txt", stringsAsFactors=FALSE)
pts <- cbind(X$Longitude, X$Latitude)
# -- This emulates arbitrary choices of origin and destination in each pair
XX <- t(combn(nrow(X), 2, function(i) c(pts[i[1],], pts[i[2],])))
k <- runif(nrow(XX)) < 1/2
XX <- rbind(XX[k, ], XX[!k, c(3,4,1,2)])
#
# Construct 4-D points for clustering.
# This is the combined array of O-D and D-O pairs, one per row.
#
Pairs <- rbind(XX, XX[, c(3,4,1,2)])
#
# Compute a distance matrix for the combined array.
#
D <- dist(Pairs)
#
# Select the smaller of each pair of possible distances and construct a new
# distance matrix for the original {O,D} pairs.
#
m <- attr(D, "Size")
delta <- matrix(NA, m, m)
delta[lower.tri(delta)] <- D
f <- matrix(NA, m/2, m/2)
block <- 1:(m/2)
f <- pmin(delta[block, block], delta[block+m/2, block])
D <- structure(f[lower.tri(f)], Size=nrow(f), Diag=FALSE, Upper=FALSE,
method="Euclidean", call=attr(D, "call"), class="dist")
#
# Cluster according to these distances.
#
H <- hclust(D)
n.groups <- 8
members <- cutree(H, k=2*n.groups)
#
# Display the clusters with colors.
#
plot(c(-131, -66), c(28, 44), xlab="Longitude", ylab="Latitude", type="n")
g <- max(members)
colors <- hsv(seq(1/6, 5/6, length.out=g), seq(1, 0.25, length.out=g), 0.6, 0.45)
colors <- colors[sample.int(g)]
invisible(sapply(1:nrow(Pairs), function(i)
lines(Pairs[i, c(1,3)], Pairs[i, c(2,4)], col=colors[members[i]], lwd=1))
)
#
# Show the points for reference
#
positions <- round(apply(t(pts) - colMeans(pts), 2,
function(x) atan2(x[2], x[1])) / (pi/2)) %% 4
positions <- c(4, 3, 2, 1)[positions+1]
points(pts, pch=19, col="Gray", xlab="X", ylab="Y")
text(pts, labels=X$Key, pos=positions, cex=0.6)