Exercícios MT1
Nenhum exercício corresponde a esta pesquisa.
Algoritmos gulosos
Mochila 0/1: escolha gulosa e valor ótimoAutoavaliação
Teste 1, 2023/24
Considere o problema da mochila 0/1 com capacidade e 3 artigos: artigo 1 , artigo 2 , artigo 3 .
a) Indique a seleção feita pelo algoritmo guloso que insere os artigos por ordem decrescente do rácio e o valor resultante. b) Essa seleção é ótima? Justifique. c) Em geral, a que distância pode a solução gulosa ficar da solução ótima? Discuta, podendo dar um exemplo.
Solução
a) Seleção gulosa: artigos 3 e 2, com valor . b) Sim, é ótima nesta instância. c) A gulosa pode ser arbitrariamente má: com e , o rácio guloso/ótimo é .
Os rácios são , e . A ordem decrescente é artigo 3, artigo 1, artigo 2. O artigo 3 enche 4 unidades; sobram 6, onde o artigo 1 (peso 7) não cabe e o artigo 2 (peso 6) cabe exatamente, dando e enchendo a mochila por completo. Como a mochila fica cheia, nenhuma solução pode ter valor superior a nesta instância. Em geral, a gulosa pode falhar por um fator arbitrário: com dois artigos de valores e e pesos e , a gulosa escolhe o primeiro (valor 1) e a ótima escolhe o segundo (valor ).
Confere a tua resposta:
- A resposta indica a seleção gulosa pelos artigos 3 e 2, com valor 78.
- A resposta conclui que, nesta instância, a seleção gulosa é ótima.
- A justificação da parte c) dá um exemplo em que o rácio guloso/ótimo tende para zero.
Estações de comboio numa linha férreaAutoavaliação
Teste 1, 2023/24
Uma linha férrea é representada por uma reta numérica onde estão marcadas as localidades. Pretende-se escolher pontos da reta para construir estações de comboio, de modo a que cada localidade fique a uma distância máxima de uma estação. As estações não precisam de coincidir com localidades.
Descreva um algoritmo guloso que encontra uma coleção mínima de localizações para as estações. Discuta a sua complexidade e a prova de otimalidade.
Solução
Percorrer as localidades por ordem crescente; para a primeira localidade ainda não coberta, colocar uma estação em . Complexidade com as localidades ordenadas. A prova de otimalidade compara com uma solução ótima qualquer e troca, uma a uma, cada estação da solução ótima pela estação que o algoritmo guloso coloca na mesma posição, sem nunca uncoverir localidades.
Se a solução ótima colocasse a sua próxima estação antes de , a localidade ficaria descoberta, pelo que a próxima estação ótima tem de estar em ou depois. Trocá-la pela estação em não descubre nenhuma localidade e faz a solução ótima coincidir com a gulosa numa estação a mais. Por troca sucessiva, a solução gulosa é ótima.
Confere a tua resposta:
- O algoritmo escolhe a primeira localidade ainda não coberta e coloca a estação a distância à sua frente.
- A complexidade indicada é (ou se as localidades não estiverem ordenadas).
- A prova de otimalidade usa um argumento de troca com uma solução ótima.
Paragens de gasolina com o menor número de depósitosAutoavaliação
Teste 1, 2022/23
O Ralph vai de Los Angeles a Chicago pela rota 66. O depósito do carro, quando cheio, dá para viajar milhas, e o mapa indica as distâncias entre os postos de gasolina da rota. Pretende-se minimizar o número de paragens para abastecer.
Dê um algoritmo eficiente que determina em que postos deve parar e prove que a estratégia é ótima.
Solução
Começando com o depósito cheio, parar no posto mais afastado que é alcançável dentro de milhas e abastecer lá; repetir a partir desse posto. O problema tem subestrutura ótima e a escolha gulosa é segura: nenhum posto para lá do -ésimo é alcançável como primeira paragem, e escolher um posto nunca permite ir mais longe. Com postos, cada um é inspecionado uma vez, logo .
Se uma solução ótima tem a primeira paragem no posto , o resto tem de ser ótimo para o subproblema dos postos seguintes, caso contrário havia uma solução com menos paragens. Como a escolha do posto deixa pelo menos tanto combustível como qualquer escolha , a gulosa nunca fica em pior posição.
Confere a tua resposta:
- A estratégia gulosa indica: abastecer no posto mais distante alcançável com o depósito atual.
- A prova usa subestrutura ótima e a propriedade da escolha gulosa.
- A complexidade indicada é para postos.
Mochila fracionária com valores todos iguaisAutoavaliação
Teste 1, 2022/23
Considere a variante da mochila fracionária em que todos os artigos têm o mesmo valor , mas pesos possivelmente diferentes, podendo incluir-se uma fração de qualquer artigo numa mochila de capacidade .
Derive um algoritmo eficiente que maximiza o valor da mochila e discuta a sua complexidade e a otimalidade da solução.
Solução
Como todos os artigos valem o mesmo, maximizar o valor é o mesmo que maximizar o número de artigos na mochila. Basta ordenar os artigos por peso crescente e ir enchendo a mochila pelos mais leves; quando a capacidade restante não chega para o artigo seguinte, insere-se a fração correspondente. A complexidade é , dominada pela ordenação.
Ordenar por rácio decrescente é, quando todos os são iguais, equivalente a ordenar por peso crescente: implica . Assim, réutiliza-se a prova de otimalidade da mochila fracionária clássica. Em alternativa, trocar um artigo mais pesado por um mais leve, de igual valor, liberta capacidade para outro artigo ou fração, aumentando o valor.
Confere a tua resposta:
- O algoritmo ordena os artigos por peso crescente e enche a mochila pelos mais leves, com fração no último.
- A complexidade indicada é , dominada pela ordenação.
- A justificação de otimalidade refere que ordenar por decrescente equivale a ordenar por peso crescente quando os valores são iguais.
Árvores abrangentes mínimas
Árvore abrangente mínima com pesos todos iguaisAutoavaliação
Teste 1, 2023/24
Considere um grafo conexo e pesado com nós em que todas as arestas têm o mesmo peso, por exemplo 1. É possível melhorar o algoritmo de Prim ou o de Kruskal para encontrar a árvore abrangente de custo mínimo? Explique.
Solução
Sim. Como todas as arestas têm o mesmo peso, basta varrer as arestas até recolher arestas que não formem ciclo, marcando os nós já alcançados. A complexidade é , uma ligeira melhoria sobre a de Prim ou Kruskal com filas de prioridade.
Qualquer conjunto de arestas sem ciclo é uma árvore abrangente e, com pesos unitários, todas as árvores abrangentes têm custo . Portanto a ordenação de arestas é dispensável e uma simples travessia com marcação de nós resolve o problema.
Confere a tua resposta:
- A resposta indica que basta marcar os nós visitados e percorrer as arestas até obter arestas sem ciclo.
- A complexidade indicada é .
Variante eficiente de Prim para pesos unitáriosAutoavaliação
Teste 1, 2022/23
Considere a classe dos grafos não dirigidos, conexos, com nós e todas as arestas de peso unitário. Adapte o algoritmo de Prim para encontrar a árvore abrangente de custo mínimo, simplificando-o numa variante mais eficiente. Descreva o algoritmo em pseudo-código e justifique a complexidade melhorada.
Solução
Basta uma travessia (por exemplo DFS) que vai adicionando arestas para nós ainda não visitados até perfazer arestas, usando um vetor booleano de visitados. Complexidade e custo da árvore .
Com pesos todos iguais, a parte mais cara de Prim, a ordenação das arestas, torna-se desnecessária: qualquer aresta que ligue um nó novo serve. Uma DFS com marcação de nós visitados escolhe essas arestas em tempo linear.
Confere a tua resposta:
- O pseudo-código usa um vetor booleano de nós visitados e para quando tiver arestas.
- A complexidade indicada é , a de uma travessia em profundidade.
- A resposta indica que o custo da árvore é .
Caminhos mínimos
Dijkstra a partir de um nó: primeira iteração e limite de um pesoAutoavaliação
Teste 1, 2023/24
Considere o grafo dirigido e pesado com nós e arestas (4), (8), (1), (4), (1), (1), (1), (3), (1).
a) Usando o algoritmo de Dijkstra a partir do nó , indique os valores das distâncias na inicialização e após uma iteração, assumindo que, em caso de empate numérico, se escolhe o nó de menor valor lexicográfico (), e ainda os valores finais. b) Qual é o menor valor que a aresta pode ter sem alterar a forma da árvore de caminhos mais curtos? Explique.
Solução
a) Inicialização ; após a primeira iteração (nó selecionado) ; finais . b) O peso de não pode ser inferior a 2.
Após inicializar com as arestas diretas de , seleciona-se (distância 1) e relaxam-se e para 2. Depois seleciona-se (empate com , vence ), depois , que leva a , e por fim , que leva a . Se o peso de fosse menor que 2, o nó passaria a ser alcançado diretamente por , alterando a árvore de caminhos mais curtos e, via , os caminhos para e .
Confere a tua resposta:
- Inicialização: ; após a primeira iteração: .
- Valores finais: , , , , , .
- A aresta não pode ter peso inferior a 2.
Dijkstra falha com arestas negativas: que aresta removerAutoavaliação
Recurso global, 2023/24
Considere o grafo dirigido e pesado com nós e arestas (2), (8), (12), (2), (), (2), (1).
a) Aplique o algoritmo de Dijkstra a partir de , indicando a ordem pela qual os nós são conhecidos e as distâncias finais que produz. b) O algoritmo encontrou algum caminho mais curto incorreto? Indique o caminho calculado e o correto. c) Se pudesse retirar apenas uma aresta, qual escolheria para que o Dijkstra produzisse resultados corretos para todos os nós?
Solução
a) Ordem , com . b) Sim: deveria ser 2 e deveria ser 1. c) Remove-se a aresta .
O Dijkstra só é correto com pesos não negativos. Aqui, depois de fixar e , a aresta negativa já não é reaplicada: o caminho dá e dá 2. Sem a aresta , todos os pesos são não negativos e o Dijkstra produz os caminhos corretos.
Confere a tua resposta:
- Ordem de seleção: , com distâncias finais , , , .
- As distâncias incorretas são (correta: 2, via ) e (correta: 1, via ).
- A aresta a remover é de peso .
Fluxo máximo
Fluxo máximo numa rede em duas camadasAutoavaliação
Teste 1, 2023/24
Considere a rede de fluxo com fonte e sumidouro , em que e . As arestas entre e os nós de têm capacidade 2, as arestas entre e têm capacidade 1, e as arestas entre e têm capacidade 1.
a) Indique um corte mínimo e a respetiva capacidade. b) Liste os caminhos de aumento que o algoritmo de Edmonds-Karp encontra, por ordem. c) Qual é o fluxo máximo entre e ? d) Quantas arestas entre e podem ser retiradas sem afetar o fluxo máximo? Explique.
Solução
a) Corte , , capacidade 3. b) , , (capacidade 1 cada). c) Fluxo máximo = corte mínimo = 3. d) Uma aresta por cada nó de .
Só entram em três arestas de capacidade 1, pelo que o fluxo máximo é no máximo 3; o corte mostra que 3 é atingível com os três caminhos indicados. Em cada nó de há duas arestas para , pelo que retirar uma delas não impede desviar o fluxo pela outra.
Confere a tua resposta:
- O corte mínimo é com capacidade 3.
- Os caminhos de aumento são , e , todos de capacidade 1.
- O fluxo máximo é 3.
- Pode retirar-se uma aresta por cada nó de , porque o fluxo se desvia para o nó alternativo de .
Fluxo máximo com capacidades X, Y e ZAutoavaliação
Recurso T1, 2022/23
Considere a rede de fluxo com fonte e sumidouro , em que , e são valores inteiros não negativos. As arestas são (20), (20), (), (), (), () e (20).
a) Qual é a expressão analítica do fluxo máximo entre e em função de , e ? b) Quais devem ser os valores de , e para que todas as arestas fiquem saturadas no fluxo máximo? c) Faz sentido aumentar para lá do valor de ? Porquê?
Solução
a) Fluxo máximo . b) . c) Não, pois o gargalo do caminho é a aresta de capacidade .
O fluxo que chega a vem dos caminhos (limitado por ) e (limitado por ), e a aresta limita tudo a 20. Para saturar as arestas de (20 cada) e a de , cada ramo tem de transportar 10, ou seja . Aumentar além de não ajuda, porque o troço partilhado de capacidade continua a limitar o caminho.
Confere a tua resposta:
- O fluxo máximo é .
- Para saturar todas as arestas: .
- Não faz sentido aumentar para lá de , porque a capacidade do caminho fica limitada por .
Divisão e conquista
Recorrência com quatro ramos de tamanho n/4Autoavaliação
Teste 1, 2023/24
Considere a função recursiva
void myAlgorithm(int arr[], int n, int blk) {
if (n == 1) return;
checkArray(arr, n, blk);
for (int i = 0; i < 4; i++)
myAlgorithm(arr, n/4, i);
}
onde checkArray não chama outras funções e o seu custo depende apenas de . Determine a complexidade assintótica de myAlgorithm discutindo os vários casos para o custo de checkArray: e se for ? E se for ? E se for ?
Solução
. Como e , : se , caso 2 do teorema mestre, ; se (por exemplo ), caso 1, ; se (por exemplo ), caso 3, .
Cada chamada gera 4 subproblemas de tamanho , pelo que a árvore de recursão tem profundidade e o trabalho fora das folhas domina conforme o expoente de comparado com .
Confere a tua resposta:
- A recorrência indicada é com .
- Para : ; para : ; para : .
Contar os zeros de uma cadeia 1^m 0^n em O(log k)Autoavaliação
Teste 1, 2023/24
Dado um vetor binário da forma , ou seja, com valores 1 seguidos de valores 0, conceba um algoritmo melhor que que encontre o número de zeros em , onde . Formalize a complexidade assintótica apresentando o pseudo-código.
Solução
Pesquisa binária sobre o índice em que o vetor muda de 1 para 0: se há zeros; se não há zeros; caso contrário divide-se o intervalo ao meio até encontrar a transição. O número de zeros é (ou ) onde é o último índice com valor 1. Complexidade .
Como o vetor está ordenado (todos os 1 antes de todos os 0), a posição da mudança é monotónica e a pesquisa binária encontra-a em passos, cada um de custo constante.
Confere a tua resposta:
- A estratégia é uma pesquisa binária pelo ponto em que o valor muda de 1 para 0.
- O pseudo-código trata os casos extremos e em tempo constante.
- A complexidade indicada é .
Recorrência com três ramos de tamanho n/9Autoavaliação
Teste 1, 2022/23
Considere a função recursiva
public int G(int n, ...) {
if (n < 1) return 1;
F(n, ...);
int x = G(n / 9, ...);
int y = G(n / 9, ...);
int z = G(n / 9, ...);
return x + y * z;
}
onde F tem custo polinomial, logarítmico ou mesmo constante em . Derive a recorrência do tempo de execução de G e a sua complexidade assintótica pelo teorema mestre, examinando vários cenários para F. Discuta a complexidade quando F(n) é linear e quando é quadrático. Faria sentido tornar F logarítmica? Porquê?
Solução
, com , e . Se ou , domina a solução homogénea: e . Se , caso 2: . Se F fosse , continuava a ser polinomialmente inferior a e : não vale a pena investir numa implementação mais eficiente de F.
O expoente crítico é . Qualquer polinomialmente acima de domina a recorrência; o próprio dá o caso 2 com fator logarítmico; abaixo disso, o custo das folhas domina.
Confere a tua resposta:
- A recorrência é com .
- Para ou : e , respetivamente; para : .
- Tornar
Flogarítmica não altera a complexidade global, que continua .
Recorrência com nove ramos de tamanho n/3Autoavaliação
Recurso T1, 2022/23
Considere a função recursiva
public int G(int n, ...) {
if (n < 1) return 1;
F(n, ...);
x = 0;
for (i = 0; i < 9; i++)
x = max(x, G(n / 3, ...));
return;
}
onde F tem custo polinomial, logarítmico ou constante em . Derive a recorrência do tempo de execução e a respetiva complexidade assintótica pelo teorema mestre, examinando vários cenários para F. Discuta a complexidade quando F(n) é linear e quando é quadrático. Faria sentido tornar F logarítmica? Porquê?
Solução
, com , e . Se , caso 1: . Se , caso 2: . Se F fosse mais eficiente que linear, a complexidade continuava , pelo que não faz sentido investir nisso.
O número de folhas é , que já domina qualquer de expoente inferior a 2. Só um F quadrático (caso 2) ou superior altera a ordem de grandeza, e nesse caso o custo de F passa a dominar.
Confere a tua resposta:
- A recorrência é com .
- Para : ; para : .
- Tornar
Fmais eficiente que linear não altera a complexidade global, que continua quadrática.
Retrocesso e ramificação
Particionar um conjunto em dois subconjuntos de soma igualAutoavaliação
Recurso global, 2023/24
Dado o conjunto , determine se pode ser particionado em dois subconjuntos e com a mesma soma (se a soma dos elementos de é , a soma dos de também é ), usando retrocesso com podas. Assuma que o primeiro elemento não está em e o segundo está em (, ).
a) Qual é o valor de ? b) Indique os elementos dos subconjuntos e . c) Quantos estados do espaço de procura (16, com e fixos) foram totalmente explorados e quantos foram podados?
Solução
a) . b) , . c) 0 estados totalmente explorados; 16 podados.
A soma total é , logo . Com e , a poda pelo limite superior (soma parcial + próximo elemento > ) e pelo limite inferior (soma parcial + soma dos restantes < ) impede qualquer ramo de chegar ao fim: a primeira solução válida, o estado , corresponde a .
Confere a tua resposta:
- O valor de é 35.
- Os subconjuntos são e .
- Dos 16 estados, nenhum foi totalmente explorado e os 16 foram podados.
Soma de subconjuntos com podas: W = {1,3,4,5}, M = 8Autoavaliação
Recurso T1, 2022/23
Considere o problema da soma de subconjuntos com e . Usando retrocesso, mostre a árvore completa de estados e, com as duas funções de poda descritas nas aulas, determine que estados podem ser podados.
As podas são: abandonar o ramo se a soma parcial mais o próximo elemento exceder ; e abandoná-lo se a soma parcial mais a soma de todos os elementos restantes for inferior a . Cada nó da árvore é um triplo (soma, nível, resto), onde "resto" é a soma dos elementos que ainda podem ser incluídos.
Solução
A árvore de estados (soma, nível, resto) é:
(0,1,13)
├── x1=1 → (1,2,12)
│ ├── x2=1 → (4,3,9)
│ │ ├── x3=1 → (8,4,5)
│ │ │ ├── x4=1 → 13 > 8, podado
│ │ │ └── x4=0 → (8,5,0), solução {1,3,4}
│ │ └── x3=0 → (4,4,5), ambos os ramos seguintes podados
│ └── x2=0 → (1,3,9), todos os ramos podados
└── x1=0 → (0,2,12)
├── x2=1 → (3,3,9)
│ ├── x3=1 → (7,4,5), podado
│ └── x3=0 → (3,4,5)
│ ├── x4=1 → (8,5,0), solução {3,5}
│ └── x4=0 → 3 < 8, podado
└── x2=0 → (0,3,9), todos os ramos podados
As soluções são e .
A poda superior impede continuar quando a soma parcial mais o próximo elemento ultrapassa (por exemplo, em (4,4,5) o próximo elemento 5 daria 9); a poda inferior impede continuar quando nem com todos os restantes se chega a (por exemplo, em (3,4,5) com a soma fica 3 < 8). Só os estados (8,5,0) atingem a soma exata.
Confere a tua resposta:
- A árvore de estados parte da raiz e cada nível escolhe ou .
- Os estados podados são os que violam uma das duas condições de poda.
- As soluções encontradas são os subconjuntos de soma 8: e .