Estou implementando o algoritmo de cancelamento de ciclo para encontrar uma solução ideal para o problema de fluxo de custo mínimo. Ao encontrar e remover ciclos de custo negativos na rede residual, o custo total é reduzido em cada rodada. Para encontrar um ciclo negativo, estou usando o algoritmo bellman-ford.
Meu problema é: o Bellman-ford encontra apenas ciclos que podem ser acessados a partir da fonte, mas também preciso encontrar ciclos que não são acessíveis.
Exemplo: na rede a seguir, já aplicamos um fluxo máximo. A beiratorna muito caro. Na rede residual, temos um ciclo de custo negativo com capacidade. Removê-lo, nos daria uma solução mais barata usando bordas e , mas não podemos alcançá-lo da fonte .
Etiquetas: Custo / Fluxo / Capacidade
Obviamente, eu poderia executar o Bellman-ford repetidamente com cada nó como fonte, mas isso não parece uma boa solução. Estou um pouco confuso porque todos os papéis que li parecem pular esta etapa.
Você pode me dizer, como usar o bellman-ford para encontrar todos os ciclos negativos (acessíveis ou não)? E se não for possível, qual outro algoritmo você propõe?
fonte
Respostas:
Para expandir meu comentário, lembre-se, esse algoritmo para encontrar fluxo de custo mínimo baseia-se no fato de quef é máximo. Executando primeiro a Ford-Fulkerson para encontrarf e a rede residual resultante Gf , o custo f é então reduzido por encontrar ciclos negativos em Gf . Ou seja, encontrando ciclos negativos emGf nós não mudamos a quantidade de fluxo, f , mas apenas o custo.
Agora, executando Bellman-Ford det no Gf podemos rastrear para trás em arestas com fluxo não negativo (por definição de Gf ) Se os ciclos estiverem adjacentes a qualquer aresta nesses caminhos, podemos "transferir" uma certa quantidade de fluxo para outras arestas do ciclo. Em outras palavras, mantemos o fluxo líquido por algum ciclo o mesmo, mas somos capazes de alterar o custo.
Observe um ciclo inacessível det deve ter fluxo zero. Caso contrário, teríamos uma contradição emf sendo máximo.
Peço desculpas pela "ondulação da mão" dessa explicação. Vou tentar ser mais formal quando tiver tempo esta noite.
fonte
Minha sugestão: você deve iniciar o algoritmo a partir de T, a fim de encontrar um ciclo negativo em sua rede residual. O resultado deve ser o mesmo, mas você pode alcançar o círculo
fonte
Eu acho que não é suficiente rodar Bellman-Ford de T ou S. Considere um exemplo em que há uma borda de S para T e um ciclo de custo negativo não alcançável nem de S nem de T.
Uma solução é adicionar um S 'auxiliar e adicionar uma aresta de S' a qualquer outro vértice com custo 0. Em seguida, execute Bellman-Ford da S '. Desta forma, todos os ciclos negativos são alcançáveis a partir de S '.
Além disso, você realmente não precisa adicionar esse vértice auxiliar S 'em sua implementação. Apenas inicialize d (v) = 0 para qualquer vértice v.
Veja como a Boost Graph Library a implementa.
fonte