Algoritmo de configuração de etiqueta para resolver o problema do caminho mais curto com janela de tempo (ESPPRC)

O artigo a seguir é do especialista em dados, autor Deng Faheng, Zhou Hang

Prefácio

Olá pessoal ~!

Presumivelmente, todos se sentirão um pouco perdidos quando começarem a aprender o modelo de pesquisa de operações? Por exemplo, muitos substantivos mágicos, todos os tipos de restrições. . . Enfim, no começo eu estava em um estado de ignorância.

Portanto, desta vez, trazemos um problema básico de caminho mais curto com a janela de tempo (Problema de Caminho Mais Curto com Janelas de Tempo, conhecido como SPPTW) , usando um algoritmo básico preciso, ou seja, o algoritmo de configuração de rótulo, para resolvê-lo. Como as referências são relativamente antigas, esse método agora foi bastante otimizado. Obviamente, somente começando pelo básico e subindo passo a passo podemos continuar a resolver problemas mais difíceis. (Francamente, é difícil para o editor ser apimentado)

Sem mais delongas, comece este artigo!

Para baixar o código e os exemplos relevantes neste artigo, preste atenção ao número público [som do programa], a resposta em segundo plano [SPPTWCPP] não inclui []

Diretório

1. Introdução ao SPPTW 2. Introdução ao
algoritmo de configuração de rótulo
3. Poda dominante: dominar
4. Ordem do processamento de rótulo: classificação de dicionário
5. Fluxo de algoritmo e exemplos
6. Compartilhamento de código-fonte em C ++

Introdução ao SPPTW

Vamos primeiro apresentar brevemente o problema a ser tratado.

Problema de caminho mais curto (SPP) :

Em um gráfico, cada aresta tem um número associado a ela e chamamos esse número de peso . Para a figura a seguir G = (N, A), cada aresta tem apenas um peso para representar o custo (pode ser entendido como o comprimento da aresta). Dado o ponto inicial p, encontre o caminho com o menor custo para que p atinja os pontos restantes .

Por exemplo, a imagem acima. Cada lado tem o direito de representar custos. O problema tradicional do caminho mais curto exige que encontremos o caminho do custo mínimo desde o ponto inicial (como v_0) até os pontos restantes. Por exemplo, o caminho mais curto de v_0 a v_4 é v_0 → v_2 → v_3 → v_4 e o custo total é 19; e o caminho de v_0 → v_4, o custo total é 30, portanto, não é o caminho mais curto de v_0 a v_4.

Observe que no problema clássico de caminho mais curto, os pesos nas bordas são geralmente positivos .

No SPPTW:

Cada aresta da figura possui dois pesos , um dos quais representa o tempo gasto e o outro representa o custo de ouvir a aresta . Cada nó i possui uma janela de tempo [a_i, b_i] e o caminho precisa atender às restrições da janela de tempo ao acessar o nó, a saber:

Se o tempo para chegar ao ponto i for anterior ao tempo a_i quando a janela de tempo for aberta, será necessário aguardar até que a janela de tempo seja aberta antes de entrar; se o tempo de chegada exceder o tempo de fechamento b_i, você não poderá acessar o nó.

(D_ij representa o tempo, c_ij representa o custo, [xx, yy] representa a janela de tempo. Veja a definição abaixo para obter detalhes)

Nesta base, encontrar o caminho com o menor custo total, do ponto inicial p (ponto v_1) aos pontos restantes, é o problema que precisamos resolver.

Na figura, podemos ver que o peso de custo de v_1 → v_4 é negativo. O algoritmo neste artigo pode não apenas resolver o caso em que o custo é positivo, mas também resolver o caso em que o custo é negativo . Apenas certifique-se de que o consumo de tempo seja positivo .

Nesta base, o modelo do problema é estabelecido:

O caminho X_1 ^ 0 pode ser representado pelo seguinte diagrama:

A modelagem tradicional de problemas de curto-circuito pode remover diretamente algumas definições e não as repetirá. Vamos primeiro examinar o método de rotulagem para lidar com o problema tradicional de caminho mais curto.

Introdução ao algoritmo de configuração de etiquetas

Os algoritmos de rotulagem (algoritmos de rotulagem) são um método importante para resolver o problema do caminho mais curto, mas também a parte principal dos algoritmos do caminho mais curto.

De acordo com diferentes estratégias de processamento para nós de etiqueta, os algoritmos de identificação podem ser divididos em dois sistemas: configuração de etiqueta (LS) e correção de etiqueta (LC).

Dois algoritmos clássicos relacionados ao problema do caminho mais curto, o algoritmo de Dijkstra e o algoritmo Bellman-Ford, pertencem ao LS e ao LC, respectivamente.

O algoritmo LS revisa gradualmente o rótulo através do processo de iteração: cada iteração seleciona o menor rótulo no conjunto de nós candidatos para sair do conjunto de nós candidatos e altera o rótulo do nó do rótulo temporário para o rótulo permanente por um longo tempo. Este é um algoritmo de caminho mais curto, baseado na estratégia gananciosa, e cada vez que o rótulo convertido em um rótulo permanente representa o caminho mais curto para o nó atual, o "melhor atual" é considerado.

O algoritmo LC não altera necessariamente nenhum rótulo de nó de um rótulo temporário para um rótulo permanente em cada iteração, mas apenas corrige o rótulo temporário uma vez e todos os rótulos de nó ainda são rótulos temporários; somente quando todas as iterações terminam O rótulo também é convertido em um rótulo permanente. O algoritmo LC considera o "ótimo final", e o caminho mais curto precisa aguardar várias iterações até que todo o algoritmo seja concluído antes de ser determinado.

Introduzimos principalmente o algoritmo LS. Aqui, apresentamos o algoritmo Dijkstra para resolver o problema do caminho mais curto sem restrições da janela de tempo. Nesse algoritmo, para o nó i, o rótulo é (C [i], p [i]), onde C [i] representa a distância mais curta do ponto inicial ao nó i ep [i] é gravado em d [i] distância , No caminho do ponto inicial ao nó i, o número do nó antes do nó i. s_0 representa o ponto de partida. c_ij representa a distância através da aresta (i, j). O processo de execução é o seguinte:

Etapa0: inicializar. Seja S vazio, S * = N, C [s_0] = 0, p [s_0] = -1; deixe a etiqueta de distância inicial C [j] = ∞ para o vértice i (i ≠ s_0) em N.

Etapa 1: julgamento de limite. Se S = N, C [j] é o menor comprimento do caminho, e o caminho mais curto pode ser obtido retornando pelas informações registradas por p [j]. Fim. Caso contrário, continue na etapa 2.

Etapa 2: atualize a marca. De S para encontrar o custo total mínimo de nó i, S-lo da eliminação, adição de S. Para todos os pontos subseqüentes j começando em i, se C [j]> C [i] + c_ij, então deixe C [j] = C [i] + c_ij, p [j] = i. Vá para o passo 1.

O cálculo principal desse algoritmo é o ciclo step2. Inclui dois processos: o processo de encontrar um nó (encontrar o nó i com o menor custo de S *) e o processo de atualizar o custo total (o custo de atualizar o nó adjacente ao nó i).

No entanto, o algoritmo Dijkstra simples não pode lidar com a restrição da janela de tempo, nem com arestas de peso negativas: no processo de loops contínuos, algumas arestas são realmente ignoradas por nós. Mesmo que seu valor de peso seja negativo, podemos otimizar o custo. Não vai se importar.

A seguir, proporemos uma versão aprimorada do algoritmo LS, que pode lidar com restrições da janela de tempo e satisfazer bordas de peso negativas.

Poda dominante: dominar

Depois de entender o algoritmo LS para resolver o problema do caminho mais curto, retornamos ao problema mais curto sob a restrição de janela de tempo. Devido ao peso do tempo, nosso marcador não pode mais registrar apenas um custo variável, como na seção anterior. Criamos um rótulo para cada estado de cada caminho para cada ponto (T, C) e registramos o tempo total e o custo total do caminho quando ele atinge o ponto .

De acordo com a definição, podemos fornecer o método de processamento da marca:

Obviamente, você pode usar a exaustão para resolver diretamente o problema com um método semelhante ao Dijkstra. Mas esperamos encontrar um método de poda eficaz para evitar a alta complexidade de tempo causada pela exaustão. Felizmente, nem todos os marcadores são válidos para encontrar o caminho mais curto do ponto de partida para cada ponto. Ilustramos pelo exemplo:

Dominate  regra nos permite filtrar tag inválida .

Podemos usar uma função para expressar visualmente esse relacionamento:

Obviamente, na figura, se a inclinação k> = 0 entre os dois pontos, o ponto final é dominado. (Como X_i ^ 1 dominaX_i ^ 5) Como os dois caminhos representados pelos dois marcadores atingirão o mesmo ponto, e o caminho no final da inclinação tem tempo e custo mais altos, é claro, pior. Quando k = 0, desenhamos várias linhas retas na figura . Cada linha é desenhada por um ponto (representando uma marca) e o próximo ponto termina. Isso significa que, no tempo correspondente a esta linha, o custo da marca é o custo mínimo. Em outros casos, não é possível determinar qual caminho é melhor.

Nós filtramos através de uma função EFF (). Na introdução da primeira parte do LS, mencionamos o conceito de marcadores permanentes , o que significa que garantimos a validade dos marcadores permanentes, e seus valores de marcadores não serão alterados durante o processo de expansão subsequente. Fornecemos um método para expandir a marca permanente correspondente ao nó j.

Definição:

Q_j é o conjunto de tags permanentes para o nó j. (O custo mínimo de todos os marcadores em Q_j é o caminho mais curto de p a j)

Expanda Q_j das seguintes maneiras:

A extensão aqui realmente implica que todos os rótulos que podem dominar o novo rótulo devem existir em Q_j. Como garantir isso? Fornecemos uma solução na próxima seção.

Marcar ordem de processamento: classificação do dicionário

No processo de tags de processamento LS, expandimos as tags na ordem dos nós; portanto, para várias tags de um nó, precisamos processá-las em uma sequência. Essa sequência é melhor para encontrar todos os pontos inválidos no processo de expansão, ou seja, procurar EFF durante a expansão.

Na imagem da função, usamos a inclinação k para representar a relação dominante; é fácil pensar em julgar k da esquerda para a direita e encontrar todos os segmentos de linha em que k> = 0. Após a conversão, ele é classificado na ordem de comparação de T e depois de C. Portanto, também consideramos o armazenamento na ordem de julgar T antes de julgar C ao armazenar a marca, e o processamento é processado de pequeno a grande. Isso é chamado de classificação de dicionário . Obviamente, essa é uma classificação total , que atende às nossas necessidades.

Temos as seguintes três proposições:

A ordem lexicográfica nasce para cooperar com o julgamento dominante. São operações semelhantes a podas para evitar a exaustão. Depois de adicionar essas duas operações, você encontrará muitos caminhos inviáveis ​​durante o processo de enumeração.Como não é possível, a expansão do caminho será interrompida imediatamente .

Dividimos todas as tags em três partes:

Q é uma coleção permanentemente marcada

P é uma coleção de tags processadas.

T é o conjunto de tags não processadas.

Classificamos todas as tags em ordem lexicográfica para garantir que todas as tags em T não possam dominar as tags em P. Como o tempo d_ij de cada aresta é positivo, a nova marca que foi expandida deve ser organizada após a marca original e a marca original não pode mais ser dominada. A relação de dominação é transitiva.De acordo com o método de indução , a marca em T não pode ser dominada por nenhuma marca P.

Também podemos usar a definição de P, Q, T para fornecer um relacionamento:

Podemos usar esta fórmula para calcular T no algoritmo.

Fluxo de algoritmos e exemplos

Um exemplo simples:

Partilha de código

O código C ++ é fornecido abaixo. As castanhas usam as castanhas simples acima, nomeadas de acordo com a definição acima. Depois de entender o fluxo do algoritmo, o código em si não é difícil. O foco do código aqui é cooperar com a explicação, como referência, para não escolher estruturas de dados complexas e habilidades gramaticais.Os amigos em necessidade podem experimentá-lo como um exercício.

Para baixar o código e os exemplos relevantes neste artigo, preste atenção ao número público [som do programa], a resposta em segundo plano [SPPTWCPP] não inclui []

Este artigo está quase aqui ~

Este tweet foi revisado várias vezes. Agradeço ao Diretor Sênior Deng Faheng e ao Professor Qin Hu por seu apoio, fiz muitas alterações! Muito obrigado!

O editor trabalhará duro para escrever tweets mais emocionantes para todos!

Até a próxima ( _ ) / ~~

Acho que você gosta

Origin www.cnblogs.com/dengfaheng/p/12672757.html
Recomendado
Clasificación