Modificando o algoritmo de Dijkstra para pesos de borda extraídos do intervalo


10

Suponha que eu tenha um gráfico direcionado com pesos de arestas desenhados no intervalo onde é constante. Se estou tentando encontrar o caminho mais curto usando o algoritmo de Dijkstra , como posso modificar a estrutura do algoritmo / dados e melhorar a complexidade do tempo para ?[1,,K]KO(|V|+|E|)


Você deve especificar: Qual é a sua estrutura de dados? E você não pode obter menos O(V+E) . Revise as palestras.
precisa saber é o seguinte

Só porque as possibilidades de pesos distintos das arestas são pequenas, não significa que o número de distâncias seja pequeno.
21412 Joe

3
Primeiros vértices coloridos do seu gráfico com azul, depois subdividir cada aresta do tamanho t em arestas t (adicionando t1 vértices não coloridos), depois execute o BFS neste novo gráfico, para encontrar caminhos mais curtos do nó inicial aos nós azuis, é O(|V|+|E|) se você tiver constante k .

@SaeedAmiri, por que não escrever isso como resposta?
22412 Joe

@ Joe, porque não está modificando dijkstra (pelo menos diretamente não está relacionado a dijkstra).

Respostas:


16

Se os pesos das arestas forem números inteiros em , você poderá implementar o Dijkstra para executar no tempo O ( K | V | + | E | ) , seguindo a sugestão de @ rrenaud. Aqui está uma explicação mais explícita.{0,1,,K}O(K|V|+|E|)

A qualquer momento, as teclas (finitas) na fila de prioridade estão em algum intervalo , em que D é o valor da última chave removida da fila de prioridade. (Cada chave é pelo menos D , porque a sequência de chaves removidas pelo algoritmo de Dijkstra não diminui e cada chave é no máximo D + K , porque cada chave tem o valor d [ u ] + w t ( u , w ) para alguma vantagem ( u ,{D,D+1,,D+K}DDD+Kd[u]+wt(u,w) onde d [ u ] é a distância da fonte a algum vértice u que já foi removido, então d [ u ] D. )(u,w)d[u]ud[u]D

Por isso, é possível implementar a fila de prioridade com uma matriz circular do tamanho K + 1 , com cada célula contendo um balde. Armazene cada vértice com a chave k no balde na célula A [ h ( k ) ] onde h ( k ) = k mod ( K + 1 ) . Mantenha o controle de D . Execute as operações da seguinte maneira:A[0..K]K+1kA[h(k)]h(k)=kmod(K+1)D

  • eliminar-min : Enquanto está vazio, incremento D . Em seguida, exclua e retorne um vértice de A [ h ( D ) ] .A[h(D)]DA[h(D)]

  • inserir com a chave : adicione o vértice ao balde de A [ h ( k ) ] .kA[h(k)]

  • tecla de diminuição para k : mova o vértice de A [ h ( k ) ] para A [ h ( k ) ] .kkA[h(k)]A[h(k)]

Inserir e diminuir chave são operações de tempo constante; portanto, o tempo total gasto nessas operações será . O tempo total gasto em apagar-min será O ( | V | ) mais o valor final de D . O valor final de D é a distância máxima (finito) a partir da fonte para qualquer vértice (porque uma exclusão min que leva i iterações aumenta D por i ). A distância máxima é no máximo K ( | V | - 1O(|V|+|E|)O(|V|)DDiDi porque cada caminho tem no máximo | V | - 1 arestas. Assim, o tempo total gasto pelo algoritmo é O ( K | V | + | E | ) .K(|V|1)|V|1O(K|V|+|E|)


Eu gosto da fila circular, que é muito melhor do que a minha ideia de ter basicamente uma matriz de tamanho K * v, onde apenas uma fatia do tamanho av é usada a qualquer momento.
Rrenaud 21/11/12

Eu o implementei usando uma lista dupla, isso ainda significa que é O (1) para encontrar a chave min?
user1675999

@ user1675999, não tenho certeza. se sua lista é classificada por chave, como você insere e diminui a chave com eficiência? se sua lista não é classificada por chave, como você exclui-min com eficiência?
Neal Young

5

Suponho aqui que é um número inteiro e os pesos das arestas são integrais. Caso contrário, ele realmente não comprar qualquer coisa, você pode pesos sempre redimensionar para que a borda min custou 1 eo máximo tem custo K , então o problema é idêntico ao problema do caminho mais curto padrão.K1K

Esboço de algoritmo / prova: implemente a fila de prioridade desse tipo maluco como uma matriz de listas codificadas pelo custo e, de outra forma, usam o algoritmo padrão do Dijkstra. Mantenha um contador que rastreie o custo do item mínimo na pilha. Resolva a chamada de remoção da fila depois que os itens forem excluídos pela varredura linear . Sim, isso parece insano, mas constante KK×|V|Kvamos enganar e enganar sua intuição algorítmica contra verificações lineares. Você só precisa procurar a partir do último marcador min, porque o algoritmo do Disjkstra é bom para a implementação da fila. No momento em que solicita uma desenfileiramento, os itens inseridos na fila são sempre maiores ou iguais ao mínimo anterior. O caminho mais curto mais longo possível possui comprimento , então seu custo de digitalização amortizado é K × | V | = O ( | V | ) se K for constante.K×|V|K×|V|=O(|V|)


-2

você pode usar a classificação topológica para encontrar a solução, deixar a fonte ter o grau 0 e ir de cada extremidade da fonte; se outro vértice tiver 0 grau, coloque-o na fila e continue fazendo isso. nesse caso (sem ciclo dentro do gráfico), ele pode atingir V + E, pois passaria por todos os vértices e arestas uma vez e apenas uma vez.


Parece não relacionado à pergunta? A questão não supõe que o gráfico seja acíclico e sua solução não utiliza o fato de que os pesos são retirados de um intervalo constante.
Xskxzr
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.