Notații asimptotice

1. Dați exemple de câte o funcție din următoarele clase de complexitate:

$ O(n)$

Trebuie sa gasim functii care cresc maxim la fel de repede ca f(n)=n. Exemple soluții posibile: g(n)=n+6, g(n)=8n+7 (aceeasi crestere), g(n)=log(n) (crestere mai mica)

$Ω(log(n))$

Trebuie sa gasim functii care cresc mai repede sau la fel de repede ca f(n)=n^2. Exemple soluții posibile: g(n)=100*log(n)+5, (aceeasi crestere), g(n)=n^3, g(n)=nlog(n) (mai repede)

$θ(n^2)$

Trebuie sa gasim functii care cresc la fel de repede ca f(n)=log(n). Exemple soluții posibile: g(n)=a*n^2+b*n+c*log(n)+d, a>0 (aceeasi crestere ca n^2, fiind dominant in functie)

$ɷ(1/n)$

Trebuie sa gasim functii care cresc strict mai repede decat f(n)=1/n. Cum 1/n este o functie descrescatoare, solutia este orice functie crescatoare. Exemple soluții posibile: g(n)=c, c = constanta, g(n)=n+23, g(n)=nlogn+n^4 etc.

$ o(3^n)$

Trebuie sa gasim functii care cresc strict mai incet decat f(n)=3^n. Exemple soluții posibile: g(n)=n^p,p>=0 etc.

2. Verificați valoarea de adevăr a următoarelor propoziții:

$ √n∈O(logn)$

f(n)=logn, g(n)=√n. Cum f si g sunt functiile f si g sunt monotone si cresctoare, verific afirmatia utilizand limite.

lim(n→∞)⁡(g(n)/f(n))=lim(n→∞)⁡(√n/log(n))=(l'Hospital)lim(n→∞)⁡(n/2*√n)=1/2*lim(n→∞)⁡(√n)=+∞ ⇒ Fals

$ logn∈O(log(log n))$

f(n)=log(logn), g(n)=logn. Cum f si g sunt functiile f si g sunt monotone si cresctoare, verific afirmatia utilizand limite.

lim(n→∞)⁡(g(n)/f(n))=lim(n→∞)⁡(logn/log(log n))=(l'Hospital)lim(n→∞)⁡(1/n / 1/logn * 1/n)=1/2*lim(n→∞)⁡(logn)=+∞ ⇒ Fals

$ n∈O(√n logn)$

f(n)=√n logn, g(n)=n. Cum f si g sunt functiile f si g sunt monotone si cresctoare, verific afirmatia utilizand limite.

lim(n→∞)⁡(g(n)/f(n))=lim(n→∞)⁡(n/√n logn)=lim(n→∞)⁡(√n/logn)=(l'Hospital)lim(n→∞)⁡(1/2 * 1/n^2 / 1/n)=1/2*lim(n→∞)⁡(1/n)=0 ⇒ Fals

$ n+logn∈θ(n)$

f(n)=n, g(n)=n + logn. Cum f si g sunt functiile f si g sunt monotone si cresctoare, verific afirmatia utilizand limite.

lim(n→∞)⁡(g(n)/f(n))=lim(n→∞)⁡(n + logn/n)=1 + lim(n→∞)⁡(logn/n)=(l'Hospital)1 + lim(n→∞)⁡(1/n)= 1 ⇒ Adevarat

$ log(nlogn)∈θ(logn)$

f(n)=logn, g(n)=log(nlogn). Cum f si g sunt functiile f si g sunt monotone si cresctoare, verific afirmatia utilizand limite.

lim(n→∞)⁡(g(n)/f(n))==(l'Hospital)lim(n→∞)⁡(1/nlogn*(logn+1) / 1/n)=lim(n→∞)⁡(1/logn*(logn+1)) =lim(n→∞)⁡(1 + 1/logn)=1 ⇒ Adevarat

$ √n∈ɷ(log n)$

f(n)=logn, g(n)= √n. Cum f si g sunt functiile f si g sunt monotone si cresctoare, verific afirmatia utilizand limite.

lim(n→∞)⁡(g(n)/f(n))=lim(n→∞)⁡(√n/logn)= (l'Hospital)lim(n→∞)⁡(1/2*√n)= ∞ ⇒ Adevarat

Analiză amortizată

1.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
 
#define COUNTER_SIZE 100
 
unsigned total_flips = 0;
 
int inc(unsigned *a, size_t m)
{
    size_t i = 0;
    unsigned current_flips = 0;
 
    while (i < m && a[i] == 1) {
        a[i] = 0;
        current_flips++;
        i++;
    }
 
    if (i == m) {
        total_flips += current_flips;
        return -1;
    }
 
    a[i] = 1;
    current_flips++;
 
    total_flips += current_flips;
 
    return 0;
}
 
int main(int argc, char *argv[])
{
    unsigned counter[COUNTER_SIZE];
    memset(counter, 0, sizeof(counter));
 
    if (argc < 2) {
        fprintf(stderr, "Usage: %s <number_of_increments>\n", argv[0]);
        return 1;
    }
 
    unsigned n = strtoull(argv[1], NULL, 10);
    if (n == 0) {
        fprintf(stderr, "Invalid number of increments: %s\n", argv[1]);
        return 1;
    }
 
    for (int i = 0; i < n; i++) {
        inc(counter, COUNTER_SIZE);
    }
 
    printf("Total flips: %u\n", total_flips);
}