Caros colegas programadores,
Estamos desenvolvendo um software que simula o tráfego de veículos. Parte do processo chamado "atribuição" refere-se à atribuição de veículos às suas rotas e deve usar algum tipo de algoritmo de localização de caminho mais curto.
Tradicionalmente, as pessoas fazem isso com o de Dijkstra, e certas literaturas científicas parecem indicar que A * e outras alternativas não oferecem nenhuma melhoria significativa, talvez devido à natureza do gráfico.
Portanto, também estamos usando o Dijkstra. Surgiu um pequeno problema: se você tratar as ligações de tráfego (vãos de estradas entre cruzamentos) como arestas e cruzamentos como nós, não poderá obter um gráfico unidirecional clássico: ao se aproximar de um cruzamento, o qual você pode mudar frequentemente depende de onde você é, enquanto em um gráfico tradicional você pode obter qualquer vantagem de um nó.
Resolvemos esse problema com bastante facilidade, representando um par de interseção de links (chame de "ripa") como um nó. Como você precisaria atravessar um link para chegar a qualquer "rampa" subsequente, ou ponto de escolha, uma aresta seria então definida como esse percurso, e você obterá um gráfico típico.
Os resultados são armazenados em uma tabela simples, N x N, onde N é o número de "ripas".
Aqui está a (inevitável?) Desvantagem. Se uma rede típica para nossa simulação pode ter, digamos, 2000 cruzamentos, ela terá algo em torno de 6000 links, ou seja, N = 3V. Obviamente, se contados em termos de interseções (V), agora chegamos a O (log (3V) * (3V + E)).
Você pode argumentar que 3 (ou 9) é um fator constante, mas do ponto de vista prático, ele diminui bastante as coisas e aumenta o espaço de armazenamento para 3V x 3V.
Alguém tem alguma idéia de como podemos reestruturar isso para melhorar o desempenho? Não é necessariamente qualquer algoritmo alternativo, talvez reformule as estruturas de dados para ajustar um gráfico de alguma outra maneira?
fonte
Respostas:
O Dijkstra's encontra o caminho mais curto entre um determinado nó e todos os outros nós, portanto, espero que seja mais caro que o A *. No entanto, parece que você está tentando pré-calcular o custo e o caminho de um nó para outro? Então o Dijkstra's é o caminho a percorrer.
Quanto a uma representação mais simples, algumas coisas vêm à mente:
Em muitos cruzamentos, você pode entrar e sair da maneira que quiser. É apenas um subconjunto que você tem restrições como "nenhuma curva à esquerda". Então você pode usar os "ripas" apenas para cruzamentos onde você realmente precisa deles. Isso deve reduzir muito o tamanho ali.
Você poderia fazer isso automaticamente procurando "ripas equivalentes" e combinando-as. Dois tornos são equivalentes se todos os links que saem forem iguais. Por exemplo, se "Intersecção X proveniente do oeste" e "Intersecção X proveniente do sul" levam ao mesmo conjunto de outros nós, com o mesmo custo, apenas os mescla em um único nó.
Tem certeza de que precisa / deseja pré-calcular o melhor caminho, em vez de computá-lo online? Os videogames geralmente calculam essas coisas online.
Além disso, como você está representando os caminhos? Na sua matriz, você só precisa representar o primeiro link no caminho. Por exemplo, para ir da casa de Bob para o trabalho de Bob, você só precisa conhecer o primeiro link, pois quando eles chegarem lá, agora você pode procurar em sua matriz como obter o primeiro link para o trabalho de Bob, o que fornecerá a você o segundo link etc.
fonte
Você tem um gráfico grande e o tornou ainda maior. Martinc C. Martin aconselhou o uso de tornos somente quando necessário, então não vou entrar nisso.
Uma das coisas que pode ajudá-lo é transformar seu gráfico em gráficos menores.
A primeira simplificação que me ajudou muito (trabalhei com redes rodoviárias dos estados europeus) foi "remover" os nós com o digree 1 e 2 recursivamente. Dessa forma, você não tem ruas sem saída e as interseções em T (originalmente grau 3) tornam-se no grau 2 e isso não é interessante, se você não estiver percorrendo esse nó ou aquele nó naquele saco de lixo removido.
Depois disso, você pode tentar dividir seu gráfico em partes que possuam grande quantidade de nós e arestas internas, mas que tenham uma conexão mínima com outras partes. Para encontrá-los, usei o corte mínimo em que a pia e a fonte estavam tão distantes uma da outra (nas arestas) uma da outra e as arestas próximas a elas tinham uma capacidade enorme e as arestas em algum lugar tinham pequenas.
fonte