Você está na página 1de 8

Algoritmos matemticos bsicos que todo cara da computao deveria

saber

Algoritmo 1 : Converso da base 10 para a base b
Primeiramente, vamos comear com o algoritmo de mudana de base numrica. Para
converter um nmero da base 10 para uma base b qualquer podemos efetuar
sucessivas divises do nmero pela base b; o resto das divises sero os dgitos do
nmero da nova base s que na ordem inversa.




Calcular nmero de dgitos d de nmero n na base b

d = log
b
n =

void base(int n, int b, int novo[], int * tam){
int k;
k = *tam = floor( log(n)/log(b) + 0.5) + 1;
while( n > 0){
k--;
novo[k] = n % b;
n = n / b;
}
}

Complexidade O(log
b
n)

Algoritmo 2: Converso de um nmero da base b para a base 10

Podemos converter um nmero da base b para a base 10 atravs desta
expresso:

N = a
n
.b
n
+ .... + a
2
.b
2
+ a
1
.b
1
+ a
0
.b
0






Vamos reescrever essa expresso da seguinte maneira:

N =b( a
n
.b
n-1
+ .... + a
2
.b
1
+ a
1
.b
0
) + a
0
.b
0

N =b( b( a
n
.b
n-2
+ .... + a
2
.b
0
)+ a
1
.b
0
) + a
0
.b
0

N =b( b( a
n
.b
n-2
+ .... + a
2
.b
0
)+ a
1
.b
0
) + a
0
.b
0

N =b(...b(b(a
n
) + a
n-1
)...) + a
0
.b
0

Agora, podemos calcular o nmero na base b realizando n multiplicaes.
N = 10011
2
A[0] = 1
A[1] = 0
A[2] = 0
A[3]= 1
A[4] = 1

X[0] = A[0]
X[i] = X[i-1]*B + A[i]

N = X[4]

X[0] = 1
X[1] = 2 + 0 = 2
X[2] = 4 + 0 = 4
X[3] = 8 + 1 = 9
X[4] = 18 +1 = 19

int base(int b, int novo[] , int tam){
int n,i;
n = novo[0];
for(i=1;i<tam;i++){
n = n*b;
n = n + novo[i];
}
return n;
}


Complexidade O(n) multiplicaes e soma


Mximo divisor Comum de a e b

Encontrar o maior nmero d que divide a e b simultaneamente.
Sabemos que se d divide a e d divide b ento d < a e d < b;

Algoritmo 1: Fora bruta

int mdc1(int a,int b){

int i,d;

d = a < b ? a : b;

for(i=d;i>=1;i--){
if(a%i==0 && b%i==0) return i;
}

}

Complexidade O( min(a,b) )


Algoritmo 2: Busca Binria
int mdc2(int a,int b){
int i,f,meio,d;
d = a < b ? a : b;
i = 1;
f = d;
while( i < f ){
meio = (i + f) / 2;
if( a%meio ==0 && b%meio==0) i = meio;
else f = meio-1;
}
return i;
}

Complexidade O( lg min(a,b) )







Algoritmo 3: Algoritmo de Euclides:




int mdc3(int a,int b){
if(b==0) return a;
else return mdc3(b,a%b);
}


O nmero de chamadas deste algoritmo proporcional ao nmero de
Fibonacci pelo seguinte teorema:

Teorema:
Se a > b >= 0 e euclides(a,b) executa k >= 1 chamadas recursivas ento a
>= F
k+2
e b >= F
k+1.
Suponha que a e b so dois nmeros de Fibonacci consecutivos ento
O nmero de chamadas recursivas de EUCLIDES(F
k+2
,F
k+1
) igual ao
nmero de chamadas recursivas EUCLIDES(F
k+1
, F
k+2
mod F
k+1
) + 1.
Temos que F
k+2
= F
k+1
+ F
k
mod F
k+1
= F
k.
. Logo, EUCLIDES(F
k+1
, F
k+2
mod
F
k+1
) = EUCLIDES(F
k+1
, F
k
) com k -1 chamadas recursivas.
O nmero de chamadas recursivas de EUCLIDES(F
k+2
,F
k+1
) k-1 +1.

Este teorema pode ser utilizado para estimar um limite superior para o
nmero de chamadas recursivas do algoritmo.

Complexidade O(k) , b >= F
k+1

Algoritmo 4: Mdc Binrio

int gcd(int u, int v){
if( u == v ) return u;
if( u == 0 ) return v;
if( v == 0 ) return u;

if(u%2 == 0){ // se u par
if(v%2 == 0) // u and v so pares
return (2*gcd(u/2, v/2));
else // u par and v impar
return gcd(u/2, v);
}
else if(v%2 == 0) // u impar e v par
return gcd(u, v/2);
else{ // ambos so impares
if(u>=v)
return gcd((u-v)/2, v);
else
return gcd((v-u)/2, u);
}
}

Usando operaes com bits:

int gcd(int u, int v){
if( u == v ) return u;
if( u == 0 ) return v;
if( v == 0 ) return u;

if(u & 1==0){ // se u par
if( v & 1 == 0) // u and v so pares
return (gcd(u >> 1, v >> 1) << 1);
else // u par and v impar
return gcd(u >> 1, v);
}
else if(v & 1 ==0) // u impar e v par
return gcd(u, v >> 1);
else{ // ambos so impares
if(u>=v)
return gcd((u-v) >> 1, v);
else
return gcd((v-u) >> 1, u);
}
}

Algoritmo : Calcular a
b


Podemos definir o algoritmo a
b
diretamente da seguinte definio
recursiva:




def exp(a,b):
if b==0: return 1
else: return a*exp(a,b-1)

O nmero de multiplicaes definido pela seguinte relao de
recorrncia:
T(n) = T(n-1) +1
T(0) = 0
Aplicando o mtodo da substituio, temos:
T(n) = T(n-1) + 1
T(n-1) = T(n-2)+1
...
T(n-(k-1))=T(n-k)+1
Simplificando as equaes, temos:
T(n) = T(n-1) + 1
T(n-1) = T(n-2)+1
...
T(n-(k-1))=T(n-k)+1
T(n)=T(n-k)+k
Tome n-k=0 isso implica que k=n.
T(n) = T(0)+n
T(n) = n

Podemos reduzir o nmero de multiplicaes, alterando a definio
recursiva para a seguinte maneira:



def fastexp(a,b):
if b==0 : return 1
else:
if b%2==0:
x = fastexp(a,b/2)
return x*x
else:
return a*fastexp(a,b-1)

O nmero de multiplicaes definido pela seguinte relao de
recorrncia supondo que n uma potncia de 2:
T(n) = T(n/2) +1
T(1) = 1
Aplicando o mtodo da substituio, temos:
T(n) = T(n/2) + 1
T(n/2) = T(n/4)+1
...
T(n/2
k-1
)=T(n/2
k
)+1
Simplificando as equaes, temos:
T(n) = T(n/2) + 1
T(n/2) = T(n/4)+1
...
T(n/2
k-1
)=T(n/2
k
)+1
T(n)=T(n/2
k
)+k
Tome n/2
k
=1 isso implica que k=log
2
n.
T(n) = T(1)+ log
2
n
T(n) = log
2
n + 1

Algoritmo: Nmero de Fibonacci

A definio recursiva do algoritmo fibonacci a seguinte:


O algoritmo iterativo pode ser definido da seguinte maneira:







def fibo_iterativo(n):
if n <= 2: return 1
else:
ant = 1
atual = 1
i = 2
while i < n:
prox = ant+atual
ant = atual
atual = prox
i = i+1
return prox

Complexidade O(n)

Podemos calcular o nmero de fibonacci a partir da
seguinte equao matricial:



Utilizando a exponenciao rpida para realizar a
multiplicao matricial podemos obter o seguinte
algoritmo:

def fastfibo(n):
[a,b,c,d] = matriz_exp(1,1,1,0,n)
return b

def matriz_exp(a,b,c,d,n):

if n==1:
return [a,b,c,d]
if n==0:
return [1,0,0,1]

if(n%2==1):
[a1,b1,c1,d1] = matriz_exp(a,b,c,d,n-1)
return [a*a1+b*c1,a*b1+b*d1,a1*c+d*c1,c*b1+d1*d]
else:
[a1,b1,c1,d1] = matriz_exp(a,b,c,d,n/2)
return [a1*a1+b1*c1,a1*b1+b1*d1,a1*c1+d1*c1,c1*b1+d1*d1]

Complexidade O(log
2
n)

Você também pode gostar