You are on page 1of 12

Anlisis de

Algoritmos

Prctica 2: Divide y Vencers
Multiplicacin de dos
nmeros binarios.

por
ESCAMILLA CAMACHO JUAN
EDUARDO
PEREZ PEREZ JOS RICARDO

DRA. GARCA MENDOZA
CONSUELO VARINIA
Profesor


1
TABLA DE CONTENIDO
INTRODUCCIN............................................................................................................... 2
DESARROLLO .............................................................................................................. 3
A) TABLA ..........................................................ERROR! BOOKMARK NOT DEFINED.
B) GRFICA ............................................................................................................. 4
C) CUESTIONARIO .................................................................................................... 4
CONCLUSIONES........................................................................................................... 5
ANEXOS ..................................................................ERROR! BOOKMARK NOT DEFINED.
A) MULTIPLICACIN BINARIA: MTODO TRADICIONAL ........... ERROR! BOOKMARK NOT
DEFINED.
B) MULTIPLICACIN BINARIA: MTODO DE DIVIDE Y VENCERS. ... ERROR! BOOKMARK
NOT DEFINED.
C) MULTIPLICACIN BINARIA: MTODO DE GAUSS. .ERROR! BOOKMARK NOT DEFINED.
BIBLIOGRAFA .......................................................ERROR! BOOKMARK NOT DEFINED.

















2

INTRODUCCION
En la cultura popular, divide y vencers hace referencia a un refrn que
implica resolver un problema difcil, dividindolo en partes ms simples tantas
veces como sea necesario, hasta que la resolucin de las partes se torna
obvia. La solucin del problema principal se construye con las soluciones
encontradas.
En las ciencias de la computacin, el trmino divide y vencers (DYV) hace
referencia a uno de los ms importantes paradigmas de diseo algortmico. El
mtodo est basado en la resolucin recursiva de un problema dividindolo
en dos o ms sub-problemas de igual tipo o similar. El proceso contina hasta
que stos llegan a ser lo suficientemente sencillos como para que se
resuelvan directamente. Al final, las soluciones a cada uno de los sub-
problemas se combinan para dar una solucin al problema original.
Esta tcnica es la base de los algoritmos eficientes para casi cualquier tipo de
problema como, por ejemplo, algoritmos de
ordenamiento (quicksort, mergesort, entre muchos otros), multiplicar nmeros
grandes (Karatsuba), anlisis sintcticos (anlisis sintctico top-down) y
la transformada discreta de Fourier.
Por otra parte, analizar y disear algoritmos de DyV son tareas que lleva
tiempo dominar. Al igual que en la induccin, a veces es necesario sustituir el
problema original por uno ms complejo para conseguir realizar la recursin,
y no hay un mtodo sistemtico de generalizacin.
El nombre divide y vencers tambin se aplica a veces a algoritmos que
reducen cada problema a un nico subproblema, como la bsqueda
binaria para encontrar un elemento en una lista ordenada (o su equivalente
en computacin numrica, el algoritmo de biseccin para bsqueda de
races). Estos algoritmos pueden ser implementados ms eficientemente que
los algoritmos generales de divide y vencers; en particular, si es usando
una serie de recursiones que lo convierten en simples bucles. Bajo esta amplia
definicin, sin embargo, cada algoritmo que usa recursin o bucles puede ser
tomado como un algoritmo de divide y vencers. El nombre decrementa y
vencers ha sido propuesta para la subclase simple de problemas.
La correccin de un algoritmo de divide y vencers, est habitualmente
probada una induccin matemtica, y su coste computacional se determina
resolviendo relaciones de recurrencia.



3

1|DESARROLLO
Implementa los siguientes algoritmos:
Algoritmo 1. Multiplicacin de dos nmeros en base 2 por el mtodo tradicional.
Algoritmo 2. Multiplicacin de dos nmeros en base 2 con Divide y Vencers a travs de
sus mitades.
Algoritmo 3. Multiplicacin de dos nmeros en base 2 con Divide y Vencers a travs de
mitades, utilizando el truco de Gauss para eliminar un producto.
A) TABLA DE COMPLEJIDAD

COMPLEJIDAD COMPLEJIDAD SIN
RECURSIVIDAD
Algoritmo 1 T(n) = n+2n. T(n) = C1*0
n+
C2*n
1
1
n+

C3*n
2
1
n+
C4*n
3
1
n+

C5*n
4
1
n+
C6*n
5
1
n.

Algoritmo 2 T(n) = 4T(n/2)+C. T(n) = C1*4
log
2
(n)
+
C2*1
log
2
(n).
Algoritmo 3 T(n) = T(n)= 3T(n/2) +
C.
T(n) = C1*3
log
2
(n)
+
C2*1
log
2
(n).

B) GRAFICA
GRAFICA COMPLEJIDAD MULTIPLICACION DE NUMEROS BINARIOS
NORMAL



4


C) CUESTIONARIO


1. La complejidad del algoritmo de la multiplicacin por mtodo tradicional
disminuye al implementarlo con la con la estrategia de Divide y Vencers?
RESPUESTA:
SI, DISMINUYE YA QUE SE HACE RECURSIVO ES DECIR QUE SE REALIZA CON
MENOS CICLOS Y SE REDUCE POR QUE TIENE UNA FUNCIN EXCLUSIVA
PARA DIVIDIR ,

2. La complejidad del algoritmo de la multiplicacin con la estrategia de Divide y
Vencers es menor cuando se disminuyen las llamadas recursivas en cada nivel
de recursividad, como se hizo con el truco de Gauss para disminuir una llamada
recursiva?
RESPUESTA:
SI, PORQUE EN EL ALGORITMO DE DIVIDE Y VENCERAS NORMAL SE RALIZA
4 RAMAS DEL ABROL PARA LA DIVISION Y CON GAUSS SE DESMINUYE YA
QUE DE 4 RAMAS SE OBTIENEN 3 RAMAS UNICAMENTE Y SE ELIMINA UN
CICLO RECURSIVO Y POR CONISGUIENTE SE DISMINUYE LA COMPELJIDAD.

3. Analizando la grfica indique para el cual, el algoritmo de menor complejidad se
vuelve cota inferior de cada uno de los otros dos algoritmos.
RESPUESTA:

PUES DESPUES DE ANILIZAR EL ALGORTIMO 3 DE DIVIDE Y VENCERAS
CON EL METODO DE GAUSS SE VUELVE LA COTA INFERIOR DE LOS DEMAS
ALGORITMOS
4. Cul es el cdigo ms sencillo? Por qu lo considera ms sencillo?
RESPUESTA:
PUES EL CDIGO MAS SENCILLO ES EL PRIMER OSEA, EL PROGRAMA DE
MULTIPLICACION DE BINARIOS POR METODO TRADICIONAL YA QUE
OCUPAMOS EL METODO DE PROGRAMACION A NIVEL DE BITS Y OCUPAMOS
OPERACION DE COMPUERTAS LGICAS Y NO NECESITAMOS OCUAPAR UNA
FUNCION DE CONVERSION DE BINARIO A DECIMAL ESTO SE SUSTITUYO


5
CON EL SIGNO DE CORRIMIENTO A LA IZQUIERDA << Y CON ESTE EL
COMPILADOR AUTOMTICAMENTE LO CONVIERTE Y NO SE ENCESITA
LLENAR CON CEROS POR QUE AL PROGRAMA AL NIVEL DE BITS SE LLENA
CON CEROS , Y TODO EL PROGRAMA SE REALIZA CON 12 LINEAS DE CDIGO
APROXIMADAMENTE.
2|CONCLUSIONES
JUAN EDUARDO ESCAMILLA CAMACHO
El objetivo principal de este proyecto consista en el anlisis del Algoritmo Divide y
Vencers pro medio de un software sobre el mtodo de multiplicacin de nmeros binarios
utilizando 3 algoritmos son tres: Mtodo normal, Divide y vencers y Divide y Vencers
por medio de Gauss.
Se utiliz un proceso de desarrollo especfico y una herramienta que permite programar
diferentes aplicaciones en diferentes lenguajes NETBEANS Y CODEBLOCKS Esta
herramienta complementa el marco de trabajo para la reutilizacin de requisitos y
constituye la parte prctica de la misma prctica
El resultado de emplear esta mtodo es poder reducir la complejidad de ciertos programas
utilizando este mtodo el cual se ocupado desde hace mucho tiempo atrs, adems de
reducir la complejidad reduce el tiempo de ejecucin del mismo y la programacin se
torna ms sencilla ya que nos ahorramos cdigo y ciclos ya que utilizamos clases en el caso
de Java y funciones en el caso de C en CodeBlocks.

PEREZ PEREZ JOS RICARDO
Para esta prctica personalmente me fue muy interesante ya que al llevar 6 semestres en la
carrera jams haba entendido bien el funcionamiento de la recursividad y como se
implementaba. Al aplicar la regla de Divide y Vencers y conocer cmo se implementa en
los sistemas me permiti darme una idea de cmo se pueden ahorrar bastantes lneas de
cdigo y tiempo de desarrollo del programa as como la complejidad de los mismos.
Para los problemas a solucionar cada uno fue programado en un lenguaje de programacin
distinto pero la base del algoritmo fue el mismo, para el primer problema la solucin se dio
en el lenguaje C, para el segundo problema de multiplicacin binaria se resolvi el
problema con C# y para el ltimo y ms difcil se tuvo que implementar la solucin en
JAVA ya que al desarrollarlo en C# se present la problemtica que al compilarlo y correrlo
este entraba en un bucle infinito y al implementar la solucin en JAVA este ya no
presentaba tal problema.
Fue una experiencia grata el poder desarrollar esta prctica as como desarrollar el cdigo
de la solucin a nuestro problema, aunque fue un poco estresante el pensar la solucin se
que es buena prctica para desarrollar nuestras habilidades en el anlisis de algoritmos.



6

3|ANEXOS
A) PRIMER ALGORITMO
#include<stdlib.h>
#include<conio.h>
#include<time.h>
#include <stdio.h>
#include <string.h>
main(){
int i,j,k,valor2,suma,resultado;
char *primernumero,*segundonumero;

primernumero=(char*)malloc(sizeof(char));//se regresa el puntero que se le
asigno para primernumero
segundonumero=(char*)malloc(sizeof(char));//se regresa el puntero que se le asigno
para segundonumero
for(;;){
resultado=0;
suma=0;
/* Pantalla de inicio. */
system( "COLOR 47" );
printf( "\n\t ****************************************\n" );
printf( "\n\n\t\t ESCUELA SUPERIOR DE COMPUTO\n\n", 224 );
printf( "\t\t ANALISIS DE ALGORITMOS", 214 );
printf( "\n\n\t\t ESCAMILLA CAMACHO JUAN EDUARDO" );
printf( "\n\n\t\t PEREZ PEREZ JOSE");
printf("\n\n\t\t PRODUCTO DE BINARIOS NORMAL \n\n",214);
printf( "\t ****************************************\n\n" );


7
time_t ahora;
struct tm *fecha;
time( &ahora );
fecha = localtime( &ahora );
printf( "\t\t\t\t\t\t FECHA DE HOY( %d/%d/%d )\n" , fecha->tm_mday , fecha-
>tm_mon+1 , fecha->tm_year+1900 );
system( "PAUSE" );
system("cls");
int w=0,i=0;
char aux,aux_1[200];
system("cls");
system("COLOR 47");
printf( "\n\t
**********************************************************\n" );
printf(" \n\n\t\t MULTIPLICACION DE BINARIOS (OJALA ESTE BIEN
=P)\n\n\n",224 );
printf(" \n\n\t\t META NUMEROS EN BINARIOS\n\n\n",214);
printf("\t
**********************************************************\n\n");
system("cls");
printf("COLOCA EL NUMERO BINARIO: \n\n");
scanf("%s",primernumero);
system("cls");
printf("COLOCA EL NUMERO BINARIO: \n\n");
scanf("%s",segundonumero);
system("cls");
//system ("pause");
printf("BIEN EL PRIMER NUMERO QUE INGRESASTE FUE:
%s\n",primernumero);


8
printf("BIEN EL SEGUNDO NUMERO QUE INGRESASTE FUE:
%s\n\n",segundonumero);
if(strlen(segundonumero) <= strlen(primernumero))
{
for(i=strlen(segundonumero)-1,k=0;i<=0;i--,k++){//se iguala i con la longitud de
segundo numero es decir lo que trae en el primer registro
for(j=strlen(primernumero)-1,valor2=0,suma=0;j<=0; j--,valor2++)//se iguala j con
el tamao de la cadena cuando se ingreso al segundo valor
suma|=( ( (segundonumero[i]&1)&(primernumero[j]&1) )<<valor2 );// como se
trabaja a nivel de bits ocupasmos operacion booleanas
resultado+=(suma<<k);
}
}else{
printf("");
}
for(i=strlen(segundonumero)-1,k=0;i>=0;i--,k++){//se iguala i con la longitud de
segundo numero es decir lo que trae en el primer registro
for(j=strlen(primernumero)-1,valor2=0,suma=0;j>=0; j--,valor2++)//se iguala j con
el tamao de la cadena cuando se ingreso al segundo valor
suma|=( ( (segundonumero[i]&1)&(primernumero[j]&1) )<<valor2 );// como se
trabaja a nivel de bits ocupasmos operacion booleanas
resultado+=(suma<<k);//primeramente se realiza la multplicacion de numeros
bianrios por medio de la and y se almacena en un arreglo unidemensional cada numero
// entonces el resultado se desplaza a la izquiera y con el operador |= se realiza la
suma con la operacion que salga y nos da el resutlado
// << Este operador binario realiza un desplazamiento de bits a la izquierda. El bit
ms significativo (ms a la izquierda) se pierde, y se le asigna un 0 al menos significativo
(el de la derecha). El operando derecho indica el nmero de desplazamientos que se
realizarn.
//Recurdese que los desplazamientos no son rotaciones; los bits que salen por la
izquierda se pierden, los que entran por la derecha se rellenan con ceros. Este tipo de
desplazamientos
//se denominan lgicos en contraposicin a los cclicos o rotacionales.
//el compilador realiza una conversion automatica de tipo


9
}
printf("\nBIEN EL RESULTADO DE TU MULTIPLICACION ES LA SIGUIENTE:
%d\n",resultado);
system("pause");
}
}/*End main*/
B) SEGUNDO ALGORITMO

public int PDyV (int[]a,int[]b){ //Recibe dos matrices de tipo entero cada una

Operacion o = new Operacion (); //Declaramos un objeto de nuestra clase Operacion que
es donde se encuentran todos nuestros mtodos a utilizar

int n,p,q,w;
int[] ai,ad,bi,bd;
n = a.Length; //n toma el tamao de nuestro primer arreglo
if (a.Length == 1 && b.Length == 1) { //Si ambos arreglos recibidos son de tamao uno
se multiplican entre si.

return o.productoMatrices(a,b);

} else {
//Se declaran nuestros arreglos en donde se guardaran nuestras divisiones ai, ad y bi y bd
ai = new int[a.Length/2];
ad = new int[a.Length/2];
bi = new int[b.Length/2];
bd = new int[b.Length/2];

ai = o.divide (a, 1);


10
ad = o.divide (a, 2);
bi = o.divide (b, 1);
bd = o.divide (b, 2);
q = Convert.ToInt32 (Math.Pow (2, n));
w = Convert.ToInt32 (Math.Pow (2, n / 2));
//Se retorna la operacin final del algoritmo aplicando recursividad con los valores
obtenidos de ai,ad,bi y bd
return (q*PDyV(ai,bi)) + (w*PDyV(ai,bd)) + (w*PDyV(ad,bi)) + (PDyV(ad,bd));
}
}

C) TERCER ALGORITMO

//Se reciben dos String donde se encuentran nuestros valores y la base (2)

int multiplicaBase(String a, String b, int base){
//Declaramos un objeto de nuestra clase Operacion que es donde se encuentran todos
nuestros mtodos a utilizar
Operacion o = new Operacion();
String xi,xd,yi,yd,x,y;
int p1,p2,p3,p4,mayor;
if(a.length()==1 && b.length()==1){
{ //Si ambos arreglos recibidos son de tamao uno se multiplican entre si.
return Integer.parseInt(a,base)*Integer.parseInt(b,base);
}
else{
//Se declaran nuestros arreglos en donde se guardaran nuestras divisions ai,ad y bi y bd
xi=o.divide(a,1);
xd=o.divide(a,2);


11
yi=o.divide(b,1);
yd=o.divide(b,2);

x=Integer.toString((Integer.parseInt(xi, base)+Integer.parseInt(xd, base)),base);
y=Integer.toString((Integer.parseInt(yi, base)+Integer.parseInt(yd, base)),base);
mayor=o.obtenMayor(Integer.parseInt(x,base),Integer.parseInt(y,base));
x=o.acompleta(x,mayor,base);
y=o.acompleta(y,mayor,base);

p1=multiplicaBase(xi,yi,base);
p2=multiplicaBase(xd,yd,base);
p3=multiplicaBase(x, y, base);

//Se retorna la operacin final del algoritmo aplicando recursividad con los valores
obtenidos de ai,ad,bi y bd

return ((int)Math.pow(base, a.length())*p1)+((int)Math.pow(base,
a.length()/2)*(p3-p2-p1))+p2;
}
}

You might also like