Coisas que eu gostaria de saber antes de desenvolver um Autorouter
(blog.autorouting.com)"Lições importantes para criar o autorouter mais rápido do mundo"
Usar o algoritmo A* em todo lugar
- A* é o algoritmo mais poderoso e flexível para problemas de busca
- Pode ser usado não só em uma simples grade 2D, mas também em vários tipos de problema
- O A* é uma "busca informada" que, de forma mais rápida e eficiente que o BFS, prioriza a exploração de nós mais próximos do destino
- Na maioria dos casos, DFS ou BFS usados em código existente podem ser substituídos por A*
- Para melhorar o desempenho, pode-se executar várias instâncias de A* e alocar mais recursos às configurações que apresentarem melhor performance
O algoritmo é mais importante do que a linguagem de programação
- Não houve problema algum em desenvolver o autorouter em Javascript
- O ponto central da otimização é reduzir o número de repetições
- Mais importante do que a performance da linguagem é "quão inteligente é o algoritmo que você consegue criar, e com que rapidez consegue criá-lo"
- Javascript favorece mais algoritmos inteligentes do que iteração rápida
Spatial Hash Indexing é mais eficiente do que estruturas em árvore
- Estruturas de dados baseadas em árvore, como Quadtree, em geral são lentas
- O Spatial Hash Index agrupa e processa objetos espacialmente próximos ao aplicar hash na posição deles
- Estruturas baseadas em hash oferecem desempenho de busca próximo de O(1)
- É preciso escolher bem o tamanho da célula para obter efeito, e essa escolha adequada não é difícil
Particionamento espacial e cache são 1000 vezes mais importantes do que o algoritmo
- Mesmo placas de circuito complexas costumam ter padrões repetitivos
- Assim como no desenvolvimento de jogos, armazenar resultados pré-calculados em cache pode melhorar drasticamente o desempenho
- Estruturas cacheáveis e particionamento espacial serão a base dos autorouters do futuro
- O armazenamento está ficando barato rapidamente, e até alguns GB de cache já podem trazer grandes ganhos de performance
Sem visualização, não dá para resolver o problema
- Para todo problema, a primeira coisa a fazer foi criar uma ferramenta de visualização
- Com visualização, foi possível melhorar a velocidade de depuração em mais de 10 vezes
- Mesmo etapas simples do algoritmo, quando visualizadas, permitem identificar rapidamente a causa do problema
As ferramentas de profiling do Javascript são muito úteis
- Na aba Performance das ferramentas de desenvolvedor do Chrome, dá para verificar o tempo gasto por trecho de código
- Mesmo sem framework adicional, é fácil analisar Flame Chart, uso de memória etc.
- São ferramentas muito úteis para depuração de performance
Não use funções recursivas
- Funções recursivas geralmente são síncronas e difíceis de converter para A*
- Implementações iterativas são mais rápidas e facilitam o rastreamento de nós visitados
- Em funções recursivas, é difícil alterar estado e isso tende a ser ineficiente
- Sempre que possível, escreva com base em laços iterativos
Evite algoritmos de Monte Carlo
- Algoritmos baseados em aleatoriedade são não determinísticos e difíceis de depurar
- Heurísticas especializadas no domínio sempre oferecem desempenho melhor
- Nenhum designer de PCB traça linhas aleatoriamente → não é uma abordagem realista
- Ainda assim, no começo pode ser útil para ganhar intuição
Mantenha as etapas do algoritmo ancoradas no espaço real do problema
- Normalizar subalgoritmos com base na origem dificulta entender o fluxo completo
- Visualizar as entradas e saídas de cada etapa ajuda a identificar qual etapa está causando erro
- É importante manter o fluxo do algoritmo preservando um sistema de coordenadas consistente
Visualize o processo iterativo com animação
- Dá para perceber visualmente o quanto o algoritmo está explorando de forma ineficiente
- Animações são muito eficazes para reduzir o número de iterações e aumentar a eficiência
- Também facilitam detectar situações problemáticas (por exemplo, uma busca presa em loop infinito)
A matemática de detecção de interseção basta, sem grade
- Em vez de usar uma grade, usar matemática vetorial é muito mais rápido
- Em muitos casos, operações matemáticas podem ser mais rápidas do que acesso à memória
- Graças aos LLMs, ficou mais fácil implementar também a matemática de detecção de interseção
- Usar grade sem necessidade é uma causa de queda de desempenho
Medir a probabilidade de falha em cada etapa ajuda a priorizar a possibilidade de solução
- É possível estimar a probabilidade de falha em cada nó do particionamento espacial
- Depois, prioriza-se a reconfiguração ou nova exploração dos nós com maior chance de falhar nas etapas seguintes
- A probabilidade de falha pode ser medida claramente e tem mais potencial de melhoria do que heurísticas
- Aumentar a chance de resolver o problema como um todo pode ser mais eficaz do que buscar apenas otimização
Com Weighted A*, é possível ganhar 100 vezes em velocidade
- O A* padrão garante o caminho ótimo, mas é lento
- O Weighted A* explora de forma mais gulosa e pode aumentar drasticamente a velocidade
- Pode ser implementado apenas ajustando o peso em
f(n) = g(n) + w * h(n) - Mesmo abrindo mão de um pouco de optimalidade, ele consegue resolver o problema muito mais rápido
- É uma técnica usada com frequência também no desenvolvimento de jogos e vale a referência
1 comentários
Comentários no Hacker News
Descartar métodos de Monte Carlo rapidamente é um grande erro
Tenho a posição de que "não se deve confiar em auto-routers"
O artigo menciona pontos importantes sobre visualização e efeitos de cache
É uma excelente discussão sobre autorroteamento
95% do foco deveria estar em reduzir o número de iterações
numpy,pandas,OpenCVeTensorFlowsão implementados em C++/assembly/CUDA de alto desempenhoQuadTree e estruturas de dados em árvore de modo geral são muito lentas
Quase tudo isso bate com heurísticas de desenvolvimento de jogos
"indexação por hash espacial > estruturas de dados em árvore" é bom neste domínio, mas não deve ser tomado como verdade universal
Lembro das palavras-chave que aprendi na universidade
Como alguém que não lida diretamente com problemas espaciais 2D/3D, a maior lição para mim é o valor da visualização