Я должен найти кратчайший путь от точки D до R. Это неподвижные точки. Это пример ситуации:
Коробка также содержит стены, через которые вы не можете пройти через них, если вы не сломаете их. Каждая стеновая разладка стоит вам, пусть говорят "a", где "a" - положительное целое число. Каждое движение, которое не связано с стеной, стоит вам 1 балл.
Миссия состоит в том, чтобы выяснить из всех путей минимальной стоимости, которая имеет наименьшее количество разбитых стен.
Так как ширина окна может достигать 100 ячеек, это не имеет значения для использования обратного отслеживания. Это слишком медленно. Единственное решение, которое я придумал, - это одно:
Повторите шаги 1, 2, 3, пока "пассажир" не достигнет точки R. Между этими тремя шагами существуют отношения "еще-если".
Можете ли вы придумать лучший алгоритм проблемы? Я программирую в C++.
Используйте Dijkstra, но за это стоит 1 за ход, который не разрушает стену, и (a + 0,00001) для взлома стены. Тогда Дийкстра даст вам то, что вы хотите, путь, который разбивает наименьшие стены среди всех дорог с минимальными затратами.
Концептуально представьте себе путешественника, который может перепрыгнуть через стены - при этом отслеживать стоимость - и также может разбиться на двух одинаковых путешественников, столкнувшись с выбором двух путей, чтобы взять их обоих (возьмите это, Роберт Фрост!). Только один путешественник движется за один раз, тот, кто понес самую низкую стоимость до сих пор. Этот движется и пишет на полу "Я добрался сюда за счет только х". Если я нахожу такую заметку уже там, если я туда поделюсь дешевле, я стираю старую записку и пишу сам; если этот другой путешественник стал там дешевле, я совершу самоубийство.
Двухчастная "стоимость сначала, а затем сломанные стены" может быть представлена в виде пары (c, w), которая сравнивается лексикографически. c - стоимость, w - количество сломанных стенок. Это делает его "единственной вещью" снова (в некотором смысле), поэтому это вещь, которую вы можете использовать в алгоритмах и т.д., Которые ожидают просто "затрат" (как абстрактная вещь, которая может добавить другую стоимость или сравнить к другой стоимости).
Таким образом, мы можем просто использовать A * с эвристикой на расстоянии Манхэттена (возможно, там что-то умнее, которое не игнорирует стены полностью, но это будет работать - недооценка расстояния недопустима). Стоимость движения, конечно, не будет игнорировать стены. Соседи будут все смежные квадраты. Все затраты будут парой, описанной выше.
Это можно легко смоделировать как взвешенный график, а затем применить к нему алгоритм кратчайшего пути Дейкстры. Каждый квадрат является узлом. Он подключен к узлам квадратов, к которым он примыкает. Вес соединений равен 1 или "а", в зависимости от того, есть ли стена или нет. Это даст вам минимальные затраты. Возможно, что минимальная стоимость и минимальное количество разрывов стен могут быть разными.
Вот общий алгоритм (вам нужно выполнить реализацию самостоятельно):
Преобразуем матрицу в взвешенный граф:
Vertex
.Vertex
создайте массив Edges
, по одному для каждого соседнего Vertex
.Edge
определите вес в зависимости от стоимости разрушения стены между двумя Vertices
которые соединяет Edge
. Затем запустите алгоритм Дейкстры (http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm) на графике, начиная с Vertex D
В качестве вывода у вас будет самый короткий (самый дешевый) путь от Vertex D
до любого другого Vertex
на графике, включая Vertex R