Upload
vukhanh
View
214
Download
0
Embed Size (px)
Citation preview
Unive rsidad e F
ede ral do Espír ito S
a nto – CC
A U
FE
S
Universidade Federal do Espírito SantoCentro de Ciências Agrárias – CCA UFESDepartamento de Computação
Tópicos Especiais em ProgramaçãoSite: http://jeiks.net E-mail: [email protected]
Recursividade Exaustiva e Backtracking
Unive rsidad e F
ede ral do Espír ito S
a nto – CC
A U
FE
S
2
Recursividade Exaustiva e Backtracking
● Nas chamadas recursivas, formamos uma “árvore”/pilha de chamadas que forma uma linha da função inicial até a “base” do problema.– Entenda como “base” o final da recursividade, como por exemplo, o
retorno do fatorial de 1 ou 0.
● O desempenho do algoritmo depende do tamanho que essa pilha de chamadas atinge.– O que é determinado pelo quão rápido conseguimos alcançar o caso
base do problema.
● Exemplos:– Se formos criar um arquivo reverso com recursividade, necessitamos de
uma pilha do tamanho do arquivo.
– Se formos trabalhar com pesquisa binária, já é interessante trabalhar com recursividade somente na metade seguinte de cada nó.
Unive rsidad e F
ede ral do Espír ito S
a nto – CC
A U
FE
S
3
Recursividade Exaustiva e Backtracking
● Já considerando uma função recursiva com subconjuntos ou com permutações,– Não fazem somente uma chamada recursiva, mas várias.
– Geram uma árvore de chamadas de muitos níveis.
– Devido aos fatores multiplicativos sendo utilizados na árvore, o número de chamadas pode crescer de forma enorme.
– Assim, a recursividade tem um potencial de ser muito custosa.
● A forma de melhorar isso é explorar o diminuir o tempo de pesquisa.
● O backtracking é um método para melhor trabalhar com isso.
Unive rsidad e F
ede ral do Espír ito S
a nto – CC
A U
FE
S
4
Backtracking
● O backtracking é, de forma genérica, uma técnica algorítmica:– Que pesquisa todas as combinações possíveis buscando resolver
problemas de otimização.
● Também é conhecido como:– busca em profundidade ou
– dividir para conquistar.
● A ideia é inserir conhecimento ao problema para fazer a árvore de pesquisa ser podada,– Isso evita casos que não gerarão resultados satisfatórios.
● Enquanto o backtraking é útil para diversos problemas de nível complexo, ele é a pior solução para problemas comuns que já possuem outras técnicas de solução.
Unive rsidad e F
ede ral do Espír ito S
a nto – CC
A U
FE
S
5
Backtracking
● Para entender melhor o método de backtracking,– vamos estudar alguns casos com recursividade e
– depois ver como o backtracking resolve isso melhor.
Unive rsidad e F
ede ral do Espír ito S
a nto – CC
A U
FE
S
6
Caso clássico de permutação● Pseudocódigo:
SE você não tem mais caracteres restantes para reorganizar:
ENTAO imprima a permutação atual.
SENÃO:PARA (cada escolha possível entre os caracteres restantes para organizar)
{
Faça uma escolha e adicione este caractere para a permutação até o momento.
Utilize a recursividade para reorganizar o restante das letras.
}
permutacao_rec.cpp
Unive rsidad e F
ede ral do Espír ito S
a nto – CC
A U
FE
S
7
Caso clássico de subconjuntos
● Pseudocódigo:
SE não há mais elementos restando:
ENTÃO imprima o subconjunto atual
SENÃO:
Considere o próximo elemento dos restantes.
Adicioneo ao subconjunto atual e utilize a recursividade para continuar o processo.
Não adicioneo ao subconjunto atual e utilize a recursividade para continuar o processo.
subconjuntos_rec.cpp
Unive rsidad e F
ede ral do Espír ito S
a nto – CC
A U
FE
S
8
Backtracking
● Tanto no exemplo de permutação quanto no exemplo de subconjuntos que vimos:– Todas as possibilidades foram exploradas.
– Em cada ponto de decisão:● Uma escolha foi feita;● Logo após foi desfeita e● Tentou-se então as outras opções;
– Isso foi realizado até que todas as opções fossem testadas.
– É custoso, principalmente com vários pontos de decisões a fazer.
● Com backtracking:– Uma escolha será feita e ela somente será desfeita se não trouxer
o resultado desejado.
Unive rsidad e F
ede ral do Espír ito S
a nto – CC
A U
FE
S
9
Backtracking● Pseudocódigo:
bool Solve(configuration conf) {if (não tem mais escolhar) // Critério de parada
return (conf é o estado objetivo);
for (todas as escolhas disponíveis) {
teste uma escolha c;
// resolver recursivamente após escolher c
ok = Solve(conf com a escolha c efetuada);
if (ok)
return true;
else
desfazer escolha c;
}// tentou todas as escolhas e não encontrou solução
return false;
}
Unive rsidad e F
ede ral do Espír ito S
a nto – CC
A U
FE
S
10
Backtracking
● Códigos fontes:– backtracking.cpp;
– permutacao_bckt.cpp;
– subconjuntos_bckt.cpp;
● Vamos ver alguns problemas que podem ser resolvidos com o Backtracking...
Unive rsidad e F
ede ral do Espír ito S
a nto – CC
A U
FE
S
11
Sudoku:
Encontre a lin,col de uma célula não escolhida
Se não houver nenhum número,retorne TRUE
Para os dígitos de 1 à 9:Se não há conflito para o dígito na lin,col:
Atribua esse dígito nessa lin,col e
tente preencher o resto recursivamente.
Se a recursividade retornou TRUE:
retorne TRUE
Caso contrário:
remova este dígito e tente outro.
Se todos os dígitos foram testados e nenhum funcionou,
retorne FALSE para desencadear o backtracking.
Unive rsidad e F
ede ral do Espír ito S
a nto – CC
A U
FE
S
12
Problema das 8 rainhas:
Comece da coluna mais a esquerda
Se todas as rainhas já foram colocadas:retorne TRUE
Para (todas escolhas possíveis entre as linhas dessa coluna):
Se a rainha pode ser colocada sem conflitos:
faça essa escolha e
tente colocar as outras rainhas de recursivamente.
Se a recursividade retornou TRUE,
retorne TRUE
Caso contrário,
remova a rainha e tente outra linha dessa coluna
Se todas as linhas foram testadas e nenhuma funcionou,
retorne FALSE para desencadear o backtracking
Unive rsidad e F
ede ral do Espír ito S
a nto – CC
A U
FE
S
13
Construção de Soluções
● Para construir boas soluções, temos que pensar em como utilizar corretamente o backtrack.
● A poda é uma boa opção para deixar de efetuar pesquisas desnecessárias na árvore.
● No problema das rainhas, por exemplo:– Não pesquisar em nós que estejam na mesma
linha, coluna ou diagonal;
oito_rainhas.cpp