кратчайшее расстояние в ряду координат xy

У меня есть задание, которое сравнивает 2 разных алгоритма для проблемы. Вот проблема:

Предположим, у меня есть ряд таких координат xy:

A(2,3), B(5,6), C(7,8), D(6,2), E(5,5) и т.д..

И я хочу найти 2 координаты, которые имеют кратчайшее расстояние между ними. Одним из решений является использование грубой силы (сопоставление их одного за другим), но есть и другое решение, использующее метод «разделяй и властвуй».

Не могли бы вы помочь мне с методом «разделяй и властвуй»?


person Jason    schedule 02.12.2012    source источник


Ответы (2)


Рекурсивный подход «разделяй и властвуй» работает следующим образом:

1) Отсортировать точки по их координатам x.
2) Разделить набор точек на два подмножества одинакового размера вертикальной линией x=xmid.

3) Рекурсивно решить задачу в левом и правом подмножествах. Это
дает минимальное расстояние слева и справа dLmin и dRmin соответственно.

4) Найдите минимальное расстояние dLRmin среди пары точек, в которых одна точка лежит слева от разделяющей вертикали, а вторая — справа.

5) Окончательный ответ – это минимум среди dLmin, dRmin и dLRmin. (источник)

Он имеет сложность O(n log n). Также есть реализация псевдокода здесь и визуальное описание метода здесь.

person dreamcrash    schedule 02.12.2012

Подумайте о том, что означают части «разделить» и «слить». Очевидно, что «разделить» означает разделить проблему на 2 более мелкие отдельные. Как? Затем, учитывая, что вы решили две меньшие проблемы, как вы объедините их вместе? Какова временная сложность обоих методов? Если вам нужно больше разъяснений, оставьте комментарий.

person jonathanasdf    schedule 02.12.2012
comment
Я думаю, суть вопроса в том, как разделить и как завоевать. - person John Dvorak; 02.12.2012
comment
Да, но это также вопрос домашнего задания, поэтому вместо того, чтобы просто давать ответ, я лично предпочел бы более интерактивное обсуждение. Иногда такой мелочи, как повторная постановка вопроса, например, что я здесь делаю, оказывается достаточно, чтобы человек мог решить ее самостоятельно. - person jonathanasdf; 02.12.2012
comment
Я понимаю концепцию, но не технические детали. Как разбить координаты на подзадачи, которые легко решить, и как все это слить в решение... С какого основания делить?... - person Jason; 02.12.2012
comment
Ну, вы хотите разделить точки на две части, которые не пересекаются. Как правило, вы можете провести любую случайную линию через набор точек, которая делит точки на две части одинакового размера. Однако реализовать это сложно. Но, если разделить его вертикальной линией (или горизонтальной линией), то несложно как найти линию, которая делит его на равные половины, так и собственно сообразить, какая точка с какой стороны (упражнение осталось за вами) . - person jonathanasdf; 02.12.2012
comment
Раз у вас есть две половинки, то, очевидно, возможны 2 случая: либо замыкающая пара полностью лежит внутри одной из половинок, либо одна лежит на одной половине, а другая — на другой половине. Рекурсивно вызывая свою функцию для каждой из двух половин (назовем их левой и правой), вы можете найти ближайшую пару слева и ближайшую пару справа. Попробуйте выяснить, как теперь вы можете объединить две части. Позаботьтесь о том, чтобы помнить, что такое базовый случай! (Всякий раз, когда у вас есть что-то рекурсивное, всегда сначала выясняйте базовый случай.) Попробуйте сначала решить это на бумаге, а не в коде. - person jonathanasdf; 02.12.2012