Contexto
Os antigos jogos da Lucas Arts (era ScummVM) apontam e clicam em aventuras gráficas usadas como busca pré-computada. Aqui está um esboço da técnica.
Passo 1
O piso de cada quarto era dividido no que eles chamavam de "caixas de passagem", que eram praticamente equivalentes a nós em uma malha de navegação, mas limitados a formas trapezoidais. Por exemplo:
______ _____ _________ _____
\ A | B | C | D \
\_____| | |_______\
|_____| |
|_________|
Passo 2
Um algoritmo offline (por exemplo, Dijkstra ou A *) calcularia o caminho mais curto entre cada par de nós e armazenaria a primeira etapa do caminho em uma matriz 2D, indexada em cada dimensão pelo nó inicial e final usado. Por exemplo, usando as caixas de passagem acima:
___ ___ ___ ___
| A | B | C | D | <- Start Node
___|___|___|___|___|
| A | A | A | B | C | ---
|___|___|___|___|___| |
| B | B | B | B | C | |
|___|___|___|___|___| |-- Next node in shortest path
| C | B | C | C | C | | from Start to End
|___|___|___|___|___| |
| D | B | C | D | D | ---
|___|___|___|___|___|
^
|
End Node
Como você pode imaginar, os requisitos de memória aumentam rapidamente à medida que o número de nós aumenta (N ^ 2). Como um pequeno normalmente seria grande o suficiente para armazenar cada entrada na matriz, com um mapa complexo de 300 nós que resultaria no armazenamento de um extra:
300^2 * sizeof(short) = 176 kilobytes
etapa 3
Por outro lado, calcular o caminho mais curto entre dois nós foi extremamente rápido e trivial, apenas uma série de pesquisas na matriz. Algo como:
// Find shortest path from Start to End
Path = {Start}
Current = Start
WHILE Current != End
Current = LookUp[Current, End]
Path.Add(Current)
ENDWHILE
A aplicação desse algoritmo simples para encontrar o caminho mais curto de C a A retorna:
1) Path = { C }, Current = C
2) Path = { C, B }, Current = B
3) Path = { C, B, A }, Current = A, Exit
Questão
Suspeito que, com o hardware poderoso de hoje, juntamente com os requisitos de memória para fazer isso em todos os níveis, quaisquer benefícios que essa técnica tenha tido agora sejam superados com a simples realização de um A * em tempo de execução.
Também ouvi dizer que hoje em dia as pesquisas de memória podem até ser mais lentas que a computação geral, e é por isso que criar tabelas de pesquisa de seno e cosseno não é mais tão popular.
Mas devo admitir que ainda não conheço muito bem esses assuntos de eficiência de hardware de baixo nível; portanto, estou aproveitando a oportunidade para pedir a opinião daqueles mais familiarizados com o assunto.
No meu mecanismo, eu também precisava da capacidade de adicionar e remover nós dinamicamente ao gráfico em tempo de execução ( veja isso ), para que a rota pré-computada só tornasse as coisas mais complicadas, então eu a desfiz (sem mencionar que minha solução A * em tempo de execução já estava funcionando perfeitamente) ) Ainda assim, fiquei me perguntando ...
Bottom line, esta técnica ainda é relevante hoje em dia em qualquer cenário?