Я написал быстрый и грязный тестер расстояния по сетке в scala, который сравнивает среднее значение с минимумом исчерпывающего поиска:
class Coord (val x:Int, val y: Int) {
def delta (other: Coord) = {
val dx = math.abs (x - other.x)
val dy = math.abs (y - other.y)
List (dx, dy).max
}
override def toString = " (" + x + ":" + y + ") "
}
def run (M: Int) {
val r = util.Random
// reproducable set:
// r.setSeed (17)
val ucells = (1 to 2 * M).map (dummy => new Coord (r.nextInt (M), r.nextInt (M))).toSet take (M) toSeq
val cells = ucells.sortWith ((a,b) => (a.x < b.x || a.x == b.x && a.y <= b.y))
def distanceSum (lc: Seq[Coord], cell: Coord) = lc.map (c=> cell.delta (c)).sum
val exhaustiveSearch = for (x <- 0 to M-1;
y <- 0 to M-1)
yield (distanceSum (cells, new Coord (x, y)))
def sum (lc: Seq[Coord]) = ((0,0) /: lc) ((a, b) => (a._1 + b.x, a._2 + b.y))
def avg (lc: Seq[Coord]) = {
val s = sum (lc)
val l = lc.size
new Coord ((s._1 + l/2) / l, (s._2 + l/2) / l)
}
val av = avg (ucells)
val avgMethod = distanceSum (cells, av)
def show (cells : Seq[Coord]) {
val sc = cells.sortWith ((a,b) => (a.x < b.x || a.x == b.x && a.y <= b.y))
var idx = 0
print ("\t")
(0 to M).foreach (i => print (" " + (i % 10)))
println ()
for (x <- 0 to M-1) {
print (x + "\t")
for (y <- 0 to M -1) {
if (idx < M && sc (idx).x == x && sc (idx).y == y) {
print (" x")
idx += 1 }
else if (x == av.x && y == av.y) print (" A")
else print (" -")
}
println ()
}
}
show (cells)
println ("exhaustive Search: " + exhaustiveSearch.min)
println ("avgMethod: " + avgMethod)
exhaustiveSearch.sliding (M, M).toList.map (println)
}
Вот пример вывода:
run (10)
0 1 2 3 4 5 6 7 8 9 0
0 - x - - - - - - - -
1 - - - - - - - - - -
2 - - - - - - - - - -
3 x - - - - - - - - -
4 - x - - - - - - - -
5 - - - - - - x - - -
6 - - - - A - - x - -
7 - x x - - - - - - -
8 - - - - - - - - - x
9 x - - - - - - - - x
exhaustive Search: 36
avgMethod: 37
Vector(62, 58, 59, 60, 62, 64, 67, 70, 73, 77)
Vector(57, 53, 50, 52, 54, 57, 60, 63, 67, 73)
Vector(53, 49, 46, 44, 47, 50, 53, 57, 63, 69)
Vector(49, 46, 43, 41, 40, 43, 47, 53, 59, 66)
Vector(48, 43, 41, 39, 37, 37, 43, 49, 56, 63)
Vector(47, 43, 39, 37, 36, 37, 39, 46, 53, 61)
Vector(48, 43, 39, 36, 37, 38, 40, 43, 51, 59)
Vector(50, 44, 40, 39, 38, 40, 42, 45, 49, 57)
Vector(52, 47, 44, 42, 42, 42, 45, 48, 51, 55)
Vector(55, 52, 49, 47, 46, 47, 48, 51, 54, 58)
Среднее значение не всегда является идеальной позицией (как показано в этом примере), но вы можете следить за соседями с более или менее значимым значением, чтобы найти лучшую позицию.Это хорошая отправная точка, и я не нашел образец локального оптимума, где вы застряли.Это может быть важно для огромных наборов данных.
Но у меня нет доказательств, всегда ли это так, и как найти идеальную позицию напрямую.