Aula 11: Backtracking
20/02/2003
Também disponível nos formatos pdf e no formato ps.
Vamos considerar um problema resolvido por uma estratégia força bruta. O espaço de solução para este problema corresponde ao conjunto de todas as soluções viáveis. Vamos supor ainda que esse espaço solução é finito. A estratégia força bruta seria:
Em vez de tentar todas as soluções, backtracking reduz o espaço de solução, através de uma análise de restrições, eliminando aquelas soluções parciais que não têm chance de sucesso (poda do espaço de soluções).
As soluções são representadas por
-tuplas ou vetores de solução
. Cada
é escolhido a partir de um conjunto
finito de opções
.
Um algoritmo de backtracking inicia com um vetor vazio. Em cada etapa, o
vetor é extendido com um novo valor formando um novo vetor que pode
representar uma solução parcial do problema. Na
avaliação de um vetor
, se for constatado
que ele não pode representar uma solução parcial, o algoritmo faz o
backtrack, eliminando o último valor do vetor, e continua tentando extender
o vetor com outros valores alternativos.
Aqui apresentamos um esquema genérico de algoritmos de backtracking:
Um aspecto bastante importante nos problemas que são tratados por soluções baseadas em backtracking, é a definição de restrições. Existem dois tipos de restrições: restrições explícitas e restrições implícitas.
Restrições explícitas correspondem às regras que restringem cada
em tomar valoes de um determinado conjunto. Isto está relacionado
com a representação do problema e as escolhas possíveis.
Restrições implícitas determinam quais das
-tuplas no espaço
de soluções correspondem a soluções para um determinado problema.
Se
é o domínio de
, então
é
o espaço de soluções do problema. O critério de validação (determinado
pelas restrições implícitas) determina que parte deste conjunto solução
necessita ser considerado.
A busca pelo espaço de soluções pode ser representado por um caminhamento em profundidade de uma árvore.
O exemplo da mochila binária já é bastante conhecido. A restrição
explícita, neste caso, é:
.
Assim, se fizermos a enumeração exaustiva do espaço de soluções
para
, teremos a seguinte árvore:
Uma outra restrição explícita é o fato de que
,
que indica a capacidade da mochila. Supondo que
, podemos
usar esta restrição para podar nossa árvore.
Finalmente, podemos utilizar restrições implícitas para podar ainda mais a
árvore. Se estamos interssados em ter o maior lucro e, em uma determinada
solução temos lucro
, não adianta considerar aquelas soluções parciais
que não levem a um lucro de pelo menos
.
Considere um tabuleiro de xadrez
. O problema consiste em colocar
rainhas no tabuleiro sem que nenhuma delas possa atacar uma outra rainha.
O espaço de solução é
. Tentando todas as
possibilidades possíveis temos
possibilidades. Como as rainhas devem
estar em diferentes colunas, o número de possibilidades se reduz a
.
Usando backtracking e considerando que duas rainhas não podem estar na mesma coluna, linha ou diagonal, podemos reduzir o espaço de busca.
Este problema assume um conjunto de
cidades e um caixeiro-viajante
que necessita visitar cada uma das cidades. Por questão de economia, ele
deve visitar uma única vez cada cidade e por fim retornar a cidade de
origem. Portanto, o problema consiste em determinar uma turnê de custo
mínimo.
No exemplo abaixo, a rota
é a de custo mínimo (51).
O problema do caixeiro viajante é NP-hard (veremos isso mais na frente).
isso implica dizer que não existe uma solução em tempo polinomial para
ele. A solução por backtracking define um vetor de cidades
que representa a melhor rota.
Como critério de poda podemos utilizar o número de cidade na rota obtida.
esse número não pode ser maior do que
. Neste caso, o algoritmo deve
buscar
possibilidades.
Se o critério de poda verificar a repetição de cidades, o número de
possibilidades é reduzido para
.
Branch-and-bound (BB) é uma estratégia bastante similar a backtracking. Também utiliza uma estrutura de árvore para explorar todas as possíveis soluções. A principal diferença entre as duas estratégias está na forma como a árvore é explorada. Como vimos, backtracking utiliza uma busca em profundidade. Na estratégia BB, utiliza busca em aplitude. Através de computação auxiliar, BB decide em cada etapa qual dos nós deve ser o próximo a ser explorado. Uma lista de prioridade mantém os nós que foram gerados mas que ainda permanecem inexplorados.