Подтвердить что ты не робот

Минимизировать максимальное расстояние в манхэттене от точки до набора точек

Для трех точек в 2D:

P1(x1,y1), 
P2(x2,y2), 
P3(x3,y3) 

Мне нужно найти точку P(x,y), такую, что максимум манхэттенских расстояний

max(dist(P,P1), 
    dist(P,P2), 
    dist(P,P3))

будет минимальным.

Любые идеи об алгоритме?

Я бы предпочел бы точный алгоритм.

4b9b3361

Ответ 1

Существует точный, нетериративный алгоритм проблемы; как указал Кноте, расстояние Манхэттена является вращательно эквивалентным чебышевскому расстоянию, а P тривиально вычислимо для чебышевского расстояния как среднее из крайних координат.

Точки, достигаемые от P в пределах расстояния Манхэттена x, образуют алмаз вокруг P. Поэтому нам нужно найти минимальный алмаз, который охватывает все точки, а его центр будет P.

Если мы поворачиваем систему координат на 45 градусов, алмаз представляет собой квадрат. Поэтому проблему можно свести к нахождению наименьшего квадрата окружности точек.

Центр наименьшего охватывающего квадрата можно найти как центр самого маленького прямоугольника (который тривиально вычисляется как max и min координат). Существует бесконечное количество наименьших закрывающих квадратов, так как вы можете сдвинуть центр вдоль более короткого края минимального прямоугольника и по-прежнему иметь минимальный квадрат. Для наших целей мы можем просто использовать тот, центр которого совпадает с охватывающим прямоугольником.

Итак, в алгоритмической форме:

  • Поворот и масштабирование системы координат путем присвоения x '= x/sqrt (2) - y/sqrt (2), y' = x/sqrt (2) + y/sqrt (2)
  • Вычислить x'_c = (max (x'_i) + min (x'_i))/2, y'_c = (max (y'_i) + min (y'_i))/2
  • Поворот назад с помощью x_c = x'_c/sqrt (2) + y'_c/sqrt (2), y_c = - x'_c/sqrt (2) + y'_c/sqrt (2)

Тогда x_c и y_c дают координаты P.

Ответ 2

Если приблизительное решение в порядке, вы можете попробовать простой алгоритм оптимизации. Вот пример, в Python

import random
def opt(*points):
    best, dist = (0, 0), 99999999
    for i in range(10000):
        new = best[0] + random.gauss(0, .5), best[1] + random.gauss(0, .5)
        dist_new = max(abs(new[0] - qx) + abs(new[1] - qy) for qx, qy in points)
        if dist_new < dist:
            best, dist = new, dist_new
            print new, dist_new
    return best, dist

Объяснение: Мы начинаем с точки (0, 0) или любой другой случайной точки и изменяем ее несколько тысяч раз, каждый раз сохраняя лучшее из новой и ранее лучшей точки. Постепенно это будет приблизительно соответствовать оптимальному.

Примечание, которое просто выбирает среднее или медианное из трех точек, или решение для x и y независимо не работает при минимизации максимального расстояния в манхэттене. Противопоставление: рассмотрите точки (0,0), (0,20) и (10,10) или (0,0), (0,1) и (0,100). Если мы выберем среднее из наиболее разделенных точек, это даст (10,5) для первого примера, и если мы возьмем медиану, это будет (0,1) для второго примера, у которого оба имеют более высокий максимальный манхэттен чем оптимальный.

Обновление: Похоже, что решение для x и y независимо, а среднее значение самых отдаленных точек действительно работает, при условии, что выполняется некоторая предварительная обработка и постобработка, как указано thiton.