Re: Поиск ближайшей точки | |
---|---|
Влад Колосов Сообщений: 22664 Откуда: Ростов-на-Дону Дата регистрации: 05.05.2005 |
Караул какой-то... Может я немного упустил перетекание темы в другое русло, но задача решается одим простым запросом:
Суть в том, что сначала мы смещаем систему координат к нулевой точке, а затем производим преобразование координат в правый верхний квадрант. Дальше задача решается так, как описал Владимир Максимов еще на первом листе. ------------------ Совершенство - это не тогда, когда нельзя ничего прибавить, а тогда, когда нечего убавить. Исправлено 1 раз(а). Последнее : Влад Колосов, 04.03.10 12:38 |
Re: Поиск ближайшей точки | |
---|---|
Влад Колосов Сообщений: 22664 Откуда: Ростов-на-Дону Дата регистрации: 05.05.2005 |
Э! При равных суммах длин некорректно вычисляет...
------------------ Совершенство - это не тогда, когда нельзя ничего прибавить, а тогда, когда нечего убавить. Исправлено 1 раз(а). Последнее : Влад Колосов, 04.03.10 12:50 |
Re: Поиск ближайшей точки | |
---|---|
medstrax Забанен Сообщений: 5964 Дата регистрации: 23.03.2007 |
Помимо упомянутой книги по выч. геометрии(весьма старой) рекомендую ознакомиться с en.wikipedia.org, там описана задача в более общем варианте
и есть ссылки на различные способы решения. |
Re: Поиск ближайшей точки | |
---|---|
leonid Сообщений: 3204 Откуда: Рига Дата регистрации: 03.02.2006 |
Теория очень хорошая вещь. И приведенные в википедии ссылки вне всякого сомнения крайне поучительны. В первую очередь это, конечно, касается Кнута. Его я настоятельно рекомендую почитать (хотя бы попробовать - он довольно сложный) всем, кто хочет повысить свой уровень, как програмист. Но я все-таки хочу подчеркнуть одну особенность данной задачи, которая накладывает на применение к ней теории весьма большую специфику. Дело в том, что решать ее надо на фоксе, а фокс - интерпретатор. Давным давно, еще на Basic-е, столкнулся с тем, что некоторые теоретически оптимальные алгоритмы дают неважную скорость, в то время, как более грубые, но с использованием встроенных функций, работают значительно лучше. Ясно дело, встроенные функции прогоняют циклы на ассемблере, а это намного быстрее, чем самый оптимальный цикл, прогнанный интерпретатором. Если посмотреть эту ветку сначала, видно что главный вопрос был в том, как пристроить к данной задаче Рашмор, поскольку это то, что обычно дает в фоксе максимальное приращение скорости. Именно из-за Рашмора появились два квадрата с отношением сторон sqrt(2). Это связано с тем, что Рашмор позволяет оптимизировать проверку наличия точки в произвольном квадрате, и в то же время не может оптимизировать проверку наличия точки в произвольном круге. Уверен, что подобных квадратов нет ни в одной из приведенных в википедии ссылок. Хотя в остальном полученный метод похож на какой-то из методов из википедиевских ссылок (извиняюсь, не очень подробно посмотрел). Кстати, метод хеширования из приведенных ссылок может очень хорошо показать себя в случае, если точки распределены не равномерно, а скоплениями. |
Re: Поиск ближайшей точки | |
---|---|
Влад Колосов Сообщений: 22664 Откуда: Ростов-на-Дону Дата регистрации: 05.05.2005 |
Любопытно, что вычисление квадратного корня не приводит к замедлению выполнения, т.е.
SELECT top 1 PointId, ABS(coordX - myX) + ABS(CoordY - myY) sum1, ds FROM points ORDER BY 2 и SELECT top 1 PointId, SQRT((coordX - myX)^2 + (CoordY - myY)^2) test_value, ds FROM points ORDER BY 2 отрабатывают одинаково. Я брал 10^5 значение, приблизительно 0.6 секунды время выполнения. ------------------ Совершенство - это не тогда, когда нельзя ничего прибавить, а тогда, когда нечего убавить. |
Re: Поиск ближайшей точки | |
---|---|
Crispy Сообщений: 18571 Дата регистрации: 16.05.2005 |
Любопытная задача однако.
Применений в принципе много может быть. Когда-то вроде тоже натыкался на необходимость выборки одновременно по двум полям, чего не позволяет например команда LOOKUP(). А казалось бы, ну что им стоило добавить туда возможность такой выборки. Тоже пришла мысль - выбирать в несколько этапов: 1) пошагово расширяем квадрат поиска до первого попадания в него точки, 2) поскольку при этом первой попасть туда может и более далекая точка - войдя через диагональ квадрата, и не попасть более близкая, но только-только приблизившаяся к ребру - среди нескольких точек, уже ограниченных этим кругом с радиусом, равным расстоянию до найденной точки, ищем минимум расстояния, 3) позиционируем запись в таблице на найденные координаты - получаем номер точки. Алгоритм вроде верный. Но над реализацией особо не стал размышлять - попытался сделать "стандартными" командами. И как оказалось зря. Если на маленьких таблицах все работает отлично, то на огромных - получаются явные тормоза. Ну правда не знаю как учесть тот фактор, что у меня на компе даже само создание таких таблиц занимает минуты, видимо из-за ограничений по памяти и процессору. Не у всех же под рукой двухъядерные и прочие. ;) Люди и на селеронах-1.8 с 512 мб сидят. Попутно, когда размышлял над построением алгоритма, захотелось посмотреть как это все будет выглядеть визуально - все эти точки. В результате накидал вот такую штучку. Получилась как бы такая картинка вселенной - с солнцем (главной точкой) и звездами. Заодно добавил к мышке возможность определения, что за точка (звезда) находится под курсором и расстояние до нее. Поисковик там, как и сказал уже не самый удачный, но для такой маленькой картинки лучший в принципе и не нужен. Хотя можно заменить и на любой другой. Допустим проверять, насколько точно он ищет. Единственный недостаток рисования фокса, как оказалось - он рисует точки в виде квадратиков из четырех точек. При этом координаты такой "точки" привязаны к левому верхнему углу, из-за чего визуально расстояния выглядят чуть не так, как высчитываются. ------------------ В действительности все иначе, чем на самом деле. (Антуан де Сент-Экзюпери) |
Re: Поиск ближайшей точки | |
---|---|
Crispy Сообщений: 18571 Дата регистрации: 16.05.2005 |
Да, собственно вот и сама эта программка вселенной.
------------------ В действительности все иначе, чем на самом деле. (Антуан де Сент-Экзюпери) |
Re: Поиск ближайшей точки | |
---|---|
Crispy Сообщений: 18571 Дата регистрации: 16.05.2005 |
Интересно бывает наблюдать за различными ситуациями распределения - если закрывать окошко любой клавишей, а запускать, например расположив мышку над кнопкой run.
Получается как бы наблюдать вселенную со всеми удобствами, работая всего лишь легкими движениями двух пальцев. ------------------ В действительности все иначе, чем на самом деле. (Антуан де Сент-Экзюпери) |
Re: Поиск ближайшей точки | |
---|---|
Goodwin Автор Сообщений: 3539 Откуда: Омск Дата регистрации: 03.05.2006 |
Проблема была именно в скорости. Тут простой селект отстаёт ~ в 1000 раз. ------------------ Что мы знаем о лисе? Ничего. И то не все. (С)Б. Заходер |
Re: Поиск ближайшей точки | |
---|---|
pasha_usue Сообщений: 3650 Откуда: Е-бург Дата регистрации: 06.10.2006 |
Ctrl+E рулит ;) |
Re: Поиск ближайшей точки | |
---|---|
Влад Колосов Сообщений: 22664 Откуда: Ростов-на-Дону Дата регистрации: 05.05.2005 |
И какое же решение приято к эксплуатации?
------------------ Совершенство - это не тогда, когда нельзя ничего прибавить, а тогда, когда нечего убавить. |
Re: Поиск ближайшей точки | |
---|---|
sphinx Сообщений: 31184 Откуда: Каменск-Уральски Дата регистрации: 22.11.2006 |
Да, присоединяюсь к вопросу. Какое именно решение устроило? (особо не вникал в проблему, но слежу за темой, ибо интересно) ------------------ "Veni, vidi, vici!"(с) |
Re: Поиск ближайшей точки | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Влад, всё собственно говоря крутилось вокруг того как избежать полного перебора, при этом наиболее простым и быстрым способом, а ты снова здорово
Если бы речь шла про C/C++ или там Oracle - то очевидно что решение было бы наверное другим, но мы то про фокс толкуем... Вариант с ABS заведомо некорректный, о чём тут уже тут писали - т.к. расстояние от нуля до точки (2, 2) реально меньше (примерно 2.83) чем расстояние до точки (0,3) которое даёт ровно 3 - тогда как по твоему выходит что вторая ближе. В любом случае, вопрос будет прежде всего в том чтобы как-то подсунуть индекс, чтобы отбор НЕ проходил по всем точкам - что-то мне сомнительно что вариант с ABS(X-A)+ABS(Y-B) может быть оптимизирован в принципе... А если его "развернуть" чтобы ушёл модуль, то получим... ровно тот-же "квадрат" поиска Он один не позволит найти решение, зато позволит отсеять большую часть точек и потом среди оставшихся искать полным перебором - используя квадраты/корни. Переход к полярной системе координат так-же ничего не даёт, как ты не выбирай начальную точку - а расстояние по полярной системе, или перевод исходной системы в новую, где начало совпадает с искомой точкой всё одно потребует обработки всей таблицы, и никак это не оптимизировать... Вот алгоритмы предварительного разбиения всего множества на области и последующее оперирование именно в рамках одного (ну или нескольких ближайших) подмножества - это да - это разумно и хорошо - но IMHO чересчур уж сложно в реализации, да и не факт что даст выигрыш для любых распределений, скажем для равномерного (ну получится тупо мозаика из равномерно распределённых равноразмерных пятиугольников, или скажем квадратов - спрашивается на кой было стараться, если тот-же эффект дают банальные 2 индекса по X и Y плюс описанный выше механизм поиска). Но для "специфической" задачи (или скажем "особенности распределения точек") такое решение может оказаться более чем уместным - это без сомнений. ------------------ WBR, Igor |
Re: Поиск ближайшей точки | |
---|---|
medstrax Забанен Сообщений: 5964 Дата регистрации: 23.03.2007 |
Кто нибудь пробовал реализовать на фоксе упомянутые алгоритмы? При всем уважении к leonid'у
хотелось бы увидеть конкретные цифры на различных массивах точек. На просто рандомном массиве и на каких-то конкретно подобранных вариантах. К примеру все множество точек лежит на одной прямой. Тут диаграммы Вороного явно не рулят, в другие алгосы не особо пока вник. |
Re: Поиск ближайшей точки | |
---|---|
Goodwin Автор Сообщений: 3539 Откуда: Омск Дата регистрации: 03.05.2006 |
Слегка облегчённый вариант Игоря. Время поиска в 10^6 ~ 0.003 секунды против 1.5 секунд постого скана, что вполне устраивает. ------------------ Что мы знаем о лисе? Ничего. И то не все. (С)Б. Заходер |
Re: Поиск ближайшей точки | |
---|---|
Crispy Сообщений: 18571 Дата регистрации: 16.05.2005 |
И еще одна идея на днях пришла, но не обобщенно-теоретическая, а чисто для практического использования. Что позволит возможно и еще дополнительно ускорить нахождение нужной точки как минимум на порядок. Возможно и на несколько порядков. Суть данного улучшения в том, что если по условию допустимо любое предварительное преобразование и обработка таблицы еще до самих вычислений, в том числе и с созданием индекса, то можно значительно намного упростить их. Сведя все по сути к элементарным вещам. Для чего достаточно лишь завести в таблице дополнительное поле, в которое вычислить заранее расстояние каждой точки (x,y) от нулевой точки. Т.е. нечто вроде SQRT(x^2+y^2). Возможно еще проще (для дальнейших вычислений) будет записать туда не корень, а непосредственно саму эту сумму квадратов координат. Тогда сам поиск ближайшей точки вместо сложного двумерного поиска, как во всех вышеописанных вариантах, будет сведен всего лишь к поиску по одной переменной. Что при дополнительном индексировании по ней можно уже будет осуществить явно намного более проще. И естественно во сколько-то раз быстрее. ------------------ В действительности все иначе, чем на самом деле. (Антуан де Сент-Экзюпери) Исправлено 1 раз(а). Последнее : Crispy, 26.03.10 08:38 |
Re: Поиск ближайшей точки | |
---|---|
Goodwin Автор Сообщений: 3539 Откуда: Омск Дата регистрации: 03.05.2006 |
Этот вариант предлагал PaulWist.
На второй странице есть реализация. ------------------ Что мы знаем о лисе? Ничего. И то не все. (С)Б. Заходер |
Re: Поиск ближайшей точки | |
---|---|
Crispy Сообщений: 18571 Дата регистрации: 16.05.2005 |
Пересмотрел внимательно несколько раз, но так и не нашел. Возможно мы о разных вещах говорим? Я имел в виду добавление нового поля в таблицу, равного сумме квадратов x и y, чтобы осуществлять затем поиск не по вычисляемому выражению функции x,y, а по этому уже заранее вычисленному полю. Т.е. задача сводится всего лишь к поиску ближайшего значения по одному-единственному индексированному полю. Всего лишь элементарный LOCATE или SEEK! Ну в смысле чуть посложнее, но всего лишь поиск ближайшего единственного числа к числу "расстояния точки"=x^2+y^2. Насколько я понимаю во всех приводившихся выше вариантах идет вычисление как раз по двум переменным x и y, используя понятие точки. Здесь же само понятие точки можно даже и не использовать - используется всего лишь число "расстояние точки до 0". Еще и еще смотрю и упорно не вижу, где PaulWist (или кто-либо еще) говорит об единственном поле. Везде вроде обсуждают поиск в квадрате и т.п. Или я что-то все-таки пропустил? Как бы вместо использования плоскости и двух координат - переходим к вычислению на прямой. ------------------ В действительности все иначе, чем на самом деле. (Антуан де Сент-Экзюпери) Исправлено 1 раз(а). Последнее : Crispy, 26.03.10 10:23 |
Re: Поиск ближайшей точки | |
---|---|
Mitchman Сообщений: 9978 Откуда: Николаев Дата регистрации: 24.05.2002 |
не годится такое решение - или с очень ограниченными условиями бо для огромного числа разных XY будет одинаковым сумма их квадратов
простейший массив таких чисел это бесконечноечисло прямоугольных треугольников с одинаковой гипотенузой- кроме того есть еще и отрицательные числа и т.д.т.д ------------------ - «свидомые украинцы озабочены не столько созданием украинской культуры, сколько уничтожением русской» - Олесь Бузина |
Re: Поиск ближайшей точки | |
---|---|
Crispy Сообщений: 18571 Дата регистрации: 16.05.2005 |
А блин. Точно! Нужно же еще и направление - вектор же.
------------------ В действительности все иначе, чем на самом деле. (Антуан де Сент-Экзюпери) Исправлено 2 раз(а). Последнее : Crispy, 26.03.10 11:32 |
© 2000-2024 Fox Club  |