Soruyu açıklığa kavuşturmanız, her iki köken de yakın ve her iki hedef de yakın olduğunda herhangi bir iki başlangıç noktası (OD) çiftinin "kapalı" olarak değerlendirilmesi gerektiği için , kümelemenin gerçek satır segmentlerine dayalı olmasını istediğinizi gösterir. , hangi noktanın başlangıç noktası veya hedef olarak kabul edildiğine bakılmaksızın .
Bu formülasyon, zaten iki nokta arasındaki mesafe d hissine sahip olduğunuzu gösterir : uçak uçarken mesafe, haritadaki mesafe, gidiş-dönüş seyahat süresi veya O ve D olduğunda değişmeyen başka bir metrik olabilir. açık. Tek komplikasyon, segmentlerin benzersiz temsillere sahip olmamasıdır: sıralanmamış çiftlere {O, D} karşılık gelir , ancak (O, D) veya (D, O) sıralı çiftler olarak temsil edilmelidir . Bu nedenle, toplamları veya kareleri gibi d (O1, O2) ve d (D1, D2) mesafelerinin simetrik bir kombinasyonu olmak için sıralı iki çift (O1, D1) ve (O2, D2) arasındaki mesafeyi alabiliriz. karelerinin toplamının kökü. Bu kombinasyonu şu şekilde yazalım:
distance((O1,D1), (O2,D2)) = f(d(O1,O2), d(D1,D2)).
Sıralanmamış çiftler arasındaki mesafeyi iki olası mesafeden daha küçük olacak şekilde tanımlamanız yeterlidir:
distance({O1,D1}, {O2,D2}) = min(f(d(O1,O2)), d(D1,D2)), f(d(O1,D2), d(D1,O2))).
Bu noktada, bir mesafe matrisine dayalı herhangi bir kümeleme tekniği uygulayabilirsiniz.
Örnek olarak, en kalabalık ABD kentlerinden 20'si için haritadaki 190 noktadan noktaya mesafelerin tümünü hesapladım ve hiyerarşik bir yöntem kullanarak sekiz küme istedim. (Basitlik için Öklid uzaklık hesaplamaları kullandım ve kullandığım yazılımda varsayılan yöntemleri uyguladım: pratikte sorununuz için uygun mesafeleri ve kümeleme yöntemlerini seçmek isteyeceksiniz). İşte çözüm, her çizgi parçasının rengiyle gösterilen kümeler. (Renkler rastgele kümelere atandı.)
İşte R
bu örneği üreten kod. Girdisi şehirler için "Boylam" ve "Enlem" alanlarına sahip bir metin dosyasıdır. (Şekildeki şehirleri etiketlemek için "Anahtar" alanı da içerir.)
#
# 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)