Кратчайшее расстояние пути между точками, заданными как координаты X-Y

В настоящее время я работаю над проектом, в котором есть вектор, содержащий координаты X и Y примерно для 800 точек. Эти точки представляют собой электрическую сеть линий. Моя цель — вычислить путь кратчайшего расстояния между точкой A и точкой B, который может быть или не быть расположен вдоль пути, заданного векторами, содержащими координаты X-Y электрических линий.

Я читал об алгоритме Дейкстры, но, поскольку я не очень хорошо с ним знаком, я не уверен, следует ли мне двигаться в этом направлении. Я буду очень благодарен, если смогу получить от вас какие-либо отзывы или комментарии, которые помогут мне решить этот вопрос.


person Christian Lopez    schedule 05.01.2013    source источник
comment
Подожди. Вам нужно кратчайшее возможное расстояние между двумя точками, которые не являются вектором, который у вас есть? Или просто кратчайшее расстояние между двумя точками?   -  person Linuxios    schedule 05.01.2013
comment
почему бы не использовать стандартную библиотеку c++ std::shortest_path_between_points_in_electric_network_of_lines?   -  person Cheers and hth. - Alf    schedule 05.01.2013
comment
@Cheersandhth.-Alf: О, да ладно. Мы все знаем, что текущая реализация этого материала по-прежнему не работает во всех основных компиляторах.   -  person Zeta    schedule 05.01.2013
comment
800 баллов не должно быть сложно перебором и получить ответ в кратчайшие сроки со скоростью современных компьютеров. В каждой точке возьмите минимальное расстояние от всех соседей плюс расстояние, чтобы добраться до этого узла, и остановитесь, когда ничего не изменится (Дейкстра немного эффективнее). Не беспокойтесь об эффективном алгоритме для чего-то такого маленького. Инициализируйте каждую точку бесконечностью, кроме начальной точки, и устанавливайте ее в ноль каждый раунд.   -  person Robert Richter    schedule 05.01.2013
comment
@RobertRichter +1, ранняя оптимизация плохая. Кроме того, кодирование простого подхода, вероятно, облегчит понимание более сложных подходов, таких как алгоритм Дейкстры.   -  person Anthony Burleigh    schedule 05.01.2013
comment
Есть ли какая-либо документация о том, как использовать алгоритм Дейкстры, когда исходные точки задаются как координаты X-Y в одном векторе? или мне нужно преобразовать мои исходные точки во что-то другое? Спасибо @RobertRichter за ваш ответ.   -  person Christian Lopez    schedule 05.01.2013
comment
@ChristianLopez Метод, который вы используете для хранения своих данных, не должен иметь отношения к используемому вами алгоритму - он может изменить результирующий код, но не концепцию. Алгоритм Дейкстры потребует, чтобы вы могли найти все точки, связанные с текущей точкой, и измерить расстояние между любыми двумя точками — если вы можете получить эту информацию из своей структуры данных, тогда все в порядке.   -  person Anthony Burleigh    schedule 05.01.2013
comment
Можно ли предположить, что каждая точка может иметь линию, соединяющую ее с любой другой точкой? Если да, то в каждой точке получите расстояние от начала. Инициализируйте все точки до бесконечности, кроме начала. Что-то вроде этого может быть с элементом 0, установленным на 0 (ваша начальная точка) для (i=1; i‹Points; ++i) Distance[i]=infinity; for(i=1; i‹Points; ++i) { for(j=0; j‹Points; ++j) { if PointDistance(i, j)+Distance[j]‹Distance[i] Distance[i ]=PointDistance(i, j)+Distance[j]; } }   -  person Robert Richter    schedule 05.01.2013
comment
В моем последнем комментарии: Если вы ищете линии (траншеи), соединяющие кратчайший путь точек, то запишите, какая точка (значение j) дала кратчайшее расстояние в каждой точке (i), и у вас будет тропа, по которой вы можете вернуться. от конца к началу.   -  person Robert Richter    schedule 05.01.2013
comment
@RobertRichter, существует примерно 310 строк, и каждая линия может иметь до 10 точек XY, описывающих ее путь. Я сохранил эти данные в векторе размером 310, и каждая строка одновременно содержит два отдельных вектора, один для координат X, а другой для координат Y. Проблема в том, что 310 строк не хранятся графически последовательно, а это означает, что, например, строка 0 на самом деле не связана со строкой 1, но, возможно, со строкой 15.   -  person Christian Lopez    schedule 05.01.2013
comment
По-прежнему используйте что-то похожее на цикл, как я описал, и напишите функцию расстояния, и если не может быть найдена линия, соединяющая точку I с J в вашем векторе 310, затем верните что-то, указывающее на отсутствие пути, и поэтому вы не можете получить расстояние от этой точки. Если путь может быть найден, пусть ваша функция расстояния берет фактическую стоимость, а не по мере полета орла (пифагорейский метод).   -  person Robert Richter    schedule 05.01.2013


Ответы (3)


Любой алгоритм поиска пути зависит от путей, точки просто бессмысленны. Теперь у вас есть список «путевых точек». Однако вы не объяснили, как эти точки соединяются. Например, если любая и каждая точка соединена друг с другом, кратчайшее расстояние будет просто пифагоровым расстоянием между A и B. - Я также не уверен, что вы подразумеваете под координатами X-Y электрических линий, такая «линия» всегда будет есть начальная и конечная позиция?

Итак, первый шаг — добавить к каждой точке не только координаты x,y, но и список соединяемых точек.

Как только вы это сделаете, вы можете начать использовать алгоритм поиска пути (хотя в этом случае A * будет лучше, чем алгоритм Дейкстры). Это была бы просто стандартная реализация с каждой «стоимостью» фактического расстояния между точками. (А для A* эвристикой будет пифагорическое расстояние до конечной точки).

Чтобы получить хороший учебник по A* (и другим алгоритмам), вы должны проверить страницы Амита.

РЕДАКТИРОВАТЬ, в ответ на комментарии.

Кажется, первый шаг — преобразовать набор отрезков в «точки». Я бы прошел через это:

collection AllPoints {containing Location & LinksToOtherPoints}
for each Segment
    get start/end Point of Segment
    if Point.Location is not in allPoints
        add Point to AllPoints
    add the other Point of Segment to LinksToOtherPoints

Затем у вас есть просто список со всеми точками и соединениями между ними. Поскольку вам нужно постоянно искать коллекцию allPoints, я предлагаю хранить ее в двоичной древовидной структуре (наборах?).

person paul23    schedule 05.01.2013
comment
@ paul123 да, paul, вы правы, мне нужно поработать над своей структурой данных, чтобы каждая из точек соединялась последовательно, одна за другой. На данный момент это не так. У меня есть размер вектора 310 (310 строк), и каждая строка имеет два отдельных вектора с координатами X-Y, которые описывают путь каждой строки. Однако линия 0 соединяется не с линией 1, а, возможно, с линией 3 или 4. Поэтому я сначала исправлю это в своем векторе, чтобы каждая точка соединялась с предыдущей и последней. - person Christian Lopez; 05.01.2013
comment
Похоже, первый шаг — каким-то образом связать конечные точки с чем-то, что хранит информацию о вершинах. Затем просто перебирайте строки. Например, если в конечной точке 1 указана стоимость 50, а в конечной точке 2 указана стоимость 90), но в строке указана стоимость 6, то вы должны обновить конечную точку 2, указав стоимость 56. Если в конечной точке 1 указана стоимость 90, а в конечной точке 2 указано стоимость 40, то конечная точка 1 будет обновлена ​​до стоимости 46. Если какая-либо конечная точка изменилась, повторите попытку. - person Robert Richter; 05.01.2013
comment
(Комментарий слишком длинный, разбитый) Если каждая вершина записывает линию, которая использовалась для установки нового минимума, то, когда минимальное расстояние стабилизируется (ничего не меняется, так что вы закончили), вы можете работать в обратном направлении от конца к началу. чтобы получить путь. - person Robert Richter; 05.01.2013
comment
Остерегайтесь неприятных ошибок, которые могут возникнуть в результате оптимизации с плавающей запятой. Предположим, что вы вычисляете расстояние и из-за внутреннего округления (расширенная точность в MPU и использование кэшированного значения MPU) вы говорите, что новая запись была достигнута, но при сохранении она сохраняет то же значение, что и раньше, вы можете получить в цикле, который никогда не выходит. - person Robert Richter; 05.01.2013
comment
@ paul23, но как мне подготовить свой двумерный вектор, содержащий координаты XY, для реализации поиска кратчайшего пути? Каждая линия имеет начальную координату x-y, а также конечную координату x-y. у меня больше набора парных координат в строке, так как начало и конец не всегда соединены по диагонали. Я теряюсь в том, как реализовать алгоритм... - person Christian Lopez; 06.01.2013
comment
Можете ли вы подготовить массив вершин и в каждой строке посмотреть на начальную и конечную точки и посмотреть, есть ли уже вершина для нее. Если это так, пометьте конечную точку как принадлежащую этой вершине. Если нет, добавьте новую вершину и затем отметьте конечную точку. Сделайте это для обеих конечных точек. Итак, ваши линии должны содержать следующую информацию: индекс вершины для конечной точки 1, индекс вершины для конечной точки 2 и стоимость линии (все ее сегменты вместе взятые?). Каждая вершина должна содержать стоимость получения значения, а также то, какая линия и конечная точка привели к текущему значению. - person Robert Richter; 06.01.2013

Для вычисления кратчайшего пути Диякстра подойдет.

Вы можете получить более быстрые результаты, используя A*, который использует наилучшее предположение о расстоянии в чтобы сфокусировать свой поиск в нужном направлении, тем самым быстрее туда добраться.

Если вы повторно запрашиваете один и тот же набор данных, то запоминание подойдет.

Те люди, которые рекомендуют алгоритм грубой силы, — дураки — стоит потратить немного времени, чтобы научиться программировать эффективное решение. Но вы можете рассчитать кратчайший путь между всеми точками, используя алгоритм Флойда-Уоршалла. К сожалению, это не скажет вам, каков кратчайший путь, а только насколько он длинный.

person Richard    schedule 06.01.2013

Просто рассчитайте расстояние для всех возможных путей и выберите самый короткий. 800 путей для современного ПК - это ничто. Вы даже не заметите этого.

person Hooch    schedule 05.01.2013
comment
Если вы не будете осторожны и наивно используете рекурсию для поиска пути, она будет ломаться экспоненциально, и 2 ^ 800 может быть ОЧЕНЬ долго. - person Robert Richter; 05.01.2013
comment
Для каждой перестановки из 800 сегментов проверьте, ведет ли она из А в Б. Если да, запишите путь и расстояние, сохранив самый короткий из найденных на данный момент. - person Yakk - Adam Nevraumont; 05.01.2013
comment
Ой. Я неправильно понял его вопрос. - person Hooch; 06.01.2013