คำถามง่าย ๆ แก้ยาก
วิธีที่ดีที่สุดที่ฉันรู้ใช้การจำลองแบบการอบ (ฉันใช้สิ่งนี้เพื่อเลือกจุดสองสามหมื่นจากนับหมื่นและปรับขนาดได้อย่างดีมากในการเลือก 200 คะแนน: การปรับสเกลเป็นแบบไม่เชิงเส้น) แต่ต้องใช้การเข้ารหัสอย่างระมัดระวัง เช่นเดียวกับการคำนวณจำนวนมาก คุณควรเริ่มต้นด้วยการดูวิธีที่ง่ายกว่าและเร็วกว่าก่อนเพื่อดูว่าจะเพียงพอหรือไม่
วิธีหนึ่งคือคนแรกที่จะจัดกลุ่มสถานที่จัดเก็บ ภายในแต่ละคลัสเตอร์เลือกร้านค้าที่อยู่ใกล้กับศูนย์คลัสเตอร์มากที่สุด
วิธีการจัดกลุ่มได้อย่างรวดเร็วจริงๆคือK-วิธี นี่คือ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 = 1,000 ร้านและดูว่าโซลูชันมีลักษณะอย่างไร:
# 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 วินาที:
คุณสามารถเห็นว่ามันไม่ดี (แต่ก็ไม่ได้แย่เกินไป) การที่จะทำได้ดีกว่านั้นคือต้องใช้วิธีการสุ่มเช่นการจำลองแบบการอบหรืออัลกอริทึมที่มีแนวโน้มที่จะขยายขนาดแบบเอ็กซ์โปเนนเชียลกับขนาดของปัญหา (ฉันได้ใช้อัลกอริทึมดังกล่าว: ใช้เวลา 12 วินาทีในการเลือก 10 คะแนนที่เว้นระยะกันมากที่สุดจาก 20. การใช้มันกับ 200 กลุ่มเป็นไปไม่ได้สำหรับคำถาม)
ทางเลือกที่ดีสำหรับ K-mean คืออัลกอริธึมการจัดกลุ่มแบบลำดับชั้น ลองใช้วิธีการ "ของวอร์ด" ก่อนและลองทำการทดสอบกับลิงก์อื่น ๆ สิ่งนี้จะใช้การคำนวณมากกว่านี้ แต่เรายังคงพูดถึงเพียงไม่กี่วินาทีสำหรับร้านค้า 1,000 แห่งและคลัสเตอร์ 200 แห่ง
วิธีอื่นมีอยู่ ตัวอย่างเช่นคุณสามารถครอบคลุมพื้นที่ด้วยตารางหกเหลี่ยมปกติและสำหรับเซลล์ที่มีร้านค้าหนึ่งสาขาขึ้นไปให้เลือกร้านค้าที่อยู่ใกล้ศูนย์กลางมากที่สุด เล่นกับเซลล์เล็ก ๆ น้อย ๆ จนกว่าจะมีประมาณ 200 ร้านค้าที่ได้รับการคัดเลือก สิ่งนี้จะสร้างระยะห่างของร้านค้าเป็นประจำซึ่งคุณอาจต้องการหรือไม่ต้องการ (หากสถานที่เหล่านี้เป็นสถานที่จัดเก็บอย่างแท้จริงนี่อาจเป็นวิธีแก้ปัญหาที่ไม่ดีเพราะมีแนวโน้มที่จะเลือกร้านค้าในพื้นที่ที่มีประชากรน้อยที่สุดในแอปพลิเคชันอื่นอาจเป็นวิธีที่ดีกว่ามาก)