Ваше роз'яснення питання вказує на те, що ви хочете, щоб кластеризація базувалася на фактичних сегментах рядків , в тому сенсі, що будь-які дві пари вихідних цілей (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)