Почему допущение движения по диагонали сделало бы неприемлемыми А* и Манхэттенское расстояние?

Меня немного смущает диагональное движение в сетке с использованием A * и метрики расстояния Манхэттена. Кто-нибудь может объяснить, почему использование диагонального движения делает его недопустимым? Не будет ли движение по диагонали найти лучшее оптимальное решение, например, сделать меньше шагов, чтобы добраться до целевого состояния, чем вверх вниз влево вправо, или я что-то упустил?


person Schonge    schedule 12.12.2013    source источник
comment
Каково манхэттенское расстояние от (1,1) до (2,2)? Что такое диагональное (евклидово) расстояние? Учитывая, что допустимая эвристика не может завышать реальное расстояние до цели, вы видите проблему?   -  person beaker    schedule 12.12.2013


Ответы (2)


Во многом, как указывает комментарий стакана, Манхэттенское расстояние будет переоценивать расстояние между состоянием и состояниями, доступными для него по диагонали. По определению, эвристика, переоценивающая расстояния, недопустима.

Теперь, почему именно это так?

Предположим, что ваша процедура Manhattan Distance выглядит примерно так:

function manhattan_dist(state): 
    y_dist = abs(state.y - goal.y)
    x_dist = abs(state.x - goal.x)
    return (y_dist + x_dist)

Теперь рассмотрим случай применения этой процедуры к состоянию (1,1) и предположим, что целью является состояние (3,3). Это вернет значение 4, которое переоценивает фактическое расстояние, равное 2. Следовательно, манхэттенское расстояние в этой ситуации не будет работать как допустимая эвристика.

На игровых полях, которые позволяют двигаться по диагонали, вместо этого обычно используется Расстояние Чебышева. Почему?

Рассмотрим эту новую процедуру:

function chebyshev dist(state): 
    y_dist = abs(state.y - goal.y)
    x_dist = abs(state.x - goal.x)
    return max(y_dist, x_dist)

Возвращаясь к предыдущему примеру (1,1) и (3,3), эта процедура вернет значение 2, которое действительно не является завышенной оценкой фактического расстояния.

person Juser1167589    schedule 12.12.2013
comment
Отличный эвристический метод! - person Jorjon; 12.09.2014

Хотя эта тема старше, я хотел бы добавить другое решение, которое использует самый быстрый свободный путь к цели, если разрешено диагональное движение.

function heuristic(state):
    delta_x = abs(state.x - goal.x)
    delta_y = abs(state.y - goal.y)
    return min(delta_x, delta_y) * sqrt(2) + abs(delta_x - delta_y)

Этот метод возвращает эвристику, которая перемещает максимальное количество по диагонали, а остаток — по прямой к цели, и представляет максимально возможную эвристику, которая не переоценивает затраты на движение к цели.

person philkark    schedule 06.07.2016