Basit soru, zor çözüm.
Bildiğim en iyi yöntem, simüle edilmiş tavlama kullanır (bunu on binlerce arasından birkaç düzine nokta seçmek için kullandım ve 200 nokta seçmek için son derece iyi ölçekleniyor: ölçeklendirme alt doğrusal), ancak bu dikkatli kodlama ve önemli deneyler gerektiriyor, büyük miktarda hesaplama. Bunların yeterli olup olmadığını görmek için önce daha basit ve daha hızlı yöntemlere bakarak başlamalısınız.
Bunun bir yolu, ilk önce mağaza konumlarını kümelemektir . Her kümede, küme merkezine en yakın mağazayı seçin.
Gerçekten hızlı bir kümeleme yöntemi K-demektir . İşte R
onu kullanan bir çözüm.
scatter <- function(points, nClusters) {
#
# Find clusters. (Different methods will yield different results.)
#
clusters <- kmeans(points, nClusters)
#
# Select the point nearest the center of each cluster.
#
groups <- clusters$cluster
centers <- clusters$centers
eps <- sqrt(min(clusters$withinss)) / 1000
distance <- function(x,y) sqrt(sum((x-y)^2))
f <- function(k) distance(centers[groups[k],], points[k,])
n <- dim(points)[1]
radii <- apply(matrix(1:n), 1, f) + runif(n, max=eps)
# (Distances are changed randomly to select a unique point in each cluster.)
minima <- tapply(radii, groups, min)
points[radii == minima[groups],]
}
Bağımsız değişkenler scatter
, mağaza konumlarının ( n'ye göre 2 matris olarak) ve seçilecek mağazaların sayısıdır (ör. 200). Bir dizi konum döndürür.
Uygulamasına bir örnek olarak, rastgele yerleştirilmiş n = 1000 mağaza oluşturalım ve çözümün neye benzediğini görelim:
# Create random points for testing.
#
set.seed(17)
n <- 1000
nClusters <- 200
points <- matrix(rnorm(2*n, sd=10), nrow=n, ncol=2)
#
# Do the work.
#
system.time(centers <- scatter(points, nClusters))
#
# Map the stores (open circles) and selected ones (closed circles).
#
plot(centers, cex=1.5, pch=19, col="Gray", xlab="Easting (Km)", ylab="Northing")
points(points, col=hsv((1:nClusters)/(nClusters+1), v=0.8, s=0.8))
Bu hesaplama 0.03 saniye sürdü:
Harika olmadığını görebilirsiniz (ama çok da kötü değil). Daha iyisini yapmak için, ya simüle edilmiş tavlama gibi stokastik yöntemler ya da sorunun büyüklüğü ile katlanarak ölçeklenmesi muhtemel algoritmalar gerekecektir. (Böyle bir algoritma uyguladım: 20'nin en geniş aralıklı 10 noktasını seçmek 12 saniye sürüyor. 200 kümeye uygulamak söz konusu değil.)
K-araçlarına iyi bir alternatif hiyerarşik bir kümeleme algoritmasıdır; önce "Ward's" yöntemini deneyin ve diğer bağlantıları denemeyi düşünün. Bu daha fazla hesaplama gerektirecek, ancak 1000 mağaza ve 200 küme için sadece birkaç saniyeden bahsediyoruz.
Başka yöntemler de vardır. Örneğin, bölgeyi düzenli bir altıgen ızgara ile kaplayabilir ve bir veya daha fazla mağaza içeren hücreler için merkezine en yakın mağazayı seçebilirsiniz. Yaklaşık 200 mağaza seçilene kadar hücre boyutu ile biraz oynayın. Bu, isteyebileceğiniz veya istemeyeceğiniz çok düzenli bir mağaza aralığı oluşturacaktır. (Bunlar gerçekten mağaza konumlarıysa, bu muhtemelen kötü bir çözüm olacaktır, çünkü en az kalabalık alanlarda mağaza seçme eğilimi olacaktır. Diğer uygulamalarda bu çok daha iyi bir çözüm olabilir.)