Divide y Venceras

December 2, 2022 | Author: Anonymous | Category: N/A
Share Embed Donate


Short Description

Download Divide y Venceras...

Description

 

Cuestiones generales La té técn cnic ica a de di dise seño ño de al algo gori ritm tmos os ll llam amad ada a "d "div ivid ide e y ve venc ncer erás ás"" (divide and conquer) consiste en descomponer el problema original en va vario rios s su sub-p b-pro roble blemas mas más sen sencil cillos los,, par para a lue luego go resol resolve verr és éstos tos mediante un cálculo sencillo. Por ltimo, se combinan los resultados de cada sub-problema para obtener la soluci!n del problema original. l pseudoc!digo ser#a$ funcion divide_y_venc divide_y_venceras_1(problem eras_1(problema) a) {   descomponer el problema en n subproblemas más pequeños;   para i=1 hasta n hacer   resolver el subproblema k;   combinar las n soluciones;  

%n e&emplo de "divide y vencerás" es el quic'sort. n ella, se divid#a el arr arregl eglo o en do dos s sub sub-a -arre rreglo glos, s, para para lue luego go resol resolve verr cad cada a uno por separado, y unirlos. l tiempo necesario para ordenar un arreglo de elementos mediante el método de la burbu&a es cuadrático$ ' . *i dividimos el arreglo en dos y ordenamos cada uno de ellos, el tiempo nece ne cesa sari rio o pa para ra re reso solv lver erlo lo es a+ a+or ora a '( '( ) )'()('). l tiem ti empo po ne nece cesa sari rio o pa para ra orde ordena narl rlo o es la mi mita tad, d, pe pero ro si sigu gue e si sien endo do cuadrático. Pero a+ora, si los subproblemas son todav#a demasiado grandes, /por qué no utili0ar la misma táctica con ellos, esto es, dividirlos a ellos también, utili0ando un algoritmo recursivo que vaya dividiendo más el sub-problema sub-problem a +asta que su soluci!n sea trivial1 %n algoritmo del tipo$ funcion divide_y_venc divide_y_venceras(problema) eras(problema) {   si el problema es trivial   entonces resolver el problema;   si no es trivial   {   descomponer el problema en n subproblemas más   pequeños;   para i=1 hasta n hacer   divide_y_venceras(subproblema_k);   combinar las n soluciones;     

*i aplicamos este método al quic'sort, el tiempo disminuye +asta ser logar#tmico, con lo que el tiempo a+orrado es mayor cuanto más aumenta .

Divide y Venceras

 

1

 

Tiempo de ejecución l tiempo de e&ecuci!n de un algoritmo de divide y vencerás, 2(n), viene dado por la suma de dos elementos$ l tiempo que tarda en resolver los 3 subproblemas en los que se divide el original, 342(n5), donde n5 es el tamaño de cada sub-



problema. l tiempo necesario para combinar las soluciones de los subproblemas para +allar la soluci!n del original6 normalmente es 7(n ') 

Por tanto, el tiempo total es$ 2(n)  342(n5)  7(n '). La soluci!n de esta ecuaci!n, si 3 es mayor o igual que 8 y 5 es mayor que 8, es$ si 395', 2(n)  7(nlog53) si 35', 2(n)  7(n'4log n) si 3:5', 2(n)  7(n')

Determinación del umbral  Determinación %no de los aspectos que +ay que tener en cuenta en los algoritmos de divide y vencerás es d!nde colocar el umbral, esto es, cuándo se consider cons idera a que un subsub-prob problema lema es su;ic su;icient ienteme emente nte pequ pequeño eño como para no tener que dividirlo para resolverlo. ormalmente esto es lo que +ace que un algoritmo de divide y vencerás sea e;ectivo o no. Por e&emplo, en el algoritmo de ordenaci!n quic'sort, cuando se tiene un array de longitud   {   au.=array5i6; ++ Kntercambiar# Kntercambiar #   array5i6=array5d6;   array5d6=au.;      else ++ si se han cruCado>   break; ++ salir del bucle#      if(d==desdeE1) if(d==desdeE1) ++ Ai la se%unda b-squeda se sale del array   d=desde; ++ es que el pivote es el elemento   ++ más pequeño> se cambia con Ll mismo#   au.=array5d6; ++ olocar el pivote   array5d6=array5desde6; array5d6=arra y5desde6; ++ en su posiciHn#   array5desde6=au.;      

if(d==k) return(array5d6); return(array 5d6); ++ /l pivote es el elemento buscado else if(d$k)

  return(seleccionrapida(a return(selec cionrapida(arraydesdedE rraydesdedE1)); 1)); ++ Fuscar en el primer array#   else   return(seleccionrapida(a return(selec cionrapida(arrayd:1hast rrayd:1hasta)); a)); ++ Fuscar en el se%undo array#  

n es esta ta so solu luci ci!n !n en ti tiem empo po me medi dio o li line neal al se de desc scar arta tan n s! s!lo lo un unos os cuanto cua ntos s ele eleme mento ntos s cad cada a ve ve0 0 que se lla llama ma a la ;un ;unci! ci!n n re recur cursiv siva, a, depen dep endie diendo ndo de dell pivote pivote que eli&a eli&amo mos. s. Pa Para ra des descar cartar tar una ;ra ;racci cci!n !n constante de elementos (y me&orar el tiempo de e&ecuci!n del peor caso) +abr#a que elegir un me&or pivote, a ser pre;erible la mediana (cosa que no puede ser, porque es &ustamente ella la que estamos buscando). 2ampoco se puede perder muc+o tiempo en buscar un buen pivote, porque +ar#a demasiado lento el programa. %na opci!n ser#a elegir tres elementos y utili0ar como pivote la mediana de esos tres, pero en el peor caso eso sigue siendo una mala opci!n. @ay un algoritmo de elecci!n del pivote llamado "partici!n con base en la mediana de la mediana de cinco", que consiste en$ •





?iv ivid idir ir los los n eleme lemen ntos tos en nA gr grup upos os de A ele leme men ntos tos (ignorando los ltimos elementos). ncontrar la mediana de cada grupo de A elementos, lo que da una lista de nA medianas B. @allar la mediana de B, o un buen pivote en B, lo que se puede +acer utili0ando este algoritmo recursivamente.

Divide y Venceras

 

7

 

*e puede probar que, utili0ando este método, y en el peor de los casos, cada llamada a la ;unci!n recursiva desprecia a más del i >ili liar ar pa para ra la bsqueda del pivote. l problema completo ser#a$ !include "stdio#h$ !include "stdlib#h$ !include "strin%#h$ int seleccionrapida(int 0int 0intintint); int hallamediana(int 0int 0int); int main() {   int numamk;   int 0array0pos;            

scanf(7 8d79num); ++ 3edir el tamaño del array array=(int 0)malloc(siCeof(int)0num 0)malloc(siC eof(int)0num); ); for(a=;a"num;a::) for(a=;a"num;a::) ++ ar valores al array scanf(7 8d79array5a6); 8d79array5a6); scanf(7 8d79k); ++ 3edir el valor k kEE;

 

pos=(int 0)malloc(siCeof(int)0num 0)malloc(siC eof(int)0num); );

 

m=seleccionrapida(arrayp m=seleccionra pida(arrayposnumE1k) osnumE1k); ; ++ 3ara llamar a la funciHn

 

printf(78d@n7m);

  return();   int seleccionrapida(int 0arrayint 0posint desdeint hastaint k) {   int idau.; ++ i realiCa la b-squeda de iCquierda a derecha   ++ y D realiCa la b-squeda de derecha a iCquierda#        

++   {   au.=array5i6; ++ Kntercambiar# Kntercambiar #   array5i6=array5d6;   array5d6=au.;      

 else ++ si se han cruCado> break; ++ salir del bucle#

Divide y Venceras

 

8

 

             

 if(d==desdeE1) if(d==desdeE1) ++ Ai la se%unda b-squeda se sale del array d=desde; ++ es que el pivote es el elemento ++ más pequeño> se cambia con Ll mismo# au.=array5d6; ++ olocar el pivote array5d6=array5desde6; array5d6=arra y5desde6; ++ en su posiciHn# array5desde6=au.;

  if(d==k)   return(array5d6); return(array 5d6); ++ /l pivote es el elemento buscado   else if(d$k)   return(seleccionrapida(a return(selec cionrapida(arrayposdesd rrayposdesdedE1k)); edE1k)); ++ Fuscar en el primer array#   else   return(seleccionrapida(a return(selec cionrapida(arrayposd:1 rrayposd:1hastak)); hastak)); ++ Fuscar en el se%undo array#   int hallamediana(int 0arrayint 0posint num) {   int a0array2bcd; a0array2bc d;   if(num"M) ++ Ai hay menos de M elementos   return(pos56); return(pos5 6); ++ vale el primero (lo que devuelve esta   ++ funciHn es el 4ndice de la mediana en la variable 7array7 de la funciHn   funciHn#                                                

++ seleccionrapida seleccionrap ida que llama por primera veC a esta

++ to (3*EHH) con nombre B%L2 B%L2..K*, que contendrá una secuencia de m l#neas con el resultado de las multiplicaciones$ La l#nea ' del arc+ivo de salida representa la multiplicaci!n de los enteros contenidos en las l#neas ' y '8 del arc+ivo de entrada. Los enteros se representan también como una cadena de caracteres (d#git (d# gitos os po posib sible lemen mente te pre prece cedid didos os del sig signo no I-I). I-I). Lo Los s re resul sultad tados os no pueden tener ceros super;luos a la i0quierda.

Divide y Venceras

 

15

 

Ejemplo de entrada ? E12NMQPPQW 1TMWPTQ ?NM N2  2?

Ejemplo de salida E1?M2TP?QN1N?WNQ? 1NNW 

Divide y Venceras

 

16

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF