Рассчитайте кратчайший путь через продуктовый магазин
Я пытаюсь найти способ найти кратчайший путь через продуктовый магазин, посетив список мест (список покупок). Путь должен начинаться с заданной начальной позиции и может заканчиваться на нескольких конечных позициях (имеется несколько счетчиков проверки).
Кроме того, у меня есть некоторые предопределенные ограничения на пути, такие как "элемент x в списке покупок должен быть последним, вторым последним или третьим последним элементом на пути". Существует функция, которая вернет true или false для данного пути.
Наконец, это нужно вычислить с ограниченной мощностью процессора (на смартфоне) и в течение секунды или около того. Если это невозможно, то приближение к оптимальному пути также нормально.
Возможно ли это? Пока я думаю, что мне нужно начать с вычисления расстояния между каждым элементом в списке, используя что-то вроде A * или Dijkstra's. После этого, следует ли относиться к нему как к проблеме коммивояжера? Потому что в моей проблеме есть заданный старт node, указанные конечные узлы и некоторые ограничения, которые не входят в проблему коммивояжера.
Ответы
Ответ 1
Кажется, что просмотр его как проблемы с TSP усложняет задачу. Кто-то отметил, что продуктовые истории не так уж сложны. В продуктовых магазинах, с которыми я знаком (в США), существует не так уж много разумных маршрутов. Особенно, если у вас есть заданная отправная точка. Я думаю, что продуманная эвристика, вероятно, сделает трюк.
Например: я обычно начинаю с одного конца - если это большая поездка, я убеждаюсь, что я прохожу через замороженные продукты в последний раз, но это часто не имеет значения, и я начну ближе всего к тому, где я войду в магазин. Я вообще хожу вокруг снаружи, только спускаюсь по отдельным проходам, если мне что-то нужно в этом. Как только вы зайдете в проход, возьмите все в этом. С некоторыми проходами лучше упасть в один конец, схватить предмет и вернуться к исходной точке, а другие вы просто передадите весь проход - это функция последнего элемента, который вам нужен в этом проходе, и где вам нужно быть следующим - как выйти из прохода зависит от следующего необходимого предмета - он может включать или не включать обратный путь - но компьютер может легко вычислить кратчайший путь к следующим элементам.
Поэтому я согласен с полезными подсказками других проблем выше, но, возможно, будет работать более общий алгоритм. И, вероятно, будет работать лучше с ограниченными ресурсами. TSP говорит нам, однако, вы не можете доказать, что это оптимальный подход, но я подозреваю, что это действительно не нужно...
Ответ 2
Ну, в основном это проблема коммивояжера, но с вашими требованиями вы довольно хорошо ограничиваете пространство поиска. Если мест не так много, вы можете попытаться рассчитать все возможные варианты, но если это невозможно, вам нужно еще больше ограничить пространство поиска.
Вы можете ограничить время поиска, чтобы вы вернули кратчайший путь, который вы можете найти за 1 секунду, но это может быть не самое короткое из всех, но все равно довольно короткое.
Вы также можете применить Жадный алгоритм, чтобы найти следующее ближайшее место, затем используя Backtracking выберите следующее ближайшее место и т.д.
Псевдокод для возможного решения:
def find_shortest_path(current_path, best_path):
if time_limit()
return
if len(current_path) == NUM_LOCATIONS:
# destionation reached
if calc_len(current_path) < calc_len(best_path):
best_path = current_path
return
# You need to sort the possible locations well to maximize your chances of finding the
# the shortest solution
sort(possible_locations)
for location in possible_locations:
find_shortest_path(current_path + location, best_path)
Ответ 3
Ну, вы можете ограничить пространство поиска, используя информацию о макете магазина. Например, типичный магазин (по крайней мере, здесь, в Германии) имеет много полок в нем, которые можно считать сформированными дорожками. Между ними расположены ортогональные полосы, которые соединяют полки. Теперь вы определяете пересечения как узлы, а полосы - ребрами в графе. Края помечены всеми элементами на полках этой секции дорожки. Теперь даже для большого магазина этот график будет довольно маленьким. Теперь вам нужно найти кратчайший путь, который включает все метки-метки (элементы), которые вам нужны. Это должно быть возможно, используя подход жадного/обратного отслеживания Туомас Пелконен предложил.
Это просто идея, и я не знаю, действительно ли она работает, но, возможно, вы можете ее отсюда отсюда.
Ответ 4
Только поиск по ширине гарантирует, что вы не пропустите путь через магазин, который лучше, чем текущее "лучшее" решение, но вам не нужно искать каждый node в пути. Узлы, которые "явно" дольше, чем текущее "лучшее" решение, могут быть расширены позже.
Это означает, что вы подходите к проблеме, как "поиск в первый раз", но изменяете расширение своих узлов на основе текущего пройденного расстояния. Некоторые ветки дерева поиска будут расширяться быстрее, чем другие, потому что им удается посещать больше узлов за тот же промежуток времени.
Итак, если расширение node не является первым дыханием, почему я продолжаю использовать это слово? Поскольку после того, как вы найдете решение, вы все равно должны расширить текущий набор "рассмотренных узлов", пока каждый из этих путей поиска не превысит решение. Это позволяет избежать пропущенного пути, который требует много времени на начальные ножки, но заканчивается быстрее, чем текущее решение, потому что последний шаг быстро освещен.
Ответ 5
Требование о начале node является фиктивным. Используя TSP, вы получите тур, в котором вы можете выбрать нужный старт node, не изменяя стоимость решения.
Это несколько сложнее, когда дело доходит до счетчиков: вам нужно решить проблему на ориентированном графе с отсутствующими отсутствующими дугами (или, что то же самое, когда некоторые дуги имеют действительно высокую стоимость).
Начиная с полного направленного графика, вы должны изменить затраты на соответствующие дуги, чтобы:
- отклоняется от элементов до начала node
- отклоняется от счетчиков к элементам
- отклоняется от начала node к счетчикам
- позволяют перейти от счетчиков к началу node с нулевой стоимостью (это необходимо только для закрытия пути)
- после того, как нарисовал вещь, скажите мне, если я что-то пропустил:)
НТН