Việc làm rõ câu hỏi của bạn cho biết bạn muốn phân cụm dựa trên các phân đoạn dòng thực tế , theo nghĩa là bất kỳ hai cặp điểm gốc (OD) nào cũng được coi là "đóng" khi cả hai nguồn gốc đều đóng và cả hai đích đều đóng , bất kể điểm nào được coi là điểm gốc hoặc điểm đến .
Công thức này cho thấy bạn đã có cảm giác về khoảng cách d giữa hai điểm: đó có thể là khoảng cách khi máy bay bay, khoảng cách trên bản đồ, thời gian di chuyển khứ hồi hoặc bất kỳ số liệu nào khác không thay đổi khi O và D chuyển. Sự phức tạp duy nhất là các phân đoạn không có các biểu diễn duy nhất: chúng tương ứng với các cặp không có thứ tự {O, D} nhưng phải được biểu diễn dưới dạng các cặp theo thứ tự , (O, D) hoặc (D, O). Do đó, chúng ta có thể lấy khoảng cách giữa hai cặp theo thứ tự (O1, D1) và (O2, D2) là một số kết hợp đối xứng của khoảng cách d (O1, O2) và d (D1, D2), chẳng hạn như tổng của chúng hoặc hình vuông gốc của tổng bình phương của họ. Hãy viết kết hợp này là
distance((O1,D1), (O2,D2)) = f(d(O1,O2), d(D1,D2)).
Chỉ cần xác định khoảng cách giữa các cặp không có thứ tự là nhỏ hơn trong hai khoảng cách có thể:
distance({O1,D1}, {O2,D2}) = min(f(d(O1,O2)), d(D1,D2)), f(d(O1,D2), d(D1,O2))).
Tại thời điểm này, bạn có thể áp dụng bất kỳ kỹ thuật phân cụm dựa trên ma trận khoảng cách.
Lấy ví dụ, tôi đã tính toán tất cả 190 khoảng cách điểm-điểm trên bản đồ cho 20 thành phố đông dân nhất Hoa Kỳ và yêu cầu tám cụm sử dụng phương pháp phân cấp. (Để đơn giản, tôi đã sử dụng các tính toán khoảng cách Euclide và áp dụng các phương thức mặc định trong phần mềm tôi đang sử dụng: trong thực tế, bạn sẽ muốn chọn khoảng cách phù hợp và phương pháp phân cụm cho vấn đề của mình). Đây là giải pháp, với các cụm được chỉ định bởi màu của từng đoạn. (Màu sắc được phân ngẫu nhiên vào các cụm.)
Đây là R
mã đã tạo ra ví dụ này. Đầu vào của nó là một tệp văn bản với các trường "Kinh độ" và "Vĩ độ" cho các thành phố. (Để gắn nhãn các thành phố trong hình, nó cũng bao gồm trường "Khóa".)
#
# 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)