Practica Multiplicacion Matrices

21
INSTITUTO POLITÉCNICO NACIONAL ESCUELA SUPERIOR DE CÓMPUTO UNIDAD DE APRENDIZAJE: ANALISIS DE ALGORITMOS PROFESORA: GARCIA MENDOZA CONSUELO VARINIA ALUMNOS: BENITEZ CRUZ DANIELA OLIVARES REYES CARLOS ALBERTO SAAVEDRA PALESTINA ROBERTO PRACTICA 3: Multiplicación de Matrices GRUPO: 3CM4

description

Programación de operaciones con matrices. Análisis y de Algoritmos.

Transcript of Practica Multiplicacion Matrices

Page 1: Practica Multiplicacion Matrices

INSTITUTO POLITÉCNICO NACIONAL

ESCUELA SUPERIOR

DE

CÓMPUTO

UNIDAD DE APRENDIZAJE:

ANALISIS DE ALGORITMOS

PROFESORA: GARCIA MENDOZA CONSUELO VARINIA

ALUMNOS: BENITEZ CRUZ DANIELA

OLIVARES REYES CARLOS ALBERTO SAAVEDRA PALESTINA ROBERTO

PRACTICA 3:

Multiplicación de Matrices

GRUPO: 3CM4

Page 2: Practica Multiplicacion Matrices

Introducción

Producto de matrices

Dadas dos matrices A y B, su producto es otra matriz P cuyos elementos se obtienen multiplicando las filas de A por las columnas de B. De Es evidente que el número de columnas de A debe coincidir con el número de filas de B. Si A tiene dimensión m x n y B dimensión n x p, la matriz P será de orden m x p:

La división en submatrices sugiere una estrategia recursiva de divide y vencerás, que puede ser especialmente ventajoso en sistemas de memoria compartida. La ventaja de esta estrategia es que en cada paso de recursión, los datos transmitidos son más pequeños y están más localizados.

Algoritmo de StrassenEn la disciplina matemática del álgebra lineal, el algoritmo de Strassen, llamado así por Volker Strassen, es un algoritmo usado para la multiplicación de matrices. Es asintóticamente más rápido que el algoritmo de multiplicación de matrices estándar, pero más lento que el algoritmo más rápido conocido, y es útil en la práctica para matrices grandes.

Dadas dos matrices:

Podemos poner……

Page 3: Practica Multiplicacion Matrices

Entonces el producto queda:

Este procedimiento requiere 7 multiplicaciones para calcular el producto de A y B (pero más sumas que el método tradicional).

Algoritmo de multiplicación de StrassenSi reemplazamos cada elemento de A y B por una matriz de n x n, las fórmulas anteriores nos dan una forma de multiplicar dos 2n X 2n matrices.

A partir de esto tenemos un método recursivo para calcular el producto de matrices con n Algoritmo de multiplicación de Strassen potencia de 2.

Este método se puede generalizar también a matrices cuyas dimensiones no sean de la forma 2n

Objetivos

Realizar un programa para dar solución al problema de la multiplicación de matrices, mediante el método divide y vencerás, y por medio de Strassen.

Page 4: Practica Multiplicacion Matrices

Programa

MULTIPLICACION DE MATRICES CON DIVIDE Y VENCERAS.

CODIGO:

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

int max(int,int);

int **multiplicamatriz(int **,int **,int); // Funci?n recursiva que multiplica matrices

int **suma(int **,int **,int); // suma de matrices

int **resta(int **,int **,int);// Resta de matrices

void libera(int **,int); // Libera memoria

int max(int a,int b)

{

return((a>b)?a:b);

}

int **multiplicamatriz(int **mapa1,int **mapa2,int num)

{

int **sol,**M[8],**f1,**f2,**f3,**f4,**f5,**f6,**f7,**f8,**f9,**f10,**aux,**aux2;

int **A[2][2],**B[2][2],**C[2][2];

Page 5: Practica Multiplicacion Matrices

int a,q,w,r,b;

sol=(int **)malloc(sizeof(int *)*num);

for(a=0;a<num;a++){

sol[a]=(int *)malloc(sizeof(int)*num);

}

if(num==1)

{

sol[0][0]=mapa1[0][0]*mapa2[0][0];

return(sol);

}

else{

// Crear las submatrices de A y B.

for(q=0;q<2;q++)

{

for(w=0;w<2;w++)

{

A[q][w]=(int **)malloc(sizeof(int *)*(num/2));

for(a=0;a<num/2;a++)

{

A[q][w][a]=(int *)malloc(sizeof(int)*(num/2));

for(r=0;r<num/2;r++){

A[q][w][a][r]=mapa1[a+(num/2)*q][r+(num/2)*w];

}

}

Page 6: Practica Multiplicacion Matrices

B[q][w]=(int **)malloc(sizeof(int *)*(num/2));

for(a=0;a<num/2;a++)

{

B[q][w][a]=(int *)malloc(sizeof(int)*(num/2));

for(r=0;r<num/2;r++){

B[q][w][a][r]=mapa2[a+(num/2)*q][r+(num/2)*w];

}

}

}

}

// Hallar las matrices M.

f1=resta(B[0][1],B[1][1],num/2);

f2=suma(A[0][0],A[0][1],num/2);

f3=suma(A[1][0],A[1][1],num/2);

f4=resta(B[1][0],B[0][0],num/2);

f5=suma(A[0][0],A[1][1], num/2);

f6=suma(B[0][0],B[1][1],num/2);

f7=resta(A[0][1],A[1][1],num/2);

f8=suma(B[1][0],B[1][1],num/2);

f9=resta(A[0][0],A[1][0],num/2);

f10=suma(B[0][0],B[0][1],num/2);

M[1]=multiplicamatriz(A[0][0],f1,num/2);

Page 7: Practica Multiplicacion Matrices

M[2]=multiplicamatriz(f2,B[1][1],num/2);

M[3]=multiplicamatriz(f3,B[0][0],num/2);

M[4]=multiplicamatriz(A[1][1],f4,num/2);

M[5]=multiplicamatriz(f5,f6,num/2);

M[6]=multiplicamatriz(f7,f8,num/2);

M[7]=multiplicamatriz(f9,f10,num/2);

// Hallar las submatrices de C.

C[0][0]=suma(M[5],M[4],num/2);

aux=C[0][0];

C[0][0]=resta(C[0][0],M[2],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[1],M[2],num/2);

C[1][0]=suma(M[3],M[4],num/2);

C[1][1]=suma(M[1],M[5],num/2);

aux=C[1][1];

C[1][1]=resta(C[1][1],M[3],num/2);

aux2=C[1][1];

Page 8: Practica Multiplicacion Matrices

C[1][1]=resta(C[1][1],M[7],num/2);

libera(aux,num/2);

libera(aux2,num/2);

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);

}

Page 9: Practica Multiplicacion Matrices

int **multiplicaDyV(int **mapa1,int **mapa2,int num)

{

int **sol,**M[8],**f1,**f2,**aux,**aux2;

int **A[2][2],**B[2][2],**C[2][2];

int a,q,w,r,b;

sol=(int **)malloc(sizeof(int *)*num);

for(a=0;a<num;a++){

sol[a]=(int *)malloc(sizeof(int)*num);

}

if(num==1)

{

sol[0][0]=mapa1[0][0]*mapa2[0][0];

return(sol);

}

// Crear las submatrices de A y B.

for(q=0;q<2;q++)

{

for(w=0;w<2;w++)

{

A[q][w]=(int **)malloc(sizeof(int *)*(num/2));

for(a=0;a<num/2;a++)

Page 10: Practica Multiplicacion Matrices

{

A[q][w][a]=(int *)malloc(sizeof(int)*(num/2));

for(r=0;r<num/2;r++){

A[q][w][a][r]=mapa1[a+(num/2)*q][r+(num/2)*w];

}

}

B[q][w]=(int **)malloc(sizeof(int *)*(num/2));

for(a=0;a<num/2;a++)

{

B[q][w][a]=(int *)malloc(sizeof(int)*(num/2));

for(r=0;r<num/2;r++){

B[q][w][a][r]=mapa2[a+(num/2)*q][r+(num/2)*w];

}

}

}

}

// Hallar las matrices M.

M[0]=multiplicaDyV(A[0][0],B[0][0],num/2);

M[1]=multiplicaDyV(A[0][1],B[1][0],num/2);

M[2]=multiplicaDyV(A[0][0],B[0][1],num/2);

Page 11: Practica Multiplicacion Matrices

M[3]=multiplicaDyV(A[0][1],B[1][1],num/2);

M[4]=multiplicaDyV(A[1][0],B[0][0],num/2);

M[5]=multiplicaDyV(A[1][1],B[1][0],num/2);

M[6]=multiplicaDyV(A[1][0],B[0][1],num/2);

M[7]=multiplicaDyV(A[1][1],B[1][1],num/2);

// Hallar las submatrices de C.

C[0][0]=suma(M[0],M[1],num/2);

C[0][1]=suma(M[2],M[3],num/2);

C[1][0]=suma(M[4],M[5],num/2);

C[1][1]=suma(M[6],M[7],num/2);

for(a=0;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++){

Page 12: Practica Multiplicacion Matrices

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++){

Page 13: Practica Multiplicacion Matrices

sol[a][b]=mapa1[a][b]+mapa2[a][b];

//printf("suma sol : %d\n", sol[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];

//printf("resta sol : %d\n", sol[a][b]);

}

}

return(sol);

}

Page 14: Practica Multiplicacion Matrices

void libera(int **mapa,int num)

{

int a;

for(a=0;a<num;a++) // Liberar la tabla din?mica de 2D.

free(mapa[a]);

free(mapa);

}

int main()

{

int **mapa1,**mapa2,**sol, **sol1;

int f1,c1,f2,c2,a,b,m,m1;

printf("Introduce el tama?o de la columna de la primer matriz:\n");

scanf("%d",&f1);

printf("Introduce el tama?o de la fila de la primer matriz:\n");

scanf("%d",&c1);

//scanf(" %d %d",&f1,&c1); // Tama?o de la primera matriz

printf("Introduce el tama?o de la columna de la segunda matriz:\n");

scanf("%d",&f2);

printf("Introduce el tama?o de la fila de la segunda fila:\n");

scanf("%d",&c2);

//scanf(" %d %d",&f2,&c2); // Tama?o de la segunda matriz

m1=max(f1,max(c1,max(f2,c2)));

for(m=1;m<m1;m*=2); // El tama?o de las matrices cuadradas a multiplicar

Page 15: Practica Multiplicacion Matrices

//debe ser de la forma 2k, si no se completan con ceros.

mapa1=(int **)malloc(sizeof(int *)*m); // Se crea la primera matriz

for(a=0;a<m;a++)

{

mapa1[a]=(int *)malloc(sizeof(int)*m);

memset(mapa1[a],0,sizeof(int)*m);

}

puts("Datos primer matriz\n");

for(a=0;a<f1;a++){ // Se cogen los datos de la primera matriz.

for(b=0;b<c1;b++){

//printf("Introduce los valores del elemento (%d , %d) de la primera matriz:", a+1 , b+1);

scanf(" %d",&mapa1[b][a]);

//printf("valor %d , %d = %d\n",b,a,mapa1[b][a]);

}

}

for(a=0;a<m;a++){

for(b=0;b<m;b++){

printf("%d", mapa1[a][b]);

}printf("\n");

}

mapa2=(int **)malloc(sizeof(int *)*m); // Se crea la sedunda matriz.

Page 16: Practica Multiplicacion Matrices

for(a=0;a<m;a++)

{

mapa2[a]=(int *)malloc(sizeof(int)*m);

memset(mapa2[a],0,sizeof(int)*m);

}

puts("Datos segunda matriz\n");

for(a=0;a<f2;a++){ // Se cogen los datos de la segunda matriz.

for(b=0;b<c2;b++){

//printf("Introduce los valores del elemento (%d , %d) de la segunda matriz:", a+1 , b+1);

scanf(" %d",&mapa2[b][a]);

//printf("valor %d , %d = %d\n",b,a,mapa2[b][a]);

}

}

for(a=0;a<m;a++){

for(b=0;b<m;b++){

printf("%d", mapa2[a][b]);

}printf("\n");

}

sol=multiplicaDyV(mapa1,mapa2,m); // Se multiplican.

sol1=multiplicamatriz(mapa1,mapa2,m);

printf("Solucion DyV: \n");

for(a=0;a<m;a++) // Se imprime el resultado.

Page 17: Practica Multiplicacion Matrices

{ for(b=0;b<m;b++){

printf(" %d ",sol[a][b]);

} printf("\n");

}

printf("Solucion Strassen: \n");

for(a=0;a<m;a++) // Se imprime el resultado.

{ for(b=0;b<m;b++){

printf(" %d ",sol1[a][b]);

} printf("\n");

}

system("pause");

return(0);

}

Page 18: Practica Multiplicacion Matrices

Conclusiones

Con esta práctica observamos que el problema de multiplicación de matrices se puede resolver de diferentes formas, por medio de divide y vencerás y el método de Strassen, con esto aprendimos que para este problema en particular la técnica divide y vencerás es más lenta, aunque no quedo muy claro ya que las matrices que utilizamos no fueron lo suficientemente grandes como para observar completamente esta diferencia.

Referencias

http://es.wikipedia.org/wiki/Algoritmo_de_Strassen

http://www.ing.ula.ve/~aguilar/actividad-docente/AYDA/Clase7MiniSem.pdf