c1 int x; c2 int i; c3 int n; c4 x = 5; c5 scanf("%d", &n); n*c6 for(i = 0; i < n; i++) n*c7 x++; C = c1 + c2 + c3 + c4 + c5 + n*c6 + n*c7 Suponha cj < c para todo j > 0 logo, C' = c + c + c + c + c + n*c + n*c C' = 5c +2nc Suponha que c = 1000 segundos logo, C' = 5000 + 2000n. ---------------------------------------- DE MODO INFORMAL: ---------------------------------------- Se n > 2, é fácil perceber que o custo maior é do termo 2000n. E quanto maior o n, maior será a parte que o termo 2000n representa no custo final do código. logo, o custo do código é fundamentalmente o custo do 2o termo. Perceba, que pela mesma lógica, como 2000 é um número constante, quanto maior o n, de fato, o valor que representa o custo do programa é somente o termo n. Perceba que, se uma máquina M1 o tempo C for 2000 segundos e em outra M2, muito mais rápida, for de 100 segundos, não importa para o resultado final, pois o tempo que, de fato importa, é o termo n. Obs.: perceba que quando n tende a infinito, fazer 2000 x infinito ou 100 x infinito, é a mesma coisa, ou seja, o custo de fato é o termo n, por isso O(n). Portanto, a complexidade de execução do código anterior pode ser escrita como C' = O(n). ---------------------------------------- ---------------------------------------- DE MODO FORMAL ---------------------------------------- Para isso, foi definida a notação assintótica O (Big-O). Essa notação representa a complexidade assintótica (tempo de execução, espaço de memória ocupado etc) de um algoritmo. O conceito formal da notação O (Big-O) é: -> Suponha que f(n) represente o custo de execução de um determinado algoritmo -> Então, f(n) pertence a O(g(n)) se existem c > 0 e n0 >= 1 tais que: 0 <= f(n) <= c·g(n), para qualquer n >= n0. Apliquemos no exemplo: f(n) = C' = 5000 + 2000n Logo, 0 <= 5000 + 2000n <= c.g(n) Suponha que queiramos testar se g(n) = n é um limite assintótico superior para f(n), logo 0 <= 5000 + 2000n <= c.n Defina c = 7000, logo 0 <= 5000 + 2000n <= 7000.n A partir disso, é fácil observar que, a partir de n0 = 1, temos que: 5000 + 2000n <= 7000n para qualquer n >= n0 Portanto, f(n) pertence a O(n). ---------------------------------------- Nota final: -> limite inferior: Omega (não tem o símbolo na página de código 850) O conceito formal da notação Omega é: -> Suponha que f(n) represente o custo de execução de um determinado algoritmo -> Então, f(n) pertence a O(g(n)) se existem c > 0 e n0 >= 1 tais que: 0 <= c.g(n) <= f(n), para qualquer n >= n0. Suponha o mesmo custo anterior: 0 <= c.g(n) <= 5000 + 2000n com g(n) = n, então 0 <= c.n <= 5000 + 2000n Escolha um c = 2000, logo 0 <= 2000n <= 5000 + 2000n E isso é válido para qualquer n >= 1, pois 2000n - 2000n <= 5000 + 2000n - 2000n 0 <= 5000 Pontanto, f(n) pertence a Omega(n). Conclusão: se f(n) pertence a O(n) E f(n) pertence a Omega(n) então, f(n) pertence a Teta(n)