Esta é uma excelente pergunta. Não tenho uma explicação totalmente satisfatória, mas deixe-me dar um começo nisso.
Primeiro, é importante entender que não podemos resolver esse problema simplesmente enumerando todos os ciclos e verificando o peso de cada um. Por que não? Porque pode haver (e muitas vezes existem) exponencialmente muitos ciclos. Portanto, apenas enumerá-las levará necessariamente um tempo exponencial - tempo demais para ser viável.
Então, como funciona Bellman-Ford? Ele funciona com algum truque inteligente que evita a necessidade de examinar individualmente cada ciclo, um por um. Em vez disso, cria um resumo que resume algo sobre o efeito de todos os caminhos e ciclos de comprimento atén. Efetivamente, para cada vérticev, resume todos os caminhos que começam em v, termina em ve tire no máximo npassos. Como todo ciclo deve conter um caminho desse formulário, o resumo de alguma forma encapsula o efeito de todos os ciclos possíveis.
Por que não podemos usar isso para detectar (por exemplo) se existe um ciclo de peso ≥1? É porque o resumo de Bellman-Ford inclui caminhos que percorrem o ciclo várias vezes. Se o ciclo é longok, então incluirá caminhos de comprimento n, ou seja, caminhos que percorrem o ciclo sobre n/kvezes. Por exemplo, se você tiver um ciclo de duraçãon/3, o resumo inclui um caminho que percorre o ciclo três vezes.
Qual é o efeito de andar de bicicleta várias vezes? Se você deseja distinguir ciclos de peso positivo daqueles que não são positivos, caminhar várias vezes não faz mal. Se o ciclo tiver peso positivo, você poderá caminhar algumas vezes e o peso total ainda será positivo. Se o peso do ciclo não for positivo, você poderá contorná-lo algumas vezes e o peso total ainda não será positivo. Portanto, se tudo o que nos importa é a diferença entre peso positivo e não positivo, caminhar várias vezes no ciclo não faz mal.
Mas agora considere como as coisas mudam se o que nos importa é a diferença entre "peso ≥1peso "vs" <1". Se temos um ciclo cujo peso é <1 e percorremos esse ciclo várias vezes, o peso total pode se tornar ≥1. Por exemplo, se o peso do ciclo for1/2 e andamos pelo ciclo três vezes, então o peso total desse caminho é 1.5, qual é ≥1: começamos com um ciclo de peso <1 e acabou com um caminho de peso ≥1.5. Esse fato estraga totalmente a Bellman-Ford e torna inútil verificar se existe um ciclo de peso≥1. (Você vê a diferença?)
Sei que essa não é uma resposta 100% satisfatória. Ele explica por que a Bellman-Ford não vai funcionar para resolver seu problema. No entanto, não lhe dá nenhuma intuição para explicar por que isso é difícil em geral (por exemplo, por que é difícil encontrar outro algoritmo para resolvê-lo). Não tenho uma intuição muito boa para isso - talvez alguém tenha uma explicação melhor para você. Enquanto isso, talvez isso lhe permita começar a entender por que esse problema é difícil.
Vamos considerar as versões mais simples desses problemas em que as arestas não são ponderadas.
Dado um gráficoG verifique se G tem um ciclo.
Dado um gráficoG e um número k verifique se G tem um ciclo de duração pelo menos k .
O primeiro é fácil e pode ser resolvido usando o DFS. O segundo é NP-difícil.
Vejamos um problema ainda mais simples:
Dado um gráficoG e dois vértices s e t , verifique se existe um caminho simples de s para t no G .
Dado um gráficoG e dois vértices s e t e um número k , verifique se existe um caminho simples de s para t no G de comprimento pelo menos k .
Todos esses problemas são do mesmo sabor. O superior é fácil, enquanto o inferior é NP-hard. Vou explicar a diferença para o último porque é mais simples, mas a mesma explicação se aplica aos outros pares.
A razão pela qual as primeiras são fáceis, enquanto as inferiores não são, é o resultado da estrutura das respostas para esses problemas.
Vamos primeiro examinar o problema de encontrar um caminho simples e tentar resolvê-lo recursivamente. Se apenas tentarmos resolver esse problema diretamente, precisaremos acompanhar os vértices que usamos até agora:
Se tentarmos resolver o problema com esse ingênuo algoritmo recursivo, levará um tempo exponencial: existem exponencialmente muitas possibilidades para o conjunto de vértices não utilizados! Temos que ser mais inteligentes.
Por que obtivemos exponencialmente muitas possibilidades? Como estávamos tentando encontrar um caminho simples e impor essa condição, precisávamos acompanhar os vértices não utilizados.
OK, então vamos abandonar essa condição e ver onde podemos obter:
Considere o problema de encontrar um caminho (não é necessário simples) des para t . Como o caminho não precisa ser simples, não precisamos rastrear vértices não utilizados. Em outras palavras, o gráfico não muda com o tempo.
Mas nós ainda não acabamos. A questão é que não sabemos sePathG(s,u)
é um problema menor que PathG(s,t) . Portanto, essa solução recursiva pode terminar em um loop e nunca terminar.
Para evitar isso, podemos adicionar um parâmetro extra que garanta que o problema fique menor: o número de arestas no caminho.
Agora observe que existe um caminho simples des para t se houver um caminho de s para t com no máximo n arestas. Em outras palavras:
Os pontos essenciais aqui são:
Todo caminho simples (não trivial) des para t
consiste em um caminho simples de s para algum vértice u e uma vantagem ut .
Podemos assumir quet não aparece no caminho simples de s para u .
Não precisamos manter explicitamente a lista de vértices não utilizados.
Essas propriedades nos permitem ter uma recursão inteligente pela existência de um problema de caminho simples.
Agora, isso não se aplica ao problema de encontrar um caminho de comprimento pelo menosk . Não sabemos como reduzir o problema de encontrar pelo menos um caminho simples de comprimentok
para um subproblema menor sem manter a lista de vértices não utilizados. Essas propriedades nos permitem resolver a existência do problema do caminho com eficiência.
Quando um gráfico não tem um ciclo negativo, ele nos permite resolver a existência de um caminho de comprimento, no máximok problema e o menor caminho simples problemas com eficiência.
No entanto, eles não sustentam a existência de um caminho de comprimento pelo menosk . Considere um gráfico com3 vértices s,u,t .
w(su)=1000,w(st)=1000,w(ut)=10,w(tu)=10 . O caminho do comprimento pelo menos1001 de s para t contém u e o caminho de comprimento pelo menos 1001 de s para u contém t . Portanto, não podemos reduzir uma instância do problema para uma instância menor do problema sem fornecer explicitamente a lista de vértices não utilizados.
Em outras palavras, não sabemos uma recursão inteligente para a existência de um caminho simples de comprimento pelo menosk problema enquanto conhecemos uma recursão inteligente pela existência de um caminho simples.
Voltando à última parte da sua pergunta, há um problema com o seu argumento.
É verdade que a existência de um ciclo de duração>k
pode ser resolvido em tempo polinomial para qualquer fixo k (ie k não faz parte da entrada). (Semelhante a como se pode verificar se um gráfico não ponderado tem um ciclo de duraçãok
em tempo O(nk) .)
No entanto, quandok faz parte da entrada, isso não se sustenta mais, já que o tempo de execução depende de k de um jeito ruim.
fonte