Divide y Venceras
Divide y Venceras
Divide y Venceras
Divide y Venceras
Tiempo de ejecucin
El tiempo de ejecucin de un algoritmo de divide y vencers, T(n),
viene dado por la suma de dos elementos:
El tiempo que tarda en resolver los A subproblemas en los que se
divide el original, AT(n/B), donde n/B es el tamao de cada subproblema.
El tiempo necesario para combinar las soluciones de los subproblemas para hallar la solucin del original; normalmente es O(n k)
Por tanto, el tiempo total es: T(n) = AT(n/B) + O(nk). La solucin de
esta ecuacin, si A es mayor o igual que 1 y B es mayor que 1, es:
si A>Bk, T(n) = O(nlogBA)
si A=Bk, T(n) = O(nklog n)
si A<Bk, T(n) = O(nk)
Divide y Venceras
Divide y Venceras
<stdio.h>
<stdlib.h>
<string.h>
<math.h>
Divide y Venceras
return(0);
Divide y Venceras
Divide y Venceras
Divide y Venceras
return(0);
Divide y Venceras
}
if(d==desde-1) // Si la segunda bsqueda se sale del array
d=desde; // es que el pivote es el elemento
// ms pequeo: se cambia con l mismo.
aux=array[d]; // Colocar el pivote
array[d]=array[desde]; // en su posicin.
array[desde]=aux;
if(d==k)
return(array[d]); // El pivote es el elemento buscado
else if(d>k)
return(seleccionrapida(array,pos,desde,d-1,k)); // Buscar en el
primer array.
else
return(seleccionrapida(array,pos,d+1,hasta,k)); // Buscar en el
segundo array.
}
int hallamediana(int *array,int *pos,int num)
{
int a,*array2,b,c,d;
if(num<5) // Si hay menos de 5 elementos
return(pos[0]); // vale el primero (lo que devuelve esta
// funcin es el ndice de la mediana en la variable
"array" de la funcin
// seleccionrapida que llama por primera vez a esta
funcin.
// Hallar la mediana de cada cinco elementos.
array2=(int *)malloc(sizeof(int)*((num/5)+4));
for(a=0;a+4<num;a+=5)
{
memcpy(array2+(a/5),array,sizeof(int)*5);
for(b=0;b<5;b++)
for(c=b+1;c<5;c++)
if(array2[b]>array2[c])
{
d=array2[b];
array2[b]=array2[c];
array2[c]=d;
d=pos[b];
pos[b]=pos[c];
pos[c]=d;
}
array2[a/5]=array[a+2];
pos[a/5]=pos[a+2];
}
// Hallar la mediana de las medianas.
a=hallamediana(array2,pos,num/5);
free(array2);
return(a);
}
Divide y Venceras
Multiplicacin de matrices
Dadas dos matrices A y B de tamao n x n, hallar C, el producto de
las dos. Un primer algoritmo se saca de la definicin de producto de
matrices: Ci j es el producto escalar de la i-sima fila por la j-sima
columna. Su tiempo de ejecucin sera O(n3):
int i,j,k;
int A[n][n],B[n][n],C[n][n];
// Dar valores a A y B.
for(i=0;i<n;i++)
for(i=0;i<n;i++)
{
C[i][j]=0;
for(i=0;i<n;i++)
C[i][j]+=A[i][k]*B[k][j];
}
=
=
=
=
=
=
=
Divide y Venceras
10
=
=
=
=
M1
M4
M6
M2
+
+
+
-
M2 - M4 + M6
M5
M7
M3 + M5 - M7
Divide y Venceras
11
{
mapa2[a]=(int *)malloc(sizeof(int)*m);
memset(mapa2[a],0,sizeof(int)*m);
}
for(a=0;a<f2;a++) // Se cogen los datos de la segunda matriz.
for(b=0;b<c2;b++)
scanf(" %d",&mapa2[a][b]);
sol=multiplicamatriz(mapa1,mapa2,m); // Se multiplican.
for(a=0;a<f1;a++) // Se imprime el resultado.
{
for(b=0;b<c2;b++)
printf("%d ",sol[a][b]);
printf("\n");
}
}
return(0);
Divide y Venceras
12
}
// Hallar las matrices M.
f1=resta(A[0][1],A[1][1],num/2);
f2=suma(B[1][0],B[1][1],num/2);
M[1]=multiplicamatriz(f1,f2,num/2);
libera(f1,num/2);
libera(f2,num/2);
f1=suma(A[0][0],A[1][1],num/2);
f2=suma(B[0][0],B[1][1],num/2);
M[2]=multiplicamatriz(f1,f2,num/2);
libera(f1,num/2);
libera(f2,num/2);
f1=resta(A[0][0],A[1][0],num/2);
f2=suma(B[0][0],B[0][1],num/2);
M[3]=multiplicamatriz(f1,f2,num/2);
libera(f1,num/2);
libera(f2,num/2);
f1=suma(A[0][0],A[0][1],num/2);
f2=B[1][1];
M[4]=multiplicamatriz(f1,f2,num/2);
libera(f1,num/2);
f1=A[1][1];
f2=resta(B[0][1],B[1][1],num/2);
M[5]=multiplicamatriz(f1,f2,num/2);
libera(f2,num/2);
f1=A[1][1];
f2=resta(B[1][0],B[0][0],num/2);
M[6]=multiplicamatriz(f1,f2,num/2);
libera(f2,num/2);
f1=suma(A[1][0],A[1][1],num/2);
f2=B[0][0];
M[7]=multiplicamatriz(f1,f2,num/2);
libera(f1,num/2);
// Hallar las submatrices de C.
C[0][0]=suma(M[1],M[2],num/2);
aux=C[0][0];
C[0][0]=resta(C[0][0],M[4],num/2);
aux2=C[0][0];
C[0][0]=suma(C[0][0],M[6],num/2);
libera(aux,num/2);
libera(aux2,num/2);
C[0][1]=suma(M[4],M[5],num/2);
C[1][0]=suma(M[6],M[7],num/2);
C[1][1]=resta(M[2],M[3],num/2);
aux=C[1][1];
C[1][1]=suma(C[1][1],M[5],num/2);
aux2=C[1][1];
C[1][1]=resta(C[1][1],M[7],num/2);
libera(aux,num/2);
libera(aux2,num/2);
Divide y Venceras
13
for(a=1;a<=7;a++)
libera(M[a],num/2);
// Unir las submatrices de matrices C en sol.
for(q=0;q<num;q++)
for(w=0;w<num;w++)
sol[q][w]=C[q/(num/2)][w/(num/2)][q%(num/2)][w%(num/2)];
// Liberar las submatrices de A, B y C.
for(q=0;q<2;q++)
for(w=0;w<2;w++)
{
libera(A[q][w],num/2);
libera(B[q][w],num/2);
libera(C[q][w],num/2);
}
return(sol);
}
int **suma(int **mapa1,int **mapa2,int num)
{ // sumar mapa1 y mapa2.
int a,b;
int **sol;
sol=(int **)malloc(sizeof(int *)*num);
for(a=0;a<num;a++)
{
sol[a]=(int *)malloc(sizeof(int)*num);
for(b=0;b<num;b++)
sol[a][b]=mapa1[a][b]+mapa2[a][b];
}
return(sol);
}
int **resta(int **mapa1,int **mapa2,int num)
{ // Restar mapa2 de mapa1.
int **sol;
int a,b;
sol=(int **)malloc(sizeof(int *)*num);
for(a=0;a<num;a++)
{
sol[a]=(int *)malloc(sizeof(int)*num);
for(b=0;b<num;b++)
sol[a][b]=mapa1[a][b]-mapa2[a][b];
}
return(sol);
}
void libera(int **mapa,int num)
{
int a;
for(a=0;a<num;a++) // Liberar la tabla dinmica de 2D.
free(mapa[a]);
free(mapa);
}
Divide y Venceras
14
Salida
La salida del programa ha de grabarse en un archivo de texto (ASCII)
con nombre MULT.RES, que contendr una secuencia de m lneas con
el resultado de las multiplicaciones:
La lnea k del archivo de salida representa la multiplicacin de los
enteros contenidos en las lneas 2k y 2k+1 del archivo de entrada.
Los enteros se representan tambin como una cadena de caracteres
(dgitos posiblemente precedidos del signo '-'). Los resultados no
pueden tener ceros superfluos a la izquierda.
Divide y Venceras
15
Ejemplo de entrada
3
-0124576679
10859687
00345
42
0
23
Ejemplo de salida
-1352863741439473
14490
0
Divide y Venceras
16