Lista de exercícios

Aula prática 07: decisões, caminhos e podas

Desafios sobre árvores de estados, backtracking, limites e escolhas ótimas.

Nesta lista, cada desafio mostra uma decisão que altera as próximas possibilidades. Os cenários são fictícios e trazem todas as regras necessárias. Não é preciso conhecer os jogos nem programar.

Resolva um exercício por vez e abra a solução para conferir. Não há entrega nem nota. Em cada solução, Resposta esperada é um modelo para comparação e autocorreção. Os exercícios são independentes, exceto 6 e 7, que usam o mesmo jogo. Quando houver uma sequência de operações, o enunciado informa se ela é cumulativa.

A busca em profundidade (DFS) é uma estratégia de exploração que segue um ramo até o fim e depois retorna para explorar alternativas, sendo esse retorno apenas parte do percurso; o backtracking usa esse comportamento da DFS, mas acrescenta poda por inviabilidade, abandonando um ramo assim que detecta que ele não pode levar a uma solução válida; já o branch-and-bound é voltado à otimização e também pode percorrer a árvore em profundidade, mas poda não só ramos inviáveis, como também aqueles cujo limite otimista (bound) mostra que não podem superar a melhor solução já encontrada, chamada incumbente.

Exercício 1: mesmo corredor, mesmas escolhas?

Represente os estados de um jogo ambientado em um festival. Dois caminhos chegam ao Corredor: pelo Credenciamento, onde se recebe uma pulseira, ou pela Praça, onde não há pulseiras. A porta dos Bastidores fica no Corredor e só abre para quem tem pulseira. Nenhuma outra escolha muda a posse da pulseira.

Mostre o estado ao chegar ao Corredor por cada caminho e diga em qual deles a porta pode ser escolhida. Separe as informações que mudam entre os estados da regra fixa da porta.

Solução

Explicação

Os dois caminhos terminam no mesmo lugar, mas produzem possibilidades diferentes. A posição e a posse da pulseira precisam fazer parte do estado para decidir se a porta pode ser usada. Se a busca tratar os dois estados como iguais, pode descartar o caminho com pulseira e perder a solução. O percurso pode ser guardado separadamente se o jogo precisar exibir a rota.

Objetivo de aprendizagem: reconhecer que um estado precisa conter todas as informações que alteram as próximas escolhas, mesmo quando dois caminhos chegam ao mesmo lugar.

Resposta esperada

Caminho até o CorredorEstado ao chegarPode escolher a porta dos Bastidores?
Pelo CredenciamentoPosição = Corredor; pulseira = simSim
Pela PraçaPosição = Corredor; pulseira = nãoNão

Regra fixa: a porta dos Bastidores só abre com pulseira. Registrar apenas “posição = Corredor” confundiria dois estados com próximas escolhas diferentes.

Exercício 2: quatro planos, duas pistas

Desenhe a árvore de tentativas para obter o código de saída de uma sala de enigmas. Primeiro escolha Estúdio ou Oficina; depois leve Lanterna UV ou Chave. No Estúdio, o código só aparece com a Lanterna UV. Na Oficina, ele está em um armário que só a Chave abre. As outras combinações falham.

Represente as escolhas já feitas nos nós e cada nova escolha na ligação. Marque nas quatro folhas se o código foi encontrado. Identifique a raiz e a subárvore que começa em Estúdio.

Solução

Explicação

A raiz ainda não contém escolhas. Cada sala produz um estado parcial; escolher um objeto completa uma tentativa. A subárvore de Estúdio inclui esse nó e suas duas continuações. As quatro folhas mostram o resultado de cada plano, permitindo verificar quais caminhos atingem o objetivo.

Objetivo de aprendizagem: interpretar nós como estados, ligações como decisões e folhas como tentativas completas que podem ter resultados diferentes.

Resposta esperada

flowchart TD
    root["Nenhuma escolha: raiz"] -->|Estúdio| studio["Estúdio"]
    root -->|Oficina| workshop["Oficina"]
    studio -->|Lanterna UV| studio_light["Estúdio + Lanterna UV: código"]
    studio -->|Chave| studio_key["Estúdio + Chave: falha"]
    workshop -->|Lanterna UV| workshop_light["Oficina + Lanterna UV: falha"]
    workshop -->|Chave| workshop_key["Oficina + Chave: código"]

A subárvore de Estúdio contém Estúdio, Estúdio + Lanterna UV e Estúdio + Chave. As quatro folhas são planos completos: dois encontram o código e dois falham. Uma busca por qualquer código pode parar ao encontrar a primeira folha bem-sucedida.

Exercício 3: explorar, registrar ou encerrar?

Classifique três estados de uma busca que escolhe exatamente duas cartas diferentes para uma arena tática. A dupla precisa somar pelo menos 6 de ataque e 5 de defesa. Cada carta pode ser escolhida uma vez; não há terceira vaga.

CartaAtaqueDefesa
Vega42
Iris24
Atlas33
Rook51
EstadoCartas escolhidas
AVega
BVega, Atlas
CVega, Rook

Uma carta escolhida permanece no estado ao explorar suas continuações. Para cada estado, indique se está completo e escolha a próxima ação: explorar outra carta, registrar uma solução ou encerrar sem solução. Não é preciso antecipar quais continuações funcionarão.

Solução

Explicação

A ainda tem uma vaga. Sua pontuação atual não é solução, mas também não prova que o ramo inteiro falhará, então a busca testa a próxima carta. B já soma 7 de ataque e 5 de defesa. C soma 9 de ataque, mas só 3 de defesa; como não restam vagas, nenhuma continuação pode corrigir a falta de defesa.

Objetivo de aprendizagem: distinguir um estado parcial ainda aberto, uma solução completa e um estado completo sem solução, sem resolver antecipadamente os descendentes.

Resposta esperada

EstadoAtaque e defesaCompleto?Próxima ação e motivo
A4 e 2NãoExplorar outra carta; ainda não há prova de impossibilidade
B7 e 5SimRegistrar solução; atingiu os dois mínimos
C9 e 3SimEncerrar sem solução; falta defesa e não há vaga

Continuar o ramo A não garante que ele contenha uma solução; apenas evita descartá-lo sem justificativa. Os estados B e C encerram caminhos da árvore, mas só B é uma solução.

Exercício 4: encontrar a saída e voltar quando necessário

Rastreie a busca em profundidade numa sala de enigmas. A partir da Entrada, teste Galeria antes de Oficina. A Galeria permite testar Corredor antes de Arquivo; ambos terminam sem saída. A Oficina leva à Saída. Não há outros caminhos. Uma sala sem saída obriga a desfazer a última escolha. A busca para na primeira rota encontrada.

Registre a sequência cumulativa de caminhos ativos, após cada entrada ou retorno, até encontrar a Saída. Indique quando a rota é guardada.

Solução

Explicação

A busca esgota a subárvore da Galeria antes de tentar a Oficina. Ao voltar de um caminho sem saída, restaura o caminho anterior; não mantém o Corredor ou o Arquivo como parte da nova tentativa.

Objetivo de aprendizagem: rastrear a busca em profundidade e perceber que desfazer uma escolha restaura o caminho ativo antes da próxima tentativa.

Resposta esperada

OperaçãoCaminho ativo após a operação
IniciarEntrada
Entrar na GaleriaEntrada → Galeria
Entrar no Corredor, sem saídaEntrada → Galeria → Corredor
Desfazer CorredorEntrada → Galeria
Entrar no Arquivo, sem saídaEntrada → Galeria → Arquivo
Desfazer ArquivoEntrada → Galeria
Desfazer GaleriaEntrada
Entrar na OficinaEntrada → Oficina
Entrar na Saída e guardar a rotaEntrada → Oficina → Saída

A rota guardada é Entrada → Oficina → Saída. Como o objetivo é encontrar uma rota, a busca pode parar nesse ponto.

Exercício 5: quando uma combinação já perdeu?

Justifique a poda de uma montagem de equipamentos para um desafio cooperativo. O grupo dispõe de 6 unidades de energia. Duas escolhas já fixadas consomem 4 e 3 unidades. Escolhas futuras só podem acrescentar consumo, nunca retirar equipamentos já fixados.

Explique por que nenhuma continuação desse estado pode ser válida e qual ação permite testar outro ramo.

Solução

Explicação

O consumo atual é 7, acima do limite 6. Como as próximas escolhas não diminuem o consumo, toda continuação conserva a violação. A única forma de testar outra combinação é desfazer uma escolha já feita.

Objetivo de aprendizagem: justificar uma poda por inviabilidade com uma restrição que nenhuma escolha futura consegue reparar.

Resposta esperada

Pode podar por inviabilidade: 4 + 3 = 7 > 6, e nenhuma continuação reduz esse total. Para testar outro ramo, a busca desfaz a última escolha e retorna ao estado anterior. Podar descarta continuações do estado inviável; desfazer restaura o estado de trabalho.

Exercício 6: quanto ainda cabe na mochila?

Calcule um limite superior fracionário para a mochila de uma missão de exploração. A mochila suporta 7 unidades de peso. Cada equipamento pode ser escolhido inteiro uma vez, e o objetivo é maximizar a soma dos pontos.

EquipamentoPesoPontosSituação neste ramo
Gancho25Já incluído
Scanner36Ainda não decidido
Câmera44Ainda não decidido

O estado atual tem peso 2 e valor 5, com Gancho já incluído. Scanner e Câmera são as próximas decisões, nessa ordem; cada um pode ser incluído ou rejeitado. Calcule, pela mochila fracionária, o limite superior do valor final deste ramo e justifique por que ele é seguro para a mochila 0-1.

Solução

Explicação

Restam 7 − 2 = 5 unidades de peso. O Scanner fornece 6/3 = 2 pontos por unidade; a Câmera fornece 4/4 = 1. Por ter maior densidade, o Scanner entra primeiro: trocar espaço dele por espaço da Câmera não aumentaria o valor fracionário. Assim, o melhor preenchimento fracionário usa o Scanner inteiro e 2/4 da Câmera. Toda seleção 0-1 também é permitida nesse modelo ampliado, então seu ótimo não pode ficar abaixo do melhor valor real do ramo.

Objetivo de aprendizagem: calcular um teto seguro para um estado parcial pela relaxação fracionária, sem confundir a fração usada na prova com uma escolha válida da mochila.

Resposta esperada

O limite superior é 13 pontos: 5 já obtidos com Gancho, mais 6 com Scanner inteiro e (2/4)×4=2(2/4)\times4=2 com metade da Câmera. O Scanner ocupa 3 das 5 unidades livres; as 2 restantes só entram no teto como fração da Câmera. Nenhuma continuação 0-1 pode superar o ótimo fracionário, mas 13 não é uma seleção válida, pois a Câmera real não pode ser dividida.

Exercício 7: quais configurações ainda merecem teste?

Decida quais ramos podar na mochila de capacidade 7 com Gancho (peso 2, valor 5), Scanner (peso 3, valor 6) e Câmera (peso 4, valor 4). Já existe uma seleção completa e válida de 10 pontos, Scanner + Câmera. Ela é o incumbente. Procuramos uma seleção de valor máximo; não precisamos encontrar outras seleções que apenas empatem. Os limites superiores fracionários abaixo são seguros. Avalie os ramos de forma independente, antes de qualquer atualização do incumbente, e registre para cada um podar ou continuar.

RamoDecisões já fixadasValor atualLimite superiorIncumbente
AGancho incluído51310
BGancho incluído; Scanner rejeitado5910
CGancho rejeitado01010
Solução

Explicação

Em maximização, um ramo só pode melhorar o incumbente se seu teto ultrapassar 10. O ramo A ainda permite uma melhora segundo o limite, mesmo que seu valor atual seja 5. Os ramos B e C podem conter seleções válidas, mas seus tetos já impedem uma pontuação maior que 10.

Objetivo de aprendizagem: comparar o limite superior de cada ramo com o incumbente para decidir uma poda sem perder uma melhora possível.

Resposta esperada

RamoDecisãoJustificativa
AExplorarO teto 13 ainda pode superar 10
BPodarO teto 9 não supera 10
CPodarO teto 10 só permite empatar com 10

O teto 13 do ramo A não prova que exista uma seleção 0-1 de valor 13. Se o objetivo fosse listar todas as seleções ótimas, um ramo que só permite empatar, como C, precisaria continuar elegível.

Exercício 8: quando o jogo termina?

Determine se a busca pode parar em cada objetivo abaixo. Em uma sala de enigmas, foi encontrada uma rota completa e válida de 10 pontos. Ainda há um ramo não explorado cujo limite superior seguro é 13 pontos. Avalie os objetivos de forma independente.

  1. Encontrar qualquer rota válida.
  2. Listar todas as rotas válidas.
  3. Encontrar uma rota de pontuação máxima e provar que ela é ótima.
Solução

Explicação

Encontrar uma rota resolve a busca por existência. A mesma descoberta não informa se há outras rotas ou se a pontuação é máxima. Para listar todas as rotas válidas, um teto de pontuação não autoriza a poda: mesmo rotas com menos de 10 pontos precisam ser encontradas. Nesse objetivo, a busca deve explorar todos os ramos que ainda possam conter rotas válidas. O ramo pendente também pode superar 10 pontos, portanto a melhor pontuação ainda não foi provada.

Objetivo de aprendizagem: relacionar o critério de parada ao objetivo da busca: encontrar uma solução, listar todas ou provar a melhor.

Resposta esperada

  1. Pode parar: a rota encontrada já é válida.
  2. Não pode parar: é preciso explorar todos os ramos que ainda possam conter rotas válidas. O teto 13 não muda essa decisão, pois a pontuação não importa para listar todas. Não se pode podar um ramo por seu teto, mas um ramo comprovadamente inviável pode ser descartado.
  3. Não pode parar: o teto 13 ainda permite uma rota melhor que 10. A prova de otimalidade exige explorar ou podar com segurança todos os ramos restantes.

Exercício 9: quantos testes antes de lançar a demo?

Conte os estados que uma equipe precisa considerar para testar todas as histórias de uma demo interativa. Há três decisões, sempre nesta ordem:

  1. Entrada: telhado ou garagem.
  2. Pistas: arquivo ou servidor.
  3. Fuga: moto ou barco.

As duas opções de cada decisão continuam disponíveis após qualquer escolha anterior. Considere a árvore inteira, sem podas. Informe a quantidade de estados por nível, o total incluindo a raiz e os estados parciais, e o número de histórias completas.

Solução

Explicação

Cada decisão duplica os estados do nível anterior, pois nenhuma escolha elimina opções posteriores. As histórias completas ficam no último nível, mas a equipe também precisa considerar os estados parciais que levam até elas.

Objetivo de aprendizagem: contar tanto os estados parciais quanto as folhas para medir o tamanho da árvore potencial.

Resposta esperada

Há 1 estado na raiz, depois 2, 4 e 8 estados. O total é 1 + 2 + 4 + 8 = 15 estados, dos quais 8 são histórias completas.

Exercício 10: a poda garante uma demo rápida?

Avalie a promessa de uma equipe que busca o final de maior pontuação numa demo com nn decisões binárias. Cada opção gera um estado distinto, e todas as histórias completas são válidas. A equipe calcula um limite superior seguro para podar ramos que não podem superar a melhor história já encontrada e afirma que isso garante tempo não exponencial em qualquer versão da demo. O cálculo do limite pode percorrer até nn decisões. Julgue a promessa considerando o pior caso, a quantidade de estados e o trabalho em cada um.

Solução

Explicação

Com uma decisão binária adicional, o número de histórias completas sem poda dobra. Um limite seguro pode ser pouco informativo e não permitir nenhuma poda. Nesse caso, a equipe ainda visita a árvore inteira e calcula o limite nos estados encontrados.

Objetivo de aprendizagem: reconhecer o pior caso exponencial e considerar o trabalho por estado ao estimar o tempo da busca.

Resposta esperada

A promessa é falsa. No pior caso, nenhum limite permite podar: há 2n2^n histórias completas e 2n+1−12^{n+1}-1 estados no total. Como calcular o limite de cada estado pode percorrer até nn decisões, um limite conservador para o tempo é O(n2n)O(n2^n). A poda reduz o trabalho nas versões em que descarta ramos, sem garantir esse ganho em todas elas.

Exercício 11: guardar um final ou arquivar todos?

Compare a memória de duas versões de um testador de histórias com nn decisões binárias. Ambas percorrem toda a árvore em profundidade, usam uma chamada recursiva por decisão e reutilizam um vetor de nn escolhas ao trocar de ramo. Cada chamada guarda uma quantidade constante de dados.

  • Versão A: mantém uma única cópia de história completa. Uma nova história pode substituir a cópia anterior.
  • Versão B: acrescenta uma cópia de cada história completa a uma coleção que permanece na memória até o fim.

Para três decisões, quantos níveis de chamada podem coexistir, contando a chamada inicial? Para nn decisões, determine quantas histórias completas existem e a ordem de memória de cada versão. Considere que cada cópia guarda as nn escolhas.

Solução

Explicação

As duas versões têm a mesma pilha e o mesmo vetor de trabalho. A diferença está no que permanece salvo depois de visitar uma folha: a versão A substitui uma cópia, enquanto a B acumula todas. Percorrer em profundidade não impede o crescimento da memória usada para armazenar resultados.

Objetivo de aprendizagem: distinguir a memória do caminho ativo da memória usada para guardar resultados e reconhecer quando armazenar todas as soluções torna o espaço exponencial.

Resposta esperada

Com três decisões, coexistem no máximo quatro níveis de chamada, contando a chamada inicial. Para nn decisões, há 2n2^n histórias completas. A pilha e o vetor de trabalho ocupam O(n)O(n) memória em ambas as versões.

  • Versão A: guarda uma cópia de nn escolhas por vez. A memória total é O(n)O(n).
  • Versão B: guarda 2n2^n cópias de nn escolhas. A coleção ocupa Θ(n2n)\Theta(n2^n) memória, que domina a pilha e o vetor de trabalho.

Assim, a busca em profundidade economiza memória no percurso, mas não reduz o espaço necessário quando o próprio objetivo é manter todas as histórias completas.

Exercício 12: qual busca combina com a missão?

Compare backtracking e branch-and-bound em duas missões independentes de um jogo de exploração:

  1. Encontrar qualquer rota até a base sem ultrapassar a energia disponível. Cada deslocamento acrescenta consumo não negativo.
  2. Selecionar equipamentos inteiros de maior pontuação dentro da capacidade da mochila e provar que nenhuma combinação é melhor.

Considere busca em profundidade, com no máximo nn decisões por caminho, guardando o caminho ativo e, quando necessário, uma resposta completa. Indique a técnica mais adequada a cada missão, a prova que permite descartar um ramo e as consequências para tempo e memória. Não é preciso calcular uma rota nem conhecer valores dos equipamentos.

Solução

Explicação

Como os deslocamentos não reduzem o consumo, uma rota que ultrapassa a energia disponível não pode voltar a ser válida enquanto as escolhas anteriores permanecerem fixas. Para maximizar pontuação, um limite superior seguro pode descartar até uma combinação parcial válida quando nenhuma continuação supera a melhor resposta completa conhecida.

Objetivo de aprendizagem: escolher a técnica de busca pelo resultado exigido e pela justificativa de poda disponível, considerando também tempo e memória.

Resposta esperada

MissãoTécnicaPoda e justificativa
Encontrar uma rotaBacktrackingPodar por inviabilidade quando o consumo já supera a energia disponível; parar ao encontrar uma rota válida
Maximizar a pontuação da mochilaBranch-and-boundPodar por inviabilidade se a capacidade for excedida e por limite se o teto do ramo não superar o incumbente; encerrar após resolver todos os ramos capazes de melhorar

Enumerar todas as combinações válidas e comparar pontuações também encontra o ótimo, mas a segunda missão permite usar a poda por limite para evitar ramos desnecessários.

Nas duas missões, as podas podem reduzir o tempo em certas entradas, sem eliminar o pior caso de muitos estados. Sob a implementação em profundidade descrita, a pilha, o caminho ativo e a cópia de uma resposta ocupam O(n)O(n) memória auxiliar para nn decisões, sem guardar toda a árvore. Calcular limites acrescenta trabalho por estado na segunda missão.

Exercício 13: qual configuração vence na garagem?

Encontre e prove a configuração de maior pontuação em um jogo de corrida. A garagem aceita até 5 unidades de espaço. Cada melhoria pode ser incluída inteira uma vez ou rejeitada; a pontuação é a soma das melhorias incluídas. Espaço e pontos são não negativos, e a garagem pode ficar parcialmente vazia.

MelhoriaEspaçoPontos
Turbo38
Pneus25
Nitro46

A busca começa com a garagem vazia e sem incumbente. Percorra a árvore em profundidade, decidindo as melhorias na ordem da tabela e testando incluir antes de rejeitar. Registre ou atualize o incumbente ao encontrar uma configuração completa e válida. Em cada estado, use como teto otimista a pontuação atual mais os pontos de todas as melhorias ainda não decididas, mesmo que elas não caibam juntas. Mostre quando o incumbente aparece, quais ramos precisam continuar, quais podem ser podados e por quê. As decisões são cumulativas em cada caminho da árvore.

Solução

Explicação

Sem incumbente, ainda não há valor com o qual comparar os tetos. A primeira tentativa segue Turbo, Pneus e Nitro. Incluir os três excede a capacidade; rejeitar Nitro produz a primeira configuração completa e válida, com 13 pontos. Só então esse valor se torna o incumbente. O teto é seguro porque soma todos os pontos ainda disponíveis sem impor a restrição de espaço; assim, não subestima nenhuma continuação real.

Na árvore abaixo, P é o espaço usado, V é a pontuação atual e U é o teto. Os números nas ligações indicam a ordem da busca. O incumbente B nasce no passo 4 e permanece em 13 nos passos seguintes.

flowchart TD
    root["P=0, V=0, U=19. B=nenhum"]
    with_turbo["P=3, V=8, U=19"]
    without_turbo["P=0, V=0, U=11. Poda"]
    with_tires["P=5, V=13, U=19"]
    without_tires["P=3, V=8, U=14"]
    invalid_three["P=9, V=19, U=19. Inviável"]
    first_solution["P=5, V=13, U=13. B=13"]
    invalid_nitro["P=7, V=14, U=14. Inviável"]
    turbo_only["P=3, V=8, U=8. Completa"]

    root -->|1 Incluir Turbo| with_turbo
    with_turbo -->|2 Incluir Pneus| with_tires
    with_tires -->|3 Incluir Nitro| invalid_three
    with_tires -->|4 Rejeitar Nitro| first_solution
    with_turbo -->|5 Rejeitar Pneus| without_tires
    without_tires -->|6 Incluir Nitro| invalid_nitro
    without_tires -->|7 Rejeitar Nitro| turbo_only
    root -->|8 Rejeitar Turbo| without_turbo

Objetivo de aprendizagem: rastrear a criação do incumbente e combinar ramificação, limite superior e inviabilidade para provar que uma configuração válida é ótima.

Resposta esperada

  1. Antes da primeira solução: não existe incumbente. A raiz tem teto 19, e os ramos com Turbo e com Turbo + Pneus também têm teto 19; a busca continua por eles. Incluir Turbo e Pneus leva a espaço 5 e valor 13. Tentar incluir Nitro excede a capacidade, pois 3 + 2 + 4 = 9 > 5. Ao rejeitar Nitro, a configuração completa Turbo + Pneus é válida e passa a ser o primeiro incumbente, de 13 pontos.
  2. Com Turbo e sem Pneus: o teto 8 + 6 = 14 supera o incumbente 13, então o ramo precisa continuar. Incluir Nitro excede a capacidade, pois 3 + 4 = 7 > 5. Rejeitar Nitro encerra com 8 pontos e não altera o incumbente.
  3. Sem Turbo: o teto otimista 5 + 6 = 11 não supera o incumbente 13, então o ramo pode ser podado por limite, mesmo que Pneus e Nitro não caibam juntos.

Nenhum ramo restante pode superar 13 pontos. Portanto, Turbo + Pneus é uma configuração ótima. O incumbente foi encontrado durante a busca, antes da poda por limite.