Você está na página 1de 23

Técnica de Backtracking

O Problema das n-Rainhas

Aula 25

Leila Silva 1
Técnica de Backtracking
 Geralmente aplicada em problemas combinatoriais de difícil solução.
 Se aplicada sem restrições resulta em algoritmos de complexidade exponencial,
pois seria equivalente a uma busca irrestrita em grafos.
 A técnica baseia-se na construção de uma árvore de estados cujos nós refletem as
escolhas feitas para se atingir a configuração que o nó representa. A técnica não
prossegue a partir de uma dada configuração (nó), tão logo haja a garantia de que
configurações posteriores derivadas destas (nós descendentes na árvore) não
possam gerar a solução para o problema. Quando um nó falha, ou seja, atinge uma
configuração inviável para o problema, a busca de soluções retrocede ao nó pai,
para que outras escolhas sejam exploradas. Se não houver mais escolhas no nó pai,
retrocede ao nó avô, e assim sucessivamente, até a raiz.
 Com um critério de corte apropriado, para que a árvore de estados não explore
todos os possíveis estados do problema, o emprego desta técnica pode ser factível
na resolução de instâncias grandes de alguns problemas combinatoriais.
 A exploração dos estados (configurações) da árvore é realizada em profundidade,
similar a uma busca em profundidade em grafos.

Leila Silva 2
Técnica de Backtracking
 Árvore de estados:
 Raiz: estado inicial, antes do processo de busca por soluções ter
iniciado.
 Nós do nível i: Representam as escolhas feitas para o i-ésimo
componente da solução que está sendo construída.
 Um nó é dito promissor, se a configuração que ele representa pode
gerar uma solução válida para o problema. Caso contrário, é dito não
promissor e a busca da solução não prossegue a partir dele.
 As folhas da árvore de estados ou são nós não promissores, ou
representam uma solução para o problema.
 A técnica será ilustrada na resolução do Problema das n-Rainhas.

Leila Silva 3
Problema das n-Rainhas
 Considere um tabuleiro de xadrez n⨉n e n rainhas. O problema consiste
em determinar se é possível dispor as n rainhas no tabuleiro de forma que
nenhuma rainha ataque outra rainha.
 Uma rainha ataca outra rainha se estão na mesma coluna, na mesma linha
ou na mesma diagonal do tabuleiro.
 Para n=1 a solução é trivial. Para n=2 e n=3, não há solução possível.
Experimentem as possíveis configurações como exercício.
 E para os demais valores de n?
 Iremos ilustrar a técnica de backtracking para n=4, por razões didáticas. A
mesma técnica se aplica para qualquer valor de n≥4. Mas antes vamos
explorar um pouco o problema.

Leila Silva 4
Problema das n-Rainhas
 Uma solução força bruta para o problema seria gerar todas as possíveis
combinações de posições de rainha para o tabuleiro e depois checar se são
soluções válidas. Teríamos possibilidades de posicionamento.
 Uma solução é válida se não temos nenhum par de rainhas na mesma
linha, nem na mesma coluna, nem na mesma diagonal. Checar linha e
coluna é fácil, basta observar os índices de localização na matriz
(tabuleiro). Mas como sabemos se duas rainhas estão na mesma diagonal?

(s,t)
(i,j)

(k,l)

Leila Silva 5
Problema das n-Rainhas
 Sejam duas rainhas com localizações (i,j) e (k,l). Duas rainhas estão na mesma diagonal se
atende a: |j-l|=|i-k|. Experimente com as coordenadas abaixo.
(1,3)
(2,2)

(4,4)

 Logo, dadas as localizações de um par de rainhas, checar se a localização é válida para um par
é tempo constante. Se temos pares, para n rainhas, então checar se uma solução é válida para
n rainhas é O(n2).
 Para determinar a solução do problema temos que checar a validade de todas as possíveis
soluções candidatas. Ou seja, um número de computações muito grande.
 Como exemplo, para n=8, = = 4.426.165.368 soluções candidatas. Para cada uma delas faz-se
= 28 checagem de pares de posições de rainhas!

Leila Silva 6
Problema das n-Rainhas
 Problemas que podem ser resolvidos por backtracking podem expressar a
sua solução através de uma tupla. No caso do problema das n-rainhas cada
valor da coordenada da tupla representaria a coluna em que a rainha está e
cada posição da coordenada da tupla a linha. Assim, supondo 4 rainhas,
uma solução expressa por (2,4,1,3) representaria uma solução em que a
rainha 1 estaria na linha 1 e coluna 2, a rainha 2 na linha 2 e coluna 4, a
rainha 3 na linha 3 e coluna 1 e a rainha 4 na linha 4 e coluna 3.

R1
R2
R3
R4

Leila Silva 7
Problema das n-Rainhas
 Como sabemos que o problema pode ser expresso por uma tupla, ao estabelecer
que cada coordenada de uma tupla representa uma linha diferente, já conseguimos
eliminar todas as soluções candidatas que repetem linhas, ou seja, que as rainhas se
atacam por estarem na mesma linha. Com esta restrição apenas, seríamos livres
para alocar cada rainha em uma das n colunas disponíveis. Então, o número de
soluções candidatas seria nn, pois cada coordenada da tupla pode assumir n
valores.
 Retomando nosso exemplo, para n=8 teríamos 16.777.216 soluções candidatas para
checar a validade, uma redução substancial de possibilidades, somente pela forma
de expressão da solução do problema como tuplas.
 Podemos refinar ainda mais e restringir que o valor de cada coordenada da tupla
seja distinto. Isto equivale a eliminar soluções que possuam a mesma coluna, ou
seja, que uma rainha ataque outra por estar na mesma coluna. Então, a quantidade
de soluções candidatas seria o número de permutações possíveis com valores de 1 a
n, ou seja, n!.
 Para n=8, seriam 8! = 40.320 soluções candidatas possíveis para se verificar se há
ataque na diagonal, uma redução extremamente significante!!!!

Leila Silva 8
Problema das n-Rainhas
 Aplicando a técnica de backtracking para 8 rainhas, somente 104 soluções
candidatas são investigadas até que uma solução válida seja encontrada e o
processo encerre.
 Vamos ilustrar a aplicação da técnica para 4 rainhas, por razões didáticas.
 Em cada nível da árvore de estados uma escolha é feita para a i-ésima
coordenada da tupla. As coordenadas que ainda não foram consideradas
em um dado estado estão sinalizadas com -.
 O processo inicia com o estado zero representado por (-,-,-,-).
 O processo encerra quando uma solução válida é encontrada.
 Em cada estado, é verificado apenas se há ataque na diagonal.

Leila Silva 9
Problema das n-Rainhas
(-,-,-,-) (-,-,-,-) (-,-,-,-)

(1,-,-,-) (1,-,-,-)

(1,1,-,-) (1,2,-,-) (1,3,-,-)


(-,-,-,-)

(1,-,-,-)

(1,1,-,-) (1,2,-,-) (1,3,-,-)

(1,3,1,-) (1,3,2,-) (1,3,3,-) (1,3,4,-)


Leila Silva 10
Problema das n-Rainhas
(-,-,-,-)

(1,-,-,-)

(1,1,-,-) (1,2,-,-) (1,3,-,-) (1,4,-,-)

(1,3,1,-) (1,3,2,-) (1,3,3,-) (1,3,4,-)

Leila Silva 11
Problema das n-Rainhas
(-,-,-,-)

(1,-,-,-)

(1,1,-,-) (1,2,-,-) (1,3,-,-) (1,4,-,-)

(1,3,1,-) (1,3,2,-) (1,3,3,-) (1,3,4,-) (1,4,1,-) (1,4,2,-


)

(1,4,2,1) (1,4,2,2) (1,4,2,3) (1,4,2,4)

Leila Silva 12
Problema das n-Rainhas
(-,-,-,-)

(1,-,-,-)

(1,1,-,-) (1,2,-,-) (1,3,-,-) (1,4,-,-)

(1,3,1,-) (1,3,2,-) (1,3,3,-) (1,3,4,-) (1,4,1,-) (1,4,2,-


)

(1,4,2,1) (1,4,2,2) (1,4,2,3) (1,4,2,4)

Leila Silva 13
Problema das n-Rainhas
(-,-,-,-)

(1,-,-,-)

(1,1,-,-) (1,2,-,-) (1,3,-,-) (1,4,-,-)

(1,3,1,-) (1,3,2,-) (1,3,3,-) (1,3,4,-) (1,4,1,-) (1,4,2,- (1,4,3,-) (1,4,4,-)


)

(1,4,2,1) (1,4,2,2) (1,4,2,3) (1,4,2,4)

Leila Silva 14
Problema das n-Rainhas
(-,-,-,-)

(1,-,-,-) (2,-,-,-)

(1,1,-,-) (1,2,-,-) (1,3,-,-) (1,4,-,-)

(1,3,1,-) (1,3,2,-) (1,3,3,-) (1,3,4,-) (1,4,1,-) (1,4,2,- (1,4,3,-) (1,4,4,-)


)

(1,4,2,1) (1,4,2,2) (1,4,2,3) (1,4,2,4)

Leila Silva 15
Problema das n-Rainhas
(-,-,-,-)

(1,-,-,-) (2,-,-,-)

... ... ... ... (2,1,-,-) (2,2,-,-) (2,3,-,-) (2,4,-,-)

Leila Silva 16
Problema das n-Rainhas
(-,-,-,-)

(1,-,-,-) (2,-,-,-)

... ... ... ... (2,1,-,-) (2,2,-,-) (2,3,-,-) (2,4,-,-)

(2,4,1,-)

(2,4,1,1) (2,4,1,2) (2,4,1,3)

Leila Silva 17
Problema das n-Rainhas
algoritmo nQueens(n)
{- Entrada: o tamanho do tabuleiro n
Saída: a solução armazenada em X[1..n] impressa, se existir solução.
A posição 0 do vetor é 0 se não existe solução e 1 se existe -}
início
-- inicialização de X
para i = 0,1,..., n faça X[i] := 0
-- NQ aplica backtracking para achar a solução
NQ(1,n,X)
se X[0]= 1
então
imprima (“Solução: “)
para i = 1, 2, ...,n faça imprima(X[i])
senão imprima (“Não existe solução para um tabuleiro de ordem “, n)

fim

Leila Silva 18
Problema das n-Rainhas
algoritmo NQ(i,n,X)
{- Entrada: rainha i, tamanho do tabuleiro n, solução X
Saída: X[0] indicando se tem solução (1) ou não tem solução (0)
Caso exista solução, X[1..n] armazena uma solução -}
início
para j = 1, 2, ..., n faça
-- verifica se pode alocar a rainha i na coluna j
se PosicaoValida(i,j)
então
-- coloque a rainha i na coluna j
X[i] := j
-- cheque se já posicionou todas as rainhas ou se precisa continuar a
-- busca da solução
se i = n
então {X[0] := 1 ; saia do algoritmo}
senão NQ(i+1,n,X) –- prossegue para alocar a próxima rainha
fim

backtracking

Leila Silva 19
Problema das n-Rainhas
função PosicaoValida(r,col): booleano
{- Entrada: rainha r e coluna col
Saída: True se a rainha r pode ser alocada na coluna col; False, caso
contrário -}
início
-- checa se a coluna col já foi utilizada por uma rainha de índice anterior a r
-- e também se a rainha k não ataca em diagonal a rainha r
para k = 1 até r-1 faça
se (X[k] = col) || (abs(X[k]- col) = abs(k-r))
então retorne False
retorne True
fim

Leila Silva 20
Exercícios Recomendados
Levitin: Cap 12 (Exercícios 12.1.1 a 12.1.3; 12.1.7;
12.1.8)

Leila Silva 21
Leitura Recomendada
Levitin: Cap 12 (Seção 12.1).

Leila Silva 22
Vídeo Recomendado
Backtracking | N Queen Problem - step by step guide
https://www.youtube.com/watch?v=lTPIX2Ywo3U

Leila Silva 23

Você também pode gostar