Prévia do material em texto
Projetos de algoritmos
APRESENTAÇÃO
No projeto de algoritmos, são utilizadas técnicas de otimização capazes de encontrar uma
solução ótima para problemas com características distintas. Para isso, os algoritmos precisam ser
eficientes em tempo de execução para garantir um bom resultado.
Um exemplo seria a estratégia de divisão e conquista, que divide um problema em partes
menores e cada parte é tratada de forma individual e independente, e as soluções encontradas em
cada parte são combinadas para disponibilizar a solução final do problema. Uma das aplicações
da estratégia divisão e conquista é encontrar o maior ou o menor valor em um vetor.
Nesta Unidade de Aprendizagem, você vai conhecer os métodos para projetar algoritmos e
como os algoritmos de divisão e conquista, algoritmo guloso, programação dinâmica e
programação de aproximação se comportam na resolução de problemas de otimização. Além
disso, você irá estudar as soluções de problemas de aproximação, como a cobertura de vértices e
o problema de soma de subconjuntos.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Descrever os métodos para projetar algoritmos.•
Demonstrar os métodos de projeto de algoritmos.•
Identificar soluções de problemas de aproximação.•
DESAFIO
O algoritmo guloso utiliza a melhor solução em determinado momento, sem explorar as demais
soluções, e, após a escolha da melhor solução, não volta atrás. Um algoritmo guloso faz
escolhas gulosas em cada passo e garante sua eficiência.
INFOGRÁFICO
O algoritmo de divisão e conquista decompõe um problema em partes menores, e cada parte é
tratada de forma individual e independente.
Um dos algoritmos que utiliza esse método é o Quicksort, que tem
o objetivo de ordenar um conjunto de elementos considerando os elementos menores e maiores
do conjunto em relação ao pivô.
No Infográfico a seguir, você irá conhecer o algoritmo Quicksort,
que utiliza a técnica de divisão e conquista.
CONTEÚDO DO LIVRO
A otimização de problemas é um dos tópicos tratados no projeto de algoritmos e tem o objetivo
de minimizar ou maximizar a solução ótima de acordo com o problema a ser tratado para
problemas de diferentes tipos, incluindo os problemas NP-completos. Existem métodos que
auxiliam na solução desses problemas, encontrando resultados ótimos e satisfatórios para a
solução final.
No capítulo Projeto de algoritmos, da obra Análise de algoritmos, base teórica desta Unidade de
Aprendizagem, serão apresentados os métodos para projetar algoritmos e como esses métodos
se comportam na resolução de distintos problemas de otimização. Você também irá aprender
como os algoritmos de aproximação conseguem encontrar soluções aproximadas para os
problemas de cobertura de vértices e o problema de soma de subconjuntos.
Boa leitura.
ANÁLISE DE
ALGORITMOS
Cynthia da Silva Barbosa
Projetos de algoritmos
Objetivos de aprendizagem
Ao final deste texto, você deve apresentar os seguintes aprendizados:
Descrever métodos para projetar algoritmos.
Demonstrar os métodos de projeto de algoritmos.
Identificar soluções de problemas por aproximação.
Introdução
Para projetar algoritmos eficientes, são utilizados métodos de otimização
que auxiliam na solução de problemas com características distintas, como
os algoritmos de divisão e conquista, algoritmo guloso, programação
dinâmica e programação de aproximação. As soluções de problemas de
aproximação minimizam ou maximizam os resultados de acordo com as
características do problema.
Para exemplificar, imagine o caso em que um cliente realiza uma
compra em um supermercado e efetua o pagamento em dinheiro nos
guichês automáticos. Nesse caso, a devolução do troco pode ser feita
utilizando um algoritmo guloso, que iniciaria pela maior nota e, por último,
liberaria as moedas. No caso da programação dinâmica, um problema
em que pode ser aplicado seria o da mochila booleana, onde é inserida a
maior quantidade de objetos, de acordo com o peso e o valor de cada um.
Neste capítulo, você vai estudar sobre os métodos para projetar algo-
ritmos, os métodos de projeto de algoritmos e as soluções de problemas
de aproximação.
1 Métodos para projetar algoritmos
Os métodos para projetar algoritmos são aplicados em diversos problemas de
otimização e utilizam procedimentos matemáticos para a solução de problemas.
As técnicas utilizadas para a análise e o projeto de algoritmos são divisão e
conquista, algoritmo guloso, programação dinâmica e programação de apro-
ximação, todas detalhadas a seguir (CORMEN et al., 2009).
Divisão e conquista
A estratégia de divisão e conquista decompõe um problema em partes menores
(divisão), e cada parte é tratada de forma individual e independente (conquista).
As soluções encontradas em cada parte são combinadas para disponibilizar a
solução fi nal do problema (combinação). Trata-se, portanto, de uma estratégia
baseada na recursividade.
Para que a estratégia de divisão e conquista seja eficiente, é preciso que a
etapa de divisão e a etapa de combinação sejam rápidas. Uma vantagem dessa
estratégia é que o tempo de execução é facilmente determinado. Desvantagens
incluem os fatos de que ela é lenta no pior caso e de que pode ocorrer estouro
de memória em função da recursividade.
Exemplos de estratégias de divisão e conquista incluem:
pesquisa em árvore binária;
ordenação rápida (quicksort);
ordenação por intercalação (mergesort);
algoritmo da mediana.
Programação dinâmica
A programação dinâmica auxilia na resolução de problemas de otimização
combinatória e permite que sejam descobertas as melhores escolhas para
um problema. Além disso, na programação dinâmica, os subproblemas não
são independentes, e cada subproblema é resolvido apenas uma vez, tendo
sua solução armazenada em uma tabela para evitar a recursão. As soluções
encontradas são chamadas de soluções ótimas, pois contêm um valor ótimo,
sendo o valor mínimo ou máximo que satisfaz a resolução do problema.
Projetos de algoritmos2
A estratégia da programação dinâmica segue quatro passos (CORMEN
et al., 2009):
1. Diferenciar a estrutura de uma solução ótima.
2. Resolver de forma recursiva o valor de uma solução ótima.
3. Calcular o valor de uma solução ótima utilizando o processo de baixo
para cima.
4. Criar uma solução ótima baseada nas soluções calculadas.
Os passos 1, 2 e 3 compõem a estrutura da programação dinâmica de um
problema. O passo 4 é executado para auxiliar com dados adicionais, que
contribuem para encontrar a solução ótima.
A programação dinâmica utiliza uma subestrutura ótima; ou seja, a solução
ótima encontrada inclui as soluções ótimas encontradas nos subproblemas.
Estes são alguns exemplos das estratégias utilizadas pela programação
dinâmica:
programação de linha de montagem;
multiplicação de cadeia de matrizes;
algoritmo da subsequência crescente máxima;
algoritmo de Dijkstra.
Algoritmos gulosos
O algoritmo guloso é uma técnica que defi ne a solução ótima no momento,
levando em consideração os critérios locais para encontrar a solução ótima
global. O algoritmo guloso é simples e rápido, mas, em determinados proble-
mas, não consegue encontrar uma solução ótima.
Os algoritmos gulosos são míopes, uma vez que as decisões tomadas são
baseadas na iteração corrente, independentemente das soluções futuras. Além
disso, os algoritmos gulosos não voltam atrás na escolha da solução.
O algoritmo guloso segue os seguintes passos (CORMEN et al., 2009):
1. Determinar a subestrutura ótima do problema.
2. Desenvolver uma solução recursiva.
3. Demonstrar que uma das soluções ótimas é a escolha gulosa.
3Projetos de algoritmos
4. Mostrar que os subproblemas induzidos para a escolha gulosa são
vazios, com exceção de um subproblema.
5. Desenvolver um algoritmo recursivo implementando a solução gulosa.
6. Alterar um algoritmo recursivo para um algoritmo interativo.
Exemplosdo algoritmo guloso incluem:
problema da mochila fracionária;
problema da árvore de Huffman;
problema do escalonamento de intervalos;
algoritmos de Prim e Kruskal.
Você sabe quais são as diferenças entre algoritmo guloso e algoritmo de programação
dinâmica? Conforme Feofiloff (2015), o algoritmo guloso:
utiliza a solução em determinado momento, sem explorar as demais soluções;
é rápido;
após a escolha de uma melhor solução, não volta atrás.
Por sua vez, o algoritmo de programação dinâmica:
verifica todas as soluções de forma eficiente;
é lento;
após a escolha de uma melhor solução, pode rever a escolha da solução.
Programação de aproximação
Os algoritmos de aproximação foram desenvolvidos para suprir a impossibilidade
de solucionar problemas de otimização NP-difíceis. Os algoritmos de aproxi-
mação não criam uma solução ótima, mas produzem soluções que pertencem
a determinado fator de solução ótima, conhecida como solução aproximada.
(MIYAZAWA, [2020?]). Para problemas de otimização, o algoritmo de aproxi-
mação é efi ciente e disponibiliza uma boa solução (CARVALHO et al., 2020).
Segundo Cormen et al. (2009), existem três abordagens para aprimorar
um algoritmo para um problema NP-completo:
Projetos de algoritmos4
1. Se os dados de entrada são pequenos, o algoritmo com tempo de exe-
cução exponencial se adéqua ao problema.
2. É possível separar problemas importantes para resolvê-los em tempo
polinomial.
3. Soluções aproximadas podem ser encontradas em tempo polinomial.
Estes são alguns exemplos do algoritmo de aproximação:
problema de cobertura de vértices;
métodos combinatórios;
métodos de programação linear;
problema de soma de subconjuntos.
2 Demonstração dos métodos de projeto
de algoritmos
Nesta seção, você descobrirá como aplicar os algoritmos divisão e conquista,
guloso, programação dinâmica e de aproximação.
Divisão e conquista
Um dos algoritmos utilizados para demonstrar o método de divisão e conquista
é o Mergesort, cujo objetivo é ordenar um vetor por intercalação. O Mergesort
pode ser resolvido utilizando o algoritmo de divisão e conquista.
Suponha que seja necessário reordenar um vetor A[p..r] A [39, 13, 25, 84,
51, 29, 32, 56] em ordem crescente. Note que p ≤ q < r:
p q q + 1 r
39 13 25 84 51 29 32 56
O algoritmo de divisão e conquista supõe que p < r utilizando a recursão,
conforme exemplo apresentado no algoritmo da Figura 1 (FEOFILOFF, 2015).
O algoritmo Intercala (passo 5) é apresentado na Figura 3.
5Projetos de algoritmos
Figura 1. Algoritmo Mergesort.
Fonte: Adaptada de Feofiloff (2015).
Para compreender o funcionamento do algoritmo Mergesort (Figura 1),
observe a representação dos passos de execução do algoritmo sobre um vetor
de exemplo, representado na Figura 2. O algoritmo Mergesort divide o vetor
inicial em dois vetores menores (dividir), que, por sua vez, são divididos em
outros dois vetores (dividir). Depois, os vetores menores são ordenados de
forma recursiva (conquistar). O resultado em cada vetor menor é combinado
(combinar) para compor a solução final: ordenação do vetor inicial.
Figura 2. Ordenação utilizando o Mergesort.
O algoritmo Intercala é responsável por pegar os vetores crescentes A[p..q] e
A[q+1..r] e ordená-los de forma crescente utilizando um vetor auxiliar B. Nas linhas
6 e 7, o vetor é ordenado de p até q. Nas linhas 8 e 9, o vetor é ordenado de q+1 até
r. Nas linhas 12 a 17, a ordenação é refinada e armazenada no vetor original A.
Projetos de algoritmos6
Figura 3. Algoritmo Intercala.
Fonte: Adaptada de Feofiloff (2015).
Programação dinâmica
Para demonstrar o funcionamento do algoritmo de programação dinâmica,
será apresentado o produto de n matrizes (ZIVIANI, 2007).
Considere a matriz M = M1 × M2 × ... × Mn, onde Mi é uma matriz com
di – 1 linhas e di colunas. A ordem da multiplicação pode gerar grandes
implicações na quantidade total de operações de adição e multiplicação para
obter M.
Para exemplificar, veja o produto M = M1[10, 20] × M2[20, 50] × M3[50, 1]
× M4[1, 100], onde as dimensões de cada matriz estão representadas entre col-
chetes. Na matriz M, existem as seguintes possibilidades para gerar o produto:
1. M = M1 × (M2 × (M3 × M4))
2. M = (M1 × (M2 × M3)) × M4
Na opção 1, requer 125.000 operações, enquanto, na opção 2, requer 2.200.
O objetivo é minimizar a quantidade de operações realizadas (ZIVIANI, 2007).
7Projetos de algoritmos
A programação dinâmica computa os valores de mij em ordem crescente
das diferenças nos subscritos e tenta encontrar uma solução ótima sem a
necessidade de gerar todas as possibilidades de produtos entre a matriz M.
Seja mij menor custo para computar Mi × Mi+1 × · · · × Mj, para 1 ≤ i ≤ j
≤ n. A recursividade do menor custo do produto de Mi,j é:
onde:
mik é o custo mínimo para calcular M’ = Mi × Mi+1 × · · · × Mk;
mk+1,j é o custo mínimo para calcular M’’ = Mk+1 × Mk+2 × · · · × Mj;
di−1dkdj é o custo de multiplicar M’[di−1, dk] por M’’[dk, dj];
mij, j > i é o custo mínimo de todos os valores possíveis de k entre i e
j − 1, da soma dos três termos.
O algoritmo que resolve o problema de produto de matrizes é apresentado
na Figura 4.
Figura 4. Algoritmo produto de matrizes.
Fonte: Adaptada de Cormen et al. (2009).
Projetos de algoritmos8
O pseudocódigo leva em consideração uma matriz Ai com dimensões di–1
× di para i = 1,2,3..., n. A entrada para o algoritmo é uma sequência d = {d0,
d1, ..., dn}, onde comprimento [d]= n+1. Uma matriz auxiliar m[1..n, 1..n] é
utilizada para armazenar os custos m[i,j] e uma tabela auxiliar s[1..n, 1..n] que
registra qual índice de k chegou no custo ótimo do cálculo m[i,j]. A tabela s é
usada para construir uma tabela ótima. A equação apresentada anteriormente
mostra o custo m[i,j] para calcular o produto de matrizes para j–i+1 matrizes.
Nas linhas 2 e 3, são calculadas o custo mínimo de m[i,i] 0, onde i = 1,
2, 3, ..., n. Nas linhas 4 a 12, são calculados os custos mínimos utilizando
a recursividade: m[i, i+1] para i = 1, 2, ..., n–1. Em cada fase, o custo m[i,j]
calculado nas linhas 9 a 12 depende da entrada da tabela m[i,k] e m[k + 1,j].
A matriz S contém o resultado da solução ótima (CORMEN et al., 2009).
Após a execução do programa, este foi o resultado encontrado para a matriz
M = M1[10, 20] × M2[20, 50] × M3[50, 1] × M4[1, 100]:
m11 = 0 m22 = 0 m33 = 0 m44 = 0
m12 = 10.000 m23 = 1.000 m34 = 5.000
m13 = 1.200 m24 = 3.000
m14 = 2.200
O produto da matriz m12 representa a multiplicação de M1 × M2 e possui
10.000 operações (custo do produto de matrizes), de acordo com a multiplicação:
10 (linhas de M1) × 20 (linhas de M1) × 50 (colunas de M2). O produto da
matriz m23 representa a multiplicação de M2 × M3 e possui 1.000 operações,
de acordo com a multiplicação: 20 (linhas de M2) × 50 (linhas de M2) × 1
(coluna de M3).
O produto da matriz m34 representa a multiplicação de M3 × M4 e possui
5.000 operações, de acordo com a multiplicação: 50 (linhas de M3) × 1 (linhas
de M3) × 100 (colunas de M4). No caso de m13, deve ser definida a ordem de
multiplicar da matriz M1 até M3: se será feita a multiplicação entre (M1 ×
(M2 × M3)) ou entre ((M1 × M2) × M3). Se a multiplicação for entre (M1 ×
(M2 × M3)), na tabela consta o custo de multiplicar M2 × M3 (m23) = 1.000 +
(10 (linhas de M1) × 20 (linhas de M1 × 1 (colunas de M2, M3)), totalizando
1.200 operações. Se for utilizar o produto entre ((M1 × M2) × M3), o custo será:
10.000 (m12) + (10 (linhas de M1, M2) × 50 (linhas de M1, M2 × 1 (colunas de
M3)), totalizando 10.500 operações. Assim, para obter o menor custo, basta
multiplicar (M1 × (M2 × M3)).
9Projetos de algoritmos
No caso de m24, deve ser definida qual será a ordem de multiplicar da
matriz M2 até M4: se será feita a multiplicação entre (M2 × (M3 × M4))
ou entre ((M2 × M3) × M4). No caso, o menor custo é obtido multiplicando
((M2 × M3) × M4): 1.000 (m23) + (20 (linhas de M2, M3) × 1 (linhas de M2,M3 × 100 (colunas de M4)), totalizando 3.000 operações.
No caso de m14, a melhor ordem para multiplicar da matriz M1 até M4 é
(M1 × ( M2 × M3)) e, em seguida, (M13 × M4), totalizando 1.200 operações.
Algoritmos gulosos
Para demonstrar o funcionamento do algoritmo guloso, será apresentado o
problema da mochila fracionária, conforme apresentado em Feofi loff (2015).
O problema da mochila fracionária permite carregar objetos com pesos e
valores distintos, com o objetivo de carregar a mochila com o maior número
de objetos, segundo sua capacidade.
Para exemplificar, são apresentados os vetores naturais (p1, p2, … , pn),
que representa o vetor de pesos dos objetos, (v1, v2, … , vn), que representa um
vetor de valores dos objetos, e um número natural c, referente à capacidade da
mochila. O objetivo é achar um vetor racional (x1, x2, … , xn) que maximize
x * v sob as restrições x * p ≤ c e 0 ≤ xi ≤ 1 para todo i.
O algoritmo guloso que resolve o problema da mochila fracionária é apre-
sentado na Figura 5.
Figura 5. Algoritmo guloso resolvendo o problema
da mochila fracionária.
Fonte: Adaptada de Feofiloff (2015).
Projetos de algoritmos10
O algoritmo leva em consideração a ordem dos objetos 1, 2, … , n. O al-
goritmo determina que os objetos estejam em ordem crescente do valor por
unidade de peso. A cada objeto inserido na mochila, o peso do objeto é de-
crementado de sua capacidade total (linhas 1 a 4).
A cada iteração, o algoritmo guloso pega o objeto de maior peso entre os
disponíveis e não se preocupa com o que acontecerá futuramente, além de
não se arrepender de suas escolhas.
Programação de aproximação
Para demonstrar o funcionamento do algoritmo de aproximação, será apresen-
tado o problema da mochila booleana, conforme Feofi loff (2015). O problema
da mochila booleana consiste em defi nir quais itens serão inseridos na mochila
de acordo com o peso de cada item e com a capacidade da mochila.
Para exemplificar, são apresentados os números naturais (p1, p2, … , pn),
que representa os pesos dos objetos, (v1, v2, … , vn), que representa os valo-
res dos objetos, e um número natural c, referente à capacidade da mochila.
O objetivo é achar um valor máximo de um subconjunto X de {1, … , n} que
maximize v(X) com a restrição p(X) ≤ c.
O algoritmo de aproximação que resolve o problema da mochila booleana
é apresentado na Figura 6.
Figura 6. Algoritmo de aproximação resolvendo o
problema da mochila booleana.
Fonte: Adaptada de Feofiloff (2015).
11Projetos de algoritmos
O algoritmo de aproximação cria uma mochila que pode não conter o
valor máximo, mas contém, pelo menos, metade do valor máximo. Além
disso, o algoritmo possui características gulosas; ou seja, escolhe os objetos
com o maior valor. Nesse exemplo, os dados de entrada do algoritmo estão
em ordem decrescente de valor. Nas linhas 3 a 5, o algoritmo encontra o
maior k tal que p1+ … +pk−1 ≤ c.
O algoritmo da MOCHILA-QUASE-ÓTIMA resulta em uma solução de
aproximação de 50% do ótimo.
3 Soluções de problemas de aproximação
As soluções de problemas de aproximação garantem uma solução ótima den-
tro do aceitável e são conhecidas como solução aproximada para problemas
NP-completo. Se um problema de otimização possui soluções com custo
positivo, as soluções aproximadas podem ser de minimização ou maximização,
dependendo do problema (CORMEN et al., 2009).
Nesta seção, serão apresentadas as soluções de problemas de aproximação
para os problemas de cobertura de vértices e o problema de soma de subcon-
juntos (CORMEN et al., 2009).
Problema de cobertura de vértices
O problema de cobertura de vértices de um grafo é um conjunto de vértices
que incide pelo menos a uma aresta do conjunto. O objetivo é encontrar uma
cobertura de vértices mínima ou cobertura de vértice ótima de um grafo.
Para exemplifi car o funcionamento do algoritmo de aproximação APROXI-
MAÇÃO_COBERTURA_VÉRTICE (apresentado na Figura 8), considere os
grafos apresentados na Figura 7.
Projetos de algoritmos12
Figura 7. Operação do algoritmo de aproximação resolvendo o problema de cobertura
de vértices.
Fonte: Adaptada de Cormen et al. (2009).
O grafo de entrada G (Figura 7a) possui 7 vértices e 8 arestas. O algoritmo
seleciona a aresta (b, c) para iniciar (Figura 7b). Os vértices b e c são inseridos
no conjunto C com os vértices que estão sendo criados. As arestas (a, b), (c,
e) e (c, d) que estão tracejadas são removidas por estarem cobertas por um
vértice em C. A aresta (e, f ) é selecionada (Figura 7c). Os vértices e e f são
inseridos a C. A aresta (d, g) é escolhida (Figura 7d). Os vértices d e g são
inseridos a C. O conjunto C contém a cobertura dos vértices gerados pelo
algoritmo APROXIMAÇÃO_COBERTURA_VÉRTICE, com seis vértices:
b, c, d, e, f, g e h (Figura 7e). A Figura 7f mostra a cobertura ótima para o
problema com três vértices: b, d e e.
13Projetos de algoritmos
O algoritmo de aproximação possui, como entrada, um grafo não orientado
G e, como saída, devolve uma cobertura de vértices ótima (Figura 8). Na
linha 1, a variável C é inicializada com 0. A variável C contém a cobertura
de vértices que serão criados. Na linha 2 E’, recebe uma cópia do conjunto
de arestas E[G] do grafo. Nas linhas 3 a 6, seleciona uma aresta (u, v) de E’,
insere suas extremidades u e v em C e remove todas arestas em E’ que estão
cobertas por u ou v.
Figura 8. Algoritmo de aproximação resolvendo o problema de cobertura de vértices.
Fonte: Adaptada de Cormen et al. (2009).
Problema de soma de subconjuntos
O problema de soma de subconjuntos (subset sum) é um par (S, t) que consiste
em um conjunto de números inteiros S {x1, x2, ...., xn} e precisa verifi car se
existe um subconjunto de S que adicione exatamente o valor de destino t.
Para exemplifi car, imagine um caminhão que não pode transportar uma carga
maior que t quilos e possui n diferentes tipos de caixas para transportar, e
que cada caixa pesa xi quilos. O objetivo é carregar o caminhão com a carga
mais pesada sem ultrapassar a carga máxima que um caminhão consegue
transportar (CORMEN et al., 2009).
Projetos de algoritmos14
Será apresentado um algoritmo (SOMA_SUBCONJUNTOS (S, t)) de
tempo exponencial para calcular soma de subconjuntos, ilustrado na Figura 9.
Para calcular a soma dos subconjuntos, para cada subconjunto de S’ de S, a
soma dos elementos em S’ não pode exceder t.
Figura 9. Algoritmo de aproximação resolvendo o problema de soma
de subconjuntos.
Fonte: Adaptada de Cormen et al. (2009).
O algoritmo SOMA_SUBCONJUNTOS (S, t) recebe como entrada um
conjunto S = {x1, x2, ...., xn} e um valor t. O algoritmo calcula a lista Li, soma
dos subconjuntos de {x1, x2, ...., xi} que não excedam o valor t, e retorna o valor
máximo em Ln. Se L = (1, 2, 3, 5, 9), então L+2 = (3, 4, 5, 7, 11). O procedimento
MERGE-LISTS (L, L’) retorna a lista ordenada das listas L e L’ retirando os
valores duplicados.
Neste capítulo, vimos que os algoritmos de projeto de algoritmos podem
ser usados para diversos problemas de otimização e contribuem para encontrar
soluções ótimas de um problema. Para cada problema, existe um algoritmo
específico. Além disso, existem diversas soluções propostas para solucionar
problemas de aproximação NP-completos, como os algoritmos de aproximação
de cobertura de vértices e soma de subconjuntos.
15Projetos de algoritmos
CARVALHO, M. H. et al. Uma introdução sucinta a algoritmos de aproximação. [S. l. : s.
n.]: 2001. Disponível em: https://www.ime.usp.br/~cris/aprox/livro.pdf. Acesso em:
4 ago. 2020.
CORMEN, T. H. et al. Introduction to algorithms. 3. ed. Cambridge (MA): MIT Press, 2009.
FEOFILOFF, P. Aulas: análise de algoritmos. In: INSTITUTO de Matemática e Estatística da
USP. São Paulo, 13 abr. 2015. Disponível em: https://www.ime.usp.br/~pf/analise_de_al-
goritmos/lectures.html. Acesso em: 4 ago. 2020.
MIYAZAWA, F. K. Algoritmos de aproximação. In: INSTITUTO de Computação da Uni-
versidade de Campinas.Campinas, [2020?]. Disponível em: https://www.ic.unicamp.
br/~fkm/problems/algaprox.html. Acesso em: 4 ago. 2020.
ZIVIANI, N. Projeto de algoritmos com implementações em Java e C++. São Paulo: Cengage
Learning, 2007.
Os links para sites da web fornecidos neste capítulo foram todos testados, e seu fun-
cionamento foi comprovado no momento da publicação do material. No entanto, a
rede é extremamente dinâmica; suas páginas estão constantemente mudando de
local e conteúdo. Assim, os editores declaram não ter qualquer responsabilidade
sobre qualidade, precisão ou integralidade das informações referidas em tais links.
Projetos de algoritmos16
DICA DO PROFESSOR
A programação dinâmica permite que as melhores escolhas para um problema sejam
encontradas. Para isso, a programação dinâmica utiliza o princípio da otimalidade. O princípio
da otimalidade pode ser definido como: entre um conjunto de soluções ótimas, cada solução em
um subconjunto também deve ser ótima.
Na Dica do Professor, você irá conhecer o princípio da otimalidade aplicado na programação
dinâmica.
Conteúdo interativo disponível na plataforma de ensino!
EXERCÍCIOS
1) Os métodos para projetar algoritmos são aplicados em diversas aplicações e
problemas de otimização e utilizam procedimentos matemáticos para solução de
problemas. Em relação às técnicas divisão e conquista e programação dinâmica,
analise as afirmações a seguir:
I. O algoritmo de divisão e conquista é baseado na objetividade de tempo e divide em
partes menores um problema.
II. As soluções ótimas encontradas pelo algoritmo da programação dinâmica podem
apenas minimizar o resultado de acordo com o problema.
III. Fazem parte dos algoritmos que compõem a programação dinâmica o algoritmo
de Dijkstra e a programação de linha de montagem.
IV. Por utilizar a recursividade, o algoritmo de divisão e conquista pode ser lento no
pior caso e pode impactar a performance do computador.
Agora, assinale a alternativa que apresenta a resposta correta:
A)
Apenas as afirmativas II e III estão corretas.
B)
Apenas as afirmativas I e IV estão corretas.
C)
Apenas as afirmativas III e IV estão corretas.
D)
Apenas as afirmativas I, II e IV estão corretas.
E)
As afirmativas I, II, III e IV estão corretas.
2) O algoritmo guloso é uma técnica que define a solução ótima no momento, levando
em consideração os critérios locais para encontrar a solução ótima global. Em relação
aos algoritmos gulosos, analise as afirmações a seguir:
I. O algoritmo guloso leva em consideração todas as soluções possíveis para
determinado problema antes de escolher a solução final.
II. São exemplos de algoritmos gulosos: problema da mochila fracionária e os
algoritmos de Prim e Kruskal.
III. O algoritmo guloso é simples e lento, porém consegue sempre encontrar uma
solução ótima para todos os problemas de otimização.
IV. Uma vez definida uma solução, o algoritmo guloso não retrocede em sua escolha.
Agora, assinale a alternativa que apresenta a resposta correta:
A)
Apenas as afirmativas I, II e III estão corretas.
B)
Apenas as afirmativas II e IV estão corretas.
C)
Apenas as afirmativas II e III estão corretas.
D)
Apenas as afirmativas I, III e IV estão corretas.
E)
As afirmativas I, II, III e IV estão corretas.
As soluções de problemas de aproximação garantem uma solução ótima dentro do
aceitável e são conhecidas como soluções aproximadas para problemas, em que não
são encontrados resultados em um tempo polinomial por meio de algoritmos
deterministas (NP-completo).
Considerando o contexto apresentado, avalie as seguintes asserções sobre as soluções
de problemas de aproximação:
3)
will-
Destacar
will-
Destacar
I. As soluções aproximadas podem ser de minimização ou maximização se o
problema tiver um custo positivo.
PORQUE
II. A solução para o problema de cobertura de vértices tem o objetivo de maximizar o
maior número de arestas de um grafo.
A respeito dessas asserções, assinale a opção correta:
A)
As asserções I e II são proposições verdadeiras, e a II é uma justificativa da I.
B)
As asserções I e II são proposições verdadeiras, mas a II não é uma justificativa da I.
C)
A asserção I é uma proposição verdadeira, e a II é uma proposição falsa.
D)
A asserção I é uma proposição falsa, e a II é uma proposição verdadeira.
E)
As asserções I e II são proposições falsas.
4) Os algoritmos de aproximação foram desenvolvidos para suprir a necessidade de
solucionar problemas de otimização NP-difíceis. Em relação aos problemas de
cobertura de vértices e ao problema de soma de subconjuntos, analise as afirmações a
seguir:
I. O algoritmo aplicado ao problema de soma de subconjuntos tolera pequenas
variações em relação ao valor total de uma carga.
II. Para que o resultado do algoritmo do problema de cobertura de vértices seja
válido, é preciso que tenha pelo menos uma referência em uma aresta do conjunto.
III. A saída do algoritmo de cobertura de vértices retorna uma saída de vértice ótima
e remove todas as arestas que não foram referenciadas no conjunto.
IV. Uma das etapas do algoritmo aplicado ao problema de soma de subconjuntos é
ordenar a lista de valores e manter os valores duplicados, garantindo a segurança do
resultado.
Agora, assinale a alternativa que apresenta a resposta correta:
A)
Apenas as afirmativas I e II estão corretas.
will-
Destacar
B)
Apenas as afirmativas III e IV estão corretas.
C)
Apenas as afirmativas II e III estão corretas.
D)
Apenas a afirmativa II está correta.
E)
As afirmativas I, II, III e IV estão corretas.
5) Para problemas de otimização, o algoritmo de aproximação é eficiente e disponibiliza
uma boa solução para o problema. Considerando o contexto apresentado, avalie as
seguintes asserções sobre o algoritmo de aproximação:
I. Os algoritmos de aproximação geram uma solução ótima, conhecida como solução
próxima e produzem resultados que estão inseridos em um conjunto de soluções
ótimas.
PORQUE
II. Um exemplo de algoritmo de aproximação seria o problema da mochila booleana,
que define os elementos que serão inseridos na mochila de acordo com a sua
capacidade.
A respeito dessas asserções, assinale a opção correta:
A)
As asserções I e II são proposições verdadeiras, e a II é uma justificativa da I.
B)
As asserções I e II são proposições verdadeiras, mas a II não é uma justificativa da I.
C)
A asserção I é uma proposição verdadeira, e a II é uma proposição falsa.
D)
A asserção I é uma proposição falsa, e a II é uma proposição verdadeira.
E)
As asserções I e II são proposições falsas.
NA PRÁTICA
A automatização de processos industriais garante a agilidade e a eficiência dos serviços
prestados. Para isso, podem ser utilizadas diversas técnicas de otimização de processos, como
divisão e conquista, algoritmos gulosos e programação dinâmica, por exemplo, de acordo com o
will-
Destacar
will-
Destacar
problema a ser tratado.
Neste Na Prática, você conhecerá um consultor de desenvolvimento de sistemas que trabalha em
uma multinacional e que irá resolver o problema do algoritmo guloso configurado na esteira
automática de separação de produtos.
SAIBA +
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do
professor:
Algoritmo guloso
Neste vídeo, é apresentado um exemplo didático do funcionamento do algoritmo guloso.
Conteúdo interativo disponível na plataforma de ensino!
Análise do algoritmo Mergesort
Neste link, é apresentado como o algoritmo Mergesort resolve a ordenação por intercalação.
Conteúdo interativo disponível na plataforma de ensino!