おそらく非常に単純な質問です。私には、約1000の地理的位置(緯度)のリストがあり、そのうち「最も広がっている」200の位置を選択する必要があります。合計平均距離が最も高い200ポイントになると思います。都市の店を考えてください。
それを行うための定義された方法はありますか?たぶんRパッケージに?
これを学ぶのに最適な場所にしてくれた皆さんに感謝します!
/クリス
おそらく非常に単純な質問です。私には、約1000の地理的位置(緯度)のリストがあり、そのうち「最も広がっている」200の位置を選択する必要があります。合計平均距離が最も高い200ポイントになると思います。都市の店を考えてください。
それを行うための定義された方法はありますか?たぶんRパッケージに?
これを学ぶのに最適な場所にしてくれた皆さんに感謝します!
/クリス
回答:
簡単な質問、難しい解決策。
私が知っている最善の方法はシミュレーテッドアニーリングを使用しています(これを数万から数十のポイントを選択するために使用し、200ポイントの選択に非常によくスケーリングします:スケーリングは準線形です)、これには注意深いコーディングとかなりの実験が必要です。膨大な量の計算。まず、単純で高速なメソッドを調べて、それらが十分かどうかを確認する必要があります。
1つの方法は、まず店舗の場所をクラスタ化することです。各クラスター内で、クラスターの中心に最も近い店舗を選択します。
本当に速いクラスタリング手法はK-meansです。R
これを使用するソリューションは次のとおりです。
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],]
}
への引数scatter
は、店舗の場所のリスト(n行 2列の行列として)と選択する店舗の数(たとえば、200)です。場所の配列を返します。
そのアプリケーションの例として、ランダムに配置されたn = 1000のストアを生成して、ソリューションがどのように見えるかを見てみましょう。
# 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))
この計算には0.03秒かかりました。
あなたはそれが素晴らしいものではないことを見ることができます(しかし、それも悪くはありません)。はるかに良いことを行うには、シミュレーテッドアニーリングなどの確率的手法、または問題のサイズに応じて指数関数的にスケーリングする可能性が高いアルゴリズムのいずれかが必要になります。(私はそのようなアルゴリズムを実装しました:20から最も広い間隔の10個のポイントを選択するのに12秒かかります。200個のクラスターに適用することは問題外です。)
K-meansの良い代替案は、階層的クラスタリングアルゴリズムです。最初に「ウォーズ」法を試して、他のリンケージを試すことを検討してください。これはより多くの計算を必要としますが、我々はまだ1000のストアと200のクラスターのほんの数秒について話しています。
他の方法があります。たとえば、領域を通常の六角形グリッドでカバーし、1つ以上の店舗を含むセルの場合は、その中心に最も近い店舗を選択します。約200の店舗が選択されるまで、セルサイズを少し試します。これにより、店舗の間隔が非常に規則的になります。(これらが本当に店舗の場所である場合、最も人口の少ないエリアで店舗を選択する傾向があるため、これはおそらく悪いソリューションになります。他のアプリケーションでは、これははるかに優れたソリューションかもしれません。)