Projeto e Análise de Algoritmos Lista 3

https://imgur.com/LjImztT.png

https://imgur.com/Nk3qtWi.png

https://imgur.com/4QKJoQ5.png

https://imgur.com/23OGRbX.png

https://imgur.com/zPrWBHG.png

https://imgur.com/4O5kASe.png https://imgur.com/va65SZ1.png

https://imgur.com/r74kgle.png

Suponha que tenhamos um conjunto \(S = {a_{1},a_{2},...,a_{n}}\) de n atividades propostas que desejam usar um recurso (ex.: uma sala) que só pode ser utilizado por uma única atividade por vez. Cada atividade \(a_{i}\) tem um tempo de início \(s_{i}\) e um tempo de término \(f_{i}\), onde 0 <= si < fi < infinito. Se selecionada, a atividade \(a_{i}\) ocorre durante o intervalo de tempo meio aberto \([s_{i}, f_{i})\). As atividades \(a_{i}\) e \(a_{j}\) são compatíveis se os intervalos \([s_{i}, f_{i})\) e \([s_{j}, f_{j})\) não se sobrepõem. Isto é, \(a_{i}\) e \(a_{j}\) são compatíveis se \(s_{i}\) > \(f_{j}\) e \(s_{j}\) >= \(f_{i}\).

https://imgur.com/yTP1Sny.png

https://imgur.com/72jCS2T.png

https://imgur.com/XkSwq43.png

typedef struct grafo {
  int V;
  int E ;
  int **adj;   
} Grafo;
typedef struct vertice {
  int no;
  struct vertice *prox;
} Vertice;


typedef struct grafo {
  int V;
  int E;
  Vertice *adj;
} Grafo;

https://imgur.com/VAcnpRU.png

https://imgur.com/kReEqT6.png

https://imgur.com/MkAwpFJ.png

https://imgur.com/2XCuBGm.png

https://imgur.com/wlZzohf.png

Qualquer subárvore de uma MST também é uma MST.

https://imgur.com/09CB3t1.png

https://imgur.com/egai0jM.png

Começamos mostrando que T não possui ciclos, assim, basta mostrar que nenhuma aresta escolhida pelo algoritmo forma um ciclo. Note que, se começarmos a percorrer o ciclo C cada vez que passamos por uma das arestas que atravessa o corte, nós mudamos de parte, e só nesse caso mudamos de parte. Ao definir o corte, separamos o grafo em duas partes: os vértices e arestas que estão dentro do corte dos que não estão. Assim, após atravessarmos o corte C um número impar de vezes, estamos numa parte diferente da que começamos. Como um ciclo tem que fechar, precisamos atravessar um número par de arestas para voltar ao começo.

Agora, mostraremos que T é geradora e alcança todos os vértices de G.

Prova(Volta): Com base no lema de arestas na fronteira e supondo que existe um corte (A,B) sem arestas, tal que \(u \epsilon A\) e \(v \epsilon B\). Basta verificar que não existe caminho de u até V, caso contrário, teriamos uma aresta atravessando (A,B), portanto o grafo é desconexo.

Prova(Ida): Com base no lema de arestas na fronteira e supondo que o grafo não é conexo. Seja A o conjunto de todos os vértices alcançados a partir de V. Seja B = V \ A. Note que \(u \epsilon B\) (não existe caminho entre u e V para ser alcançado). Assim (A,B) é um corte sem arestas cruzando sua fronteira. Sabendo que G=(V,E) é conexo usando o lema do corte vazio, concluímos que ele não possui qualquer corte (A,B) sem arestas. Portanto, o algoritmo nunca vai parar no meio de uma iteração.

https://imgur.com/w33Yhx6.png

Assim, mostramos que T tem custo mínimo pela propriedade do corte, pois, toda aresta escolhida pelo algoritmo é a mais barata de um corte e, pela propriedade, ela deve estar na MST.

https://imgur.com/45yEU7Y.png

https://imgur.com/4KLFEku.png https://imgur.com/QVVRPN7.png

A entrada do algoritmo de Dijkstra é um grafo ponderado com um vértice inicial especificado. O grafo é representado por uma matriz de adjacência, onde cada entrada indica o peso da aresta entre dois vértices. O vértice inicial é especificado como um inteiro que representa o seu índice na matriz de adjacência.

A saída do algoritmo de Dijkstra é uma lista de vértices que representa o caminho mais curto do vértice inicial a todos os outros vértices do grafo.

https://imgur.com/N1vjtZm.png

https://imgur.com/tJfFPqo.png

https://imgur.com/JT8aZmN.png

\(SAT \alpha CLIQUE\)

Satisfabilidade: Dada uma fórmula booleana, existe uma atribuição de valores às suas variáveis que a torne verdadeira. A formula deve estar na forma normal conjuntiva ou disjuntiva - clausulas definidas apenas com o operador \(\wedge\) e \(\vee\).

Ex.: Existe uma combinação de valores booleanos para que \(x_{1}, x_{2}, x_{3}\) na expressão \((x_{1} \vee \sim x_{2}) \wedge (x_{1} \vee x_{3}) \wedge (\sim x_{1} \vee x_{2})\) seja verdadeira?

A ideia é construir um grafo a partir da formula booleana em tempo polinomial tal que: \(instância_{A} \rightarrow instância_{B}\). Seja K o número de cláusulas (expressões entre parênteses), para cada elemento na fórmula (qualquer \(x_{i}\) ou \(\sim x_{i}\)) crie um vértice (se o mesmo elemento aparecer mais de uma vez, cada cópia resulta em um vértice).

Para cada par de elementos em clausulas diferentes que podem ser verdadeiras ao mesmo tempo, adicionamos uma aresta a eles. Assim:

SAT: \(x_{1} \wedge (\sim x_{1} \vee x_{2} \vee \sim x_{3}) \wedge x_{3}\)

Passos do CLIQUE:

https://imgur.com/aBgtp9G.png

https://imgur.com/fwr0j15.png

No exemplo acima, \(x_{2}\) não é comparado com \(\sim x_{3}\) pois eles pertencem a mesma cláusula, a comparação deve ser feita em cláusulas diferentes.

Com isso, podemos nos pertguntas: toda resposta no CLIQUE é verdadeira no SAT e toda resposta falsa no CLIQUE também é falsa no SAT? No exemplo acima dado o número de cláusulas K=3, podemos afimar que como o SAT é NP-Completo o CLIQUE também é.

\(Ciclo Hamiltoniano (CH) \alpha TSP\)

O caixeiro viajante é um problema que tenta determinar a menor rota para percorrer uma série de cidades visitadas uma única vez cada uma.

Considere o grafo G=(V,E) sendo uma instância do CH, nós precisamos construir então uma instância do TSP a partir dele.

https://imgur.com/vj7QbqR.png

Temos então um caminho hamiltoniano h = 1->2->3->4->5->1.

Para criar e formar um TSP precisamos construir um grafo completo G’(V,E’).parte

https://imgur.com/eOT8y6W.png

Assim:

https://imgur.com/3i2SeBc.png

Em seguida, definimos uma função C, dada por:

\[C(i,j) = \left\{\begin{matrix} 0, & Se & i,j \in E \\ 1, & Se & i,j \notin E \end{matrix}\right.\]

https://imgur.com/bTK6CN4.png

Assim, dado C uma função que mapeia tanto E’ quanto E, mostramos que o grafo G tem um ciclo hamiltoniano se e somente se existe um grafo G’ com peso máximo ‘0’ que é isomorfo a um grafo G. Com isso, pela definição do CH podemos concluir que o TSP é NP-Completo.

\(Cob.Vert. (CV) \alpha Conj.Ind. (CI)\)

Uma cobertura de vértices é o conjunto mínimo de vértices que cobrem todas as arestas do grafo.

Um conjunto independente é um conjunto de vértices que não possui arestas ligando-se diretamente.

https://imgur.com/0HljhoH.png

No grafo acima, temos que uma das coberturas de vértices é CI = {A,C} e outra CI2 = {D, B}. Também temos como cobertura de vértices CV = {A, E, C} e outra CV2 = {B, D, E}.

Para provar que a CV é NP-Completo primeiro precisamos mostrar que o problema está na classe NP basta apresentar um algoritmo não deterministico que execute em tempo polinomial para resolver o problema. Outra maneira é encontrar um algoritmo determinista polinomial que verifica que uma dada solução é valida. Em seguida precisamos provar que CV está em NP-Completo, basta reduzir um problema existe do conjunto NP-Completo ao problema CV.