Sei sulla pagina 1di 888

Tejiendo algoritmos

v IFH

Leandro Rabindranath Len lrleon@ula.ve Centro de Estudios en Microelectrnica y Sistemas Distribuidos Universidad de Los Andes 1 de septiembre de 2010

Prefacio
uisier que este texto se onsiderse omo un vdemeum en el diseo efetivo y en l progrmin de lgoritmos y de estruturs de dtos que soporten progrms omputE ionlesF demum es un plr ltin onstruid medinte el impertivo ltn vde que onnot venD nd o minD y meumD que signi( onmigoF eprender es preido trnsitr un minoY enser es preido mostrrselo un peregrinoF inE ser proviene del ltn insign re D vero ompuesto de in @enA y signre @selrAY l expresin n se emple undo se sel on el dedo un send seguirF esD un vdeE meum pretende ser un gu de trnsito por un send de prendizjeY en este soD l de progrmin de omputdorsF

Modo y medios
ermtseme introduir el modo de ensenz de este textoD expresdo por este ntiqusimo proverio orientlX gundo esuhoD olvidoD gundo veoD reuerdoD gundo hgoD entiendoF v propiin efetiv de un onoimiento ourre undo ste se entiendeF il enE tendimiento se torn relidd undo un prendiz onsum l hehur de oss rtersE tis de su prti hindols l mismoF hiho de otr mnerD el modo de ensenz es mostrr entermente mo se elor un estrutur de dtos y un lgoritmoF fjo este modo intentr guir un potenil prendiz por el mino de l prti de l progrmin vnzdF r ello empleo lgunos mediosF

C++
r representr los lgoritmos y ls espei(iones de estruturs de dtos empleo el lenguje de progrmin C++ F ist deisin no se tom sin digns ojeionesD ls ulesD resumidmenteD se pueden lsi(r en dos gruposF il primero uestion el eventul desonoimiento del letor sore el lenguje C++ F e esto deo replir que no slo C++ es uno de los lengujes ms populres e importntes de l progrmin de sistemsD sino que su sintxis y semnti son reminisentes l myor de los otros lengujes proedurles y ojetosF he hehoD en el qurum tul de los lengujes de progrmin proedurles no slo domin C++ D sino que el resto de los lengujes se inspirn en l o en su preursorD el lenguje CY por instnisD javaD pythonD perlD C# y DF i

ii

PREFACIO

il segundo tipo de ojein denuni que l omprensin se torn ms di(ultosD lo ul replio on dos rgumentosF il primero es que los lengujes de progrmin se pensron tmin en un estilo oloquil 1 respeto l progrminF gonsideremosD por ejemploD el siguiente pseudoprogrm en un pseudolenguje stellnoX
Repita mientras m > 0 y m < n si a[m] < a[x] entonces m = m/2; de lo contrario m = 2*m fin si Fin repita mientras

el ul es equivlente l trduin literlD oloquilD del siguiente loque en C++ X


while (m > 0 and m < n) { if (a[m] < a[x]) m = m/2; else m = 2*m; }

eunque un ejemplo no st pr generlizr mi defens sore el uso del lenguje C++ D el heho es que ulquier que onsidere serimente l progrmin tendr que progrE mr y esto deer herlo en un lenguje de progrminD el ulD pr ien o mlD fue pensdo en lengu inglesF or tntoD inevitlementeD un prendiz hispnoprlnte deE er progrmr en un lenguje de progrmin nglizdoF reh l otin nteriorD tmin podemos deir que el progrm en stellno y su equivlente en C++ tienen el mismo signi(doF es puesD es dudosoD undo menosD (rmr que l omprensin se torn ms di(ultosF n ondd que se triuye l uso de un pseudolenguje es que ste es independiente de l implementinF in mi riterioD esto es prilmente orretoF or ejemploD ls plntills en C++ plnten un prolem de porttiilidd en otros lengujes que no ls tienenF elguien podr duir que el uso de plntills son rptis pr el prendizF ero est ojein slo tiene sentido si no se omprende el onepto y (n de un plntillD ul no es otro que l generiiddF intendido estoD un progrm on plntills es tnto o ms genrio que uno expresdo en un pseudolengujeY y result que este es el prinipl rgumento de quienes de(enden l ensenz de progrmin en un pseudolenguje3F he todos modosD si se usse un pseudolengujeD entones tmin hr que plnterse el prolem de trduir un lenguje de progrmin rel2 F wi segundo rgumento estri en queD hid uent de l populridd y trnsendeni del C++ D reo que es ms fil trduir un progrm ien estruturdo en C++ hi otro lengujeD por ejemploD javaD que uno relizdo en un pseudolenguje3 F
1 2 3
Es imposible ser completamente coloquial en un lenguaje de programacin. Una traduccin con ms esfuerzo si se trata de un pseudolenguaje en castellano. De hecho, muchos textos de programacin aparecen en diferentes ediciones para distintos lenguajes.

En muchos de estos casos, el autor escribe los programas en un solo lenguaje y luego emplea traductores ++ hacia el otro lenguaje. Tales son los casos de Sedgewick o Weiss y sus series en C, C y java

iii

Biblioteca

ALEPH

iste texto ontiene en s mismo un implementin onret de un ilioteD lireD llmd ALEPHD ontentiv de tods ls estruturs de dtos y lgoritmos trtdos en este textoF v letur posiilit l del fuente de l iliote y revel spetos de su instrumentE inF lvo errores n no desuiertos o mejors que ulquier desee proponerD el letor tiene l posiilidd de poyrse en un implntin onret que le filite l propiin de sus onoimientosF vos digos fuentes de ALEPH estn disponiles enX

http://webdelprofesor.ula.ve/ingenieria/lrleon/aleph.tbz
illos fueron utomtimente indentdos on bcpp IUF e lo lrgo de mi experieni omo ensente he intentdo reompensr los desuriE dores de errores y proponentes de mejors on un ponderin en su li(inF xo veo ningn impedimento que un terero plique lo mismo si este texto se us omo mteril instruionlF i lgn letor fuer de mi rulo de ensenz dese reportr lgn error o her lgun mejorD entones le grdezo que lo reporte l emil lrleon@ula.veF v doumentin de l iliote est disponile en el enleX

http://webdelprofesor.ula.ve/ingenieria/lrleon/aleph/html
st fue esrit pr proesrse on el exelente progrm doxygen QVF
Programacin literaria

iii

in l elorin de este texto se utiliz un sistem llmdo noweb IRUD VTD el ul es un sistem progrmdo que gener este texto y los fuentes en C++ prtir de un solo rhivo fuenteF il fuente entrelz pros explitiv on loques de digo de l implntin de l ilioteF iste estilo de esritur de progrms se denomin progrmin literri y fue proE puesto por unuth WTF v ide es presentr un estilo ms oloquil pr esriir progrms que el mero estilo deformdo de un lenguje de progrminD junto on l gnni de que l doumentin y l ltim versin del progrm @presumilemente orretA residn en un slo fuenteF eprte de digo en C++ D los loques pueden ontener referenis otros loquesF n de(niin de loque omienz por su nomre entre prntesis ngulresF or ejemploD onsideremos determinr si un nmero n es o no primoF r elloD podemos de(nir el siguiente loqueX Calcular si n es primo iii if (n <= 2) // n es un nmero primo const int raz_de_n = static_cast<int>(ceil(sqrt(n))); for (int i = 3; i < raz_de_n; i += 2) if (n % i == 0) // n no es primo // n es un nmero primo

iv

PREFACIO

vos loques se enumern segn el nmero de l pgin en que se de(nen por primer vezF i hy ms de un loque en un pginD entones ste se le de un letr queD en el orden lftioD se orresponde on su orden de priinF elgunos loques referenin otros loques o vrilesF vos loques estn esritos en un orden que Ese reeE es preferile pr l omprensin que el mero listdo de digoF esD grdeer tod rti que se me pued her sore el estilo y orden de presentin de un estrutur de dto o lgoritmo en progrmin liE terriD pero soliito l rtio un esfuerzo primigenio por omprr el estilo noweb on el listdo plno de digo yD entonesD jo es onsiderinD her su rtiF n instrumento que podr ser til es el ndie de identi(dores de digo @pgF ??AD el ul que se enuentr en el pndie y ontiene los identi(dores de lses y mtodos de(nidos lo lrgo del textoF r d identi(dorD se ui en surydo el nmero de pgin dnde fue de(nido y los nmeros de ls pgins de segmentos de digo que le hen refereniF uede deirse que este texto ontiene l implntin de unt estrutur de dtos o lgoritmo se estudieF imperoD tomrse esto l pie de l letr rrer stnte ppelY dems de que hr este texto ms voluminoso y repetitivoF in ese sentidoD en pro del espioD se hn heho ortes de dos tiposX IF wnejo de exepionesX unque este speto onstituye un de ls onddes ms elegntes de C++ D este texto si no los presentF PF wtodos de lses repetitivos o muy simplesF in mos sosD el digo de l ilioteD diretmente generdo prtir del fuente noweb de este textoD est ompletoY es deirD l iliote ontiene los mnejdores de exepiones y mtodos omitidos en este textoF
Ejercicios

gulquier que se l prtiD no hy otr mner de que un prtinte onsume sus onoimientos que no se hiendo prtiF or ms esfuerzo l orientrle y enserleD el prendiz deeD preferilemente guido por un mestroD ejeritr por s solo lo prendidoF ry tres mnersD que no deen ser exluyentesD de llevr o lo nteriorX IF esoluin de ejeriios propuestosX en este sentidoD l (nl de d ptulo se present un onjunto de ejeriios destindos primordilmente l resoluin en solitrio por prte del prendizF elgunos ejeriios son terios en el sentido de que no neesrimente requieren esE riir un progrm ompilleF or supuestoD no est prohiido sentrse frente l omputdor e intentr onretr el ejeriio medinte un progrmF ytros ejeriios son prtios y onsisten en extensiones l ilioteF istos ejeriios son distinE guiles de los terios porque enunin su resultdo en trminos de un ojeto de l ilioteF vos ejeriios estn lsi(dos segn un di(ultd sujetiv juzgd por mF xo es fil ponderr el tiempo de resoluin de un ejeriioD pues ste depende del estudinteD pero he qu mi lsi(inX

@A xingun ruz denot un ejeriio onsiderdo senilloF vos terios deern de resolverse en el orden de ino minutosD mientrs que los prtios en el de un dF @A n ruz @CA expres un tiempo estimdo de un dos hors en el so de un ejeriio terio y de dos ds en el prtioF @A hos rues @CCA expresn y un di(ultd muho myorF or lo generlD est lse de ejeriios plnten l prendiz un desurimiento o revelin de un truo o tni queD un vez reveldD dee reduir l omplejidd del ejeriio ningun ruzF il tiempo de un ejeriio terio dee ser l menos de un dD mientrs que el de uno prtio ser de tres @QAF @dA res rues @CCCA representn un ejeriio de liteD difil n pr un mestroD uyo tiempo de resoluin no est delimitdoF PF ijeuin de ejeriios guidos en lortorioX uno de los grndes ostulos que lo strto plnte l prendiz Euno dir que ello ourre en ulquier prtiED es que su ondiin novii le di(ult eptr que lo que pr l puede ser en prinipio strto se onvertirD trvs del ejeriioD en onretoF hiho lo nteriorD puede deirse que el sentido de un ejeriio en lortorio es permitirle l estudinte iniir l onrein de sus onoimientosF e tl (nD en el lortorioD pueden llevrse o tres tividdesX @A gontemplin de un prolem omputionlD junto on su soluinD en el ul se hg uso de lgun estrutur de dtos o lgoritmo de estudioF il gu de lortorio puede enunir el prolem y presentr l instrumentin de su soluinF vuegoD invitr l estudinte revisr los fuentes e inferirD ntes de su ejeuinD ls tnis y estilos utilizdos en l instrumentinF @A gontemplin de l ejeuin del progrm pr diverss ominiones de enE trdF ist es l fse en l ul el prendiz omienz sentir onreinY es deirD que los oneptos strtos desemoquen en soluiones onretsF hurnte est tividd puede ser reomendle l utilizin de un depurdorF @A pinlmenteD resoluin de un vrinte del prolem prtir de l soluin primE igeniF in este punto es muy importnte que se trje sore el mismo prolem y fuentesD pero on lgun vrinteY un mpliin pr resolver otrs lses de entrdsD por ejemploF QF rjos prtiosX indudlementeD en el espritu del proverio itdoD est es l fse que enj on el her pr entender F gmo dee ser el proyetoc hee orresponder un prolem originl pr y on sentido l ontexto en el ul se enseeD es deirD formuldo por y pr usrse en l omunidd en donde se imprt este ursoF or ejemploD si ledo l lugr de ensenz se pdeen de prolems de tr(oD entones puede plnterse un onjunto mplsimo de proyetos en torno l simulin del tr(o y l estudio de diverss tnis pr evitr su ongestinF n proyeto de este tipo requerirD por ejemploD l modelizin on grfos de ls vs de irulinD de menismos de ontrol omo los semforos y de gentes irulntes omo los utomvilesF

vi

PREFACIO

o riesgo de ser exesivmente repetitivoD deo insistir en l importni de los ejeriiosF isto y dee ser ovio desde l perspetiv del estudinteD pues es el nio medio de ejeritrseF el instrutorD por otr prteD le permite enriqueer l ensenz undo se plnte ejeriios que ompletn o omplementn el onoimiento imprtidoD s omoD medinte l orreinD supervisr el nivel de sus estudintesF

Estructura del texto


or rzones didtis y de espioD este texto est dividido en dos tomosF il primero de ellos es fundmentl y omprende un urso medino y riguroso de lgoritmos y estruturs de dtosD s omo tnis pr ritir su efetividd y e(ieniF iste tomo puede emplerse omo liro texto o de refereni pr un urso de estruturs de dtosD diseo de lgoritmos o progrmin medinF il segundo tomo es y un texto vnzdo y se onsgr dos tems priniplesX tnis vnzds de reuperin de informin en memori primri y grfosF vos grfos onformn uno de los mundos ms omplejos de l omputin y de l optimizinD y su pliilidd es vst pr otros dominios que trnsienden ls ienis omputionlesF in pos del mejor rendimiento de lgoritmos sore grfosD menudo es neesrio empler tnis de lto rendimiento pr reuperr informin en memori primriD pero ests tnis tmin son requerids en otros mundos lgortmiosF he h el porqu de su inlusinF v omprensin de tomo ss exige un nivel de progrmin vnzdo y uens uliE ddes en el diseo y nlisis de lgoritmos y estruturs de dtosF iste tomo puede usrse omo texto o refereni de un urso vnzdo de lgoritmos o de grfosD tnto en el mito de pregrdo omo en el de postgrdoF emos tomos pueden fungir de refereni pr el queher ingenierilF

Estructura de este tomo


il presente tomo omienz por ordr en el ptulo I los fundmentos de strin empledos en el resto del textoF il ptulo P se dentr profundmente en l ide de seueniD uiu e indispensle en l progrminF n vez domind e instrumentd lmente l ide de seueniD el ptulo Q estudi ls tnis onoids pr ritir un lgoritmo o estruturs de dtosD tnto desde l perspetiv de l e(ieni @nlisisA omo desde l de l efetividd @orretitudAF pinlmenteD el ptulo R se onsgr estudir l estrutur de dtos rolD ul tmin es mplimente usd en l omputinF

Historia
gomen l elorin de l iliote ALEPH en myo de IWWVF in quel entones me onsgr esriir lses de ojetos pr representr lists @ls jerrqus Slink y DlinkAD roles inrios @ls jerrqus BinNode<Key> y Avl_Tree<Key>A y tls hsh @l lse LhashTable<Key>AF

vii

rtes de este texto omenzron preer medidos de IWWWD luego de que lgunos estudintes me oservsen que les ser til leer lgoritmos en digo y que stos fuesen ien omentdosF pue entones undo pel nowebD uy mgistrl efetividd y h onoido undoD estudindo generin dinmi de digoD me fue oportunsimo leer el liro de ompildores de rnson y prser TWF in ese tiempo esri prte de lo que hoy es el ptulo PD onerniente seuenisF e medidos del PHHH omen el ptulo R sore roles y prte del SD referente ls tls hshF il ptulo R h tenido stntes modi(iones su ontenido originl y didursD ourrids en su myor prte en el lrgo perodo omprendido entre PHHI y PHHRF in noviemre del PHHI redt si entermente lo que tulmente es el ptulo T sore equilirio de rolesF e medidos del PHHR inii l extensin de l iliote hi grfosD tem presentdo en el ptulo U F vs estruturs y lgoritmos en torno este dominio hn vrido stnte en form y no h sido hst gosto del PHHU undo hn tomdo un versin estleF greo que en este dominio es donde este texto plsm sus priniples portesF hesde ferero de PHHT me plnte el esfuerzo de revisr y uni(r los ptulos jo lo que hoy onform este textoF isri entermente los ptulos ID sore strin de dtosD y el QD onerniente l rti de lgoritmos y estruturs de dtosF il septiemre de PHHU ulmin el ptulo S referente ls tls hshF v myor de ls (gurs de este liro fue generd utomtimente medinte proE grms elordos on l propi iliote ALEPHF in ese sentidoD hy tres progrmsX IF btreepic pr diujr roles inrios PF ntreepic pr diujr roresenis y roles en generl QF graphpic pr diujr grfos il primer progrmD btreepicD fue produto de mi instisfin on los diujos de roles inrios generdos on progrms espeiles tles omo Xfig y diaF e esto se un l imposiilidd mteril de diujr roles enormes Ede ientos o miles de nodosEF in virtud de esto soliit un trjo esolr l respetoD uyos resultdosD pesr de stisferme esolrmenteD distron de serme su(ientesF e rz de es experieni deid por mi propi uent progrmr btreepicF gundo tuve que diujr roles generles soliit el mismo tipo de progrmY entones prei un estudinte exelsoD llmdo tos fritoD quien forj un primer versin llmd xtreepic y que est distriuid en ALEPHF vmentleE menteD est versin oper sore un versin de roles que l po de mi neesidd y revisin y er duD por lo que prefer reher entermente el progrm jo el nomre de ntreepicF r l elorin del progrm me fue muy til el hermoso texto sore diujdo de grfos de uozo ugiym ITSF pinlmenteD undo me enontr en l mism neesidd respeto los grfosD proveh l osin pr desrrollr si entermente el orpus lgortmio en geometr omputionlF il progrm resultnteD graphpicD es n muy simple y evde tod l lgortmi vinuld l diujdo utomtio de grfosY de hehoD ls deisiones sore diujdo son tomds por el usurioD pero podr deir que graphpic tiene l virtud de operr entermente sore geometr omputionl y que ello no slo vlid este mpoD sino que re futuros desrrollosF in wrzo de PHHV inii l esritur de l doumentin de l ilioteF we enfrent un prolemX gmo integrr l doumentin en el fuente de este texto sin que st

viii

PREFACIO

prez en el textoc equer esriirl en el mismo sitio donde esri este liro porque de ese modoD jo l mism dotrin de nowebD un modi(in de l iliote se podr tulizr rpidmente en l doumentinF heid entones diser un (ltro de texto que reonoiese los loques de doumentin dentro del fuente noweb y los eliminse AiF l (ltro se llm deldoxygen y fue de mner que no preiesen en l slid v esrito on el generdor de nlizdores lexiogr(os flex y C++ F elguien dir que pude herlo heho en treint minutos on uno de los lengujes de sripting modernos @perlD pythonD etFAF rolemente se ierto si yo fuese mestro en lguno de quellos lengujesD peroD en didurD djeseme replir on tres hehosF rimeroD demor un pr de hors en esriir deldoxygen porque ten quine os sin usr flex y no reord ien el lengujeY no es pues muh l difereniF egundoD mi (ltro tiene muhs ms posiiliddes de ser orretoD pues fue espei(do Eno progrmdoE jo el formlismo de ls expresiones regulres y los utmtsY en un lenguje de sriptingD est orretitud ten que progrmrse y no espei(rse omo fue el soF pinlmenteD el (ltro dee ser onsiderlemente ms veloz que un ontrprte sriptingY yo dirD undo menosD en dos rdenes de mgnitudF gundo me enontr en l ediin (nl de est versin @wrzo PHHVA hue de prehender que el texto onten @y n ontieneA loques noweb on pedzos de digo sin muho vlor didtioD por ejemploD repetir funiones uyo sentido y fue explido en otro lugr pr otr lse de ojetoF heid entones diser otro (ltro de texto que reonoiere delimitdores dentro del fuente noweb y que se invose ntes de nowebF il AiD los (ltro se denomin nobookD fue esrito tmin en flex y eliminD pr l slid v loques delimitdosF

Cosas que faltan y sobran


hesde muhs perspetivsD siempre un texto dolee de flt de lgoF equ deseo referirme lo queD reoD huier deido perfetmente her y lo queD on ertitudD no de herF greo sinermente que ls estruturs de dtos y lgoritmos fundmentles estn preE sentes en este textoD unqueD on seguriddD lgn pr disreprF or otr prteD mteril que mi juiio es de lto intersD que est presente en l iliote ALEPHD no est preE sente en este textoF vos ejemplos ms notles de eso son ls lists skipD oloredos de grfosD minos eulerinos y hmiltoninosD estruturs de grfos onurrentesD de gentes y de simulinD estruturs de grfos y sus lgoritmos sdos en olonis de hormigs y geometr omputionlF we hr gustdo inluirls en este liroD pero y me soreps el momento y got el lmite de espioF espetos no desrrolldos en ALEPH y que sern dignos de inluirse son los heps de pioniD ls fmilis de roles dedidos sistems de rhivo y squed en memori seundri @f+ y derivdosA y los roles qudtreesF in este texto se pel l lenguje de modeldo wv pr filitr l ompresin de reliones entre ojetosF greo sinermente que wv tiene muho vlor pr omprender sistems omplejosD y desrrolldosD y un poo menos de vlorD unque preileD pr diserlosF ero en lo que te este texto y sus ursos derivdosD no es de trsendente utiliddF

ix

Deudas
e ul se l orD st se irunsrie gris y pr un ulturF v primer deudD puesD que ulquier individuo dquiere on un or es hi su ulturD l ul le entreg el trsfondo irunstnilD en onoimientos y sentimientosD que posiilitn e inspirn l or en uestinF in este mismo esprituD un vez entregd l orD otr dquirid es hi l ultur que reie y reonoe l orF rfrsendo yrteg y qssetD uno es uno y su irunstniD pero ulquier que st seD en ell siempre se enuentr l in)ueni rumdor del otroF we sientoD puesD en frn deud hi quienes siento que deo lo que soy yD en lo prtiulr de este textoD hi quellos que inidieron muy diretmente en su elorinF tor frvoD grlos xvD tun vus ghves y tun grlos rgs fueron mis primeros dispulos en est y el re de sistems distriuidosF tor instrument l primer versin de l lse LinearHashTable<Key> presentd en SFIFU @gF RIPAF grlos instrument l primer versin de un sistem omuniionl de envergdur sustentdo en el uso de ALEPHY el sistem n es opertivo hoy en dF tun grlos instrument los roles ev hildos y on rngosD los ulesD si ien no estn presentes en este textoD su instrumentin yud mejorr y depurr l lse Avl_Tree<Key>F endrs eri fue un usurio intensivo de ALEPH durnte de su tesis de mestrD lo ul me permiti ver spetos que luego inidieron en extensiones y mejors de l ilioteF veonrdo igD fldimir gontrers y grlos eost diseron y progrmron treepicD preursor de btreepicD un progrm pr diujr los roles inrios de este liroF tos frito esrii xtreepicD preursor de ntreepicD usdo pr diujr roles y roresenis generlesF torge edondo y oms vpez hiieron ls primers prues de desempeo sore los diversos roles inrios de squedF tess nhez hizo prte de l implntin pril de l iliote estndr C++ jo ALEPHF in prues de desempeo trdiionlesD l iliote estndr jo ALEPH es de mejor desempeo que l de qxF tun puentes instrument prte de y depur l lse genri de rol Tree_Node F yrlndo iu y elejndro wuji enontrron errores importntes en los roles y grfosD s omo plnteron sugerenis muy preiles sore el estilo de implntinF in l onfein de este texto se hn empledo entermente progrms liresX A v i IHTD i ITWD nowebD fIBi PPD gnu make QHD imake VPD gnuplot TID R IRTD Maxima IPID Xfig IVSD dia QTD Umbrello IUHD doxygen QVD bcpp IUD graphviz SVD RPD RQD entre otrosF iste texto y los progrms fueron editdos on gnu Emacs RRF vos progrms fueron mnejdos on todos los utilitrios GNU THF tun eevedoD profesor de l pultd de rumniddes de l niversidd de vos endesD me supervis los omentrios etimolgios en ltn y griegoF vus niguD orretor del gonsejo de uliiones de l niversidd de vos enE desD se h tomdo muy gentilmente su deer de revisr onienzudmente este textoF e ese tenorD deo expresrle mi grtitud por sus numeross y sorprendentes orreiones y ensenzsF elguns veesD l oservr lgunos gestos y titudes en dispulos me pree notrles lguns de mis ensenzsD lo ul evo l lejn posiilidd de mi improntF ero ese

PREFACIO

tenor deo lrr que soy yoD ms ienD quien port sus leiones yD por tntoD quien les expres grtitudF wis mdsimos pdresD xelly y edelisD hn ontriuido lo que me triuir omo un sensiilidd prtiulr hi l tenologF wi mdre ley y orrigi entermente este trsritoD s omo ellosD otror mi doleseniD me enseron esriir un pooF re oservdo que si todo utor de liro texto tnio expres grdeimientos su fmili @esposo@A e hijo@A@sAAF in el trnsurso de est ediin me pert de que ello prolemente oedez que ellosD en mi so on desrd e irresponsle negligeniD uno les olvidF or rzones muy ntimsD pr nd tnisD no puedo medir ni expresr mo y unto soy gris mi esposD wgdielD pero s puedo lmr que no ser nd sin ellF e pues on y hi ellD por su mor y su perdnD mi myor y prinipl deud . . . y grtitudF

ndice
1 Abstraccin de datos 1

IFI

IFP

IFQ

IFR

IFS IFT
2

ispei(iones de dtos F F F F F F F F F F F F F IFIFI ipo strto de dto F F F F F F F F F F F IFIFP xoin de lse de ojeto F F F F F F F F F IFIFQ vo sujetivo de un ojeto F F F F F F F F F IFIFR n ejemplo de eh F F F F F F F F F F F F IFIFS il lenguje wv F F F F F F F F F F F F F F rereni F F F F F F F F F F F F F F F F F F F F F F F IFPFI ipos de hereni F F F F F F F F F F F F F IFPFP wultihereni F F F F F F F F F F F F F F F F IFPFQ olimor(smo F F F F F F F F F F F F F F F F il prolem fundmentl de estruturs de dtos IFQFI gomprin generl entre lves F F F F F IFQFP yperiones pr onjuntos ordenles F F IFQFQ girunstnis del prolem fundmentl IFQFR resentiones del prolem fundmentl hiseo de dtos y striones F F F F F F F F F F IFRFI ipos de strin F F F F F F F F F F F F IFRFP il prinipio (nEE(n F F F F F F F F F F F F IFRFQ snduin y deduin F F F F F F F F F F F IFRFR yultmiento de informin F F F F F F F xots iliogr(s F F F F F F F F F F F F F F F F F ijeriios F F F F F F F F F F F F F F F F F F F F F F erreglos F F F F F F F F F F F F F F F F F F PFIFI yperiones sis on erreglos PFIFP wnejo de memori pr rreglos PFIFQ erreglos dinmios F F F F F F F F PFIFR il eh DynArray<T> F F F F F F PFIFS erreglos de its F F F F F F F F F erreglos multidimensionles F F F F F F F sterdores F F F F F F F F F F F F F F F F F vists enlzds F F F F F F F F F F F F F F PFRFI vists enlzds y el prinipio (n PFRFP il eh Slink @enle simpleA F F F F F F F F F F F F F F F F F F F F F F F F F F F F F (n F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

Q R S T U IH II IP IP IQ IU IW IW IW PH PH PI PP PP PQ PR PS
27

Secuencias

PFI

PFP PFQ PFR

PV PW QP QR QR SQ SV SW TI TR TS

xi

xii

NDICE

PFS

PFT

PFU PFV PFW


3

PFRFQ il eh Snode<T> @nodo simpleA F F F F F F F F F F F F F F F F F F PFRFR il eh Slist<T> @list simplemente enlzdA F F F F F F F F F PFRFS sterdor de Slist<T> F F F F F F F F F F F F F F F F F F F F F F F F PFRFT il eh DynSlist<T> F F F F F F F F F F F F F F F F F F F F F F F F PFRFU il eh Dlink @enle doleA F F F F F F F F F F F F F F F F F F F F PFRFV il eh Dnode<T> @nodo doleA F F F F F F F F F F F F F F F F F F PFRFW il eh DynDlist<T> F F F F F F F F F F F F F F F F F F F F F F F F PFRFIH epliinX ritmti de polinomios F F F F F F F F F F F F F F F F ils F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F PFSFI epresentiones de un pil en memori F F F F F F F F F F F F F PFSFP il eh ArrayStack<T> @pil vetorizdA F F F F F F F F F F F F PFSFQ il eh ListStack<T> @pil on lists enlzdsA F F F F F F F F PFSFR il eh DynListStack<T> F F F F F F F F F F F F F F F F F F F F F PFSFS epliinX un evludor de expresiones ritmtis in(js F F F PFSFT ilsD llmds proedimientos y reursin F F F F F F F F F F F gols F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F PFTFI rintes de ls ols F F F F F F F F F F F F F F F F F F F F F F F F PFTFP epliiones de ls ols F F F F F F F F F F F F F F F F F F F F F F F PFTFQ epresentiones en memori de ls ols F F F F F F F F F F F F F PFTFR il eh ArrayQueue<T> @ol vetorizdA F F F F F F F F F F F F PFTFS il eh ListQueue<T> @ol on lists enlzdsA F F F F F F F F PFTFT il eh DynListQueue<T> @ol dinmi on lists enlzdsA F istruturs de dtos ominds E wultilists F F F F F F F F F F F F F F F xots iliogr(s F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F ijeriios F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F enlisis de lgoritmos F F F F F F F F F F F F F F F F F F F F QFIFI nidd o pso de ejeuin F F F F F F F F F F F F F QFIFP elrtori sore los mtodos de ordenmiento F F QFIFQ yrdenmiento por selein F F F F F F F F F F F F F QFIFR fsqued seuenil F F F F F F F F F F F F F F F F F QFIFS il prolem fundmentl y los rreglos dinmios QFIFT fsqued de extremos F F F F F F F F F F F F F F F F QFIFU xotin O F F F F F F F F F F F F F F F F F F F F F F QFIFV yrdenmiento por inserin F F F F F F F F F F F F F QFIFW fsqued inri F F F F F F F F F F F F F F F F F F F QFIFIH irrores de l notin O F F F F F F F F F F F F F F F QFIFII ipos de nlisis F F F F F F F F F F F F F F F F F F F elgoritmos dividirGominr F F F F F F F F F F F F F F F F QFPFI yrdenmiento por mezl F F F F F F F F F F F F F F QFPFP yrdenmiento rpido @uiksortA F F F F F F F F F F enlisis mortizdo F F F F F F F F F F F F F F F F F F F F F QFQFI enlisis potenil F F F F F F F F F F F F F F F F F F F QFQFP enlisis ontle F F F F F F F F F F F F F F F F F F F QFQFQ elein del potenil o rditos F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

TV TW UH UI UP VQ VR WI WV WW IHI IHQ IHS IHT IIP IPP IPQ IPQ IPQ IPR IPV IQH IQI IQQ IQS
145

Crtica de algoritmos

QFI

QFP

QFQ

IRU IRV ISH ISH ISR ISS IST ISU ITP ITS ITT ITU ITV ITW IUQ IVU IVW IWI IWP

NDICE

xiii

QFR

QFS

QFT QFU
4

gorretitud de lgoritmos F F F F F F F F F F F QFRFI lntemiento de un demostrin de QFRFP ipos de errores F F F F F F F F F F F F QFRFQ revenin y detein de errores F F F i(i y e(ieni F F F F F F F F F F F F F F F QFSFI v regl del VHEPH F F F F F F F F F F F QFSFP gundo tr l e(ienic F F F F F QFSFQ wners de mejorr l e(ieni F F F QFSFR er(lje @pro(lingA F F F F F F F F F F F QFSFS volidd de refereni F F F F F F F F QFSFT iempo de desrrollo F F F F F F F F F F xots iliogr(s F F F F F F F F F F F F F F F ijeriios F F F F F F F F F F F F F F F F F F F F

F F F F F F F orretitud F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F

F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

IWQ IWQ IWR IWR PIH PIP PIP PIQ PIR PIR PIS PIT PIU
223

rboles

RFI RFP

RFQ

RFR

RFS

goneptos sios F F F F F F F F F F F F F F F F F F F F F F F F epresentiones de un rol F F F F F F F F F F F F F F F F F F RFPFI gonjuntos niddos F F F F F F F F F F F F F F F F F F F RFPFP euenis prentizds F F F F F F F F F F F F F F F F F RFPFQ sndentin F F F F F F F F F F F F F F F F F F F F F F F F RFPFR xotin de hewy F F F F F F F F F F F F F F F F F F F F epresentiones de roles en memori F F F F F F F F F F F F RFQFI vists enlzds F F F F F F F F F F F F F F F F F F F F F RFQFP erreglos F F F F F F F F F F F F F F F F F F F F F F F F F F roles inrios F F F F F F F F F F F F F F F F F F F F F F F F F RFRFI epresentin en memori de un rol inrio F F F F RFRFP eorridos sore roles inrios F F F F F F F F F F F F RFRFQ n eh genrio pr roles inrios F F F F F F F F RFRFR gontenedor de funiones sore roles inrios F F F F RFRFS eorridos reursivos F F F F F F F F F F F F F F F F F F F RFRFT eorridos no reursivos F F F F F F F F F F F F F F F F F RFRFU glulo de l rdinlidd F F F F F F F F F F F F F F F F RFRFV glulo de l ltur F F F F F F F F F F F F F F F F F F F RFRFW gopi de roles inrios F F F F F F F F F F F F F F F F RFRFIH hestruin de roles inrios F F F F F F F F F F F F F RFRFII gomprin de roles inrios F F F F F F F F F F F F RFRFIP eorrido por niveles F F F F F F F F F F F F F F F F F F F RFRFIQ gonstruin de roles inrios prtir de reorridos RFRFIR gonjunto de nodos en un nivel F F F F F F F F F F F F F RFRFIS rildo de roles inrios F F F F F F F F F F F F F F F F RFRFIT eorridos pseudohildos F F F F F F F F F F F F F F F F RFRFIU gorrespondeni entre roles inrios y mErios F F F n eh genrio pr roles F F F F F F F F F F F F F F F F F RFSFI yservdores de Tree_Node F F F F F F F F F F F F F F RFSFP wodi(dores de Tree_Node F F F F F F F F F F F F F F RFSFQ yservdores de roles F F F F F F F F F F F F F F F F F

PPT PPV PPV PPW PQH PQI PQI PQI PQP PQQ PQR PQR PQV PRP PRQ PRT PRW PRW PSH PSH PSH PSI PSQ PSR PSS PSV PTH PTR PTT PTU PTW

xiv

NDICE

RFT

RFU

RFV

RFW

RFIH RFII

RFIP RFIQ

RFSFR eorridos sore Tree_Node F F F F F F F F F F F F F RFSFS hestruin de Tree_Node F F F F F F F F F F F F F F RFSFT fsqued por nmero de hewy F F F F F F F F F F F RFSFU glulo del nmero de hewy F F F F F F F F F F F F F RFSFV gorrespondeni entre Tree_Node y roles inrios elgunos oneptos mtemtios de los roles F F F F F F F F RFTFI eltur de un rol F F F F F F F F F F F F F F F F F F F RFTFP vongitud del mino internoGexterno F F F F F F F F F RFTFQ roles ompletos F F F F F F F F F F F F F F F F F F F reps F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F RFUFI snserin en un hep F F F F F F F F F F F F F F F F F F RFUFP iliminin en un hep F F F F F F F F F F F F F F F F RFUFQ gols de prioridd F F F F F F F F F F F F F F F F F F F RFUFR repsort F F F F F F F F F F F F F F F F F F F F F F F F RFUFS epliiones de los heps F F F F F F F F F F F F F F F RFUFT il eh BinHeap<Key> F F F F F F F F F F F F F F F F inumerin y digos de roles F F F F F F F F F F F F F F RFVFI xmeros de gtln F F F F F F F F F F F F F F F F F F RFVFP elmenmiento de roles inrios F F F F F F F F F roles inrios de squed F F F F F F F F F F F F F F F F F RFWFI fsqued en un eff F F F F F F F F F F F F F F F F F RFWFP il eh BinTree<Key> F F F F F F F F F F F F F F F F RFWFQ snserin en un eff F F F F F F F F F F F F F F F F F F RFWFR rtiin de un eff por lve @splitA F F F F F F F F RFWFS nin exlusiv de eff @join exlusivoA F F F F F F F RFWFT iliminin en un eff F F F F F F F F F F F F F F F F RFWFU snserin en rz de un eff F F F F F F F F F F F F F RFWFV nin de eff @joinA F F F F F F F F F F F F F F F F F F RFWFW enlisis de los roles inrios de squed F F F F F il eh DynMapTree F F F F F F F F F F F F F F F F F F F F F F ixtensiones los roles inrios F F F F F F F F F F F F F F F RFIIFI elein por posiin F F F F F F F F F F F F F F F F F RFIIFP glulo de l posiin in(j F F F F F F F F F F F F F F RFIIFQ snserin por lve en rol inrio extendido F F F F RFIIFR rtiin por lve F F F F F F F F F F F F F F F F F F F RFIIFS snserin en rz F F F F F F F F F F F F F F F F F F F F RFIIFT rtiin por posiin F F F F F F F F F F F F F F F F F RFIIFU snserin por posiin F F F F F F F F F F F F F F F F F RFIIFV nin exlusiv de roles extendidos F F F F F F F F RFIIFW iliminin por lve en roles extendidos F F F F F RFIIFIH iliminin por posiin en roles extendidos F F F RFIIFII hesempeo de ls extensiones F F F F F F F F F F F F F otin de roles inrios F F F F F F F F F F F F F F F F F F RFIPFI otiones en roles inrios extendidos F F F F F F gdigos de ru'mn F F F F F F F F F F F F F F F F F F F F F F RFIQFI n eh pr roles de digo F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

PUH PUH PUI PUP PUQ PUS PUS PUU PVH PVP PVR PVS PVV PVW PWI PWQ QHP QHU QII QIQ QIS QIW QPH QPI QPQ QPR QPT QPU QPW QQP QQS QQU QQV QQV QQW QRH QRH QRI QRP QRP QRQ QRQ QRR QRS QRS QRU

NDICE

xv

RFIQFP heodi(in F F F F F RFIQFQ elgoritmo de ru'mn F RFIQFR he(niin de smolos y RFIQFS godi(in de texto F F RFIQFT yptimin de ru'mn RFIR roles esttios ptimos F F F RFIRFI yjetivo F F F F F F F F F RFIRFP smplntin F F F F F F RFIS xots iliogr(s F F F F F F F RFIT ijeriios F F F F F F F F F F F F
5 Tablas hash

F F F F F F F F F F F F F F freuenis F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F

F F F F F F F F F F

F F F F F F F F F F

F F F F F F F F F F

F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

QRW QSH QSP QSQ QSS QSV QTH QTH QTQ QTS
379

SFI

SFP

SFQ

SFR SFS
6

wnejo de olisiones F F F F F F F F F F F F F F F F F F SFIFI il prolem del umpleos F F F F F F F F F F SFIFP istrtegis de mnejo de olisiones F F F F F F SFIFQ indenmiento F F F F F F F F F F F F F F F F SFIFR hireionmiento ierto F F F F F F F F F F F SFIFS ejuste de dimensin en un tl hsh F F SFIFT il eh DynLhashTable @uets dinmisA SFIFU ls hsh lineles F F F F F F F F F F F F F F puniones hsh F F F F F F F F F F F F F F F F F F F F F SFPFI snterfz l funin hsh F F F F F F F F F F F SFPFP rolgur de dispersin F F F F F F F F F F F F F SFPFQ legdo o doldo de lve F F F F F F F F F F SFPFR reurstis de dispersin F F F F F F F F F F F SFPFS hispersin de dens de rteres F F F F F SFPFT hispersin universl F F F F F F F F F F F F F F SFPFU hispersin perfet F F F F F F F F F F F F F F F ytros usos de ls tls hsh y de l dispersin F F F SFQFI sdenti(in de dens F F F F F F F F F F F SFQFP upertrz F F F F F F F F F F F F F F F F F F F SFQFQ ghe @el eh Hash_Cache A F F F F F F F F F xots iliogr(s F F F F F F F F F F F F F F F F F F F ijeriios F F F F F F F F F F F F F F F F F F F F F F F F iquilirio de roles F F F F F F F F F F F F F roles letorizdos F F F F F F F F F F F F F TFPFI il eh Rand_Tree<Key> F F F F F F TFPFP enlisis de los roles letorizdos reps F F F F F F F F F F F F F F F F F F F F F TFQFI il eh Treap<Key> F F F F F F F F TFQFP snserin en un trep F F F F F F F F TFQFQ iliminin en trep F F F F F F F F F TFQFR enlisis de los treps F F F F F F F F F TFQFS rioriddes implits F F F F F F F F roles ev F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

QVI QVI QVP QVQ QWQ RHW RIH RIP RPQ RPQ RPQ RPR RPR RPW RQH RQI RQI RQI RQR RQS RRS RRT
451

rboles de bsqueda equilibrados

TFI TFP

TFQ

TFR

RSP RSS RSS RTH RTR RTS RTU RTV RUH RUI RUI

xvi

NDICE

TFS

TFT

TFU TFV TFW


7

TFRFI il eh Avl_Tree<Key> F F F F TFRFP enlisis de los roles ev F F F roles rojoEnegro F F F F F F F F F F F F TFSFI il eh Rb_Tree<Key> F F F F F TFSFP enlisis de los roles rojoEnegro roles sply F F F F F F F F F F F F F F F TFTFI il eh Splay_Tree<Key> F F F TFTFP enlisis de los roles sply F F F gonlusin F F F F F F F F F F F F F F F F xots iliogr(s F F F F F F F F F F F F ijeriios F F F F F F F F F F F F F F F F F

F F F F F F F F F F F

F F F F F F F F F F F

F F F F F F F F F F F

F F F F F F F F F F F

F F F F F F F F F F F

F F F F F F F F F F F

F F F F F F F F F F F

F F F F F F F F F F F

F F F F F F F F F F F

F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

RUP RVQ RWH RWI SHQ SHU SHW SIQ SIW SPQ SPS
535

Grafos

UFI UFP

UFQ

UFR UFS

UFT

pundmentos F F F F F F F F F F F F F F F F F F F F F F F F F istruturs de dtos pr representr grfos F F F F F F F F UFPFI wtries de dyeni F F F F F F F F F F F F F F F UFPFP vists de dyeni F F F F F F F F F F F F F F F F F n eh pr grfos @List_GraphA F F F F F F F F F F F F F UFQFI qrfos F F F F F F F F F F F F F F F F F F F F F F F F F UFQFP higrfos @List_DigraphA F F F F F F F F F F F F F F UFQFQ xodos F F F F F F F F F F F F F F F F F F F F F F F F F UFQFR eros F F F F F F F F F F F F F F F F F F F F F F F F F UFQFS etriutos de ontrol de nodos y ros F F F F F F F UFQFT wros de eso nodos y ros F F F F F F F F F F UFQFU gonstruin y destruin de List_Graph F F F F UFQFV yperiones genris sore nodos F F F F F F F F F UFQFW yperiones genris sore ros F F F F F F F F F UFQFIH smplntin de List_Graph F F F F F F F F F F F F eh mino sore un grfo @Path<GT>A F F F F F F F F F F eorridos sore grfos F F F F F F F F F F F F F F F F F F F F UFSFI sterdores (ltro F F F F F F F F F F F F F F F F F F F F UFSFP eorrido en profundidd F F F F F F F F F F F F F F UFSFQ gonetividd entre grfos F F F F F F F F F F F F F F UFSFR eorrido en mplitud F F F F F F F F F F F F F F F F UFSFS rue de ilos F F F F F F F F F F F F F F F F F F F UFSFT rue de iliidd F F F F F F F F F F F F F F F F UFSFU fsqued de minos por profundidd F F F F F F F UFSFV fsqued de minos por mplitud F F F F F F F F F UFSFW roles rdores de profundidd F F F F F F F F UFSFIH roles rdores de mplitud F F F F F F F F F F UFSFII roles rdores en rreglos F F F F F F F F F F F UFSFIP gonversin de un rol rdor un Tree_Node UFSFIQ gomponentes inonexos de un grfo F F F F F F F F UFSFIR untos de rtiulin de un grfo F F F F F F F F F UFSFIS gomponentes onexos de los puntos de orte F F F wtries de dyeni F F F F F F F F F F F F F F F F F F F F

SQU SRP SRP SRR SRS SRT SRU SRU SSI SSS STI STP STQ STQ STR SUV SVI SVP SVS SVW SVW SWP SWQ SWT THH THQ THS THT THV TIH TIQ TPP TPV

NDICE

xvii

UFTFI il eh Ady_Mat F F F F F F F F F F F F F F F F F F F UFTFP il eh Bit_Mat_Graph<GT> F F F F F F F F F F F F UFTFQ elgoritmo de rshll F F F F F F F F F F F F F F F F UFU qrfos dirigidos F F F F F F F F F F F F F F F F F F F F F F F F UFUFI gonetividd entre digrfos F F F F F F F F F F F F F UFUFP snversin de un digrfo F F F F F F F F F F F F F F F UFUFQ gomponentes fuertemente onexos de un digrfo F UFUFR rue de iliidd F F F F F F F F F F F F F F F F UFUFS glulo de ilos en un digrfo F F F F F F F F F F F UFUFT rue de onetividd F F F F F F F F F F F F F F F UFUFU higrfos lios @heqA F F F F F F F F F F F F F F F UFUFV lni(in de tres F F F F F F F F F F F F F F F F UFUFW yrdenmiento topolgio F F F F F F F F F F F F F F UFV roles rdores mnimos F F F F F F F F F F F F F F F F UFVFI wnejo de los pesos del grfo F F F F F F F F F F F F UFVFP elgoritmo de uruskl F F F F F F F F F F F F F F F F UFVFQ elgoritmo de rim F F F F F F F F F F F F F F F F F F UFW gminos mnimos F F F F F F F F F F F F F F F F F F F F F F F UFWFI elgoritmo de hijkstr F F F F F F F F F F F F F F F F UFWFP elgoritmo de ploydErshll F F F F F F F F F F F F UFWFQ elgoritmo de fellmnEpord F F F F F F F F F F F F F UFWFR hisusin sore los lgoritmos de minos mnimos UFIH edes de )ujo F F F F F F F F F F F F F F F F F F F F F F F F F UFIHFI he(niiones y propieddes fundmentles F F F F F UFIHFP il eh Net_Graph F F F F F F F F F F F F F F F F F F UFIHFQ wnejos de vrios fuentes o sumideros F F F F F F F UFIHFR yperiones topolgis sore un red pitd UFIHFS gortes de red F F F F F F F F F F F F F F F F F F F F F UFIHFT plujo mximoGorte mnimo F F F F F F F F F F F F F UFIHFU gminos de umento F F F F F F F F F F F F F F F F F UFIHFV glulo de l red residul F F F F F F F F F F F F F F UFIHFW glulo de minos de umento F F F F F F F F F F F UFIHFIH snremento del )ujo por un mino de umento F F UFIHFII il lgoritmo de pordEpulkerson F F F F F F F F F F F UFIHFIP il lgoritmo de idmondsEurp F F F F F F F F F F F UFIHFIQ elgoritmos de empuje y pre)ujo F F F F F F F F F F UFIHFIR glulo del orte mnimo F F F F F F F F F F F F F F UFIHFIS eumento o disminuin de )ujo de un red F F F F UFII eduiones l prolem del )ujo mximo F F F F F F F F F UFIIFI plujo mximo en redes no dirigids F F F F F F F F F UFIIFP gpiddes en nodos F F F F F F F F F F F F F F F F UFIIFQ plujo ftile F F F F F F F F F F F F F F F F F F F F F UFIIFR wximo emprejmiento iprtido F F F F F F F F F UFIIFS giruliones F F F F F F F F F F F F F F F F F F F F F UFIIFT gonetividd de grfos F F F F F F F F F F F F F F F F UFIIFU glulo de Kv (e) F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

TPW TQQ TQS TQU TQV TQV TQW TRV TSH TSP TSQ TSR TSS TTH TTH TTI TTT TUR TUS TVS TWP UHU UHV UHV UIH UII UIQ UIT UIV UPH UPQ UPS UPS UPT UQI UQT UTT UTW UUQ UUQ UUR UUR UUU UVQ UVS UWP

xviii

NDICE

UFIP plujos de oste mnimo F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F UFIPFI il eh Net_Max_Flow_Min_Cost F F F F F F F F F F F F F F F F F F F UFIPFP elgoritmos de mximo )ujo on oste mnimo medinte eliminin de ilos F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F UFIPFQ enlisis de los lgoritmos sdos en eliminin de ilos negtivos UFIPFR rolems que se reduen enunidos de )ujo mximo oste mnimo F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F UFIQ rogrmin linel F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F UFIQFI porm estndr de un progrm linel F F F F F F F F F F F F F F F F F UFIQFP n ejemplo de estndrizin F F F F F F F F F F F F F F F F F F F F F UFIQFQ porm holgd de un progrm linel F F F F F F F F F F F F F F F F UFIQFR il mtodo simplex F F F F F F F F F F F F F F F F F F F F F F F F F F F F UFIQFS gonlusin sore l progrmin linel F F F F F F F F F F F F F F F F UFIR edes de )ujo y progrmin linel F F F F F F F F F F F F F F F F F F F F F F UFIRFI gonversin de un red pitd de ostes un progrm linel F F UFIRFP edes generlizds F F F F F F F F F F F F F F F F F F F F F F F F F F F UFIRFQ gpiddes otds F F F F F F F F F F F F F F F F F F F F F F F F F F UFIRFR edes on restriiones lterles F F F F F F F F F F F F F F F F F F F F UFIRFS edes multi)ujo F F F F F F F F F F F F F F F F F F F F F F F F F F F F F UFIRFT edes de proesmiento F F F F F F F F F F F F F F F F F F F F F F F F F UFIRFU gonlusin sore el prolem del )ujo mximo oste mnimo F F F UFIS xots iliogr(s F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F UFIT ijeriios F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F
ndice de identicadores

UWP UWT UWV VHP VHP VIH VIP VIQ VIR VIS VPP VPP VPP VPQ VPR VPR VPS VPS VPV VPW VQI
865

Abstraccin de datos
iste texto onierne l diseo e implntin de estruturs de dtos y lgoritmos que instrumenten soluiones prolems medinte progrms de omputdorF n lgoritmo es un seueni (nit de instruiones que omete l onseuin de un (nF smos lgoritmos en diversos ontextos de l vidY por ejemploD undo preprmos un plto de omid segn lgun reetF v ultur nos h inuldo lgunos lgoritmosD ulturlesD no nturlesD pr desenvolvernos soilmenteY por ejemplosD el lgoritmo de onduir un utomvil o el lgoritmo pr ruzr un lleF in mos ejemplosD el (n que se plnte es rrir un sitioF egn unuth WUD el trmino lgoritmo proviene del nomre del nestrl mtemtio lEuhw rizm %D de l ersiD prte del tul srnD regin del plnet muy menzd de ser orrd del mpF he lEuhw rizm % tmin proviene l plr lgerD dominio desuierto por vez primer en el tul invdido y devstdo srkF r l onseuin de un (n se emplen mediosF in el so de un pltoD los medios que se utilizn son los instrumentos de oin e ingredientesY el oineroD quien puede interpretrse tmin omo un medioD onjugD en un orden espe(oD los ingredientes mediante los instrumentosF v seueni de ejeuinD o seD el lgoritmoD es fundmentl pr onseguir el plto en uestinF n lterin del orden rrer posilemente un lterin sore el sor del pltoF hurnte l preprin de un pltoD el oinero requiere periir y reordr l seueni de ejeuinF l requiereD por ejemploD sofrer lgunos lios ntes de mezlrlos on l rneF egn l experieni y l omplejiddD es posile que el oinero lleve nots que memorien el estdo de preprinY por ejemploD notr l hor en que omenz hornerF in todo momentoD on nots o sin ellsD el oinero requiere tener onsieni del estdo en el ul se ui l preprin respeto su reetF r eso se sirve de su memoriF in el so de un progrmD el omputdor funge de oineroD el ul ejeut (elmente ls reets que se le proporionnF il omputdor es entones un ejeutor que orgniz y us lgunos medios pr lnzr l soluin de lgn prolemD segn lgun reet llmd progrm y que reuerd estdos de lulos medinte un memoriF eprte del gD quien funge de oineroD el omputdor se vle de un medio fundE mentlX l memoriF he por sD l memori en ruto es un seueni de eros y unos uyo sentido lo imprte el progrmdor en form de dtosF gulquier progrm que opere en un omputdor puede dividirse en dos prtesX l seueni de instruiones de ejeuin y los dtosF vs instruiones son resultdo de quello que esriimos omo digo fuenteF in osionesD ls instruiones pueden geneE rrse durnte l ejeuin del progrmF vos dtos representn el estdo de lulo en I

1. Abstraccin de datos

lgn momento del tiempo de ejeuinF v plr dto proviene del ltn datum D prtiipio psdo de d o @drAF hto onnotD puesD lgo que fue ddo en el psdo y que nos interes reordrY ese es el sentido de que se memorizdoF in el so de l progrminD un dto reuerd un prte del estdo de ejeuin del progrmF il mnimo nivel de orgnizin de un dto es su tipo o clase F n tipo de dto de(ne un onjunto ompuesto por todos los vlores que puede dquirir un instni del dtoF n tipo de dto puede onformrse por vrios tipos de dtosF in este so lo tipi(mos de dto estruturdo o estrutur de dtosF in lgunos sosD los dtos pueden ser reursivos @reurrentes1 AY es deirD segn el tipo de dto se reurren s mismos o entre ellosF elgunos ejemplos en C++ podrn dr luz de este suntoF r representr nmeros enteros se utiliz el tipo de dto intD el ul indi que su vlor pertenee l onjunto ZF in este so no se die nd er de mo se represent el tipo int en l memori de un omputdorY ien pudier trtrse de 19D de 937 o de 2535301200456458802993406410049D entre in(nitos vlores posilesF r representr nmeros reles que perteneen RD usmos el tipo floatD ms inE teresnte que el nterior porque trslue prte de su implntin en l memori de un omputdor undo expresD medinte el nomre floatD que l representin del nmero es en punto )otnteD es deirD est estruturd en tres mpos de form similr l siguienteX
0 00001000 001011110010110001001010

Signo

Exponente

Parte fraccional

il sentido de est estrutur es her rpidmente sums medinte juste del expoE nente y de l prte frionlF eunque no onoemos el tmo de los mpos nterioresD el onoimiento de l estrutur y de l mner de mnipulrl nos lert sore el lere e inevitle error de redondeo que ourre undo trjmos on ritmti )otnteF r ilustrr un dto reurrente nos vldremos del tipo ilemento de seueni 2 D uy espei(in en C++ puede plnterse omo sigueX Elemento de secuencia 2 struct Elemento { int dato; Elemento * siguiente_elemento; }; ilemento de seueni 2 modeliz un elemento entero perteneiente un seueniF xotemos que el triuto siguiente_elemento se re(ere un struct Elemento e indi l direin en memori del siguiente elemento en l seueniF hiversos intereses iniden en el diseo de un estrutur de dtosF intre los ms tpios podemos destrX l omprensin y mnipulin del progrm por prte del progrmdorD el desempeo y l dptin un lgoritmo o onepto prtiulrF in el ejemplo del tipo float hy dos rterstis deisivsF v primer es que ls operiones
1
Segn su raz latina, el trmino recurrir la misma, pero basada en

reurs us,

re urr o,

connota volver, regresar. En ingls, la raz es En este texto se da preferencia a

que signica vuelta, retorno.

recursin en lugar de recurrencia.

1.1. Especicaciones de datos

ritmtis son muy rpidsF he hehoD siempre tomn tiempo onstnte e independiente del vlor prtiulr del dtoF v segund rtersti onierne l espioD es deirD d dto en punto )otnte siempre oup l mism ntidd de espioD uestin que no sueder si usrmos ritmti ritrriF r los tipos de dtos que mos de ejempli(r @int y floatA disponemos de un fondo ulturlD mtemtio y de progrmin que nos permite selrlos y omprenderE los sin neesidd de detllr minuiosmente en qu onsistenF emosD sin tener que indirlo explitmenteD que existen ls operiones ritmtis trdiionles de sumD restD produto y divisinD s omo qu hen y ules son sus resultdosF

1.1 Especicaciones de datos


upongmos que un oinero onsumdo dese esriir un de sus reets pr divulgrl entre otrosF in est situinD segn el orpus ognitivo de su experieniD el oinero sume que sus letores poseen un lenguje omn que les filitr entender ls instruE iones de su reetF or ejemploD se requiere que el oinero y sus letores tengn el mismo onepto de lo que es un ollF in el mro de ese lenguje omnD l reet dee ser preisY no dee ontener mE igeddes que loqueen l ejeutnteF edemsD dee ser omplet pr que el ejeutnte prepre plenmente el plto en uestinF in l perepin del prendiz de progrmin existe un difereni esenil entre elE orr un plto de oin y ejeutr un progrmF in oin se oper sore oss onrets pr l perepin humnF in progrminD el omputdor oper sore dtos onretos en su memoriD pero strtos pr nuestr perepinF reguntmosnosX existe un nmerocD existe un rregloc in nuestr menteD un rreglo onstituye un strin que no se pt on nuestr perepin sensorilF in el omputdor no tiene sentido l strin rregloD pues ste no entiende lo que es un nmero o rregloF in el so de l progrminD s omo en otros dominios derivdos de l mtemtiD un nmero o un rreglo son oneptos strtos que onformn un lenguje omn pr omunirlos y permitir l onstruin de ms oneptosF intre progrmdoresD s omo en el resto de ls prtisD es muy importnte disponer de un orpus omnD sore l mner de strerD que permit l omuniin de mner homogneF gonsideremos un situin en l que deseemos disponer de un nuevo tipo de dtoF lntemosnos dos lses de pregunts en el siguiente ordenX IF IX gul es su (nc oD diho de otr mnerD pr qu puede servirc PF PX gmo se puede de(nircD qu represent el dtoc v primer pregunt nos indi l lse de prolem pr el ul el tipo de dto se irunsrie omo prte de l soluinF i esto no est de(nidoD entones no tiene ningn sentido onsiderr el tipo de dtoF v segund pregunt nos expres qu es el tipo de dtoD pero ese qu-es depende del pr qu ste se usF i tenemos lro el (nD entones un dto se de(ne segn ls operiones permisiles y sus resultdosF or ejemploD si nos enontrmos en un situin en l ul requirmos lulo de vrile omplejD entones es esenil tener un tipo de dto nmero omplejoF vvmese

1. Abstraccin de datos

gomplejo 5 este tipo y de(nmoslo omo un sum cr + ci i | cr , ci RD donde el oe(iente cr es llmdo prte rel yD ci prte imginriY este ltimo represent un frin del nmero imgindo 1 F el igul que on los tipos nterioresD est de(niin sume que el letor uent on un ultur mtemti en l ul tienen sentido los nmeros omplejosF gomo operiones estleemos l onsult de l prte rel e imginri respetivE menteF
1.1.1 Tipo abstracto de dato

remos diho que un tipo de dto represent un onjuntoF fjo l presunin de un se ulturl mtemtiD l ul omprende l onepto de onjuntoD el tipo gomplejo 5 se de(ne en torno l noin mtemti de nmero omplejo que le rind su omprensinF fjo ese lengujeD el ejemplo nterior stisfe ls pregunts I y P respetivmenteF i no dispusirmos del orpus mtemtio de nmero omplejoD entones nos ser muy difil interpretr el sentido del tipo gomplejo 5 F v mtemtiD siempre y undo se hy psdo por su entrenmientoD de(ne un orE pus ognitivoD stnte strto por iertoD que nos permite de(nir el nuevo tipo de dtoF i nos remitimos l de(niin de tipo de dtoD entonesD segn l mtemtiD de(nir un tipo de dto estri en de(nir un onjunto de ls dos mners que tiene l mtemtiX por extensin o por omprensinF he(nir un onjunto por extensin es muy ojetivoD pero tmin muy rduo yD en muhos sosD imposile undo el onjunto es in(nitoD por ejemploF in el so de l progrminD un tipo de dto se de(neD prdjimenteD por omprensin medinte un form metodolgi denomind tipo strto de dto o ehD l ulD en l versin de este textoD onst de ls siguientes prtesX IF n desripin del (n pr el ul se destin el tipo de dtoF PF n onjunto de xioms y preondiiones que de(nen el dominio del tipo2 F QF n interfz de(nid por tods ls operiones posiles sore el eh en l ulD por d operinD se estlezn dos tipos de espei(ionesX
Especicacin sintctica:

nomre de l operinD tipo de resultdo y nomres y desripin de lo que he l operin sore el estdo

tipos de los prmetrosF


Especicacin semntica:

del ehF in est prte puede ser til indir xiomsD preondiiones y postondiionesF isenil destr queD onoidoD entendido y eptdo el (nD dquieren ompleto senE tido ls espei(iones sintti y semnti de un ehF in este texto nos vldremos del onepto de lse de ojeto pr llevr o prte de l espei(inF
2
Dominio en el sentido de una funcin matemtica.

1.1. Especicaciones de datos

1.1.2

Nocin de clase de objeto

v plr ojeto proviene del ltn ojetum @oEjetum u oEietumAD omposiin de oD que signi( sore el @lAD frente D y jetumD que es el prtiipio psdo de i ereD timo direto de yer y que signi( tenderD ehrF es puesD ojetum @oietumA es lo que ye l frenteD lo que es visile de un osD su r externF in similr ontrsteD l plr sujetoD tmin proveniente del ltn sujetumD uyo pre(jo ltino su sel dejoD signi( lo que est dejo de l osD oultoD que le es internoY diho de otro modoD invisile en prieni3 F in progrminD s omo en otrs ingeniersD lo ojetivoD o seD l r visileD se denomin interfzY de interEfzY es deirD lo que est entre l rY lo que se ofree l exteriorF in el ontexto de l progrminD un lse de ojetoD o simplemente lseD es un representin ojetiv de un tipo strto de dto que de(ne su espei(in sinttiF or ojetiv pretendemos deir que slo nos referimos ls prtes externsD visilesD que tendr un ojeto perteneiente un lse ddF in el so de un tipo de dtoD ls prtes visiles ls onformn el nomre del tipoD los nomres de ls operionesD los nomres de los prmetrosD los tipos de dto de los prmetros y los resultdos de ls operionesD es deirD su espei(in sinttiF r stisfer l ojetividd de l espei(in sintti es neesrio ordr un lenguje omn entre los progrmdoresD pues de lo ontrrio ser muy difil interpretr l interfzF n utomvilD por ejemploD tiene un interfz de uso onsistenteD entre otrs ossD de los pedlesD el volnte y el tleroF r poder onduirlo se requiere que el ondutor est entrendo en l utilizin de es interfzF hel mismo modoD pr que un progrmdor omprend un espei(in sinttiD ste dee entender el lenguje en que se espei( l lse o ehF in el so de este texto hremos espei(iones sinttis de eh en el lenguje C++ o en digrms de lses wvF in C++ D el ejemplo del eh gomplejo 5 podr modelizrse del siguiente modoX Complejo 5 struct Complejo { Complejo(float r, float i); Complejo(const Complejo & c); float & obtenga_parte_real(); float & obtenga_parte_imag(); }; ist de(niin estlee ojetivmente l espei(in sintti del eh gomplejo 5 D l ulD und l lenguje y l orpus mtemtio ulturl de l noin de nmero omE plejoD omplet l espei(in sintti del ehF u suedi on l espei(in semnticD est omplet l espei(inc i sumimos que el letor de l espei(in del eh gomplejo 5 onoe su mtemti inherenteD entones los nomres de ls operiones permiten omprender diretmente qu he d operin sin neesidd de expliitrloF ixiste lgun dud sore lo que he l operin obtenga_parte_real()c v respuest dependeD entre otros ftoresD del grdo de entendimiento mtemtio que teng el uestionnteF i el letor no onoe l noin
3
Estas aclaratorias etimolgicas fueron descubiertas en [56].

1. Abstraccin de datos

de nmero omplejoD entones se requerir un espei(in semnti que le imprt lo que es un omplejoF vo ojetivo posiilit un uerdo omn entre diferentes persons er de l interE pretin de un tipo de dtoF r que este uerdo ourrD es neesrio que ls persons en uestin ven o interpreten homognemente l ojetoF gonseuentementeD l interE pretin de un eh depende del grdo en que sus interesdos omprtn el lenguje on que se exprese su espei(inF
1.1.3 Lo subjetivo de un objeto

i trtmos un dto en trminos ojetivosD entonesD en qu onsiste trtrlo en trminos sujetivosc qrosso modoD l respuest es que l sujetividd de un eh se trt durnte su espei(in semntiF ixistenD simenteD tres fuentes de sujetividdF v visinD interpretin yD en onseueniD el sentido de un ehD dependen de l experieni y onoimiento que teng l person que utilie el ehF ero esto es muy sujetivoD pues d quien tiene su propi experieniD l ul no dee trtrse ojeE tivmenteF v primer fuente de sujetividd es entones l interpretin del usurio del eh er de su sentidoF uienes hyn estudido lmente los nmeros omE plejos tendrn un ompresin del eh gomplejo 5 ms homogne que quienes no lo hyn estudidoF r estos ltimos puede ser neesrio omplementr l espei(inF in el so del eh gomplejo 5 es muy onveniente tener un tryetori de estudios mtemtiosF uede un progrmdor sin est tryetori mnejr el eh gomplejo 5 c infrentr est pregunt revel perspetivs ontrditorisF in primer lugrD si el usurio del eh gomplejo 5 ept l interfzD entonesD el desrrollo de progrms que usen nmeros omplejos permite gnr omprensin er de l mtemti omplejF imperoD este usurioD l no disponer del orpus mtemtio requeridoD es ms propenso utilizr l interfz pr un (n diferente l que fue oneido el eh gomplejo 5 Y por ejemploD pr representr puntos en el plno rtesinoF i ien esto puede representr un horro de digoD puede rrer tmin grndes onfusiones entre los progrmdores y mntenedoresF v segund fuente de sujetividd proviene del mismo disedor del ehF il ojeto resultnte depende tmin de l experieni del disedorF ersons diferentes tienden proponer interfes diferentesF v ltim fuente de sujetividd se re(ere l implntin del ehF histintos proE grmdores hrn implntiones diferentesF i ien est es primrimente l sujetividd que pretende esonder un ehD puede ser esenil onsiderrl por dos rzonesX el tiempo de implntin y el tiempo de ejeuinF il tiempo de desrrollo de un eh puede ser tn extenso que ompromet un proyetoF enlogmenteD el tiempo de ejeuin del progrm resultnte puede ser tn lento que hg neesrio repetir l implntin del ehF in ulquier de ests situiones puede ser onveniente indir los spetos generles de l implntinF in resumenD ls fuentes de sujetividd se tipi(n omo sigueX IF ujetividd de interpretin del usurio PF ujetividd de interpretin del disedor

1.1. Especicaciones de datos

QF ujetividd de implntin or ms nfsis que se le hg l orientin ojetosD los progrmdores que se irunsrin en desrrollos oopertivos deen estr onsientes de ests sujetividdes l momento de her l espei(in semnti de un ehF v ide en l espei(in semnti es entones deurse l expettiv ognitiv del grupo de persons involuE rds en el desrrollo y uso de un ehF i quel grupoD por instniD omprende l mtemti omplejD entones no slo es inneesrio hondr en un espei(in semnE ti que explique l noin de numero omplejoD sino que tmin puede tornrse muy tediosoF in este soD l fuente de sujetividd slo es de implntinD l ul es preisE mente l sujetividd que pretende oultr un ehF or l rzn nteriorD l espei(in semnti no es ojetivF ehor ienD mo llevr o un espei(in semnti efetivD es deirD que logre el efeto de eptrse entendid por un grupo de progrmdoresc espuest resumidX medinte un lenguje deudoF r disertr en torno est uestinD es propido imginr mo dos interE loutores trtn l noin de lo ojetivo y sujetivo er de un os de progrmin y un ehF in el sentido en que lo hemos trtdoD lo ojetivo de l os progrmd es perepE tile l visin omn de los interloutoresD mientrs que lo sujetivo les est oultoD l menos l mird de uno de ellosD o de mosF or visinD el letor no dee sumir el mero sentido sensorilD sino l pidd de periir un os o fenmeno medinte ls striones y onstruiones inteletules que l experieni de los interloutores les permitF gomo prte de l experieniD es rtio que los interloutores tengn destrezs de progrmin equiprlesF upongmos que un interloutor e le present un eh otro fF hos situiones iniiles son posilesX @IA f ve e interpret el eh de l mism mner que e y @PA f no lo interpret igulF in ulquier de los dos sosD es esenil que e onoz l opinin de f pr poder determinrse ul de ls dos situiones ourreF gundo ourre l primer situinD los interloutores tienen entones un mird homogne del eh y l sujetividd que qued es de implntinD l ulD en el estdio de diseoD si siempre es ueno oultrlF i ourre l segund situinD entones e y f deen homogeneizr l visin e inE terpretin del eh de form que sus sujetividdes de interpretin lleguen ser ojetivsF v ni mner hst hor onoid de herlo es medinte el dilogoF or eso el lenguje es fundmentl en l espei(in de un ehF ero el lenguje no es meE rmente unidireionlF e no tiene ningun form de orroorr si f omprte su mird si no esuh l interpretin que teng f er del ehF or tntoD undo se dise un nuevo ehD es esenil que el disedor lo expong nte los interesdos e iniie un proeso de dilogo que dure hst que no hyn sujetividdes de interpretin y slo queden ls de implntinF
1.1.4 Un ejemplo de TAD

ixperienis dquirids en el desrrollo de progrms de diujdo permiten modelizr un ehD llmdo pigure 8a D uyo (n es generlizr operiones inherentes l diujdo de un (gur sore lgn fondo de ontrsteF l eh es til pr desrrollr progrms

1. Abstraccin de datos

8a

que hgn diujosD y un propuest de de(niin es omo sigueX Figure 8a struct Figure {

};

Constructores de Figure 8b Observadores de Figure 9b Modicadores de Figure 9c

Figuras concretas 12
used in chunks 8b, 9a, 12, and 15a.

Denes:

Figure,

8b

il eh pigure 8a modeliz un (gur generl que se diujr en lgn medio de ontrsteF is generl en el sentido de que slo stremos operiones generles sore un (gur geomtri ulquierD es deirD ls operiones son generles 4 porque opern sore ulquier (gur independientemente de su prtiulriddF or ulquier (gur pretendemos expresr que su formD udrtiD tringulrD etterD no nos importD slo nos interes un (gur omo strin generl pr diujr y l mner generl de operr sore ell trvs de operiones generles omunes tods ls (gurs existentesF xo se deeD y es preferile sumir que no se puedeD de(nir un strin sin onoer el pr qu de tl de(niinF or es rznD undo disemos un eh deemos seE gurrnos de tener lro el (n que perseguimosF in este sentidoD en lo que onierne l eh pigure 8a D el (n es diujr (gurs en lgn medio de ontrsteF i este (n no est lroD no tiene sentido hlr de (gurs y de sus operionesF v espei(in sintti del eh pigure 8a est dd por su de(niin en C++ F n operin sore un lse se denomin mtodoD trmino proveniente del ltn meth odusD el ul proviene del griego @met E h odosAF in este so met onnot fuerD ms ll y h odos signi( minoF wtodo quiere deirD puesD un mino hi el (n que est fuerY es deirD un mino on destinoD on sentidoF r de(nir l semnti de d operinD deemos denotr el eh PointD pues lo referenin lguns operiones del eh pigure 8a F upeditdo l (n del eh pigure 8a D un punto destin l uiin de l (gur l momento de su diuE jdo y no nos onvieneD por horD de(nirl msD pues no tenemos ide Ey es por hor tmin preferile no tenerlE del medio en el ul se diujrn ls (gursY por ejemplosD un medio plnrX ppel o pntllY o un medio tridimensionlX proyetor tridimensionl u hologrfF r el primer tipo de medio el punto requiere dos oordendsD mientrs que pr el segundo tresF ry dos forms de onstruir un (gur strt expresds por los siguientes onsE trutoresX Constructores de Figure 8b (8a) 9a Figure(const Point & point); Figure(const Figure & figure);
Uses

Figure

8a.

il primer onstrutor requiere un puntoY el segundo opi l (gur prtir del punto donde se enuentre otr (gurF
4
La redundancia es adrede.

1.1. Especicaciones de datos

9a

il destrutor del eh pigure Constructores de Figure 8b + virtual ~Figure();


Uses

8a

dee ser virtulX


(8a) 8b

Figure

8a.

9b

pues de es mner se grntiz l invoin de ulquier destrutor soido un (gur prtiulrF e un mtodo que no ltere o modi(que el estdo del ojeto suele llmrsele oserE vdorF in este sentidoD un (gur tiene un solo oservdorX Observadores de Figure 9b (8a) 16 const Point & get_point() const; el ul oserv su punto de refereni en el plnoF in C++ D el li(dor const sore un mtodo indi l ompildor que el mtodo no lter el estdo del ojetoF e un mtodo que lter o modi( el estdo de un ojeto se le li( de modi(dor oD vees tudorF vos tudores de un (gur son los siguientesX Modicadores de Figure 9c (8a) virtual void draw() = 0; virtual void move(const Point & point) = 0; virtual void erase() = 0; virtual void scale(const Ratio & ratio) = 0; virtual void rotate(const Angle &angle) = 0; vos nomres de mtodos draw(), move() y erase() indin lrmente su funin5 F il mtodo scale() just el tmo @eslA de un (gur segn un rdio ddoF il tipo Ratio espei( un mgnitud de esl que signi( l proporin en que l esl se modi(Y si ste es menor que unoD entones l (gur se hiD de lo ontrrio se grndF pinlmenteD el mtodo rotate() gir o rot l (gur en el medio segn un ngulo de tipo AngleF vos wodi(dores de pigure 9c representn operiones generles sore un (gurF odemos diujrlD moverl hi otro puntoD orrrlD eslrl segn lgun mgnitudD o rotrl segn lgn ngulo en rdines uyo signo indi el sentido de rotinF in todos los sos trtmos on (gurs strtsD no onretsF el igul que on el tipo PointD en este estdio no es onveniente pensr en ls imE plntiones de los tipos Ratio y AngleF lo st on onoer su utilizin on ojetos de tipo Figure irunsrit (n de diujrlsF wenin prtiulr mereen dos li(dores sinttios del C++ F il primero lo onE form el pre(jo reservdo  virtualD el ul indi que l operin puede implntrse segn l prtiulridd de l (gurY por ejemploD un udrdo se diuj diferente que un ruloF il segundo est ddo por el heho de iniilizr l operin on el vlor eroF ist es l sintxis de C++ pr de(nir un mtodo virtul puroD el ulD su vezD de(ne un lse strtD o seD strin purD sin ningn rter onretoD pues si noD l lse no ser strtF r prehender est oservinD omenemos por preguntrnos ul (gur se re(ere el eh pigure 8a cF v respuest orret es que no lo semosD pues se trt de un lse strtD no de un onretF vos mtodos virtules puros tienen que implntrse en lses derivds de l lse Figure que onretn implntiones prtiulres de un (gur strtF or ejemE
5
A condicin de que se conozcan los trminos ingleses.

9c

10

1. Abstraccin de datos

ploD el mtodo scale() de un tringulo se implnt en un lse Triangle derivd de FigureF il onepto de derivin ser estudido on ms detlle en IFP @gF IIAF
1.1.5 El lenguaje UML

rst hor nos hemos servido del lenguje C++ pr resolver l espei(in sinttiF in efetoD en este lengujeD y en otros orientdos ojetosD su propi sintxis indii todos los spetos sinttios de inters yD si se esogen nomres deudosD fundment los semntiosF roy en d existen muhos lengujes orientdos ojetosD uy preseni nos di(E ult uni(r mirds en espei(iones y diseosF r plir este prolemD desde he ms de un ddD un onsorio llmdo ywq @yjet wngement qroupA intent homogeneizr l mner de espei(r eh TSF hiho lenguje se llm rnimE mente wvX ni(ed wodeling vnguge y se sirve de un medio que no tienen todos los lengujes y que es nsono on l ide de lo ojetivoX el gr(oF n gr(o die ms que mil plrs rez un ntiguo proverioD y wv lo honr undo se requiere oservr diferentes eh y sus relionesF il eh pigure 8a puede modelizrse pitrimente en wv omo en l (gur IFIF n retngulo represent un lse on tres seionesF il nomre de l lse se enuentr en l sein superiorF il ttulo en letr ursiv indi que l lse es strtF
Figure
-point: Point +Figure(in point:Point) +Figure(in figure:Figure) +~Figure() +get_point(): Point +draw(): void +move(in p:Point): void +erase(): void +scale(in ratio:Ratio): void +rotate(in angle:Angle): void

pigur IFIX higrm wv de l lse Figure v segund sein indi los triutos y l terer los mtodos u operionesF il pre(jo E en d nomre de triuto u operin indi que el miemro es inesileD mientrs que el smolo C indi que es ompletmente esileF n nomre de operin en letr ursiv indi que l operin es virtul o polimorfY onepto que estudiremos prontmenteF vos nomres de tipos de retorno y de prmetros se seprn de los nomres de funin y de prmetros on dos puntos @ l ntiguD pero elegnteD usnz del sl y elgolAF vos prmetros tienen un pre(jo li(dor que pueden tener vlores inD out o inout pr espei(r prmetros de entrdD slid o entrdGslid respetivmenteF n progrm omplejo ontiene muhos tipos strtosF gundo est ntidd es grndeD ulquier lenguje result omplido pr mirr en unidd l sistem y dentro de l oservr sus tipos de dtos e interrelionesF v grn ventj de wv es su rter gr(oD el ul filit oservrD slo visul y ojetivmenteD los tipos strtos en un sol mirdF

1.2. Herencia

11

in este texto usremos wv slo pr espei(r digrms de lses e interreliones entre ellsF wv es un lenguje de modeldo muho ms rio y l experieni h deE mostrdo que pr gnr homogeneidd de interpretin en un proyetoD ste es ms simple que un lenguje de progrminF

1.2 Herencia
il eh pigure 8a modeliz un (gur generl que no indi nd er de su form onretF in emrgoD l momento de diujr un (gur se tiene que onretr y onoer de ul (gur se trtF in l jerg ojetosD onretr se le die espeilizr y se represent medinte un relin llmd hereni de lseF in wvD onretr lguns (gurs jo un digrm wvD resumidoD ejemplriz el onepto de un form que nos permite visulizr ls lses y sus reliones en un espeie de genelog o txonomD tl omo se ilustr en l (gur IFPF
Figure
-point: Point +Figure(in point:Point) +Figure(in figure:Figure) +~Figure() +get_point(): Point +draw(): void +move(in p:Point): void +erase(): void +scale(in ratio:Ratio): void +rotate(in angle:Angle): void

Triangle
-hypotenuse: float -angle_hypotenuse: float +get_hypotenuse(): float +get_angle_hypotenuse(): float +...()

Square
-side_size: float +get_side_size(): float +...()

Circle
-ratio: float +get_ratio(): float +...()

pigur IFPX terrqu de lses espeilizds de l lse Figure v relin de hereni se expres en wv medinte un )eh ontigu que prte desde l lse espeilizd hi l lse generlF in el so ejemploD l lse generl l onform el eh pigure 8a D mientrs que ls lses espeilizds onretn ls (gurs espe(s TriangleD Square y CircleD espeiliziones de tringuloD udrdo y rulo respetivmenteF v hereni se de(ne entones omo l propiedd que tiene un lse de heredr el ser de otr lse F e l lse generl se le llm lse se o fundmentlD mientrs que l espeilizd reie el nomre de lse derivdF in el ejemplo de ls (gursD el eh pigure 8a es lse se de ls lses derivds TriangleD Square y CircleF heimos tmin que l lse derivd hered de l lse se en el sentido de que hered tod su interfz pliF n tringuloD por instniD hered el punto de refereni triuile tods ls (gurs generlesD es deirD un ojeto de tipo Triangle puede invor l mtodo get_point()D pues ste fue hereddo del eh pigure 8a F in el digrm wv de l (gur IFP se prei que ls lses derivds poseen triutos y mtodos que no se enuentrn en l lse seF or ejemploD l lse Circle posee un mtodo llmdo get_ratio() uy funin es oservr el rdio de l irunfereni que

12

1. Abstraccin de datos

12

represent un instni de ojeto de tipo CircleF il triuto  ratio tiene sentidoD segn l geometrD pr l lse CircleD pero no lo tiene pr ls lses Triangle y SquareF ehor ienD ls tres lses derivds de pigure 8a omprten el punto de refereniD pues sonD por derivinD de tipo pigure 8a F vo nterior sugiere un interpretin de l hereni quiz ms riX l relin serD es deirD l lse derivdD es tmin de lse seF he este modoD ojetos de tipo TriangleD Square y Circle sonD tminD de tipo FigureF v delrin en C++ de l relin de hereni nterior es l siguienteX Figuras concretas 12 (8a) struct Triangle : virtual public Figure { ... }; struct Square : public Figure { ... }; struct Circle : public Figure { ... };
Uses

Figure

8a.

v pseudoespei(in de l lse Triangle indi que es un lse strtF in efetoD notemos queD en el so de un tringuloD segn nuestr ultur mtemtiD podeE mos espeilizrlo n ms segn ls longitudes de sus ldosF vo grndioso de l hereni es l posiilidd de expresr oneptos y striones generles trvs de lses ses pr luego prtiulrizrls medinte derivionesF isto ofree l posiilidd de diser indutivmenteD yendo desde lo prtiulr hi lo geneE rlD o dedutivmenteD yendo desde lo generl hi lo prtiulrF hiho de otro modoD yendo desde lo onreto hi lo strto oD prdjimenteD desde lo strto hi lo onretoF
1.2.1 Tipos de herencia

v hereni del ejemplo nterior se denomin hereni pliD pues lo que es plio de l lse se tmin lleg ser plio en l lse derivdF ry otro modo de hereni denomindo de implntin o hereni privdF iste modo expres el heho de que l lse se se us pr implntr lD o prte de lD lse derivdF in wvD l hereni privd se represent medinte un )eh puntedD mientrs que en C++ se he medinte el li(dor private omo pre(jo l nomre de l lse seF
1.2.2 Multiherencia

in osionesD un lse de ojeto esD l vezD de dos o ms lsesF in el mundo ojetosD esto puede expresrse medinte un relin de hereni mltipleF is deirD un ojeto puede heredr de dos o ms lses seF v (gur IFQ muestr un relin de lses que modeliz los tores de un universiddF etenin espeil meree l lse PreparadorF in l vid relD un preprdor es un estudinte exelsoD uy exeleni prei l universidd pr l sisteni y mejor de sus ursosF gomo retriuinD l universidd le otorg l estudinte un estipendioF in los trminos del digrm wvD Preparador hered de ls lses Estudiante y Trabajador Universitario respetivmenteF he este modo de(nimos que un preprdor esD l vezD estudinte y trjdor universitrioF is posile tener reliones de multihereni de interfz por un prteD y de imE plntin por lgun otrF

1.2. Herencia

13

Persona
+nombres(): Nombres +cdula(): Cdula +edad(): int

Trabajador Universitario
+salario(): Salario +antiguedad(): int +...()

Estudiante
+expediente(): Expediente_Estudiante +...()

Profesor

Obrero

Empleado

Preparador

pigur IFQX eliones de lses de persons en un universidd


1.2.3 Polimorsmo

v plr polimorfo proviene del griego @polyAD que signi( muhoD mientrs que morfo proviene de @morfAD que signi( (gurD formF olimorfo onnotD puesD muhs (gursD muhs formsF in l jerg ojetosD polimorsmo es la
propiedad de expresar varias funciones o procedimientos diferentes o similares bajo el mismo nombreF

ry tres lses de polimor(smoX de sorergD de hereni y de plntillF


1.2.3.1 Polimorsmo de sobrecarga

orerg es l pidd de un lenguje ojetos pr de(nir nomres igules de funE ionesD proedimientos y mtodosF gonsideremosD por ejemploD l funin siguienteX
const int sumar(const int & x, const int & y);

uyo (n es sumr dos enterosF sumar() puede sorergrse pr que sume ms enterosX
int sumar(const int & x, const int & y, const int & z); int sumar(const int & w, const int & x, const int & y, const int & z);

il ompildorD trvs de l ntidd de prmetrosD he l distinin y deide ul de ls tres funiones es l que se dee invorF or ejemploD si el ompildor enuentrX
sumar(1, 2, 3);

intones ste generr l llmd sumar() on tres prmetrosF is posile tmin de(nir sumar() pr que sume otr lse de ojetosF or ejemploX
const string sumar(const string & x, const string & y);

v sum de dens puede interpretrse omo l onteninF il ompildor he l distinin respeto ls versiones ritmtis medinte los tipos de los prmetrosF in C++ se pueden sorergr los operdoresF or ejemploD podrmos espei(r l ontenin de dens del siguiente modoX

14

1. Abstraccin de datos

const string operator + (const string & x, const string & y);

in este soD puede esriirse lgo s omoX


string s1, s2; ... string s3 = s1 + s2;

v sorerg de operdores eD inlusiveD l de funionesD es un sunto polmio porque oult operiones y puede ontrvenir el sentido ulturl del operdorF or ejemploD el digo nterior tiene perfeto sentido ulturl pr l ritmtiD pero quiz no pr l onteninF gundo en un primer inspein un letor le l sum de densD posilemente l pensr que los operndos son numriosD lo ulD en el ltimo ejemploD no es el soF or es rzn es por lo generl reomendle evitr l sorergF
1.2.3.2 Polimorsmo de herencia

hd un relin de hereni entre tres lses XD Y y ZD expresd gr(mente de l siguiente mnerX


X
+mtodo(...): T

Y
+mtodo(...): T

Z
+mtodo(...): T

il polimor(smo de hereni se de(ne omo l posiilidd de de(nir @no de sorergrA mtodos virtules del mismo nomre en ls tres lsesD invor l mtodo desde l lse X y determinrD en tiempo de ejeuinD ul es el mtodo onreto segn se l implntin rel de l lse XF e los mtodos Y::mtodo() y Z::mtodo() se les onnot omo espeiliziones del mtodo en l lse se X::mtodo()F odr deirse que el polimor(smo de hereni es l sorerg de mtodos virtules entre ls lsesF is importnte resltr queD en este soD los prototipos de los mtodos virtules tienen que ser idntiosF eordemos que el eh pigure 8a ontiene mtodos virtulesD purosD que no se pueden implntrF i pretendisemos diujr un ojeto de tipo pigure 8a se nos preE er l preguntX gul (gurcD pues el eh pigure 8a es un (gur strtD no onretF is undo onoemos ul es l (gur que tiene sentido indgr mo diujrlF v implntin de un mtodo virtul puro se le deleg un lse derivdF r el so del eh pigure 8a D sus pigurs onrets 12 deen implntr sus mtodos virtules purosF or ejemploD los mtodos Square::draw() y Circle::draw() implntn de mner diferente el diujdo de su orrespondiente (gurF he este modoD undo se oper sore un ojeto generl de tipo pigure 8a y se invo un mtodo virtulD se seleionD en tiempo de ejeuinD el mtodo de espeilizin segn l (gur onret sore l ul se est operndoF

1.2. Herencia

15

15a

v virtud del polimor(smo de hereni es que permite esriir progrms generles que mnipulen (gurs generles6 F istos progrms no requieren onoer ls (gurs onretsD pues opern en funin de mtodos virtules generles purosF or ejemploD prtes de progrms pr diujr (gurs mnipuln (gurs en strtoD ls diujnD ls muevenD ls rotnD etterF e efetos de eonomizr digo result til l posiilidd de esriir progrms generles omo el del ejemplo siguienteX Manejo general de Figure 15a void release_left_button(const Action_Mode mode, Figure & fig) { switch (mode) { case Draw: case Move: fig.draw(); break; case Delete: fig.erase(); break; case Scale: fig.scale(dif_mag_with_previous_click()); break; case Rotate: fig.rotate(dif_angle_with_previous_click()); break; ... } }
Uses

Figure

8a.

l ul ser invod en so de que se detetse que se suelt el otn izquierdo del rtn dentro de un lienzo strto de diujdoF release_left_button() no requiere onoer l (gur onretF u digo es geE nerl y no se fet por ls modi(iones o didurs de ls (gursF or ejemploD si release_left_button() oper sore un udrdoD entones se invorn los mtodos virtules onretos de l lse SquareY nlogmenteD ourre on un ruloD so en el ul se invorn los mtodos de CircleF
1.2.3.3 Polimorsmo de plantilla (tipos parametrizados)

15b

ry situiones en ls ules un prolem y su soluin pueden espei(rse de form inE dependiente del @o losA tipo@sA de dto@sAF or ejemploD el prolem de usr un elemento en un onjuntoD y su soluinD son independientes del tipo de elementosF i suponemos que el onjunto se represent medinte un rregloD entonesD un posile mnerD genriD de usr un elementoD es omo sigueX Bsqueda dentro de un arreglo 15b template <typename T, class Compare> int sequential_search(T * a, const T& x, int l, int r) { for (int i = l; i <= r; i++) if (are_equals<T, Compare> () (a[i], x)) return i; return No_Index; }
Uses

sequential_search

154a.

De nuevo, la redundancia es adrede.

16

1. Abstraccin de datos

ist rutin us el elemento x dentro del rngo omprendido entre l y r del rreglo aF e retorn un ndie dentro del rreglo orrespondiente un entrd que ontiene un elemento igul xD o el vlor No_Index @por lo generl 1AD si el rreglo no ontiene xF eprte de los prmetros pertinentes l onjuntoD el lgoritmo genrio sequential_search<T, Compare>() requiere dos tipos prmetrizdosX el tipo de dto del onjuntoD llmdo genrimente TD y un tipo omprdor de iguldd llmdo are_equals<T, Compare>()D uyo uso ser orddo en IFQFI @gF IWAF puniones o mtodos omo sequential_search<T, Compare>() se llmn plntilE ls 7 F heimos que sequential_search<T, Compare>() es genri porque genera un fmili de funiones pr d tipo existente en el ul exist un lse are_equals()F in otrs plrsD un plntill utomtiz l sorerg de l funin o lse pr los tipos involurdos en l plntillF yservemos que unque l plntill es l mismD o seD es genriD el digo genrio sequential_search<int, are_equals<int> >(...) es diferente l lgoritmo sequential_search<string, are_equals<string> >(...)F il ompildor dee generr dos digos distintosY uno pr rreglos de enteros @intA y otro pr rreglos de deE ns @stringAF gundo se ejempli( l lse pigure 8a se indi que su (n es diujrl en un medio de ontrsteF he ul medio se hlX ppelD pntll de vdeoD televisorD hologrf FFFc il letor uioso dee herse pertdo de que ls implntiones de l lse pigure 8a @SquareD Triangle y CircleA tienen que sumir un medio en donde efetur ls operioE nesF n mner de independizrse del medio de ontrste es her l lse pigure 8a un plntill uyo prmetro seD justmenteD el medio de ontrsteF v ide se ilustr en el digrm wv de l (gur IFRF
Medium_Type:Medium

Figure
-point: Point +medium: Medium_Type +Figure(in point:Point) +Figure(in figure:Figure) +~Figure() +get_point(): Point +draw(): void +move(in p:Point): void +erase(): void +scale(in ratio:Ratio): void +rotate(in angle:Angle): void

pigur IFRX higrm wv de l lse pigure on el medio de ontrste omo prmetro in wvD los prmetros plntill de l lse se espei(n en un retngulo puntedo situdo en l esquin superior derehF n ojeto de tipo pigure 8a posee omo tipo prmetrizdo el medio en donde se mnipuln ls (gursF uede ser neesrio que ls espeiliziones de pigure 8a onozn el tipo onreto del medio de ontrsteF or est rznD l versin plntill de pigure 8a export el tipo prmetrizdo jo el nomre Medium_TypeF in C++ est in se llev o medinte l siguiente delrinX Observadores de Figure 9b + (8a) 9b
7
En ingls, template.

16

1.3. El problema fundamental de estructuras de datos

17

typedef Medium Medium_Type;

he est mnerD un espeilizin puede instnir un ojeto de tipo Medium_Type omo se ilustr en el siguiente ejemploX

void Square::draw() { /* .... */ Medium_Type m; // Instancia un objeto "medio de contraste" /* .... */ medium.put_line(...);

il triuto tipo medium de l lse Figure<Medium> le permite eso steF v espeE ilizin Square::draw() diujr lnes en el medio de ontrste orrespondientes l respetivo udrdoF v implntin de Square::draw() deviene genri respeto l medioF
1.2.3.4 Lo general y lo genrico

vos trminos generl y genrio no slo se preen muho lximenteD sino queD en efetoD tmin son muy similres semnti y etimolgimenteF v rz de mos trminos es el vero ltino gnr oD que signi( engendrrD rerF in est poD tnto generl omo genrio onnotn lo que es omn un espeieF qnr o proviene l vez del griego @genusAD que en el lenguje moderno onnot rz y que en griego se refer lo omnF he genus proviene un muy mpli vriedd de trminosX gneroD genD gentiD gentiliioD generosoD genteD genelogD genioD genilD ingenioD ingenierD etterF in su elersim y trsendentl wetfsiD eristteles distingue el gnero omo lo que le es esenilmente omn un espeieF odemos deirD puesD que l jerg ojetos estD desde he ms de PSHH osD impregnd por est ideF in el so de l progrmin ojetosD generl identi( lses de ojetos generlesY es deirD ses de otrs lses ms prtiulresD individulesD o lses que opern sore l generliddF or ejemploD l lse pigure 8a es generl tods ls (gursD mientrs que l lse are_equals() represent l omprin generl y genri entre ojetosF qenrio onnot lo que generD o seD en l orientin ojetosD ls plntillsD onepto que rein mos de presentr y ejempli(rF

1.3 El problema fundamental de estructuras de datos


ixiste un lse de prolem uy ourreni es tn uiu en prtimente todos los mitos de l progrminD que y es posile generizrl en un sol lseF e trt del onjuntoF uesto que en l myor de los sosD los elementos son del mismo tipoD es posiE le ojetizrlo en un eh genrio tl omo lo ilustr el digrm wv de l (gur IFSF il digrm en uestin modeliz lo que se onoe omo el prolem fundmentl de esE truturs de dtosF vs diferentes mners de implntrlo y sus diverss irunstnis de pliinD rn si todo el orpus de este textoF

18

1. Abstraccin de datos

Key_Type:T Compare_Type:Compare

Set
+insert(in key:T): void +search(in key:T): T * +remove(in key:T): void +size(): size_t +swap(inout set:Set<T, Compare>): void +join(in set:Set<T, Compare>): Set<T> +split(in key:T,out l:Set<T, Compare>,out r:Set<T, Compare>): void +position(in key:T): int +select(in pos:int): T* +split_pos(in pos:int,out l:Set<T, Compare>, out r:Set<T, Compare>): void

pigur IFSX higrm wv de un lse genri onjunto @etA v lse Set<T, Compare> modeliz un onjunto genrio de dtos de tipo TD on riterio de omprin CompareD uyo (n es generlizr operiones sore onjuntos sin que nos interese mo stos se implntnF ry muhs forms de implntr el tipo Set<T, Compare>F v deisin depende de sus irunstnis de usoF gonjuntos de dtos que se orrespondn on el prolem fundmentl se denominn ontenedoresF n ontenedor esD puesD un onjunto de elementos del mismo tipoF Set<T, Compare> puede modelizrse en C++ omo sigueX Conjunto fundamental 18 template <typename T, class Compare> struct Set { void insert(const T & key); T * search(const T & key); void remove(const T & key); size_t size() const; void swap(Set<T, Compare> & set); void join(Set<T, Compare> * set); void split(const T& key, Set<T, Compare> *& l, Set<T> *& r); const int position(const T& key) const; T * select(const int pos); void split_pos(const int & pos, Set<T, Compare> *& l, Set<T, Compare> *& r); }; in lnes generlesD el prolem fundmentl se de(ne omo el mntenimiento de un onjunto Set<T, Compare> de elementos de tipo T on ls operiones sis de inserE inD squedD supresin y rdinlidd y uys interfes fundmentles son insert()D search()D remove() y size() respetivmenteF preuentementeD los elementos del onjunto se llmn lvesF he ll el nomre de prmetro key en muhs de ls interfes de Set<T, Compare>F swap(set) intermi todos los elementos de set on los de thisF egn l estruE tur de dtos on que se implnte Set<T, Compare>D lguns vees est operin ser muy rpidF il mtodo join(set) une this on el onjunto referenido por el prmetro setF hespus de l operinD set deviene voF

18

1.3. El problema fundamental de estructuras de datos

19

join() puede tener vriiones segn el tipo de onjunto y l estrutur de dtosF vs ms omunes son l ontenin y l interepinF
1.3.1 Comparacin general entre claves

wuhs veesD el tipo genrio T es ordenleD es deirD ls lves pueden disponerse en un seueni ordend desde l menor hst l myor o vieversF in esos sos preen el resto de ls operiones y l lse de omprin CompareF Compare es un lse que implnt l omprin entre dos elementos de tipo TF or lo generlD Compare implnt el operdor relionl <F gon un lse de este tipo es posile relizr el resto de los operdores relionlesF or ejemploD si tenemos dos lves k1 y k2 y un lse Compare<T> uyo operdor () implnt k1 < k2D entones el siguiente pseudodigo ejempli( tods ls ompriones posilesX

if (Compare() (k1, k2)) // k1 < k2? // accin a ejecutar si k1 < k2 else if (Compare() (k2, k1)) // k2 < k1? // accin a ejecutar si k2 < k1 else // Tienen que ser iguales // accin a ejecutar si k1 == k2

1.3.2

Operaciones para conjuntos ordenables

i el onjunto es ordenleD entones ste puede interpretrse omo un seueni ordend S =< k0 , k2 , . . . , kn1 >D en l ul n es l rdinlidd del onjuntoF in ese soD pueden herse vris operiones sore l seueni SF il mtodo split(key, l, r) prtiion el onjunto en dos suonjuntos l =< k0 , k1 , . . . , ki > y r =< ki+1 , ki+2 , . . . , kn1 > segn l lve key tl que l < key < rF is deirD l ontiene ls lves menores que key y r ls myoresF hespus de l operinD this deviene voF il mtodo position(key) retorn l posiin de l lve dentro de lo que ser l seueni ordendF i key no se enuentr en el onjuntoD entones se retorn un vlor invlidoF il mtodo select(pos) retorn el elemento situdo en l posiin pos segn el ordenF i pos es myor o igul l rdinliddD entones se gener un exepinF pinlmenteD el mtodo split_pos(pos, l, r) prtiion el onjunto en l =< k0 , k1 , . . . , kpos1 > y r =< kpos , . . . , kn1 >F n exepin ourrir si pos est fuer del rngoF
1.3.3 Circunstancias del problema fundamental

gulesquiern que sen ls situiones de utilizinD los elementos de un onjunto tienen que gurdrse en lgun lse de memoriF v mner de representr en memori tl onjunto requiere de un estrutur de dtos uy form depende de sus irunstnis de usoF ry vrios ftores que iniden en el diseo o esogeni de l estrutur de dtosD entre los que e destr los onoimientos que se tengn sore l rdinliddD l distriuin

20

1. Abstraccin de datos

de refereni de los elementosD ls operiones que se usrn y l freueni on que sts se invornF v rdinlidd deide de entrd el tipo de memoriF n rdinlidd muy grnde requerir memori seundri @disoA o teriri @otros medios ms lentosAD y est deisin fet rdilmente el tipo de estrutur de dtosF ry osiones en que lguns lves son ms propenss ierts operiones que otrsF or ejemploD si ls lves fuesen pellidosD entones el ser que ls letrs x o y son poo freuentesD y que ls voles son ms freuentesD puede inidir en un estrutur de dtos que tiend reuperr rpidmente lves que tengnD por ejemploD  omo segund letrF egn el prolemD lguns operiones son ms proles que otrsY inlusiveD en muhos sosD no se utilizn tods ls operiones o l myor de ls tividdes sore el onjunto se onentrn en un o pos operionesF in estos sosD l estrutur de dtos puede diserse pr optimr l operin ms freuenteF
1.3.4 Presentaciones del problema fundamental

in el mito funionl existen vris interpretiones del tipo genrio gonjunto funE dmentl 18 F ryD en eseniD dos onsideriones digns de resltrseF v primer onsiderin onierne l repiteni o no de los elementosF gundo se permite repetir los elementos de un onjuntoD entones ste se le denomin multionE juntoF in l iliote estndr C++ D en delnte llmd stdc++D l onjunto se le onoe omo set<T, compare>D mientrs que l multionjunto omo multiset<T, compare>F v segund onsiderin es el lmenmiento de pres ordendos de tipo (Key, Elem)F v ide es un tl soitiv que reupere un instni elem Elem dd un lve key KeyF e est lse de onjunto se le onoe omo mpeo 8 F gundo ls lves pueden repetirseD entones l mpeo se le die multimpeoF in l iliote estndr C++ l mpeo se le onoe omo map<Key, Elem, compare> mientrs que l multimpeo omo multimap<Key, Elem, Compare>F in los mpeos suele implntrse el operdor [] segn l lveF

1.4 Diseo de datos y abstracciones


il diseo de striones y sus onseuentes eh es un rte que se prende on l expeE rieniF edquirirl no tiene otr lterntiv que enfrentrse responslemente prolems reles de progrminF or responsilidd se entiende l titud honorle responder por los equvoosD lo ul no slo est ondiiondo l onsieni que el prtinte teng er de su onoimientoD sino su honestidd y fuerz de rterF in lo que sigue de est sein se plnten lguns re)exiones que dee onsiderr el prendiz pr enfrentr mejor el prendizje del diseo de dtos y progrminF
8
Del ingls mapping, cuya connotacin matemtica signica funcin en el sentido de la teora de conjuntos. Por otra parte, es importante destacar que el trmino fue recientemente aceptado por la RAE.

1.4. Diseo de datos y abstracciones

21

1.4.1

Tipos de abstraccin

egn el inters que se teng l momento de diser un strin o estrutur de dtosD st puede lsi(rse en orientd hi los dtosD orientd hi el )ujo u orienE td hi el onepto o strinF n strin orientd hi los dtos es quell uyo (n est enuzdo por l orgnizin de los dtos en el omputdorF e l vezD tl orgnizin oedee reE querimientos de desempeoD horro de espio o lgn otro que t l omputdorD sistem opertivo u otros progrms sistemF iste es el so de muhs de ls estruturs de dtos que estudiremos en este textoF ijemplos de ests lses de orientin son los rreglosD ls lists enlzds y ls diverss estruturs de rol que sern estudids en este textoF wuhos prolems omputionles exhien un ptrn de proesmiento distintivo y uniformeF in tles situiones puede ser muy onveniente disponer de un estruE tur de dtos que represente el orden o esquem de proesmiento de los dtosF in este so deimos que l estrutur est orientd hi el )ujo o l ptrnF or ejemploD si los dtos deen proesrse segn el orden de priin en el sistemD entones un disposiE in de los dtos en un seueni puede representr el orden de llegdF l estrutur se denomin ol y ser estudid en PFT @gF IPPAF xotemos que en este so no se piens en l orgnizin que los dtos tengn en memoriD sino en el orden o ptrn en que stos se proesenF pinlmenteD el diseo de un estrutur de dtos puede filitr l representin de un onepto o strin onoid on mirs omprender el prolem yD onsiguientementeD desenvolverse modmente en su soluinF in este so deimos que l estrutur de dtos est orientd hi el oneptoF v ide es simpli(r l progrmdor o los usurios el entendimiento del prolem y de su soluinF ry muhos minos pr resolver prolemsF guentn que wihel prdyD preursor de l teor eletromgntiD no ten su(iente formin mtemti pr explir los fenmenos eletromgntios de sus experimentosF v genilidd de prdy lo ondujo rer sus propis striones gr(sD provenientes de sus oserviones experimentlesD prtir de ls ules fund y expli el eletromgnetismoF el igul que prdyD muhs vees remos striones que nos permiten omprender mejor un lgoritmoF ists striones onformn estruturs de dtosF n ejemplo muy notle es el onepto de grfoF itimolgimenteD el trmino grfo proviene de gr(oD pues los grfos son expresdos en trminos gr(osF in emrgoD en reliddD un grfo modeliz el onepto de relin sore el ul existe todo un orpus mtemtioF e pesr del orpus y quiz porque ste es inompletoD los grfos ofreen un visin gr( de l relin mtemti on l que es ms mod trjrF ist es otr rzn que justi( el diseo de un estrutur de dtoX un mner de representr el prolem en trminos ms senillosF istos tres tipos de orientinD de lgun form lsi(n el (n o el pr qu se dise o se seleion un estrutur de dtosF v lsi(in no es ext ni exluyenteF n estrutur de dtos puede enjr l vez en diferentes momentosD jo todos o ulquier de los tipos de orientinF ero determinr en funin de ls irunstnis ul es l orientin de un estrutur de dtosD puede guir l progrmdor en su diseo o seleinF

22

1. Abstraccin de datos

1.4.2

El principio n-a-n

gonsideremos el eh pigure 8a y repitmos l pregunt fundmentlX pr qu sirvecD ul es su (nliddc in l sein IFIFR @gF UA se pretendi generlizr operioE nes inherentes l diujdo de un (gur sore lgn fondo de ontrsteF gon este (n de(nidoD ls operiones del eh pigure 8a D diujrD moverD etterD tienen sentido sin neesidd de onoer ul es l (gur en uestinF ensemos qu sueder si no tuviseE mos lro pr qu se usr el eh pigure 8a F v respuestD no tn ovi en estos tiemposD es que nos ser muy difil omprenderloF i nuestro entendimiento no estuviese lroD entonesD quizD ometermos el error de intentr implntr el eh pigure 8a D el ulD omo y se menionD es strtoF ehor pensemos en ul ser l form de un eh Figure si ste estuviese destindo lulos geomtrios en los ulesD en lugr de diujrD se lulsen res e interseiones entre (gursF r este (nD ls operiones del eh pigure 8a no tendrn muho sentidoF n prinipio de diseo de sistems se onoe omo el prinipio (nEE(nF iste onsiste en no espei(rD menosD diser y muho menos implntrD ms ll del (n que se onoz y se uerde pr el progrmF iolr este prinipio puede ostr esfuerzo vnoD pues slo en los puntos (nles del progrmD o en sus usurios (nlesD se tiene todo el onoimiento neesrio pr diser un progrm on sentido ISRF in el ejemplo del eh gomplejo 5 D tl omo lo hemos trtdoD que onoemos er de su (nc vos nmeros omplejos tienen mpli pliin en ienis y en ingeE nierD rzn por l ul un progrmdor pudier verse tentdo enriqueer el eh on mtodos o lses derivds que filiten su futur mnipulinF e podrD por ejemploD mnejr oordends polresF in emrgoD mplir el eh gomplejo 5 no tiene senE tido si no se tiene l ertitud de que ls oordends polres sern usds por los usurios eventules del eh gomplejo 5 F v oservin nterior no se he pr eonomizr trjo Eun gnni de onsuno on el prinipio (nEE(nED sino porque el interesdo en un eh gomplejo 5 extendido on oordends polres podr mnejr otr interpretinD en uyo soD l extensin podr ser un estoroF n eh dee ser mnimo y su(ienteF or mnimo pretendemos indir que no tiene ms de lo neesrioF or su(iente queremos deir que dee ontener todo lo neesrio pr destinrlo l (n pr el ul fue de(nidoF istleer ests rrers es reltivoD pues depende del (n y de su interpretinF he llD entonesD el rter esenil que tieneD pr el xito de un proyetoD el que el (n est lrmente de(nido y que los prtiipntes no slo lo tengn lroD sino que estn omprometidos on lF uiz un forismo de intEixupry exprese mejor el sentido de minimlidd y su(E ieni del prinipio (nEE(nX ree que l perfein se lnz no undo no hy ms nd que dirD sino undo no hy ms nd que suprimir 9 F
1.4.3 Induccin y deduccin

snduin signi( ir desde lo prtiulr hi lo generlD mientrs que deduin sel ir desde lo generl hi lo prtiulrF gundo se disen strionesD por dnde
Traduccin del autor de: sl semle que l perfetion soit tteinte non qund il n9y plus rien jouterD mis qund il n9y plus rien retrnher . Saint-Exupery. Terre des hommes.

1.4. Diseo de datos y abstracciones

23

omenzrcF is un prinipio onoido en eduin y diseo el ir desde lo onreto hi lo strtoF in otrs plrsD el forjr striones prtir de l experieni onret relF in ese sentidoD undo no se teng onoimiento iniil er de un prolem ddoD el proeso de indgin dee omenzr prtir de fenmenos onretos del prolem yD luegoD prtir de ess prtiulriddesD intentr de(nir strionesF in l progrmin ojetos existen dos menismos de generlizinX l hereni de lses y ls plntillsF v hereni onierne los dtosD mientrs que ls plntills se re(eren l digoF v hereni se pli pr deliner generliddes y omportmientos omunes un iert lse de ojetoF vs lses derivds lsi(n y portn prtiulriddes de omE portmiento generl y niveles de strinF gundo se identi(quen lses o ehD usque qu es lo omn y eso llvelo lo generl trvs de lses ses o strtsF ry dos spetos generlizr medinte l hereni de lsesF il primero lo omponen los triutosD o seD ls rterstis de un ojeto ddoF in el so del eh pigure 8a D un triuto generl lo onform el punto de refereni omn tods ls (gurs prtiE ulresF il segundo speto de generlidd es funionl y te ls operionesF in el so del eh pigure 8a D los mtodos virtules draw()D move()D etterD generlizn operiones omunes tods ls (gursF gomo y indimosD lgunos lgoritmos son suseptiles de ser genrios jo l form de plntillF gonsideremos el prolem de ordenr un seueni de elementos que ser trtdo en el ptulo QF xotemos que el enunido no menion el tipo de elementos ordenrY slo espei( que se trt de un seueniF odemos ordenr pellidosD enteros o elementos de ulquier otro tipo jo el mismo esquemF yrdenr es independiente del dtoF in est lse de prolems se puede diser un ordenmiento genrio uyo prmetro ser el tipo de elementosF is importnte destr que un omportmiento genrio pree despus de onoer omportmientos onretos y no l ontrrioF xi siquier undo se pose un mpli experieni no se dee progrmr digo genrio sin ntes herlo veri(do exhustivE mente on l menos un tipo de dto onoido y onretoF r ls dos tnis de generlizinD hereni y tipos prmetrizdosD el mino omienz en lo onreto y se dirige hi lo strtoD no l revsF odemos deir que este es el estilo undo se dise y progrm on sentidoF gonforme se gn experieni onretD un disedor puede onsiderr lguns geneE rliziones priori @no todsA sin n ver ls prtiulriddesF isto es deduin y es posile despus de prehender o diser prtes onrets de l soluinF v geniliddD undo ourreD es mirr en lo strto lo que puede devenir onretoF sngenio signi( tener genio desde dentro @inAF qenio que gener idesD uensD por supuestoF hesde est perspetiv ingenier es entones l prti del inEgenioY pero no se podr tener ingenio si siempre se exigiese permneer en lo onreto y se supeditse tnis y mtodos (josF ist es l rzn por l ul l intuiin nun dee ser desrtdF
1.4.4 Ocultamiento de informacin

n eh slo espei( el (n de un dto y su interfzF gundo se uerd un diseo en torno un ehD se uerd un espei(in ojetiv que no die nd er de su

24

1. Abstraccin de datos

implntinF isto es onoido omo el prinipio de oultmiento de informinD el ul onsiste en oultr delierdmente l implntin de un ehD puesD omo y dijimosD st onform lo sujetivoD el ulD no slo es muho ms omplejoD sino que di(ult l omuniinF e vees es ueno hlr de l implntin on l interfzF or ejemploD deir que gonjunto fundmentl 18 est implntdo on rreglos ordendos proporion un ide er del desempeoY se srD por ejemploD que l squed es rpidD pero que l inserin y supresin son lentsF xotemos que en este so no se de(ne extmente mo se implnt el ehD sino que se indiD omo prte de l espei(inD un speto generl de l implntinF or tntoD l reomendin generl de diseo es que se oulte lo ms que se pued l implntinF ero si por rzones de desempeo o de requerimientos result onveniente estleer un tipo de implntinD trtese st entones en los trminos ms genrios posilesF

1.5 Notas bibliogrcas


v progrmin orientd ojetos se remont (nles de l dd de IWTHD undo prei el lenguje Simula QR on los oneptos de lseD hereni y polimor(smoF ry dos oserviones histris muy importntesF v primer es que Simula se irunsrii en el dominio de l simulin y no de l progrmin trdiionlF v segund es que todos los oneptos modernos de l orientin ojetos preieron primero que l noin mtemti de tipo de dto strtoF Simula no dee herse tenido muy en uent en su po porque trnsurrieron lguns dds ntes de que se le desempolvse y onsiderse en el prdigm tul de los ojetosF or el ontrrioD los omputistsD que se reen muy elitesosD onoen los tipos strtos de dtos desde los trjos de viskov y illes IHW y el oultmiento de informin desde los trjos de rns IRHF il lenguje C++ D vehulo de ensenz del presente textoD inspirdo en los lenguE jes C WR y Smalltalk VQD PTD ITVD fue redo por fjrne troustrupF v mejor refereni pr su prendizje es su propio texto he C++ rogrmming vnguje ITRD el ulD prte de que es posilemente el mejor pr omprender el lengujeD es un exelente trtdo de ingenier de progrminD que no tiene nd que ver on l gereni de proyetos de softwreD tividd hor injust y vulgrmente onoid jo el rtulo de ingenier del softwreF iste texto no vers sore l interfz de l iliote estndr C++ sino ms ien er de su implntinF is til sin emrgo estudir l interfz efetos de no repetir trjo y de homogeneizr riteriosF n exelente refereni sore l iliote estndr C++ es el texto de tosuttis VVF n reuento histrio er del C++ y de l progrmin ojetos puede enontrrse en ITQF v letur es muy interesnte porque revel que ls striones y oneptos soids los ojetos son resultdo del re(nmiento trvs de errores y frsosF il prinipio (nEE(n h sido oservdo desde pos remotsD pero fue quillermo de yE mD undo enuni su lere nvjD l ul rez no multiplique los entes sin neesiE dd D de quien primero se onoe su importni epistemolgiF in l progrminD el prinipio h sido oservdo en grndes sistemsD siendo l respeto emlemtio el rtulo

1.6. Ejercicios

25

de ltzer et l ISRF ore este rtulo es menester omentr que ltzer et l orientn su rtulo sistems distriuidos y no diretmente l diseo de dtosF or otr prteD el trmino (n se interpret menudo omo extremo y no omo un propsitoF e trvs de l experieni se desuren dtos generles y gneros de digoF e un tegor onsolidd de lse o digo suele denominrsele omponente o ptrnF n repertorio stnte rio de ptrones genrios sios puede enontrrse en SUF i ien pr dominr l progrmin se requieren lgunos os de experieni omo utor de progrmsD los textos de ott weyers IPTD IPU onstituyen l mejor refereni pr omprenderD dominr y ser usr muhs de ls idiosinrsis del C++ F v histori de wv TS se remont yw ISPD un lenguje gr(oD preursor del tul wvD propuesto por tmes umughD un ient(o lere de l progrmin ojetosF il onsorio ywq @yjet wngement qroupAD en el mito de los sistems distriuidos ojetosD tom yw omo se pr desrrollr el tul wvF

1.6 Ejercicios
IF hisee e implnte un eh que represente nmeros en punto )otnte y en el ul se espei(que l preisinD es deirD el tmo de l mntis y del exponenteF PF gritique el eh gomplejo 5 F ue tn ompleto escD es orret su espei(in semnticD u prolems de dominio y resultdos pueden ourrirc QF emple el eh gomplejo 5 pr mnejr oordends polresF hisut dnde poner l mpliin @en nuevos mtodosD en un lse derivdD etterA RF hisee e implnte un eh que represente nmeros de preisin ritrriF SF evise fuentes de progrms lires pr diujr omo Xfig y DIA e indgue l jerrqu de lses on que ellos modelizn ls (gursF TF sdenti(que los ojetos fundmentles pr l onduin de un utomvil que se enE uentrn en l inF r d unoD estlez su (n y ls operiones junto on sus espei(iones sintti y semntiF UF hisee indutivmente un jerrqu de lses que represente vehulos utomotoresF hiuje los digrms wvF VF hisee dedutivmente un jerrqu de lses que represente viviendsF hiuje los digrms wvF WF gonsidere ls siguientes lses de ojeto uyos nomres sugieren lo que representnX

26

1. Abstraccin de datos

Medio de locomocin Medio terrestre Energa Dirigible Patineta Moto Monopatn Patines Bicicleta

Medio areo Medio martimo Avin Barco Helicptero Globo Cohete Tren Sin motor

Submarino Carreta Con motor Bus

hisee un esquem dedutivo que relione ests lsesF IHF wenione tres o ms pliiones en ls que prez el prolem fundmentl de ls estruturs de dtosF r d pliinD explique l form en que pree y diserte revemente er de mo se implntrF IIF wenione tres o ms pliiones en ls que no prez el prolem fundmentl de ls estruturs de dtosF IPF wenione lguns estruturs de dtos onoids y disut su lsi(in segn los linemientos explidos en l sein IFRFI @gF PIAF IQF hdo un onjunto S de(nido por el tipo Set<T, Compare>D explique mo onoer el elemento orrespondiente l medin en el sentido estdstioF IRF hdo un onjunto S de(nido por el tipo Set<T, Compare>D explique mo se progrE mrD en funin de ls primitivs de gonjunto fundmentl 18 D l rutinX

template <class __Set> __Set extraer(__Set & set, int i, int j);
l ul extre de SD y retorn en un nuevo onjuntoD todos los elementos que estn entre ls posiiones i y j respetivmenteF hespus de l operinD S ontiene los elementos entre los rngos [0..i 1] y [j + 1..n 1]D donde n = |S|F ISF esum que el (n de un sistem es l dministrin de l esolridd de un rrer universitriF fjo este (n se dese disponer de ses de dtos de estudintesD proE fesoresD rrersD ursosD seionesD slonesD horrios y dems spetos propios de l dministrin esolr de un universiddF lntee eh generlesD prtiulres y prmetrizdosD que modelien ls diverss E striones que mnejr el sistemF hiuje los digrms wv pr tods ls lses disedsF ITF eonsidere el ejeriio nterior pr ilos esolres de seundri y primriF

Secuencias
in progrminD s omo en otros mitos de nuestr ulturD un seueni se de(ne omo un suesin de elementos de lgn tipoF or suesin entendemos que los elementos de l seueni puedn mirrse segn ierto orden de priin o proesmientoD uno trs otroD de izquierd derehD de rri hi jo y otrs ominiones que mntengn el rter suesivo suyente l ide de seueniF in l vid otidin lidimos on seuenis sin que si nun nos mrvillemos de sus onseuenisD ls ules se nos despreen en l unidd de l vidF in stellnoD y en otrs lengusD leemos y esriimos de izquierd dereh y desde rri hi joD o seD seuenilmenteF v myor de ls veesD l letur ourre sin que nuestro penE smiento interveng y frgmente el sentido de lo que leemosF heimos entones que leemos )udmenteF euenil situin vees suede en mtemtiD dominio donde solemos operrD l menos soitivmenteD de izquierd dereh y de lgunos otros modos ms reservdos pr los mtemtios exelsosF xo slo ls seuenis nos son uiusD sino que muhs vees sts tienen diferenE tes perspetivs de mir o distintos modos y tiempos pr presentrse e interpretrseF gonsideremosD por ejemploD el so de un pelul vist omo un seueni de eseE ns hilvnd segn el sentido que el diretor nos pretend trnsmitir de l historiF r proximrnos lo que omo pelul se quiere presentrD deemos mirr l pelul seuenE ilmenteF n orte en l seueni o un permutin entre sus esensD puede volver l pelul ininteligile oD quizD en el mejor de los sosD ofreer un interpretin disE tintF or supuestoD lo nterior no nos impideD en retrospetivD luego de her presenido entermente l pelulD mirr lguns de sus prtes pr mejorr nuestr omprensinF isto de otro modoD un pelul onsiste en un seueni de fotogrfs uy suesin reonstruye ls esens on impresin de reliddF il omputdor no esp l uiuidd de ls seuenisF xo muy otror fue lsi(do de mquin seuenilD pues se remite leer y ejeutr progrmsD los ules no son ms que seuenis de instruiones esrits en un memoriF re quD puesD un indiio serio de que ulquier strin de seueni es mplimente usd en l omputinF in este ptulo estudiremos ls siguientes estruturs de dtos rterizds omo seuenisX  erreglos  vists enlzds

PU

28

2. Secuencias

 ils  gols gulquier de ests estruturs es uiu por tods ls ienis omputionles y es muy prole que sen prte del mino rtio de ejeuinF or est rznD es desele onoer ls implntiones ms e(ientes posilesF vos rreglos y lists enlzds onformn striones de dtosD mientrs que ls pils y ols son striones de )ujoF n seueni de elementos del mismo tipo onform un onjuntoD lo ul sugiere de entrd que un seueniD vist omo strin de dtoD puede implntr el prolem fundmentl de estrutur de dtos estudido en el ptulo IF iste ser el nfsis que le imprtiremos los rreglos y ls lists enlzdsF ytrs situiones omputionles requieren un ptrn de proesmiento prtiulrF iste es el sentido de ls pils y ls olsD uyos nomres stren en iert form el orden de proesmientoF

2.1 Arreglos
n rreglo de dimensin dim es un seueni de n dim elementos del mismo tipo en l ul el eso d elemento es direto y onsume un tiempo onstnte e independiente de su posiin dentro de l seueniF or lo generlD los elementos de un rreglo se orgnizn de form diretmente ontigu en l memori del omputdorD lo que proporion dos onddes que hen l rreglo muy interesnte pr l progrmin de sistemsX IF e puede eder diretmente ulquier elemento segn su posiin dentro de l seueniF or lo generlD esto se implnt nivel de ompilin y se espei( nivel del lenguje de progrmin medinte el operdor []F or ejemploD l expresin en C++ X a[15] = 9 sign el entero 9 l dimo sexto elemento del rregloF PF il osto en espio es mnimoD si siempre l ntidd de elementosF xingun estrutur de dto ofree mejor rendimiento en el eso por posiinF il heho de que los elementos estn ontiguos fvoree extrordinrimente ls pliiones que exhin lolidd de refereniD pues es muy prole que los elementos ernos en espio y tiempo se enuentren en el he1 F v myor de los lengujes de progrmin modernos ofreen soporte pr el mnejo de rreglosF gonsideremos un rreglo A[11] de elementos de tipo T uyo tmo en ytes es sizeof(T) y que se pitoriz del siguiente modoX
0 Base 1 2 3 4 5 6 7 8 9 10

T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10

il ompildor soi l rreglo l direin del primer elemento llmd se del rregloD uyo vlor se determin segn el lugr donde ourr l delrin o instniin y el
1
En este contexto un cache es una estructura especial de dato, soportada por el hardware, la cual, si se usa correctamente, acelera considerablemente la velocidad de acceso a la memoria.

2.1. Arreglos

29

modo de delrinF gundo el ompildor enuentr un eso l iEsim posiinD ste gener el siguiente lulo de eso l memoriX hirein del elemento = base + i sizeof(T) @PFIA

v operin sume que el primer ndie del rreglo es eroD que es el so en los lengujes C y C++ F i el lenguje permite que los ndies omienen en vlores ritrriosD entones el ompildor dee generr un operin diionl ntes de poder her el lulo nteriorD lo que he un poo ms lento el esoF in generlD los ompildores no efetn veri(in de rngoF is deirD no se segurn de que el ndie de refereni l rreglo est dentro de los rngos orretosF v rzn es que est veri(in le de un oste onstnte d eso que puede ser importnteF gonseuentementeD un eso fuer de rngo es un grve error de progrmin uyos sntoms pueden psr desperiidos durnte lgn tiempoF iste tipo de error es muy difil de detetrD rzn por l ul es uen ide utilizr sertos2 de veri(in de rngos ntes de referenir un rregloF
2.1.1 Operaciones bsicas con Arreglos

ry vrios spetos onsiderr l hor de operr sore rreglosX  i los elementos estn o no ordendosF  i se onoe el orden de inserinGsupresin de los elementosF  i se onoe on ntelin el nmero de elementosF  u tn itertivs sern ls operionesc n lt intertividd signi( que ls inserionesD squeds y eliminiones pueden sueder freuentemente y on l mism proiliddF  il tmo y ptrn de eso de los elementos que lerg el rregloF gunto ms grnde se el elementoD menos ene(ios se otendrn por el heF
2.1.1.1 Aritmtica de punteros

n de ls grndes virtudes del lenguje CD trsendid l C++ D es lo que se onoe omo ritmti de punterosF l onepto onsiste en inorporr l lenguje operiones sore punteros uyos resultdos onsidern el tipo de dto l ul se puntF r lrr este onepto desrrollemos un ejemploF v instruin T * arreglo_ptr = new T[nY delr un puntero un eld de memori de tipo genrio TF e l vezD se prt memori pr lergr n elds onE tigus de tipo TD o seD un rreglo de dimensin nF xormlmenteD si arreglo_ptr es l se de un rregloD entonesD pr eder l iEsimo elemento tendrmos que efetur un lulo similr @PFIAF ehor ienD el lulo imE plido en @PFIA lo gener utomtimente el ompildor undoD por ejemploD esriiE mosX *(arreglo_ptr + i) = 5;F il operndo izquierdo de l signin se interpret
2
El D.R.A.E. expresa para aserto:

e(rmin de l ertez de lgo .

A un aserto se le conoce ms

como precondicin o invariante. En este texto se utilizan invocaciones a la primitiva

I(predicado)

de la biblioteca

nana

[144].

30

2. Secuencias

omoX ed l ontenido de l direin de memori arreglo_ptr ms i enterosF il ompildor se que se trt del tipo int y no de otro porque el puntero fue delrdo omo un puntero enteroF gon este onoimientoD el ompildorD implit y trnsprenE tementeD inorpor el tmo de un entero @sizeof(int)A en el lulo del esoF v expresin *(arreglo_ptr + i) es extmente equivlente arreglo_ptr[i]D l ul se trdueX ed l iEsimo entero de l seueni uy direin se es arreglo_ptrF uiz un prolem de este enfoque es que es ms difil distinguir el eso un rreglo explitmente delrdo de un eso medinte un punteroF or est rzn es onveniente que el nomre del puntero re)eje su ondiinF in el so ejemploD el su(jo ptr3 denot que se trt de un puntdorF
2.1.1.2 Bsqueda por clave

30

i los elementos estn ordendosD entones podemos usr un fuloso lgoritmo llmdo squed inriD uy espei(in genri es omo sigueX Bsqueda binaria 30 template <typename T, class Compare> int binary_search(T a[], const T & x, int l, int r) { int m; // ndice del medio while (l <= r) // mientras los ndices no se crucen { m = (l + r)/2;
if (Compare() (x, a[m])) // es x < a[m]? r = m - 1; else if (Compare() (a[m]), x) // es x > a[m]? l = m + 1; else return m; // ==> a[m] == x ==> encontrado!

} return m;

Denes:

binary_search,

used in chunks 31a and 32.

binary_search<T, Compare>() us un ourreni del elemento xD de tipo genrio D dentro del rngo omprendido entre l y r del rreglo ordendo aF il prinipio de l squed inri es dividir el rreglo en dos prtes igules de tmo m = (l + r)/2D y en so de que a[m] no onteng xD usr en lgun de ls mitdes segn el orden de x respeto a[m]F xtese que binary_search<T, Compare>() retorn un posiin vlid un si x no se enuentr en el rregloF isto requiere que el lienteD luego de l squedD ompre de nuevo x on el vlor de retorno pr veri(r si x fue hlldo o noF eunque esto onllev un ligero osteD permite onoer l posiin en dnde se insertr x en el rreglo de mner que ste sig ordendoF gomo estudiremos en l susein QFIFW @gF ITSAD el rendimiento de este lgoE ritmo es proporionl lg nF i ien este oste es myor que el onstnte del eso por posiinD en l prti es stnte uenoF
3
Abreviacin en ingls de pointer.

2.1. Arreglos

31

i los elementos no estn ordendosD entones puede efeturseD ost del desemE peoD l squed seuenil desrit en IFPFQFQ @gF ISA jo el nomre de funE in sequential_search<T, Compare>()F i ien l iterin requerid por est lse de squed puede requerir inspeionr tods ls elds del rregloD es eptle omo soluin pr esls medinsF
2.1.1.3 Insercin por clave

31a

i el rreglo se mntiene desordendoD entones l inserin es rpidsim medinte E didur l (nl de l seueniF he lo ontrrioD l inserin deviene ms ostosD pues se requiere usr en el rreglo l posiin de inserinD luegoD desplzr los elementos de l seueni en un posiin hi l dereh yD (nlmenteD opir el elementoF l lgoritmo se denomin inserin por pertur de reh y se instrument omo sigueX Insercin por brecha 31a template <typename T, class Compare> void insert_by_gap(T a[], const T & x, int & n) { const int pos_gap = binary_search<T, Compare>(T, x, 0, n - 1); for (int i = n; i > pos_gap; i) a[i] = a[i - 1];
a[pos_gap] = x; ++n;
binary_search
30.

}
Uses

iste lgoritmo se pitoriz del siguiente modoX

...

orden

...
pos_gap

...

orden

...
n

-i

v rutin sume que n es l ntidd de elementos que tiene l seueni y que este vlor no igul o exede l dimensin del rregloF insert_by_gap<T, Compare>() tom el tiempo de squedD que es rpidsimoD ms el tiempo de rir l reh que requiere l iterin y l opiF
2.1.1.4 Eliminacin por clave

31b

gon rreglosD l eliminin primero requiere onoer l posiin dentro del rreglo del elemento eliminrF isto puede herse medinte l rutins sequential_search<T, Compare>() o binary_search<T, Compare>()D segn que el rreglo est o no ordendoF in ms situionesD el elemento elimindo dej un hueo o reh que dee tprseF i el rreglo est desordendoD entones l eliminin puede llevrse o omo sigueX Eliminacin en arreglo desordenado 31b template <typename T, class Equal> void remove_in_unsorted_array(T a[], const T & x, int & n) { const int pos_gap = sequential_search<T, Equal>(T, x, 0, n - 1); if (a[pos_gap] != x)

32

2. Secuencias

// excepcin: x no se encuentra en a[] a[pos_gap] = a[n - 1]; n;


sequential_search
154a.

}
Uses

32

remove_in_unsorted_array<T, Equal>() tp l reh on el ltimo elemento de l seueniF i el rreglo est ordendoD entones se requiere tpr l reh medinte desplzE miento hi l izquierd de todos los elementos que estn l dereh de l reh de l siguiente formX Eliminacin en arreglo ordenado 32 template <typename T, class Equal> void remove_in_sorted_array(T a[], const T & x, int & n) { const int pos_gap = binary_search<T, Equal>(T, x, 0, n - 1); if (a[pos_gap] != x) // excepcin: x no se encuentra en a[] ;
for (int i = pos_gap; i < n; ++i) a[i] = a[i + 1]; }
Uses

n;
binary_search
30.

v tni en uestin se pitoriz de l siguiente formX

...

orden

...
pos_gap

...

orden

...
n

++i

2.1.2

Manejo de memoria para arreglos

egn el esquem en que se prte l memori pr un rregloD ste se lsi( en esttio y dinmioF
2.1.2.1 Arreglos en memoria esttica

iste tipo de rreglo se delr glol o esttimente dentro de un funin 4 y exige que se onoz l dimensin en tiempo de ompilinF il rreglo oup todo su espio durnte tod l vid del progrm y su dimensin no puede mirseF in generlD este tipo de rreglo dee usrse pr gurdr onstntes que sern utiE lizds lo lrgo de tod @o l myor prte deA l vid del progrmF min puede utilizrse omo depsito de vlores itertivosY por ejemploD un pliin numri que
4
En C y en palabra reservada

C++ , un arreglo static. En el

esttico se declara dentro de una funcin o un mdulo precedido de la caso de un mdulo, el arreglo slo es visible dentro del mdulo y a partir

del punto de declaracin. En el caso de una funcin, el arreglo slo es visible dentro de la funcin.

2.1. Arreglos

33

siempre efete operiones on mtries de dimensin (j y uyo vlores min en funin de l entrd del prolemF
2.1.2.2 Arreglos en pila

iste tipo de rreglo es el que se delr dentro de un funin 5 F il espio de memori es prtdo de l pil de ejeuin del progrmF uesto que l pil de ejeuin es vitl pr el progrmD se dee tener uiddo on un desorde de pil usdo por un exesiv longitud del rregloF isto puede ser rtio en progrms onurrentes multiEthred o en mientes que soporten orrutinsF v ventj de este tipo de rreglo es doleF rimero el ompildor no requiere onoer su dimensin pr generr ulquier digo de reservin de memori o de refereni l rregloF in onseueniD es posile esperr hst ejeutr l delrin pr onoer su dimensinF v siguiente sein de digo es ftile en ompildores [ qxX
void foo(size_t n) { int array[n]; ... }

v segund ventj es que el espio oupdo por el rreglo se prt utomtimente en el momento de ejeuin de l delrin y se lier l slid del mito de l delrinF in el ejemplo nteriorD el rreglo es lier l slid de l funin foo()F e us del riesgo de desorde de pilD el uso de este tipo de rreglo dee restringirse dimensiones pequesF hee prestrse tenin esmerd l nivel de ls llmds ls funionesD pues medid que se niden ls llmdsD se onsume ms pilF xo use rreglos en pil dentro de funiones reursivs o dentro de funiones que sern llmds reursivmenteF
2.1.2.3 Arreglos en memoria dinmica

n rreglo en memori dinmi es quel prtdo trvs del mnejdor de memoriF in C++ D por ejemploD l siguiente instruin reserv un rreglo de 1000 enterosX
int * array = new int [1000];

il tmo del rreglo slo est limitdo por l ntidd de memori disponileF v dimensin puede espei(rse omo un vrileF iste tipo de rreglo exige que l memori se liere undo el rreglo y no se requierF in el ejemplo nteriorD esto se efet medinteX
delete [] array;

is importnte resltr que el operdor delete [] dee impertivmente usr los orhetesD pues est es l mner de indir l ompildor que se lier un rreglo y no un loque de memoriF e requiere de est sintxis porque es neesrio llmr todos los destrutoresY uno por d entrd del rregloF v memori del rreglo dee lierrse pens estemos seguros de que ste no ser requeridoF il rreglo en memori dinmi es l opin de fto pr l myor de ls pliiones que usen rreglos de dimensin medin o grndeF helegue l veri(in de rngos utilitrios de depurin espeilizdos tles omo dmalloc IUW o valgrind IPWF
5
Atencin: esto no necesariamente es cierto en otros lenguajes. En FORTRAN, por ejemplo, la mayora de los arreglos son estticos.

34

2. Secuencias

2.1.3

Arreglos dinmicos

n rreglo dinmio es qul en el ul su dimensin puede modi(rse dinmimenteF isto es muy til pr pliiones que se deen ene(ir del rpido eso por posiinD pero que no onoen el nmero de elementos que se pueden mnejrF or ejemploD un tipo espeil de reuperin lveEdireinD llmdo hshing dinmioD ument y ontre progresivmente l dimensin de un rregloF ist estrutur se expli en l sein SFIFU @gF RIPAF C y C++ no soportn rreglos dinmiosF isto impli que los rreglos dinmios deen surtirse por un eh en ilioteF ehor ienD mo implementr un rreglo dinmioc v ndidez sugiere que se relolie el rregloF sniilmente se (j un dimensin y se prt memori pr el rregloF i l dimensin es lnzdD entones se determin un nuev dimensin myor y se prt un nuevo loque de memoriF hespusD los elementos se opin l nuevo loque yD (nlmenteD se lier el ntiguo loqueF iste enfoque h sido utilizdo on xito en lgunos sistems importntesF v iliote estndr C ofree un primitivD realloc()D uy sintxis es l siguienteX
void *realloc(void *ptr, size_t size);

v rutin mi el tmo del loque de memori puntdo por ptrD el ul dee her sido otenido de llmds previs malloc()D calloc() o realloc()F il onE tenido de ptr permneer inmodi(do l mnimo posile entre el ntiguo y el nuevo tmo sizeF erimenteD realloc() es inteligente y pz de prtr un loque ms grnde sin mir l direin de memoriF isto es interesnte porque se evit l opi de los elementos del ntiguo loque hi el nuevoF imperoD en l prtiD esto no es su(iente porque no es un grntF he hehoD muy pos implementiones de realloc() hen un esfuerzo por veri(r si hy memori ontigu disponile ptrF
2.1.4 El TAD

DynArray<T>

34

in est sein mostrremos tod l interfz e implementin de un ehD llmdo DynArray<T>D el ul modeliz un rreglo dinmio de elementos de tipo TF DynArray<T> stre un dimensin tul on un vlor iniil espei(do en tiempo de onstruinF l dimensin tul se onoe medinte el mtodo size()F DynArray<T> grntiz un onsumo de memori proporionl l ntidd de enE trds esrits del rregloD es deirD ls entrds que no hn sido esritsD no neesriE mente onsumen memoriF v memori se reserv slo undo se esrien ls entrds por primer vezF v dimensin tul se expnde perezos y utomtimente undo se esrie sore un ndie que est fuer de l dimensin tulF i se refereni un ndie omo letur myor o igul l dimensin tulD entones se gener l exepin fuer de rngoF v dimensin tul puede ontrerse explitmente medinte un operin llmd cut()F v funin lier entones tod l memori oupd entre l nuev y nterior dimensin tulF DynArray<T> se espei( en el rhivo tpldynerryFr 34 D el ul export l lse prmetrizd DynArray<T>X tpl_dynArray.H 34

2.1. Arreglos

35

template <typename T> class DynArray { miembros constantes de DynArray<T> 37a miembros privados de DynArray<T> 38b miembros pblicos de DynArray<T> 42 }; Iniciacin constantes DynArray<T> (never dened)
Denes:

DynArray,

used in chunks 42, 43c, 45a, 49, 50a, 54b, 155b, 253, 315a, 36163, 607, 630a, 633c, 641,

693b, 704, and 756.

is indispensle que exist el onstrutor por omisin T::T()D s omo el destruE tor T::~T()F v useni de ulquier de ellos se report omo error en tiempo de ompilinF n DynArray<T> soi un dimensin mximF n rreglo no puede expndirse ms ll de quell dimensinF or omisinD l dimensin mxim es 2 qig entrds @2 1024 1024 1024A6 F

...

...

. . . . . . . . .

. . .
Bloques

. . .

dir_size

. . .
Segmento

. . .

block_size

...
seg_size

Directorio

. . . . . . . . . . . .

. . .

pigur PFIX istrutur de dtos de DynArray<T>


Sobre una mquina de 32 bits, Pentium III, por ejemplo, un proceso dispone de un espacio de direc232 . Como el espacio de direccionamiento debe contener el cdigo del programa, sus datos 32 estticos y sus datos dinmicos, la cantidad de espacio disponible es menor que 2 . Adems, el sistema cionamiento de operativo reserva una parte del espacio de direccionamiento para s mismo. Un arreglo de 2 Giga enteros cortos (short) no cabra en un proceso. Por otra parte, se requerira al menos una memoria virtual de Giga bytes para albergar este arreglo. Por estas razones creemos que mayora de las situaciones. Lo anterior deja de ser vlido en sistemas persistentes en los cuales grandes arreglos son mapeados en disco y en memoria y dinmicamente cargados a la demanda. Las arquitecturas de 64 bits o ms, hacen posible espacios de direccionamiento persistentes de envergadura muy grande. Empero, la consecucin de un sistema operativo, paradigma de la persistencia, es an un tema muy inmaduro de investigacin.

Giga entradas es suciente para la

36

2. Secuencias

2.1.4.1

Estructura de datos de

DynArray<T>

v (gur PFI @pgin QSA esquemtiz l representin en memori de un DynArray<T>D l ul ilustr tres lses de omponentesX
Directorio: Segmento:

erreglo de puntdores segmentos uy dimensin es dir_sizeF

erreglo de |puntdores loques uy dimensin es seg_sizeF ueden existir hst dir_size segmentosF erreglo de elementos de tipo T uy dimensin es block_sizeF in totlD pueden existir hst dirsize segsize loquesF vos loques lmenn los elemenE tos del rregloF v dimensin mxim del rreglo es dirsize segsize blocksize elementosF

Bloque:

il rter dinmio del rreglo reside en el heho de que slo se utilizn los loques y segmentos que orresponden elementos del rreglo que y hn sido esritos o medinte un mtodo espeil llmdo touch()F hdo un ndie iD el eso impli lulr l entrd en el diretorioD luego l entrd en el segmento yD (nlmenteD l entrd en el loqueF istos lulos pueden efeturse omo sigueX
ndice del segmento en el directorio:

gd segmento represent segsize blocksize elementos del rregloF il ndie en el diretorio est ddo por l expresin siguienteX

posindir =

tilizremos el nomre de vrile pos_in_dir d vez que requirmos lmenr un ndie en el diretorioF
ndice del bloque en el segmento:

i segsize blocksize

@PFPA

il resto de l divisin @PFPAD denotdo restoD exE pres el nmero de loques que fltn pr llegr l ndie iF uesto que d loque posee block_size elementosD l posiin dentro del segmento est dd porX resto posinseg = @PFQA blocksize honde resto se de(ne omoX resto = i mod (segsize blocksize) @PFRA

il nomre de vrile pos_in_seg ser utilizdo d vez que se desee memorizr un ndie de segmentoF
ndice del elemento en el bloque:

il ndie del elemento dentro del loque se otiene trvs del resto de l divisin @PFQAF es puesD el resto de est divisin es el nmero de elementos que fltn pr llegr l iEsimo elemento dentro del loqueX

posinblock = resto mod blocksize

@PFSA

2.1. Arreglos

37

ustituyendo @PFRA en @PFSAX

posinblock = (i mod (segsize blocksize)) mod blocksize

@PFTA

ists operiones deen efeturse siempre que se desee her un esoF uesto que d operin tom un mximo de tiempo onstnteD se grntiz que el eso un rreglo dinmio tome un mximo de tiempo que tmin es onstnteF r mejorr el tiempo de lulo de @PFPAD @PFQA y @PFTAD los tmos de diretorioD de segmento y de loque son potenis exts de dosF he est formD l multipliin y l divisin pueden herse on simples desplzmientosF e efetos de gnr tiempo de ejeuinD lgunos lulos se relizn en tiempo de onstruin y jms vuelven modi(rse durnte el tiempo de vid de un instni de DynArray<T>F
37a

miembros constantes de DynArray<T> 37a


mutable size_t pow_dir; mutable size_t pow_seg; mutable size_t pow_block;

(34) 37b

ists onstntes lmenn ls potenis de 2 de ls longitudes del diretorioD segmento y loqueD l ules son 2pow_dir D 2pow_seg y 2pow_block respetivmenteF v dimensin mxim resultnte es 2pow_dir 2pow_seg 2pow_block F i este lulo result myor que l mxim dimensin permitid Max_Dim_AllowedD entones se gener l exepin std::length_errorF i no hy pidd numri pr efetur ls operE iones medinte desplzmientosD entones se gener l exepin std::overflow_errorF entes de ontinurD tngnse en uent ls siguientes igulddesX

segsize = 2pow_seg blocksize = 2


ustituyendo @PFUA y @PFVA en @PFPA tenemosX
pow_block

@PFUA @PFVA

posindir =
37b

2pow_seg

miembros constantes de DynArray<T> 37a +


mutable size_t seg_plus_block_pow;

i i = (pow_seg+pow_block) pow _ block 2 2


(34) 37a 38a

@PFWA

il vlor 2(pow_seg+pow_block) se gurd previmente en seg_plus_block_pow pr fuE turos lulosF ustituyendo @PFUA y @PFVA en @PFRAD tenemosX resto = i mod (2pow_seg 2pow_block ) = i mod 2(pow_seg+pow_block) @PFIHA

ehor deemos enontrr un mner de lulr rpidmente el oiente y el resto de un divisin entre un poteni ext de 2F r el so del lulo de l expreE sin @PFWAD y semos que el oiente es el resultdo de desplzr i hi l dereh seg_plus_block_pow veesF he est mnerD l expresin @PFWA resultD medinte deE splzmientosD enX

posindir = i

segplusblockpow

@PFIIA

38

2. Secuencias

il resto est ddo por los seg_plus_block_pow its menos signi(tivos de iF r onoE er los seg_plus_block_pow its menos signi(tivos onstruimos un nmero on los seg_plus_block_pow its menos signi(tivos en uno y los restntes en eroF
38a

miembros constantes de DynArray<T> 37a +


mutable size_t mask_seg_plus_block;

(34)

37b 39b

mask_seg_plus_block se lul del siguiente modoX


masksegplusblock = 2seg_plus_block_pow 1
@PFIPA

in se inriD 2seg_plus_block_pow ontiene puros eros exepto un uno en l posiE in seg_plus_block_powF gomo hy seg_plus_block_pow eros ntes de llegr l nio unoD d it provo un presto que es por (n pgdo undo se lleg l it en seg_plus_block_powF es puesD este nmero tiene los primeros seg_plus_block_pow en uno y los restntes en eroF il resto en l expresin @PFIHA puede lulrse on un AND lgio uyo operdor en C++ es &X resto = i AND masksegplusblock = i & masksegplusblock @PFIQA

is omn denotr l vrile mask_seg_plus_block omo un msr porque enmsr los its l izquierd de seg_plus_block_powF
38b

miembros privados de DynArray<T> 38b


size_t mask_seg; size_t mask_block;

(34) 39a

mask_seg se denot por l siguiente expresinX


maskseg = 2pow_seg 1 = segsize 1 ;
vo que permite un lulo pr l posiin en el loqueX @PFIRA

posinseg = resto >> powblock


honde resto es @PFIQAF mask_block se denot porX

@PFISA

maskblock = 2pow_block 1 = blocksize 1

@PFITA

r lulr el ndie dentro de un loque @PFSAD hy que lulr el resto de dividir entre block_sizeF r ello utilizmos l msr mask_blockF he est formD @PFTA se plnte omo sigueX

posinblock = (i & masksegplusblock) & maskblock

@PFIUA

ehor podemos implntr e(ientemente los esos l diretorioD segmento y loque expresdosF r ello islremos los lulos en funiones seprds on nomres que

2.1. Arreglos

39

39a

indiquen lrmente los lulos en uestinX miembros privados de DynArray<T> 38b + (34) size_t index_in_dir(const size_t & i) const { return i  seg_plus_block_pow; } size_t modulus_from_index_in_dir(const size_t & i) const { return (i & mask_seg_plus_block); } size_t index_in_seg(const size_t & i) const { return modulus_from_index_in_dir(i)  pow_block; } size_t index_in_block(const size_t & i) const { return modulus_from_index_in_dir(i) & mask_block; }

38b 39c

index_in_dir() lul el ndie dentro del diretorio ddo el ndie del rreglo i medinte l expresin @PFIIAF index_in_seg() lul el ndie dentro del segmento ddo el ndie del rreE glo i segn l @PFISAF ist funin requiere el vlor resto que orresponde modulus_from_index_in_dir()) segn @PFIQAF index_in_block() lul el ndie dentro del loque ddo el ndie i del rreglo segn @PFIUAF gomo ls funiones son inlineD l seueni intern de operiones se expone ompleE tmente l optimizdor del ompildorD el ul es pz de efetur muhs optimizionesD por ejemploD l de memorizr el resto de l divisin efetud en el lulo del ndie del diretorioF
39b

miembros constantes de DynArray<T> 37a +


mutable size_t max_dim;

(34)

38a

// 2^(pow_dir + pow_seg + pow_block) - 1

max_dim lmen l mxim dimensin que puede lnzr el rreglo segn ls lonE gitudes del diretorioD segmento y loqueF
39c

miembros privados de DynArray<T> 38b +


size_t current_dim; size_t num_segs; size_t num_blocks;

(34)

39a 40a

current_dim lmen l dimensin tulF num_segs y num_blocks ontilizn el totl de segmentos y de loques que hn sido reservdosF
2.1.4.2 Manejo de memoria

in el mnejo de memori se deen onsiderr los siguientes spetosX  il vlor NULL indi que un entrd de diretorio o segmento no tiene memori prtdF isto impli que undo un loque es lierdoD l entrd en el diretoE rio dee ser resturd l vlor NULLF

40

2. Secuencias

 vos segmentos y loques reservdos o lierdos deen ontilizrseF v entrd l diretoriosD segmento y loque omienz prtir del diretorioD el ul se delr omo sigueX miembros privados de DynArray<T> 38b + (34) 39c 40b T *** dir;

40a

40b

dir represent el puntdor l diretorioF il mnejo de memori se reliz medinte mtodos privdos espeilizdos que seprn los detlles en puntos niosD senillos de depurr y mntenerX miembros privados de DynArray<T> 38b + (34) 40a 40c
void fill_dir_to_null() { for (size_t i = 0; i < dir_size; ++i) dir[i] = NULL; } void fill_seg_to_null(T ** seg) { for (size_t i = 0; i < seg_size; ++i) seg[i] = NULL; }

fill_dir_to_null() segur que tods ls entrds del diretorio sen nulsF il vlor NULL indi que l entrd del diretorio no posee un segmento reservdoF enlogE menteD un NULL en un entrd de un segmento indir que l entrd no posee un loque reservdoF fill_seg_to_null() iniiliz7 tods l entrds del segmento puntdo por seg l vlor NULLF fill_dir_to_null() se llm undo se re el diretorio y fill_seg_to_null() undo se re un nuevo segmentoF
40c

miembros privados de DynArray<T> 38b +


void allocate_dir() { dir = new T ** [dir_size]; fill_dir_to_null(); } void allocate_segment(T **& seg) { seg = new T* [seg_size]; fill_seg_to_null(seg); ++num_segs; }

(34)

40b 41a

allocate_dir() reserv memori pr el diretorio y (j tods sus entrds en NULLF allocate_segment() sign l puntero seg l direin de memori de un nuevo segE mento uys entrds estn iniilizds en NULLF vs entrds del diretorio y de los segmentos siempre deen iniilizrse en NULLF dir[i] == NULL indi que no se h prtdo un segmentoD mientrs que dir[i][j] == NULL indi que no se h prtdo el loqueF
7
El verbo inicializar ya es parte real de la lengua espaola.

2.1. Arreglos

41

41a

in el so de iniilizr un loque deemos onsiderr l posiilidd de que el usurio de DynArray<T> espei(que un vlor iniilF r ello gurdremos en los siguientes mpos un vlor iniil de T de tods ls entrds de un loqueX miembros privados de DynArray<T> 38b + (34) 40c 41b T default_initial_value; T * default_initial_value_ptr;

default_initial_value lmen el vlor iniilD mientrs que default_initial_value_ptr un puntero l eld nteriorF or omisinD este puntero es NULLD de modo tl queD tmin por omisinD no se relie un iniilizin explitD sino l implit suyente l onstrutor por omisin T::T()F or est rznD todos los onstrutores de DynArray<T> iniilizn default_initial_value_ptr en NULL
41b

miembros privados de DynArray<T> 38b +


void allocate_block(T *& block) { block = new T [block_size]; ++num_blocks;

(34)

41a 41c

if (default_initial_value_ptr == NULL) return; for (size_t i = 0; i < block_size; ++i) block[i] = default_initial_value;

allocate_block() sign l puntero block l direin de memori de un nuevo loqueF egn se hy o no espei(do un vlor por omisinD se reorrer block y se le signr el vlor default_initial_valueD lo que exige l existeni del operdor de signin T & operator = (const T &)F
41c

miembros privados de DynArray<T> 38b +


void release_segment(T **& seg) { delete [] seg; seg = NULL; num_segs; } void release_block(T *& block) { delete [] block; block = NULL; num_blocks; }

(34)

41b 41d

istos mtodos se enrgn de lierr onsistentemente un segmento o un loqueF ytr mner de lierr involur un segmento on todos sus loquesD o todos los segmentos y loques del rreglo o el diretorioX
41d

miembros privados de DynArray<T> 38b +

(34)

41c 43b

void release_blocks_and_segment(T ** & seg) {

42

2. Secuencias

for(size_t i = 0; i < seg_size ; ++i) if (seg[i] != NULL) release_block(seg[i]); release_segment(seg); } void release_all_segments_and_blocks() { for(size_t i = 0; i < dir_size ; ++i) if (dir[i] != NULL) release_blocks_and_segment(dir[i]); current_dim = 0; } void release_dir() { release_all_segments_and_blocks(); delete [] dir; dir = NULL; current_dim = 0; }
2.1.4.3 Especicacin e implantacin de mtodos pblicos

42

il onstrutor por omisin plnte un sutilez er de l selein del tmo del loqueX miembros pblicos de DynArray<T> 42 (34) 43c DynArray(const size_t & dim = 0) : pow_dir ( Default_Pow_Dir ), pow_seg ( Default_Pow_Seg ),
seg_plus_block_pow ( pow_seg + pow_block mask_seg_plus_block ( two_raised(seg_plus_block_pow) - 1 dir_size ( two_raised(pow_dir) seg_size ( two_raised(pow_seg) block_size ( two_raised(pow_block) max_dim ( two_raised(seg_plus_block_pow + pow_dir) mask_seg ( seg_size - 1 mask_block ( block_size - 1 current_dim ( dim num_segs ( 0 num_blocks ( 0 default_initial_value_ptr (NULL) allocate_dir();
DynArray
34.

Determinacin de la potencia de 2 del bloque 43a

), ), ), ), ), ), ), ), ), ), ),

{ }
Uses

gomo se veD el onstrutor seleion un longitud de loqueF gunto ms grnde se est longitudD menor ser l ntidd de reserviones de memori usds por l expnsin del rregloF n tmo de loque muy pequeo implir que nuevos loques tendrn

2.1. Arreglos

43

que prtrse muy menudoF in didurD l mxim dimensin del rreglo ser muy limitdF heemos privilegir un longitud de loque ms o menos grndeF in prinipio se seleion un otv prte de l dimensin iniil espei(d en el onstrutorF il nio prolem ourre undo el usurio sugiere un dimensin iniil muy pequeD lo ul rrer un tmo de loque muy pequeoF r evitr estoD seleionmos un poteni de 2 de se omo longitud mnim del loqueF gomo se espei( en miemros onstntes de DynArray<T> 37a D tl poteni ser el vlor de 12D equivlente 4096 entrdsD lo que rroj un dimensin mxim por omisin de 24 +26 +212 = 222 = 4194304F in un mquin de QP itsD MaxBitsAllowed = 32F intonesD quedrn 32 22 1 potenis de dos de ms pr un loque ntes de llegr Max_Bits_AllowedF v mxim poteni de dos del tmo de un loque serX

MaxPowBlock = 32 DefaultPowDir DefaultPowSeg 1 = 21

@PFIVA

vo que he un mxim dimensin direionle on el onstrutor por omisin deX

2Default_Pow_Dir 2Default_Pow_Seg 221 = 24 26 221 = 536870912 ,


dimensin ms que su(iente pr l myor de los rreglos que quepn en memoriF v mxim poteni de dos del loque es lmend en un onstnte luld segn @PFIVAF es puesD se dee grntizr que DefaultPowBlock powblock MaxPowBlockF ist expresin se trdue del siguiente modoX Determinacin de la potencia de 2 del bloque 43a (42) pow_block (std::min(Default_Pow_Block, Max_Pow_Block)), il lulo de l prxim poteni de dos de un nmero es relizdo por l funin estti next2PowX miembros privados de DynArray<T> 38b + (34) 41d 44a static size_t next2Pow(const size_t & number) { return (size_t) ceil( log((float) number)/ log(2.0) ); } il onstrutor opi y el operdor de signin relizn un operin omnX ls reserviones de memori y opis del diretorioD segmentos y loques del rreglo destinoD se por el onstrutor o por l signinF or elloD enpsulmos est operin en un mtodo privdo omn llmdo copy_array()X miembros pblicos de DynArray<T> 42 + (34) 42 45a void copy_array(const DynArray<T> & src_array) { for (int i = 0; i < src_array.current_dim; ++i) if (src_array.exist(i)) (*this)[i] = src_array.access(i); }
Uses

43a

43b

43c

DynArray

34.

44

2. Secuencias

44a

copy_array() he uso de dos mtodos plios que implntremos ms delnteF src_array.exist(i) retorn true si l iEsim entrd existe en src_arrayY flseD de lo ontrrioF src_array.access(i) retorn l iEsim entrd de src_array sin veriE (r que dih entrd existY es deirD que teng un segmento y un loque prtE dosF xo hy neesidd de veri(r que hy memori porque esto fue veri(do on src_array.exist(i)F il operndo izquierdo de l signinD (*this)[i] = ... prt el segmento o el loque si se requiereF xotemos que copy_array() reorre d posiin de los rreglosF ry un mner muho ms e(ienteD pero ms difilD de implntr que se vle de l opi diret de loquesF v di(ultd estri undo los rreglos tienen tmos de segmentos y loE ques diferentesF l implntin se deleg ejeriioF gomo yudD se provee el mtodo advance_block_index()D el ulD ddos los ndies del segmento y del loqueD lul los ndies orrespondientes len loquesX miembros privados de DynArray<T> 38b + (34) 43b 44b
size_t divide_by_block_size(const size_t & number) const { return number  pow_block; } size_t modulus_by_block_size(const size_t & number) const { return number & mask_block; } void advance_block_index(size_t & block_index, size_t & seg_index, const size_t & len) const { if (block_index + len < block_size) { block_index += len; return; } seg_index += divide_by_block_size(len); block_index = modulus_by_block_size(len); }

44b

ytr form de opir rpidmente requiere segurr que el rreglo destino teng exE tmente l mism estrutur que el del fuenteD es deirD los tmos de diretorioD segmento y loque deen ser idntiosF fjo es premis podemos opir slo quells entrds que ontengn memori de l siguiente mnerX miembros privados de DynArray<T> 38b + (34) 44a 49a void allocate_dir(T *** src_dir) { allocate_dir(); for (int i = 0; i < dir_size; i++) if (src_dir[i] != NULL) allocate_segment(dir[i], src_dir[i]); } il mtodo he uso de l primitiv allocate_seg() en su versin de opiD l ulD su vezD he uso de allocate_block(seg[i], src_seg[i])F ists primitivs no estn mostrds en este textoD pero son filmente

2.1. Arreglos

45

45a

deduilesF wedinte allocate_dir() en su versin de opi podemos ofreer un modelo de opi ms e(ienteF ist form de opi l llmremos copy_array_exactly() y l de(nimos jo el siguiente modoX miembros pblicos de DynArray<T> 42 + (34) 43c 45b void copy_array_exactly(const DynArray<T> & array) { release_dir(); // liberar toda la memoria de this pow_dir = array.pow_dir; // asignar el resto de los atributos ... allocate_dir(array.dir); }
Uses

DynArray

34.

45b

wedinte allocate_dir() se puede implntr e(ientemente el onstrutor opiF v signinD por el ontrrioD he l opi de elemento por elementoD lo que no es lo ms e(ienteF il eso un elemento de un DynArray<T> puede herse diretmente medinteX miembros pblicos de DynArray<T> 42 + (34) 45a 45c T & access(const size_t & i) { return dir[index_in_dir(i)][index_in_seg(i)][index_in_block(i)]; }

45c

access() no veri( que l memori del loque y su segmento hy sido prtdF iste mtodo dee usrse slo undo se est solutmente seguro de que se h esrito en l posiin de eso iF r indgr si un entrd dd puede ederse sin errorD es deirD que st teng su loque y su segmentoD se proveeX miembros pblicos de DynArray<T> 42 + (34) 45b 45d
bool exist(const size_t & i) const { const size_t pos_in_dir = index_in_dir(i); if (dir[pos_in_dir] == NULL) return false; const size_t pos_in_seg = index_in_seg(i); if (dir[pos_in_dir][pos_in_seg] == NULL) return false; } return true;

45d

exist() retorn true si l posiin i tiene su loque y segmentoY falseD de lo ontrrioF in muhs osiones se requiere veri(r existeni de un entrd yD si st existeD entones relizr el esoF r evitr horrr el dole lulo de ndies en diretorioD segmento y loqueD podemos exportr l primitiv siguienteX miembros pblicos de DynArray<T> 42 + (34) 45c 46a T * test(const size_t & i) const {

46

2. Secuencias

const size_t pos_in_dir = index_in_dir(i); if (dir[pos_in_dir] == NULL) return NULL; const size_t pos_in_seg = index_in_seg(i); if (dir[pos_in_dir][pos_in_seg] == NULL) return NULL; } return &dir[index_in_dir(i)][index_in_seg(i)][index_in_block(i)];

46a

ist es l mner ms rpid posile de eder un entrd del rreglo dinmioF xotemos sin emrgo que no se he ningun veri(inF i l entrd existeD entones test() retorn un puntero l entrdY NULL de lo ontrrioF r prtr explitmente el loque y segmento de un posiin dentro del rregloD se proveeX miembros pblicos de DynArray<T> 42 + (34) 45d 46b T & touch(const size_t & i) { const size_t pos_in_dir = index_in_dir(i); if (dir[pos_in_dir] == NULL) allocate_segment(dir[pos_in_dir]);
const size_t pos_in_seg = index_in_seg(i); if (dir[pos_in_dir][pos_in_seg] == NULL) allocate_block(dir[pos_in_dir][pos_in_seg]); if (i >= current_dim) current_dim = i + 1; } return dir[pos_in_dir][pos_in_seg][index_in_block(i)];

46b

min puede prtrse tod l memori requerid pr grntizr el eso direto un rngo de posiionesF isto se efet medinte el siguiente mtodoX miembros pblicos de DynArray<T> 42 + (34) 46a 47 void reserve(const size_t & l, const size_t & r) { const size_t first_seg = index_in_dir(l); const size_t last_seg = index_in_dir(r); const size_t first_block = index_in_seg(l); const size_t last_block = index_in_seg(r); for (size_t seg_idx = first_seg; seg_idx <= last_seg; ++seg_idx) { if (dir[seg_idx] == NULL) allocate_segment(dir[seg_idx]);
size_t block_idx = (seg_idx == first_seg) ? first_block : 0; const size_t final_block = (seg_idx == last_seg) ? last_block : seg_size - 1; while (block_idx <= final_block) {

2.1. Arreglos

47

if (dir[seg_idx][block_idx] == NULL) allocate_block(dir[seg_idx][block_idx]); ++block_idx; } } // end for (...) if (r + 1 > current_dim) current_dim = r + 1;

47

reserve() prt los loques y segmentos que rn el rngo de posiiones entre l y rF he l mism mner en que se puede prtr memori pr segurr eso deterE minds posiionesD tmin es plusile indir que se liere l memori de un rngo de posiiones que el usurio determine que no usr msF il mtodo cut() just l dimensin del rreglo un dimensin inferior llmd new_dim y lier tod l memori entre new_dim y l ntigu dimensinX miembros pblicos de DynArray<T> 42 + (34) 46b 49b
void cut(const size_t & new_dim = 0) { if (new_dim == 0) { release_all_segments_and_blocks(); current_dim = 0; return; } const size_t old_dim = current_dim; // antigua dimensin // ndices cotas bloques const int idx_first_seg = index_in_dir(old_dim - 1); const int idx_first_block = index_in_seg(old_dim - 1); // ndices cotas segmentos const int idx_last_seg = index_in_dir(new_dim - 1); const int idx_last_block = index_in_seg(new_dim - 1); for (int idx_seg = index_in_dir(old_dim - 1); idx_seg >= idx_last_seg; idx_seg) // recorre descendentemente los segmentos { if (dir[idx_seg] == NULL) // hay un segmento? continue; // no ==> avance al siguiente

} current_dim = new_dim; // actualiza nueva dimensin

Liberar descendentemente los bloques del segmento 48a Liberar el segmento 48e

v lierin de loques es lgo delid porque hy que mnejr sos prtiulres pr el ltimo y primer loque8 F idx_block llev el ndie del loque en el segmento tul idx_segF r el vlor iniil dentro del segmentoD hy dos sos posilesX
8
La inversin es adrede porque la liberacin de bloques se efecta descendentemente.

48

2. Secuencias

IF i se trt del primer segmentoD entones idx_block omienz en idx_first_blockF iste so ourre un sol vez undo idx_seg == idx_first_segF PF idx_block omienz en blocksize 1F iste es el so omn y se veri( undo idx_seg != idx_first_segF il vlor iniil se de(ne entones del siguiente modoX
48a

Liberar descendentemente los bloques del segmento 48a

(47) 48d

int idx_block = // primer bloque a liberar idx_seg == idx_first_seg ? idx_first_block : seg_size - 1;

min hy dos sos posiles pr el vlor (nl de idx_blockX IF i no nos enontrmos en el ltimo segmento @idx_last_segAD entones el ltimo loque ser el de ndie 0F v ondiin de prd serD entonesD l siguienteX
48b

Se est en bloque de un segmento general 48b

(48d)

(idx_seg > idx_last_seg and idx_block >= 0)

PF i nos enontrmos en el ltimo segmentoD entones el ltimo loque ser idx_last_blockF ist ondiin l detetmos medinte el predidoX
48c

Se est en bloque del ltimo segmento 48c

(48d)

(idx_seg == idx_last_seg and idx_block > idx_last_block)

48d

il ule que lier desendentemente el loque del segmento tul se de(ne entones omo sigueX Liberar descendentemente los bloques del segmento 48a + (47) 48a // Libera descendentemente los bloques reservados del segmento while ( Se est en bloque de un segmento general 48b or Se est en bloque del ltimo segmento 48c ) { if (dir[idx_seg][idx_block] != NULL) // Hay un bloque aqu? release_block(dir[idx_seg][idx_block]); idx_block; } il segmento slo dee lierrse si todos sus loques lo hn sidoF isto se veri( si h reorrido ompletmente el segmento tulX Liberar el segmento 48e (47) if (idx_block < 0) release_segment(dir[idx_seg]);
2.1.4.4 Acceso mediante operador

48e

[]

rst el presenteD ls interfes de eso los elementos de un rreglo dinmio estn diseds pr efetur el eso en tiempo onstnte de l mner ms rpid posileF access() no veri( si l memori h sido prtdD rzn por l ul el usurio dee explitmente veri(rl trvs de exist() o prtrl medinte touch() o reserve()F n form ms simple y trnsprente de mnipulr un rreglo dinmioD en detrimento de un poo de tiempoD es trvs del operdor []F sniilmenteD el rreglo se onstruye

2.1. Arreglos

49

49a

on tn solo el diretorio prtdoF ultinmenteD medid que se esrien dtos en ls posiionesD se prtnD perezosmenteD los segmentos y loques orrespondientes ls entrds que hn sido esritsF he est mnerD l memori oupd por el DynArray<T> es proporionl ls entrds esrits y no su dimensinF r implntr est funionlidd requerimos distinguir los esos de letur de los de esriturF r eso usremos l lse medidor ProxyX miembros privados de DynArray<T> 38b + (34) 44b class Proxy {
};

Miembros dato del proxy 49c Mtodos del proxy 50a

49b

ist lse es el vlor de retorno del operdor [] en l lse DynArray<T>X miembros pblicos de DynArray<T> 42 + (34) 47 52 Proxy operator [] (const size_t & i) { return Proxy (const_cast<DynArray<T>&>(*this), i); }
Uses

DynArray

34.

49c

i se efet un eso de letur fuer de l dimensin tulD entones se geE ner std::length_errorF i es un eso de esriturD un fuer de l dimensin tulD entones se veri( si existen el loque y el segmentoY si no es el soD entones stos se prtnF uede generrse std::bad_alloc si no hy memoriD o std::length_error si el ndie i es myor o igul que l mxim dimensinF v dimensin se just utomtimente segn l myor posiin esritF i un eso de letur l iEsim entrd detet que el loque no h sido prtdoD entones se gener l exepin std::invalid_argumentF il eso de letur un entrd que no h sido esrit no siempre us un exepE inD pues l entrd y puede tener su loque prtdoY emperoD en este so el vlor de l letur es indetermindoF v ide del operdor [] es retornr un lse roxy en esper de onoer si el eso es de letur o de esriturF vos miemros dtos de Proxy mntienen l informin su(iente pr vlidr y efeE tur el esoX Miembros dato del proxy 49c (49a) size_t index; size_t pos_in_dir; size_t pos_in_seg; size_t pos_in_block; T **& ref_seg; T * block; DynArray & array;
Uses

DynArray

34.

index es el ndie del elemento que el proxy edeF pos_in_dirD pos_in_seg y pos_in_block son los ndies en el diretorioD segmento y loque orrespondientes indexF istos vlores se luln durnte l onstruin del proxyF

50

2. Secuencias

50a

ref_seg es un refereni l entrd pos_in_dir del diretorioF hee ser un referenE i porque st es suseptile de modi(rseF hd est refereniD ref_seg[pos_in_seg] denot el puntdor l loque y ref_seg[pos_in_seg][pos_in_block] denot el eleE mento del rreglo orrespondiente l ndie indexF block es un puntdor iguldo ref_seg[pos_in_seg][pos_in_block]F array es un refereni l DynArray<T> utilizd pr oservr y modi(r su estdoF wiemros dto del proxy 49c se iniin en el onstrutor del proxy omo sigueX Mtodos del proxy 50a (49a) 50b Proxy(DynArray<T>& _array, const size_t & i) : index(i), pos_in_dir(_array.index_in_dir(index)), pos_in_seg(_array.index_in_seg(index)), pos_in_block(_array.index_in_block(index)), ref_seg(_array.dir[pos_in_dir]), block (NULL), array(_array) { if (ref_seg != NULL) block = ref_seg[pos_in_seg]; // ya existe bloque para entrada i }
Uses

DynArray

34.

50b

i es el ndie del DynArray<T>array l ul el proxy he refereniF vs posiiones se luln segn ls funiones uxilires de DynArray<T>F i l refereni ref_seg ontiene un puntdor vlidoD entones block se iniiliz pr puntr l loqueF xo se efet ningun in undo se destruye un proxyF n Proxy onstruido est listo pr eder un posiin ddF egn el ontexto de invoin del operdor []D el ompildor determinr si el eso es de letur o de esriturF gundo ourr un leturD el ompildor intentr onvertir el Proxy l tipo genrio TF l onversin se de(ne del siguiente modoX Mtodos del proxy 50a + (49a) 50a 50c
operator T & () { return block[pos_in_block]; }

50c

block == NULL indi que no existe un loque pr el ndie indexF i no hy loqueD entones l letur es invlid y se gener l exepin std::invalid_argumentF he lo ontrrio se retorn el elemento referidoF v esritur puede ourrir undo se efet un signinD l ul se de(ne pr un Proxy de ls dos siguientes formsX Mtodos del proxy 50a + (49a) 50b
Proxy & operator = (const T & data) { block[pos_in_block] = data; return *this;

Obtener o apartar el segmento y el bloque 51b Vericar y actualizar la dimensin 51a

} Proxy & operator = (const Proxy & proxy) { if (proxy.block == NULL) // operando derecho puede leerse? throw std::domain_error("right entry has not been still written");

2.1. Arreglos

51

block[pos_in_block] = proxy.block[proxy.pos_in_block]; return *this;

Obtener o apartar el segmento y el bloque 51b Vericar y actualizar la dimensin 51a

51a

is deirD signin del tipo genrio T un proxyD por ejemplo array[i] = variableY o signin de proxy proxyD por ejemplo array[i] = array[j]F in el ltimo so se dee veri(r que l letur del operndo dereho se vlidD ul es el sentido del primer ifF he restoD ls dos signiones son muy similres y se remiten ytener o prtr el segmento y el loque 51b en donde se esriir y luego eri(r y tulizr l dimensin 51a F v dimensin tul slo se tuliz si se esrie en un posiin myor que l diE mensin tulX Vericar y actualizar la dimensin 51a (50c) if (index >= array.current_dim) array.current_dim = index + 1; ytener o prtr el segmento y el loque IF ytener el segmentoX
51b 51b

reliz dos psosX

Obtener o apartar el segmento y el bloque 51b

(50c) 51c

bool seg_was_allocated_in_current_call = false; if (ref_seg == NULL) // hay segmento? { // No ==> apartarlo! array.allocate_segment(ref_seg); seg_was_allocated_in_current_call = true; }

seg_was_allocated_in_current_call memoriz si se prt memori pr el segE mentoF isto permite determinr si hy que lierr o no el segmento en so de que ourr un exepin si se prt el loqueF
PF ytener loqueX
51c

Obtener o apartar el segmento y el bloque 51b +

(50c)

51b

if (block == NULL) // test if block is allocated { array.allocate_block(block); ref_seg[pos_in_seg] = block; }

i ourre un fll de memori durnte l reservin del segmentoD l exepE in std::bad_allocD generd por new y regenerd por allocate_segment() o allocate_block() puede dejrse sin pturrF i l fll de memori ourre durnte l reservin del loqueD entones l exepin std::bad_allocD generd por newD dee pturrse pr eventulmente poder lierr l memori del segmento que fue prtd por l llmd tulF ist es l rzn por l ul hy un mnejdor de exepin pr l reservin del loqueF

52

2. Secuencias

2.1.4.5

Tratamiento del arreglo como pila o cola

52

e menudoD un rreglo dinmio se utiliz omo ol o pilY dos ides que n no hemos presentdo y que estudiremos mplimente en PFS @gF WVA y PFT @gF IPPAF heido su importniD vle l penD efetos de l eonom de digoD enpsulr lguns operionesX miembros pblicos de DynArray<T> 42 + (34) 49b void append(const T & data) { (*this)[size()] = data; }
void push(const T & data) { append(data); } T pop() { T ret_val = (*this)[size() - 1]; cut(size() - 1); return ret_val; } T & top() { return (*this)[size() - 1]; } T & get_first() { return top(); } T & get_last() { return (*this)[0]; }
2.1.4.6 Uso del valor por omisin

remos reldo el heho de que l memori de un DynArray<T> se prt perezosmente en tiempo de esriturF min hemos destdo que est rtersti permite horrr memori en pliiones que usen rreglos espridosF u suede undo se ede un entrd que no h sido esritcF r estudir est uestinD supongmos un eso de letur un iEsim entrdY nte este evento podemos plnter los siguientes esenriosX IF v iEsim entrd h sido previ y explitmente esritD en uyo so se retornr el ltimo vlor esritoF PF v entrd no h sido previmente esritF in est situin pueden ourrir dos ossX @A ue no se hy prtdo un loque pr l iEsim entrdD en uyo so se trt de un error de progrmin @letur de un vlor que no h sido esritoAD el ulD en el mejor de los esenriosD generr un exepinF ist ser l situin si el eso se efet medinte el operdor []F i el eso se he medinte access()D entonesD on suerteD ourrir l exepin sistem segmentation faultF or el ontrrioD on ml suerte no ourrir ningun exepinD lo que tender oultr el errorF @A ue s se hy prtdo el loque durnte l esritur de lgun entrd en el mismo loque de l iEsim entrdF in este so se retornr el vlor que hy esrito el onstrutor por omisin T::T()F xotemos l posiiliddD no tn exepE ionlD de que este onstrutor por omisin no registre ningun esriturD en uyo soD el vlor de retorno puede ser ulquierD segn el estdo del loqueF

2.1. Arreglos

53

53

il eh DynArray<T> puede ser til pr modelizr rreglos espridosY por ejemE ploD un mtriz esprid que ontiene muhos erosF in este so podemos usr un DynArray<T> mat[n*n]F il eso un entrd de l mtriz puede herse medinte el operdor (i,j) o medinte el uso de un lse proxyF n pseudoimplntin sugerid del eso de letur un eh Matriz<T> es omo sigueX acceso matriz 53 template <typename T> const T & Matriz<T>::operator () (long i, long j) const { const int & n = mat.size(); const long index_dynarray = i + j*n; // posicin dentro de mat if (not mat.exist(index_dynarray)) return Zero_Value; return mat.access(index_dynarray); } vo gurddo en l onstnte index_dynarray se orresponde on onsiderr un mtriz omo un rreglo de rreglos 9 F i el predido not mat.exist(index) es iertoD entones no hy memori prtd pr el loque que ontendr l entrd (i,j)D rzn por l ul se retorn un vlor por omisin denomindo en este so Zero_ValueY de lo ontrrio retornmos mat.access(index)D pues el eso est grntizdo si el )ujo lleg es lneF uede presentrse l situin desrit en PD es deirD mat.access(index) no h sido previmente esritoD pero not mat.exist(index) == trueF il vlor de reE torno ser entones el espei(do por T::T() o el signdo en un llmd set_default_initial_value()F set_default_initial_value() permite espei(r diversos vlores iniiles pr el mismo tipoD lo ul ser muy til pr mpos lgerios diferentes que mnipulen el mismo tipo de operndoY ls mtries de dyeni en los grfosD por ejemploF
2.1.5 Arreglos de bits

eordemos que un dto de tipo lgioD bool en C++ slo puedetomr dos vloresX true o falseF r representr un bool slo se requiere un itD peroD por diverss rzonesD por modD l linein de memoriD en C++ un bool es trduido un yte uyo vlor puede ser ero @0A o uno @1AY desperdiio de siete @7A its despreile en l inmens myor de ls pliionesD pues l ntidd de dtos lgios es pequeF ehor ienD qu suede si tenemos un rreglo de dtos lgiosc i l dimensin del rreglo es onsiderleD entones podemos inurrir en un desperdiio de memori imE portnteF eroD existen pliiones que requiern rreglos lgiosc v respuest es (rmtiv y e deir que se presentn on iert freueniF n ejemplo es el mnejo de pgins de memori virtul efetudo por un sistem opertivoF gonsideremos un memori prinipl de 512 w y pgins de 4 uY un sistem 1024Kb = 131072 pginsF i d estdo se opertivo dee mntener el estdo de 512 4Kb represent on un yteD entones se requieren 128 u de memori pr lmenr el estdo de ls 131072 pginsF or d pginD el sistem opertivo mnej dos itsF il primero indi si l pgin se enuentr o no en memori priniplF il segundo indi si un pgin h sido o no modi(dF i se utilizn dos its por pginD se requieren

2 131072 = 32768 = 32u ; 8


9
Vase 2.2 (Pg. 58).

54

2. Secuencias

54a

queD omo se veD represent un horro de memori signi(tivoF r mnejr rreglos de its introduiremos el eh BitArrayD el ul modeliz veE tores de itsF iste eh est espei(do e implntdo en el rhivo iterryFr 54a X bitArray.H 54a
class BitArray { };

clase Byte 54c

Miembros privados de BitArray 54b Miembros pblicos de BitArray 55c


used in chunks 5557, 31113, 349, 351, 353b, 354, and 633a.

Denes:

BitArray,

54b

v se del rreglo de ytes ser lmend enX Miembros privados de BitArray 54b size_t current_size; DynArray<Byte> array_of_bytes;
Uses

(54a) 56a

DynArray

34.

54c

or rzones de verstiliddD l muy preid simpliiddD entre ellsD BitArray se fundE ment sore un rreglo dinmioF il truo pr relizr un implntin senill es disponer de un soporte que mE nipule los its dentro de un yteF hiho soporte est ddo por l lse ByteD l ul se de(ne sX clase Byte 54c (54a) class Byte { unsigned int b0 : 1; // ...

};

Lectura de bit 54d Escritura de bit 55a Constructor de Byte 55b

54d

fsimenteD l lse BitArray de(ne un msr de 8 its medinte mpos its10 F ist msr permite un eso senillo ddo un ndie de itF v letur esD entonesD implntd omo sigueX Lectura de bit 54d (54c) unsigned int read_bit(const unsigned int & i) const { switch (i) { case 0 : return b0; case 1 : return b1; // ... case 7 : return b7; } }
10
Los campos bits fueron originalmente denidos para el lenguaje C y son parte del

C++

2.1. Arreglos

55

55a

honde i es el ndie del it que se dese leerF v esritur es implntd omo sigueX Escritura de bit 55a (54c) void write_bit(const unsigned int & i, const unsigned int & value) { switch (i) { case 0 : b0 = value; break; case 1 : b1 = value; break; // ... case 7 : b7 = value; break; } } honde i es el ndie del it que se dese eder y value es el it que se dese esriirF is muy tilD expenss de un poo de tiempoD que undo se prte l memori pr un ojeto de tipo Byte todos sus its estn iniidos en eroF smplntremos est semnti en el onstrutor por omisinX Constructor de Byte 55b (54c) Byte() : b0(0), b1(0), b2(0), b3(0), b4(0), b5(0), b6(0), b7(0) {} iste onstrutor grntiz que todo rreglo de tipo Byte teng todos sus its en eroF r delrr un ojeto de tipo BitArray st on espei(r l dimensin del rregloF il onstrutor y el destrutor tienenD puesD l siguiente formX Miembros pblicos de BitArray 55c (54a) 55d BitArray(const size_t & dim = 0) : current_size(dim), array_of_bytes(get_num_bytes()) { array_of_bytes.set_default_initial_value(Byte()); }
Uses

55b

55c

BitArray

54a.

55d

r onoer l dimensin del rregloD se puede empler el mtodoX Miembros pblicos de BitArray 55c + (54a) 55c 55e const size_t & size() const { return current_size; } odemos mir l dimensin del rreglo medinteX Miembros pblicos de BitArray 55c + void set_size(const size_t & sz) { array_of_bytes.cut(); current_size = sz; }
(54a) 55d 56b

55e

il eso los elementos del rreglo se reliz medinte el operdor []D el ul es omplido de espei(r y de implntr porque ste dee distinguir los esos de letur de los de esriturF hdo el ndie i de un itD l posiin byte_index dentro de array_of_bytes se lul omo sigueX i . byte_index = 8

56

2. Secuencias

u posiin bit_index dentro del yte estr dd porX

bit_index = i mod 8 .
gonsideremos l instruin i = array[40]; que leer el vlor del it orrespondiente l entrd 40F in este soD l implntin del operdor [] dee usr el it 40 y entones retornr un representin enter Ede tipo intE del it edidoF in este soD el operdor [] dee invor read_bit()F ehor onsideremos l instruin array[40] = i; que esriir en l entrd 40 del rreglo el vlor ontenido en l vrile iF in este soD el eso dee lolizr el it 40 en el rreglo y esriirD no leerD el vlor de iF in este soD el operdor [] dee invor write_bit()F v implntin del operdor [] requiereD entonesD relizr operiones diferentes segn el tipo de esoX letur o esriturF isto no se puede relizr en l implntin de lgun de ls delriones trdiionles del operdor []D pero s se puede postergr l distinin hst lgn momento en que se posile onoer si el eso es de letur o de esriturF l distinin se reliz medinte un ominin del operdor [] y de un lse espeil denomind proxyD l ul se de(ne omo sigueX Miembros privados de BitArray 54b + (54a) 54b class BitProxy {
};

56a

miembros privados de BitProxy 56c miembros pblicos de BitProxy 57a

56b

il operdor [] de BitArray retorn un BitProxy sX Miembros pblicos de BitArray 55c + (54a) 55e 58a BitProxy operator [] (const size_t & i) const { return BitProxy(const_cast<BitArray&>(*this), i); } BitProxy operator [] (const size_t & i) { return BitProxy(*this, i); }
Uses

BitArray

54a.

56c

il primer operdor se invo pr un BitArray onstnte @delrdo constAD mientrs que el segundo pr un BitArray que no es onstnteF il operdor de signin y el onstrutor opi de BitProxy implntn l esriturD mientrs que el operdor de onversin de tipo implnt l leturF gulquier que se el tipo de esoD previmente es neesrio lulr el ndie del yte dentro de array_of_bytes y el ndie del it dentro del yteF ist informin l gurdmos en los siguientes triutosX miembros privados de BitProxy 56c (56a) const size_t index; const size_t bit_index; const size_t byte_index; BitArray * array; Byte * byte_ptr;
Uses

BitArray

54a.

2.1. Arreglos

57

57a

les triutos se iniin en el onstrutor de BitProxyX miembros pblicos de BitProxy 57a (56a) BitProxy(BitArray & a, const size_t & i) : index(i), bit_index(i % 8), byte_index(i/8), array(&a) { if (array->array_of_bytes.exist(byte_index)) byte_ptr = &array->array_of_bytes.access(byte_index); else byte_ptr = NULL; }
Uses

57b

BitArray

54a.

57b

gundo se instni un lse BitProxyD es deirD undo se invo l operdor [] de BitArrayD el mpo byte_ptr punt l yte dentro de array_of_bytes que onE tiene el it que se dese ederF bit_index ontiene el ndie del it dentro del yte *byte_ptrF i el ndie i est fuer de rngoD entones el onstrutor dispr l exepin std::out_of_range()F xtese que l momento de onstruin de un BitProxy n no se h efetudo el esoD pero s se h luldo l direin del yte dnde se enuentr el it @byte_ptrA y se h determindo ul es el it dentro de ese yte @bit_indexAF egn el ontexto de l expresin que invoque l operdor []D el ompildor distingue si el eso es de letur o de esriturF i es de leturD entones el ompildor trtr de onvertir el BitProxy un entero resultnte de l leturX miembros pblicos de BitProxy 57a + (56a) 57a 57c operator int () const { return byte_ptr != NULL ? byte_ptr->read_bit(bit_index) : 0; } gundo el ompildor enuentr un expresin omo i = array[40]D se us un onsE trutor de int on prmetro BitProxyF i noD el ompildor us un signin de BitProxy intF gomo no existe ninguno de estos operdoresD el ompildor onvierte el proxy un intF in l expresin array[40] = iD st on de(nir un operdor de signin de proxy prtir de un enteroD tl omo sigueX miembros pblicos de BitProxy 57a + (56a) 57b BitProxy & operator = (const size_t & value) { if (byte_ptr == NULL) byte_ptr = &array->array_of_bytes.touch(byte_index);
if (index >= array->current_size) array->current_size = index; byte_ptr->write_bit(bit_index, value); } return *this;

57c

v lse BitProxy permite mnejr un rreglo de its si extmente de l mism mner que se usn los rreglosF in emrgoD est tni no grntiz que siempre se

58

2. Secuencias

58a

posile usr el operdor []D ni es l de ms lto desempeoF or es rzn exportmos dos operiones expliits de letur y de esriturX Miembros pblicos de BitArray 55c + (54a) 56b 58b int read_bit(const size_t & i) const { const int bit_index = i % 8; const Byte byte = array_of_bytes[i/8]; return byte.read_bit(bit_index); } void write_bit(const size_t & i, const unsigned int & value) { array_of_bytes.touch(i/8).write_bit(i%8, value); if (i >= current_size) current_size = i + 1; } uesto que un rreglo de its es dinmioD podemos lrgrlo o ortrloD l estilo de un pil11 F r ello proveemos ls siguientes funionesX Miembros pblicos de BitArray 55c + (54a) 58a void push(const unsigned int & value) { write_bit(current_size, value); } void pop() { current_size; array_of_bytes.cut(get_num_bytes()); } void empty() { current_size = 0; array_of_bytes.cut(); } ists operiones min l dimensin del rregloF

58b

2.2 Arreglos multidimensionales


in un muy iert medidD los rreglos son reminisentes los vetores de l mtemtiF in este sentido es posile representr un mtriz n m medinte un rreglo de n de rreE glos de dimensin mD es deirD un seueni de seuenisF in C++ un mtriz de este tipo se delr del siguiente modoX
T matriz[n][m];

il lenguje implnt el eso un entrd de l mtriz medinte ominiones del operdor *]F or ejemploD l expresinX
matriz[i][j] = dato;

esign dato l jEsimo elemento de l iEsim (lF


11
El concepto de pila ser tratado ampliamente en 2.5 (Pg. 98).

2.3. Iteradores

59

il ompildor gener utomtimente el lulo de l direin de esoD el ul se puede enunir de l siguiente formX hirein del elemento = base + i m sizeof(T) + j sizeof(T) @PFIWA

in l delrin nteriorD el ompildor dee usr un espio ontiguo lo su(ienteE mente grnde pr lergr los n m elementos de l mtrizF gonforme umentn n y mD disminuye l posiilidd de enontrr tl espioF or otr prteD en C++ D l mtriz nterior es estti en el sentido de que no es posile mir su dimensinF il lulo @PFIWA generdo por el ompildor sume que n y m permneen onstntes durnte l vid de l mtrizF i ien esto no es tn prolemtioD pues se podr generr digo pr n y m vrilesD un mio en lgun de ls dimensiones olig desplzr l myor de los elementosF or ls rzones nteriores es preferile trtr explitmente un rreglo multidimenE sionl omo lo que esX un seueni de seuenisF fjo est perspetivD un mtriz n m puede delrrse omo sigueX
T ** matriz = new T * [n]; // Aparta arreglo de punteros a filas for (int i = 0; i < n; ++i) matriz[i] = new T [m]; // aparta la fila matriz[i]

iste esquem es de entrd ms dinmio que el nteriorF i se mi el nmero de (ls nD entones slo es neesrio relolizr el rreglo matrizF iD por el ontrrioD se modi( el nmero de olumnsD entones hy que relolizr d (l matriz[i]F in C++ D s omo en l myor de los lengujesD un mtriz se onsider omo un rreglo de n (ls de tmo mF in emrgoD tmin puede interpretrse l revsY es deirD omo un rreglo de m olumns de tmo nF iste es el so del lenguje de progrmin portrnD intensivmente usdo pr lulos numriosF eunque disutileD l disposiin espeil de ls mtries en portrn no es un prihoF uede que muhs operiones mtemtis sore mtries exhien un ptrn de eso que fvoree l seuenilizin por olumns en lugr de por (lsF guent hid de l populridd del portrnD los progrmdores de C y C++ deen onE siderr vrintes pr los rreglos deuds l portrnD pues es stnte ftile utilizr iliotes esrits en portrn y vieversF

2.3 Iteradores
in progrminD dien que l (n de uents no quedn sino seuenisF gulquier que se l estrutur de dtosD el quid de proesmiento siempre se remite seuenisF il ptrn es tn freuente que meree un ptrn genrio denomindo Iterator<Set, T> y espei(do en el digrm wv de l (gur PFPF v lse Iterator<Set, T> reie dos tipos prmetrizdos Set<T> del tipo explido en IFQ @gF IUA y TF u (n es filitr el proesmiento seuenil de elementos en un onjunto Set<T>F r usr un iterdor se requiere un onjunto o ontenedor Set<T>F ry dos forms de instnirloX medinte el onstrutor que rei el onjunto o medinte el onstrutor opiF in el primeroD el iterdor se posiion en el primer elemento de l seueniD mientrs que en el segundo lo he en el elemento tul del iterdor fuente de l opiF

60

2. Secuencias

Set<Type>:template T:class

Iterator
+Iterator(in ct:Set<T>) +Iterator(in it:Iterator) +Iterator() +operator =(in ct:Set<T>) +operator =(in it:Iterator) +next(): void +prev(): void +has_current(): bool +is_in_first(): bool +is_in_last(): bool +current(): T +reset_first(): void +reset_last(): void +del(): void +insert(in item:T): void +append(in item:T): void +set(in item:T): void +position(): int

pigur PFPX higrm wv de l lse genri Iterator<Set, T> itrimenteD un onjunto puede interpretrse omo un seueni genri de n elementos de lgn tipo genrio T segn l (gur PFQ
e0 e1 e2

...

ei

ei+1

...

en2

en1

en

pigur PFQX epresentin pitri de un iterdor sore un seueni gundo se instni un iterdor on un ontenedor Set<T>D ste qued posiiondo en el primer elemento de l seueni designdo en el diujo omo e0 F il elemento designdo omo en no existe en l seueniD pero steD lgimenteD denot que el iterdor est desorddo o fuer de rngoF v primitiv has_current() retorn false si el iterdor se enuentr posiiondo en el elemento (tiio en Y true de lo ontrrioF in lguns situiones puede onvenir ser si el iterdor est posiiondo en el primer o ltimo elementoF i el iterdor se enontrse en el primer elementoD entones is_in_first() retornr trueY l mism semnti se plir on is_in_last() si el iterdor se enontrse en el ltimo elementoF il elemento tul del iterdor se onsult medinte el mtodo get_current()F in el so generlD segn l implntin de Set<T>D el iterdor gener l exepE in std::overflow_error si se intent eder un iterdor desorddoF r slvgurdr el estdo de un iterdor pueden onstruirse iterdores sin que se proporione el onjuntoF yvimenteD un iterdor sin onjunto no es vlido hst que ste no se de(n medinte lgun de ls dos versiones del operdor de signinF r vnzr el iterdor hi l dereh o hi delnte se ejeut el mtodo next()F enlogmenteD pr retroederlo hi l izquierd o hE i trs se ejeut prev()F gulquier de estos mtodos puede generr ls exepE iones std::overflow_error o std::underflow_error si el iterdor est desorddoF in ALEPHD s omo en otros mitosD un onjunto ontiene su lse IteratorF is deirD Iterator es un sulse de l espeilizin de Set<T, Compare>F il siguiente digo ilustr un squed genri en un onjunto medinte un iterdorX
template <template <class> class Set, typename T, class Compare> T * search(Set<T> & set, const T & item)

2.4. Listas enlazadas

61

for (typename Set<T>::Iterator it(set); it.has_current(); it.next()) if (are_equals<T, Compare>() (it.get_current(), item)) return &it.get_current(); return NULL;

e veesD un iterdor puede reusrseF r ello es posile reiniirlo (n de que ste punte l primer o ltimo elemento del onjuntoF reset_first() reinii el iterdor l primer elementoD mientrs que reset_last() lo reinii l ltimo @indido on en1 en l (gur PFQAF vs operiones que siguen son dependientes de l estrutur de dtos on que se implnte el onjuntoF il mtodo del() elimin del onjunto el elemento tul y vnz el iterdor un posiin hi delnteF hee tenerse espeil uiddo undo se interlen next() y del() en un mism iterinF il mtodo insert() insert un nuevo elemento en l seueni  l dereh del elemento tul del iterdor sin vnzrF enlogmenteD el mtodo append() insert hi l izquierdF v primitiv set() posiion un iterdor en el elemento item perteneiente l onjuntoF or lo generlD no se vlid si item en efeto es prte del onjuntoF position() retorn l posiin del elemento tul dentro de l seueniF egn l implntin de Set<T>D el iterdor puede enriqueerse on otrs primitivsF osilemente l ms importnte de ells es el operdor de eso []D el ul retorn un elemento del onjunto segn su posiin dentro de l seueniF vos iterdores pueden usrse genrimenteD es deirD pueden her progrms que rein iterdores sin tener onoimiento del tipo de onjunto sore el ul iternF r ests situiones puede ser desele tener el tipo del onjunto y el de sus elementosF r ello se exportn los sinnimos de tipo de Set_Type y Item_Type respetivmenteF Set_Type proporion el tipo de onjunto on que normlmente se onstruye el iterdorD mientrs que Item_Type el tipo que retorn get_current())F

2.4 Listas enlazadas


n list es un seueni de longitud vrile < t1 , t2 , t3 , . . . , tn > de n elementos de lgn tipo T on ls siguientes propieddesX
Restriccin de acceso:

IF el primer elementoD t1 D se ede diretmente en tiempo onstnteF PF r eder l elemento Ti es neesrio eder seuenilmente los i 1 previos elementos < t1 , t2 , t3 , . . . , ti1 >F ist restriin se impone sore tods ls operiones que requiern eder ulquier posiin de l seueniF in onseueniD el tiempo de ejeuin en el esoD inserin y eliminin es dependiente de l posiin dentro de l listF

62

2. Secuencias

Flexibilidad:

i se onoe l direin de un elemento ti dentro de l seueni < t1 , t2 , . . . , ti , ti+1 , . . . , tn >D entonesX IF ti+1 puede eliminrse en tiempo onstnteF il estdo despus de est eliminin es < t1 , t2 , . . . , ti , . . . , tn >F

PF n elemento ulquier tj puede insertrse despus de ti en tiempo onstnteF il estdo (nl despus de l inserin esX

< t1 , t2 , . . . , ti1 , ti , tj , ti+1 , . . . , tn >


Espacio proporcional al tamao:

il espio oupdo por los elementos de l list siempre es proporionl l nmero de elementosD es deirD puede expresrse omo un funin f(n) = k nF

vs lists son idnes pr pliiones onD o lguns deD ls siguientes rterstisX  e requieren vrios onjuntos @quiz muhosA y su ntidd es vrile lo lrgo de l pliinF  vs rdinliddes de los onjuntos son desonoids y muy vriles en el tiempo de vid de l pliinF  il proesmiento es seuenilD es deirD el proesmiento del iEsimo elemento se efet despus de proesr los (i 1) elementos previosF vists on ls rterstis selds formn prte de los lengujes de progrmin funionlesD LISPD MLD CAMLD por ejemplosY y de los modernos y potentes lengujes de sriptingY en ls ourrenis ms populresD perl y pythonF vengujes de medino nivelD tles omo PascalD C o C++ D no poseen lists omo prte del lengujeD rzn por l ul es onveniente implntrls generl y genrimente en ilioteF e ls lists se les tild de enlzds porque difereni del rregloD d elemento de l seueni reside en un direin de memori que no es ontiguF r onoer ul es el siguiente elemento de l seueniD es neesrio un enle l loque de memori que lo lergF v (gur PFR muestr l lsi representin pitri de un list simpleE mente enlzd uyos elementos son ls letrs desde l e hst l iF
head A B C D E

pigur PFRX n list simplemente enlzd gd elemento de l seueni se represent medinte un j dividid en dos mE posX el elemento de l seueni y el puntdor l prxim jF n j se denomin nodoF il punto de entrd un list es l direin del primer nodoD denomindo head en l (gur PFRF

2.4. Listas enlazadas

63

63

in C o C++ D un nodo puede espei(rse omo sigueX Denicin de nodo simple 63 struct Node { char data; Node * next; }; ist es l tpi delrin de un nodo perteneiente un list enlzdF data lmen l letr y next es el puntero l prximo elementoF uesto que un Node se re(ere s mismo trvs de nextD ls lists enlzds hn sido lsi(ds de estruturs reurrentesF
first A B C D last E

pigur PFSX n list dolemente enlzd v list de l (gur PFR se tegoriz omo simplemente enlzd porque sus nodos poseen un solo enle hi el siguiente nodo en l seueniF in detrimento de un poquito ms de memoriD es posile utilizr un enle diionl l elemento predeesorF in este soD l list se tegoriz omo dolemente enlzd y se represent pitrimente omo en l (gur PFSF e efetos de mnejr el otro extremo se requiere un puntero diionl l ltimo elemento de l listF
first A B C D E

pigur PFTX n list dolemente enlzd irulr il osto en espio de un list dolemente enlzd se reompens on rees on su verstiliddF hdo un elemento perteneiente l listD ls operiones pueden referir l elemento predeesor o l suesorF gonseuentementeD l list puede reorrerse en los dos sentidosD de izquierd dereh o vieversF uiz l grn virtud de un list dolemente enlzd es l pidd de utoelimE ininF gulquier nodo posee todo el ontexto neesrio @predeesor y suesorA pr l mismo eliminrse de l listF in l (gur PFS se usn dos puntos de entrdD uno por d extremoF is posile y ms verstil si se ierrn los enles y se he l list irulrD tl omo ilustr l (gur PFTF in este soD st on mntener un puntero l primer nodo de l list pr tener eso su otro extremoF in didurD tl omo lo estudiremos posteriormenteD si se pone omo eer un nodo diionlD el ul no form prte lgi de l seueniD entones se gn en linelidd de )ujoD pues no hy que onsiderr los sos prtiulres undo l list est o deveng vF

64

2. Secuencias

vs tnis de irulridd y de nodo eer tmin pueden plirse lists simE plemente enlzdsD unque l gnni en verstilidd no es tn notle omo on ls dolemente enlzdsF
2.4.1 Listas enlazadas y el principio n a n

vs operiones sore lists enlzds pueden seprrse en los niveles jerrquiosD segn el tipo de operionesD ilustrdos en el digrm wv de ls lses que mnipuln lists en ALEPHF
Slink Dlink

1: Manejo de enlaces

:T

:T

Snode
+get_data(): T

Dnode
+get_data(): T

2: Manejo de tipo

:T

:T

Slist

Dlist

3: Manejo de nodos

:T

:T

DynSlist

DynDlist

4: Manejo de memoria

pigur PFUX higrm generl wv de ls lses pr lists enlzds in el primer nivelD el (n es el mnejo de puntdoresF lo nos oniernen ls opeE riones de enle de un nodo on otro sin onsiderrD el resto de los nodos ni el tipo de dto que stos ontienenF in este nivel se enuentrn ls lses Slink y DlinkD ls ules modelizn enles de nodos de lists simple y dolemente enlzds respetivmenteF vs operiones en este nivel son ompletmente independientes del tipo de dto que lerguen los nodosD lo que ls he generles pr tods ls lses de listsF in el segundo nivel el (n es lergr un dto genrio en el nodo que luego resulte en el tipo de elemento de l seueniF in este nivel enontrmos ls lses Snode<T> y Dnode<T> respetivmenteF il (n de ests lses es mnejr un dto genrio T sequile medinte l operin get_data()F xtese que por hereni pliD un Snode<T> es un Slink y un Dnode<T> es un DlinkF in el terer nivelD el (n es mnipulr lists de nodosD sen simples de tipo Slist<T> o doles de tipo Dlist<T>F xtese que en este nivel se hl de lists de nodos y no de lists de elementosF gd nodo de un list requiere prtr un espio de memoriF in lengujes omo C++ D el mnejo de memori es delido porque hy que segurrse de lierr d loqueD en nuestro soD d nodoD que hy sido prtdo un vez que se determin que ste y no se usr msF in didurD hy situiones en ls ules no es neesrio prtr o lierr memoriF ytr ventj de este enfoque es que podemos eliminr un nodo de un onjunto e insertrlo en otro sin neesidd de lierr y luego prtr memoriF in virtud de ests rzonesD el mnejo por nodos permite espei(r operiones sore lists sin onsiderr el mnejo de l memoriF pinlmenteD el ltimo nivel orresponde l onepto trdiionl de listD en el ulD todo est resueltoY inluido el mnejo de memoriF in este sentido se exportn ls lses

2.4. Listas enlazadas

65

DynSlist<T> y DynDlist<T>D l ules modelizn lists implntds medinte enles simples y doles respetivmente
2.4.2 El TAD

Slink

(enlace simple)

il eh SlinkD de(nido en el rhivo slinkFr 65a D represent un enle simple de un list simplemente enlzd irulr on nodo eerF

A b

pigur PFVX vist enlzd simple on Slink slinkFr export l lse SlinkX

65a

65a

slink.H 65a

class Slink { };

miembros protegidos de Slink 65b miembros pblicos de Slink 65c

funcin de conversin de Slink a clase 68a


used in chunks 65, 66, 68, 69, and 72.

Denes:

Slink,

65b

yjetos que den enlzrse en un list simple deen tener un Slink omo triuto o ser Slink por hereni pliF v (gur PFV muestr un list de utro elementos implntd medinte SlinkF ry un difereni inmeditmente preile on l (gur PFRX d lzo punt l lzo del siguiente nodo y no l nodoF isto plnte un difereni sustnil on ls lists enlzds trdiionlesD en ls ules el puntdor direion l registro ompletoF Slink tiene un solo miemro dto y protegidoX miembros protegidos de Slink 65b (65a) protected: Slink* next;
Uses

Slink

65a.

65c

v protein permite que un lse derivd de Slink utilie diretmente el miemE ro dto nextF il eh Slink es tn simple que muhos de sus mtodos onllevn un sol lneX miembros pblicos de Slink 65c (65a) 66a Slink() : next(this) { /* Empty */ }
Slink(const Slink &) { next = this; } Slink & operator = (const Slink & link)

66

2. Secuencias

next = this; } void reset() { next = this; } bool is_empty() const { return next == this; }
Uses

Slink

65a.

66a

il onstrutor Slink() re un lzo simple puntndo s mismoF v opi de un Slink slo es permitid si el lzo no est inluido dentro de lgun listY un Slink slo puede opirse si ste est voF is_empty() retorn verddero si el next punt s mismoF v ide de este mtodo es invorlo desde un nodo eerF get_next() retorn el siguiente lzo tdo thisF v inserin es respeto l suesor y es omo sigueX miembros pblicos de Slink 65c + (65a) 65c 66b void insert_next(Slink * p) { p->next = next; next = p; }
Uses

Slink

65a.

66b

insert_next() insert el lzo p despus de thisF hel mismo modoD l eliminin te l siguiente elemento y tmin es muy senillX miembros pblicos de Slink 65c + (65a) 66a
Slink * remove_next() { Slink * ret_val = next; next = ret_val->next; ret_val->reset(); return ret_val; }
Slink
65a.

Uses

remove_next() suprime el siguiente elemento respeto this y retorn el lzo elimindoF upongmos que desemos enlzr ojetos de tipo Window en un list simplemente enE lzdF ry dos forms de herloF v primer es por derivinX
class Window : public slink { ... };

in este so podemos insertr diretmente instnis de Window despus de un nodo prtiulr firstX
Window * window_ptr = new Window (...);

2.4. Listas enlazadas

67

... first->insert_next(window_ptr);

isto es posile porque Window esD por derivinD de tipo SlinkF uesto que ls operiones de l lse Slink son en funin de Slink12 D puede ser neesrio efetur un onversinF or ejemploX
window_ptr = static_cast<Window*>(first->remove_next());

gomo first->remove_next() retorn un SlinkD l onversin lo modi( pr que se trte omo de tipo WindowD el ul es el so por derivinF v segund form pr enlzr lses es por oloin de un Slink omo triuto de WindowX
class Window { ... Slink link; };

i first punt l primer nodo de un listD entones un instni window_ptr de tipo Window puede insertrse despus de first del siguiente modoX
first->insert_next(&window_ptr->link);

il enfoque nterior tiene l ventj de que he posile enlzr ojetos vris listsD o seD un ojeto puede ser prte de vris listsF r elloD simplemente deemos delrr omo triutos tntos Slink omo l ntidd de lists ls ules perteneer el ojetoF il ejemplo nterior puede multiplirse de l siguiente formX
class Window { ... Slink link_1; Slink link_2; ... Slink link_n; }; ... first->insert_next(&window_ptr->link_1); first->insert_next(&window_ptr->link_2); ... first->insert_next(&window_ptr->link_n);

gon est tni no es posile her un onversin por ompildorD pues ulquier triuto de tipo Slink no es l propi lse WindowD sino prte de ellF r otener l direin orret prtir de un SlinkD son neesrios lgunos lulos en ritmti de puntdoresF uesto que tles lulos son muy suseptiles de errorD es stnte desele enpsulrlos en un primitiv de l siguiente formX
static Window * link_to_window(Slink *& link) { Window * ptr_zero = 0;
12
Redundancia adrede.

68

2. Secuencias

size_t offset_link = (char*) &(ptr_zero->link); char * address_result = ((char*) link) - offset_link; return (Window *) address_result;

68a

xo tenemos form de onoer los nomres de los triutos Slink ni su ntiddF xo podemosD puesD ofreer un rutin genri que nos onviert un Slink l lse que onteng el SlinkD pero s ofreer un mro que prepre el terrenoX funcin de conversin de Slink a clase 68a (65a) # define SLINK_TO_TYPE(type_name, link_name) \ static type_name * slink_to_type(Slink * link) \ { \ type_name * ptr_zero = 0; \ size_t offset_link = (size_t) &(ptr_zero->link_name); \ char * address_type = ((char*) link) - offset_link; \ return (type_name *) address_type; \ }
Uses

Slink

65a.

il mro tiene dos prmetrosF type_name es el nomre de l lse que lerg un SlinkF link_name es el nomre de un triuto de tipo Slink ontenido dentro de l lse type_nameF wedinte el mro SLINK_TO_TYPED el usurio dispone de un implntin de onverE sin de Slink su lseF il mro se dee inluir dentro de l lse que utilie el SlinkF or ejemploD pr l lse WindowX
class Window { /* ... */ SLINK_TO_TYPE(Window, link); };

e gener un miemro esttio que efet el mismo trjo que funin de onverE sin de Slink lse 68a F i ien el mro es lgo omplidoD ste es independiente de l posiin de Slink en WindowF v estrutur del miemro esttio es l mism pr tod lse que use un SlinkD slo hy que mir Window y link por los nomres que el liente esojF
2.4.3 El TAD

Snode<T>

(nodo simple)

68b

Snode<T> es un lse prmetrizd que stre un nodo perteneiente un list simplemente enlzd irulrD on nodo eerD uyos dtos son de tipo TF Snode<T> se de(ne e implnt en el rhivo tplsnodeFr 68b D el ul posee l siguiente estruturX tpl_snode.H 68b
template <typename T> class Snode : public Slink { miembros privados de Snode<T> 69a miembros pblicos de Snode<T> 69b };
Snode, used in Slink 65a.
chunks 69, 71c, 103h, 104b, 116, and 129a.

Denes: Uses

2.4. Listas enlazadas

69

69a

uesto que Snode<T> deriv de SlinkD ste es tmin un Slink y heredD exepin de lgunos mtodos que deen sorergrseD l myor prte de los mtodos de SlinkF n Snode<T> tiene un nio triutoX miembros privados de Snode<T> 69a (68b) T data;

69b

data ontiene el dto lmendo en el nodoF iste dto puede onsultrse medinte el oservdorX miembros pblicos de Snode<T> 69b (68b) 69c
T& get_data() { return data; }

69c

ry dos mners de onstruir un Snode<T>X miembros pblicos de Snode<T> 69b + Snode() { /* empty*/ }
Snode(const T & _data) : data(_data) { /* empty */ }
Uses

(68b)

69b 69d

Snode

68b.

69d

il onstrutor vo re un nodo on vlor de dto indetermindoF il segundo onsE trutor re un nodo on el vlor de dto dataF il mtodo insert_next() se hered diretmente de SlinkD lo ul es permisile porque un Snode<T> es tmin un SlinkF or el ontrrioD deemos sorergr remove_next()D pues st retorn un Slink y requerimos que se retorne un Snode<T>X miembros pblicos de Snode<T> 69b + (68b) 69c 69e Snode * remove_next() { return (Snode*) Slink::remove_next(); }
Uses

Slink

65a and

Snode

68b.

69e

v mism sorerg dee efeturse pr get_next()X miembros pblicos de Snode<T> 69b + (68b) Snode * get_next() const { return (Snode*) Slink::get_next(); }
Uses

69d

Slink

65a and

Snode

68b.

2.4.4

El TAD

Slist<T>

(lista simplemente enlazada)

69f

il eh Slist<T> stre un list simplemente enlzd irulr de nodos simples y se de(ne en el rhivo tplslistFr 69f D en el ul se de(ne l lse en uestinX tpl_slist.H 69f template <typename T> class Slist : public Snode<T> { deniciones de Slist<T> 69g mtodos pblicos de Slist<T> 70a iterador de Slist<T> 70d };
Uses

Snode

68b.

69g

v lse Slist<T> modeliz un list simplemente enlzd de nodos simples que lmenn dtos de tipo TX deniciones de Slist<T> 69g (69f) typedef Snode<T> Node;
Uses

Snode

68b.

70

2. Secuencias

70a

ist delrin export el tipo Slist<T>::Node sinnimo de Snode<T>F v ni inserin posile es l prinipio de l listD tl omo sigueX mtodos pblicos de Slist<T> 70a (69f) 70b void insert_first(Node * node) { this->insert_next(node); }

70b

insert_first() insert el nodo l prinipio de l listY es deirD node deviene el primer elemento de l listF hel mismo modoD l ni form de suprimir es por el prinipio de l listX mtodos pblicos de Slist<T> 70a + (69f) 70a 70c Node * remove_first() { return this->remove_next(); } remove_first() elimin el primer elemento de l list y retorn su direinF il usurio de Slist<T> puede onoer l direin del primer nodo medinteX mtodos pblicos de Slist<T> 70a + (69f) 70b
Node * get_first() const { return this->get_next(); }

70c

il resto de los elementos pueden ederse trvs de l interfz de Slist<T>::NodeD l ul es l mism de Snode<T>F il usurio puede efetur inseriones y supresiones de l list trvs de est vF
2.4.5 Iterador de

Slist<T>
(69f)

70d

Slist<T> export un iterdor jo l suElseX iterador de Slist<T> 70d


class Iterator { };

miembros privados de iterador de Slist<T> 70e miembros pblicos de iterador de Slist<T> 70f

70e

he lgun mnerD el iterdor dee poseer l informin su(iente pr poder reorrer l listF l informin est onstituid porX miembros privados de iterador de Slist<T> 70e (70d) Slist * list; Node * current;

70f

list es un puntdor l list enlzd sore l ul se iter y current es el elemento tul del iterdorF he restoD el iterdor se de(ne simplemente omo sigueX miembros pblicos de iterador de Slist<T> 70f (70d)
Iterator(Slist & _list) : list(&_list), current(list->get_first()) {} bool has_current() const { return current != list; }

2.4. Listas enlazadas

71

Node * get_current() { return current; } void next() { current = current->get_next(); } void reset_first() { current = list->get_next(); }

il siguiente ejemplo visit todos los elementos de un listX


for (typename Slist<int>::Iterator itor(list); itor.has_current(); itor.next()) // procesar itor.get_current()->get_data();

2.4.6

El TAD

DynSlist<T>

71a

il eh DynSlist<T> modeliz un list de elementos de tipo T uyo mnejo de memori lo he internmente el propio ehF gomo tlD este eh se er ms l onepto idel de list enunido l prinipio del ptuloF u de(niin e implntin se enuentrn en el rhivo tpldynlistFr 71a D uy estrutur es l siguienteX tpl_dynSlist.H 71a template <typename T> class DynSlist : public Slist<T> { Miembros privados de DynSlist<T> 71b Miembros pblicos de DynSlist<T> 72 };

71b

DynSlist<T> hered prte de l interfz e implntin de Slist<T>F this es enE tones el nodo eer de l listF ediionlmenteD DynSlist<T> ontiliz l ntidd de elementos de l listX Miembros privados de DynSlist<T> 71b (71a) 71c size_t num_items;
entes de l priin del ptrn de iterdor presentdo en PFQ @gF SWAD ls interfes ls lists enlzds mnejn el onepto de ursorF n ursor stre un posiin de l list dentro l seueni respeto l ul se efetn sus operiones priniplesF e un ursor se le llm tmin posiin tulF r llevr el estdo del ursor se utilizn los siguientes triutosX Miembros privados de DynSlist<T> 71b + (71a) 71b 71d int current_pos; Snode<T> * current_node;
Uses

71c

Snode

68b.

71d

current_pos es el ordinl del elemento tul dentro de l seueniF current_node es el nodo predeesor l elemento tulF entes de implntr ls primitivs priniples de DynSlist<T>D requerimos un rutin de eso por posiinX Miembros privados de DynSlist<T> 71b + (71a) 71c
typename Slist<T>::Node * get_previous_to_pos(const int & pos) {

72

2. Secuencias

if (pos < current_pos) // hay que retroceder? { // Si, reinicie posicin actual current_pos = 0; current_node = this; } while (current_pos < pos) // avanzar hasta nodo predecesor a pos { current_node = current_node->get_next(); ++current_pos; } return current_node;

72

get_previous_to_pos() retorn el nodo predeesor l posiin pos y dej current_node posiiondo en diho predeesorF v memorizin del predeesor es indispensle pr los lgoritmos de inserin y elimininF vos miemros plios restntes se espei(n omo sigueX Miembros pblicos de DynSlist<T> 72 (71a) T & operator [] (const size_t & i) { return get_previous_to_pos(i)->get_next()->get_data(); } void insert(const int & pos, const T & data) { // apartar nodo para nuevo elemento typename Slist<T>::Node * node = new typename Slist<T>::Node (data); typename Slist<T>::Node * prev = get_previous_to_pos(pos); prev->insert_next(node); ++num_items; } void remove(const int & pos) { // obtener nodo predecesor al nuevo elemento typename Slist<T>::Node * prev = get_previous_to_pos(pos); typename Slist<T>::Node * node_to_delete = prev->remove_next(); delete node_to_delete; num_items; } ~DynSlist() { // eliminar nodo por nodo hasta que la lista devenga vaca while (not this->is_empty()) delete this->remove_first(); // remove_first de clase Slink }
Uses

Slink

65a.

DynSlist<T> export un iterdor uy espei(in es muy simple l herl derivd de Slist<T>::IteratorF


2.4.7 El TAD

Dlink

(enlace doble)

in el mismo espritu de diseo que el eh SlinkD el eh Dlink de(ne un dole enle ontenido en un nodo perteneiente un list dolemente enlzd irulr on nodo eerF

2.4. Listas enlazadas

73

73a

Dlink se espei( e implnt en el rhivo dlinkFr 73a que se estrutur del siguiente modoX dlink.H 73a class Dlink { miembros protegidos de Dlink 73b miembros pblicos de Dlink 73c }; macros conversin de Dlink a clase (never dened)
e prtir de este momento es muy importnte puntulizr y distinguir los siguientes (nesX IF il (n de un Dlink es fungir de nodo eer de un list irulr dolemente enE lzdF in este sentidoD ls operiones de l lse Dlink re(eren lists dolemente enlzdsD irulresD uyo nodo eer es thisF PF il (n de un Dlink* es fungir de puntdor un nodo perteneiente un list irulr dolemente enlzdF

73b

Dlink posee dos triutos protegidosX miembros protegidos de Dlink 73b


mutable Dlink * prev; mutable Dlink * next;

(73a)

73c

next y prev son puntdores l suesor y predeesor de thisF n nuevo Dlink siempre se re on sus lzos puntndo s mismoY es deirD omo un nodo eer uy list est vX miembros pblicos de Dlink 73c (73a) 73d
Dlink() : prev(this), next(this) {}

73d

iventulmenteD unque delidoD es onveniente exportr interfes pr opis y sigE nionesX miembros pblicos de Dlink 73c + (73a) 73c 73e Dlink(const Dlink &) { reset(); }
Dlink & operator = (const Dlink & l) { reset(); return *this; }

73e

in reliddD ls dos operiones no efetn opiY se exportn pr stisfer operiones on vriles temporles usds por el ompildorF xo es posile her opi este nivel porque no se mnej ningn menismo de signin de memori ni se onoe el tipo de dto que lergn los nodosF n dole enle puede reiniirse medinteX miembros pblicos de Dlink 73c + (73a) 73d 74 void reset() { next = prev = this; }

74

2. Secuencias

74

reset() reinii un list que punte s mismoF isto no es equivalente a eliminar thisF eunque no es posile signr sore un list que onteng elementosD s lo es interE mir los ontenidos de dos lists dolemente enlzds en tiempo onstnteF or est rzn se ofree l primitiv swap() uy implntin es omo sigueX miembros pblicos de Dlink 73c + (73a) 73e 75a
los nodos atados a

void swap(Dlink * link) { if (is_empty() and link->is_empty()) return; if (is_empty()) { link->next->prev = this; link->prev->next = this; next = link->next; prev = link->prev; link->reset(); } return;

if (link->is_empty()) { next->prev = link; prev->next = link; link->next = next; link->prev = prev; reset(); return; } std::swap(prev->next, link->prev->next); std::swap(next->prev, link->next->prev); std::swap(prev, link->prev); std::swap(next, link->next);

this

swap

swap

swap
link

swap

pigur PFWX yperin swap(link)

2.4. Listas enlazadas

75

75a

swap() es un grn operinD pues prte de que su tiempo de ejeuin es espetE ulrD pues es onstnteD es generl pr tods ls lists dolemente enlzds on nodo eerD sin importr ni el tipo de dto que se mneje ni mo se reserve l memoriF v (gur PFW ilustr los nodos de ls lists en los ules se llevn o los intermiosF esumiendo que this es el nodo eer de un list podemos ser si l list est v o no si ontiene un solo elemento o si su rdinlidd es menor o igul unoX miembros pblicos de Dlink 73c + (73a) 74 75b bool is_empty() const { return this == next and this == prev; }
bool is_unitarian() const { return this != next and next == prev; } bool is_unitarian_or_empty() const { return next == prev; }

75b

n punto destr de ests operiones es que no requieren ontilizr l ntidd de nodos de l listF v (gur PFIH enumer los diferentes psos involurdos en l inserinD los ules se efetn en l rutin insert()D l ul insert node omo el suesor de thisX miembros pblicos de Dlink 73c + (73a) 75a 75c void insert(Dlink * node) { node->prev = this; node->next = next; next->prev = node; next = node; }
1: node->prev
= this;

node X
= node;

2: node->next
= node;

= next;

4: next

3: next->prev

this

pigur PFIHX snserin en un list dolemente enlzd implntd on Dlink v inserin omo predeesor se denomin append() y se de(ne omo sigueX miembros pblicos de Dlink 73c + (73a) 75b 76a void append(Dlink * node) { node->next = this; node->prev = prev; prev->next = node; prev = node; } uesto que l list es irulrD insert() desde el nodo eer insert un nodo l prinipio de l listF enlogmenteD append() los insert l (nlF

75c

76

2. Secuencias

76a

hd l direin de un nodo podemos eder su suesor y predeesor medinte los siguientes mtodosX miembros pblicos de Dlink 73c + (73a) 75c 76b Dlink *& get_next() { return next; } Dlink *& get_prev() { return prev; }
this

head

(a) Antes de ejecutar


this

insert_list(head)

head

(b) Despus de ejecutar

insert_list(head)

pigur PFIIX snserin de list dentro de un list ixisten irunstnis en ls ules se requiere insertr un list omplet dentro de otr prtir de uno de sus nodosF r ello utilizmos ls primitivs insert_list() y append_list()F v (gur PFII muestr el proeso de ejeuin de insert_list(head)F hespus su ejeuinD l list uyo nodo eer est puntdo por head deviene vD pues sus nodos fueron inluidos en thisF is muy importnte notr que en este so this no neesrimente es un nodo eerD sino que puede ser ulquier otro nodoF vs implementiones son omo sigueX miembros pblicos de Dlink 73c + (73a) 76a 77a void insert_list(Dlink * head) { if (head->is_empty()) return;
head->prev->next = next; head->next->prev = this; next->prev = head->prev;

76b

2.4. Listas enlazadas

77

} void append_list(Dlink * head) { if (head->is_empty()) return; head->next->prev head->prev->next prev->next prev head->reset(); = = = = prev; this; head->next; head->prev;

next head->reset();

= head->next;

77a

in lgunos ontextosD ls operiones insert_list() y append_list() se onoen omo splie 13 F n so prtiulrD quiz muho ms omn que el splieD es l operin de ontenr lists concat_list(head)D l ul onten l list uyo nodo eer es head on thisF head deviene v despus de l operinF in este soD s se sume que this es nodo eerF el respetoD se plnte l siguiente implementinX miembros pblicos de Dlink 73c + (73a) 76b 77b void concat_list(Dlink * head) { if (head->is_empty()) return;
if (this->is_empty()) { swap(head); return; } prev->next = head->next; head->next->prev = prev; prev = head->prev; head->prev->next = this; head->reset();

77b

hd l direin de un nodo hy vris mners de invor un elimininF v ms til de todsD denomind utoelimininD se efet medinte del()F v rutin es muy til porque permite que otrs estruturs de dtos lmenen referenis eliminles elementos de un list enlzdF in otrs plrsD un nodo ulquier puede suprimirse s mismo de l listF u implementin es omo sigueX miembros pblicos de Dlink 73c + (73a) 77a 78a void del() { prev->next = next;
13
En ingls, este trmino se utiliza cuando se desea expresar que dos cosas se pegan, se juntan, por sus extremos -una punta con la otra-. En la opinin de este redactor, el equivalente castellano ms prximo es enlazar, cuyo uso plantea una ambigedad en la jerga de listas enlazadas. Por esa razn, continuaremos utilizando el trmino en ingls.

78

2. Secuencias

next->prev = prev; reset();

vos psos de del() se muestrn en l (gur PFIPF


1:
prev->next = next;

3: reset();
A B C D

2:
this

next->prev = prev;

pigur PFIPX eutoeliminin en un list dolemente enlzd implntd on Dlink hdo un nodo hy otrs dos mners de eliminrX su predeesor o su suesorD ls ules se implntn medinte los siguientes mtodosX miembros pblicos de Dlink 73c + (73a) 77b 78b Dlink * remove_prev() { Dlink* retValue = prev; retValue->del(); return retValue; } Dlink * remove_next() { Dlink* retValue = next; retValue->del(); return retValue; }

78a

78b

remove_prev() suprime el predeesor respeto thisY remove_next() suprime el sueE sorF ists primitivs son prtiulrmente tiles pr el nodo eer de l listF uesto que l list es irulrD remove_prev()D invod desde el nodo eerD suprime el ltimo nodo de l listY similrmenteD remove_next() suprime el primeroF n pliin diret de lgunos de los mtodos explidos se ejempli( medinte un rutin de inversin de nodos de l listX miembros pblicos de Dlink 73c + (73a) 78a 79a
size_t reverse_list() { if (is_empty()) return 0;

Dlink tmp; // cabecera temporal donde se guarda lista invertida // recorrer lista this, eliminar primero e insertar en tmp size_t counter = 0; for (/* nada */; not is_empty(); counter++) tmp.insert(remove_next()); // eliminar e insertar en tmp swap(&tmp); // tmp == lista invertida; this vaca ==> swap

2.4. Listas enlazadas

79

return counter;

79a

eprte de invertir l listD reverse_list() proveh el reorrido pr ontr l nE tidd de nodosY ntidd que retorn l funinF hd un listD mo prtirl por el entro en dos lists del mismo tmoc n truo onsiste en vnzr dos puntdoresF or d iterinD un puntero vnz un psoD mientrs que el otro vnz dos14 F gundo el segundo puntero se enuentre l (nl de l listD el primero se enontrr en el entroY este es el punto de prtiinF iste enfoqueD es el ms deudo pr prtiionr un list simpleD pero dee progrmrse uiddosmente los sos extremos de eroD uno o dos elementosF r lists dolemente enlzds existe un enfoque muho ms simple yD omo todo lo simpleD ms on(leX reorrer l list por d extremoF or el ldo izquierdo se reorre hi l derehY por el dereho hi l izquierdF in d iterin se elimin de d extremo y se insert en d un de ls lists resultdoF r ello disemos el mtodo split_list(l, r)D el ul reie dos eers de lists vs l y r y prtiion this por el entro en dos prtesD l izquierd en l y l dereh en rX miembros pblicos de Dlink 73c + (73a) 78b 79b size_t split_list(Dlink & l, Dlink & r) { size_t count = 0; while (not is_empty()) { l.append(remove_next()); ++count;
if (is_empty()) break; r.insert(remove_prev()); ++count; } return count;

79b

hd un list y uno de sus nodosD puede ser onveniente prtiionrl en un nodo ddoF r elloD se provee l funin cut_list() uy implntin es omo sigueX miembros pblicos de Dlink 73c + (73a) 79a 80a void cut_list(Dlink * link, Dlink * list) { list->prev = prev; // enlazar list a link (punto de corte) list->next = link; prev = link->prev; // quitar de this todo a partir de link link->prev->next = this; link->prev = list; // colocar el corte en list list->prev->next = list; } il esquem de este lgoritmo se ilustr en l (gur PFIQF cut_list() prtiion this en el nodo uy direin es linkD el ul dee perteneer l list thisF vos nodos l izquierd de link se preservn en thisD mientrs que los restntesD inluido linkD se opin listF
14
Se puede decir que el segundo duplica en velocidad al primero.

80

2. Secuencias

this

link

list

pigur PFIQX gorte de un list en un nodo ddo vos usos de Dlink son si los mismos que el de Slink desrrolldo en l susein PFRFP @gF TSAF odemos her un lse ser un Dlink por derivin pliD o herl prte de un nodo dole por delrin de un Dlink omo triuto de l lseF v difereni esenil respeto Slink es su verstiliddD expresd por l riquez de ls operiones que hemos estudidoD ls ules sern ms difiles de desrrollr que ls operiones de SlinkF el igul que on SlinkD pr situiones en que se usn registros que ontengn Dlink se requieren mros que genern funiones de onversin de un Dlink hi un lse que onteng un triuto DlinkF in este sentido hy dos posiiliddes prolesD unque no generlesX onversin hi un lse simple o onversin hi un lse prmetrizdF ists posiiliddes se englon en los mros DLINK_TO_TYPE(type_name, link_name) y LINKNAME_TO_TYPE(type_name, link_name)D los ules genern un funin de onverE sin que onvierte un puntero link de tipo Dlink en un puntero un lse que ontiene el DlinkF il mro DLINK_TO_TYPE gener un funin generl on nomre dlink_to_type()F il mro LINKNAME_TO_TYPE reie un prmetro llmdo link_nameD el ul deer orresponder extmente on el nomre del mpo dentro de l lseF v rzn de ser de est funin es que permite l usurio distintos nomres de funiones pr distintos nomres de mposY esto es indispensle en los sos en que l lse onteng dos o ms enles dolesF vos mros DLINK_TO_TYPE y LINKNAME_TO_TYPE deen utilizrse dentro de l lse que use el tipo DlinkF
Iterador de
80a

Dlink Dlink export un iterdor @ver PFQ @gF SWAA uyo esquem se present omo sigueX miembros pblicos de Dlink 73c + (73a) 79b 82c
class Iterator { atributos Dlink::Iterator };
80b

miembros pblicos iterador Dlink::Iterator

80c

80b

r mntener el estdo del iterdor requerimos dos miemrosX atributos Dlink::Iterator 80b mutable Dlink * head; mutable Dlink * curr;

(80a)

80c

head es el nodo eer de l listF curr es el nodo tul del iterdorF ry vris mners de onstruir un iterdorX miembros pblicos iterador Dlink::Iterator 80c (80a) 81a

2.4. Listas enlazadas

81

Iterator(Dlink * head_ptr) : head(head_ptr), curr(head->get_next()) {} Iterator(const Iterator &


81a

itor) : head(itor.head), curr(itor.curr) {}


(80a) 80c 81b

n iterdor puede signrseX miembros pblicos iterador Dlink::Iterator 80c + Iterator & operator = (const Iterator & itor) { head = itor.head; curr = itor.curr; return *this; }

81b

n iterdor puede reutilizrseD lo que requiere funiones de reiniiinX miembros pblicos iterador Dlink::Iterator 80c + (80a) 81a 81c void reset_first() { curr = head->get_next(); } void reset_last() { curr = head->get_prev(); }

81c

reset_first() posiion el iterdor sore el primer elementoF reset_last() posiion el iterdor sore el ltimo elementoF ixisten situiones espeiles en ls ules se dese iniilizr un iterdor prtir de un elemento tul y onoidoX miembros pblicos iterador Dlink::Iterator 80c + (80a) 81b 81d
void set(Dlink * new_curr) { curr = new_curr; } void reset(Dlink * new_head) { head = new_head; curr = head->get_next();; }

81d

set() sit el iterdor un nuevo nodo tulD mientrs reset() sit el iterdor un nuev listF il elemento tul del iterdor se ede y se veri( medinteX miembros pblicos iterador Dlink::Iterator 80c + (80a) 81c 82a
bool has_current() const { return curr != head; } Dlink * get_current() { return curr; } bool is_in_first() const { return curr == head->next; } bool is_in_last() const { return curr == head->prev; }

82

2. Secuencias

82a

r vnzr el iterdor utilizmos ls siguientes primitivsX miembros pblicos iterador Dlink::Iterator 80c + (80a) void prev() { curr = curr->get_prev(); } void next() { curr = curr->get_next(); }

81d 82b

e menudo pueden ominrse iterdores en un for que semejn l iterin sore un rregloF gomo un list no tiene eso diretoD l ondiin de iterin no dee ser un omprin por posiin del tipo i < nF in un list yD en generlD pr seuenis que se mnipulen on iterdoresD l omprin dee ser entre iterdoresF uesto que no se puede onoer l posiin dentro de l seueni pr tods ls situionesD no es posile empler los omprdores relionles <, <=, >, >=D pero s se pueden sorergr los operdores == y != tl omo en efeto lo estn en l ilioteF n estilo trdiionl de uso de l omprin entre iterdores se ilustr en este ejemE ploX
for (Dlink::Iterator curr(list); curr != end; curr.next())

honde end es un iterdor sore l list list puntndo l (nlF iste es el estilo de l iliote estndr stdc++F end es equivlente X
Dlink::Iterator end(list); list.reset_last(); list.next();

82b

is posile insertr respeto l elemento tul del iterdorF r ello st on invor sore el elemento tul ulquier de ls primitivs de inserin insert() o append()F ry situiones en ls que se requiere eliminr el elemento tul del iterdorF in este so no es posile efetur del() sore el nodo tulD pues podr perderse el estdo del iterdorF r solventr est situinD l lse Dlink::Iterator export un funin de eliminin sore el nodo tul que dej l iterdor en el nodo suesor del elimindoX miembros pblicos iterador Dlink::Iterator 80c + (80a) 82a Dlink * del() { Dlink * current = get_current(); // obtener nodo actual next(); // avanzar al siguiente nodo current->del(); // eliminar de la lista antiguo nodo actual return current; }

82c

del() retorn el enle elimindo de mner tl que el liente pued disponer de l en l form que pre(erF gomo ejemplo de uso de Dlink::Iterator onsideremos el siguiente mtodoX miembros pblicos de Dlink 73c + (73a) 80a
void remove_all_and_delete() { for (Iterator itor(this); itor.has_current(); delete itor.del()) ; }

2.4. Listas enlazadas

83

iste mtodo elimin todos los nodos y sume que l memori de d nodo fue signd medinte newF
2.4.8 El TAD

Dnode<T>

(nodo doble)

83a

in un nivel superior respeto DlinkD el eh Dnode<T> modeliz un nodo perteneiente un list dolemente enlzd irulrF Dnode<T> se de(ne e implnt en el rhivo tpldnodeFr 83a uy estrutur es l siguienteX tpl_dnode.H 83a template <typename T> class Dnode : public Dlink { mtodos privados Dnode<T> 83b mtodos pblicos Dnode<T> 83c };
Denes:

Dnode,

used in chunks 8391, 15355, 165a, 185, 384b, 385c, and 440a.

83b

Dnode<T> es un Dlink plio por derivinF v ni difereni reside en que Dnode<T> lmen un elemento de tipo de TX mtodos privados Dnode<T> 83b (83a)
mutable T data;

83c

vos mtodos de Dlink que retornen punteros Dlink* deen sorergrse pr que retornen punteros tipedos Dnode<T>*X mtodos pblicos Dnode<T> 83c (83a) 83d Dnode<T> *& get_next() { return (Dnode<T>*&) next; }
Dnode<T> *& get_prev() { return (Dnode<T>*&) prev; } Dnode<T>* remove_prev() { return (Dnode<T>*) Dlink::remove_prev(); } Dnode<T>* remove_next() { return (Dnode<T>*) Dlink::remove_next(); }
Uses

Dnode

83a.

83d

v ni funin de estos mtodos es efetur l onversin hi Dnode<T>F il mnejo de los enles se implnt por el mtodo de l lse se DlinkF il eso l dto se reliz porX mtodos pblicos Dnode<T> 83c + (83a) 83c 83e T & get_data() { return data; } n punto summente importnte es el tipo de dto de Dnode<T>D el ul se export medinte l siguiente delrinX mtodos pblicos Dnode<T> 83c + (83a) 83d 84 typedef T dnode_type; ist delrin permite que progrms genrios onozn el tipo de dto de Dnode<T>F or ejemploD si se tiene un Dnode<T> jo el tipo genrio NodeD entonesD un frgmento de progrm podr serX
typename Node::dnode_type data;

83e

84

2. Secuencias

84

el ul delr un vrile de nomre data del tipo involurdo en NodeD el ul es el mismo tipo genrio TF ry un mtodo uyo uso es exepionlD pero que puede ser extrordinrimente til en ierts irunstnisX mtodos pblicos Dnode<T> 83c + (83a) 83e static Dnode * data_to_node(T & data) { Dnode * zero = 0; long offset = (long) &(zero->data); char * addr = (char*) (&data); return (Dnode*) (addr - offset); }
Uses

Dnode

83a.

Dnode<T> Dnode<T> export un iterdor uy sintxis y semnti son idntis ls de Dlink::Iterator F uesto que el estdo y ontrol del iterdor y est implntdoD l espei(in de Dnode<T>XXstertor slo se remite l sorerg de los onstrutores y l otenin del elemento tulF
Iterador de
+exporta

Dlink::Iterator

Dlink

Node:<template <class> class T:class

T:class

MetaDlistNode

Dnode

+exporta

T:class

Dnode::Iterator
T:class Node_Type:template <class> class class T:

GenDlist

DynDlist
+exporta T:class

+exporta

GenDlist<T>::Iterator
T:class +con

Dlist_Node

GenDlist<Dlist_Node, T> Especializacin GenDlist<Dlist_Node_Vtl, T> Especializacin


T:class

T:class

DynDlist<T>::Iterator

T:class +con

Dlist_Node_Vtl

Dlist
T:class

DlistVtl Con nodos virtuales

pigur PFIRX higrm generl wv de ls lses ALEPH pr lists enlzds doles


2.4.9 El TAD

DynDlist<T>

vs lses Dnode<T> y Dlist<T> son su(ientemente verstiles omo pr llevr o pliiones omplejs que requiern lists dolemente enlzdsF in emrgoD ests lses n requieren que el progrmdor omprend lmente sus sutilezs de usoY en prtiulrD el mnejo de memoriF in un ltimo nivelD disemos l lse DynDlist<T>D l ul modeliz un list doleE mente enlzd irulr on mnejo interno de memoriF DynDlist<T> se espei( e

2.4. Listas enlazadas

85

85a

implnt en el rhivo tpldynhlistFr 85a X tpl_dynDlist.H 85a template <typename T> class DynDlist : public Dnode<T> { mtodos pblicos DynDlist<T> 85b };
Denes:

DynDlist,
Uses

used in chunks 85, 8791, 94a, 95d, 98, 155a, 207, 254b, 255, 57981, 610b, 611b, 615b, 617,

626a, 628, 64448, 656, 657, 659, 706, 712b, 769, 78082, 788a, 789, and 791.

Dnode

83a.

85b

v ide DynDlist<T> es que soporte tod l funionlidd que rrstrmos desde Dlink sin neesidd de pensr en el mnejo de puntdoresD nodos y memoriF DynDlist<T> hered plimente su implntin de l lse Dnode<T> y un uen prte de su interfzF v responsilidd esenil de DynDlist<T> es el mnejo de memoE riF il nio triuto de DynDlist<T> es num_elemD el ul ontiliz l ntidd de elementos que posee l list y puede oservrse medinteX mtodos pblicos DynDlist<T> 85b (85a) 85c const size_t & size() const { return num_elem; } v onstruin es muy simpleD puesD exepin del mnejo de memori y de l ontilizin del nmero de elementosD todo est implntdo desde l lse Dnode<T>X mtodos pblicos DynDlist<T> 85b + (85a) 85b 85d DynDlist() : num_elem(0) { /* Empty */ }
Uses

85c

DynDlist

85a.

85d

el igul que en Dnode<T>D podemos insertr elementos por el prinipio o (nl de l listF mtodos pblicos DynDlist<T> 85b + (85a) 85c 85e T & insert(const T & _data) { Dnode<T> * p = new Dnode<T> (_data); Dnode<T>::insert(p); ++num_elem; return p->get_data(); } T & append(const T & _data) { Dnode<T> * p = new Dnode<T> (_data); Dnode<T>::append(p); ++num_elem; return p->get_data(); }
Uses

Dnode

83a.

85e

vs misms operiones se de(nen pr listsD es deirD se puede ontenr un list enter tnto por el prinipio omo por el (nlX mtodos pblicos DynDlist<T> 85b + (85a) 85d 86a size_t insert_list(DynDlist & list) { Dlink::insert_list(&list);

86

2. Secuencias

} size_t append_list(DynDlist & list) { Dlink::append_list(&list); num_elem += list.num_elem; list.num_elem = 0; return num_elem; }
Uses

num_elem += list.num_elem; list.num_elem = 0; return num_elem;

DynDlist

85a.

86a

il eso un seueni DynDlist<T> se llev o por uno de sus extremosX el primer o el ltimo elementoX mtodos pblicos DynDlist<T> 85b + (85a) 85e 86b T & get_first() { return this->get_next()->get_data(); } T & get_last() { return this->get_prev()->get_data(); } emos mtodos retornn referenis l dto inluido dentro de l listF isto signi( que el usurio puede modi(rlos diretmenteF rdiionlmenteD l eliminin se reliz por lguno de los extremosX mtodos pblicos DynDlist<T> 85b + (85a) 86a 86d T remove_first() { Dnode<T> * ptr = this->remove_next();
} T remove_last() { Dnode<T> * ptr = this->remove_prev(); }
Uses

86b

obtener dato y liberar ptr 86c

obtener dato y liberar ptr 86c


83a.

Dnode

86c

obtener dato y liberar ptr 86c

(86b)

T retVal = ptr->get_data(); delete ptr; num_elem; return retVal;

86d

remove_first() suprime el primer elementoD remove_last() el ltimoF e difereni de l onsultD l eliminin retorn opis de los vloresD no referenisD pues el nodo es de existir despus de lierr l memori oupd por el nodoF is posile vir un listD esto esD eliminr todos sus elementosX mtodos pblicos DynDlist<T> 85b + (85a) 86b 87a

2.4. Listas enlazadas

87

void empty() { while (not this->is_empty()) delete this->remove_next(); num_elem = 0; }


87a

ist primitiv dee ser invod por el destrutorX mtodos pblicos DynDlist<T> 85b + ~DynDlist() { empty(); }
Uses

(85a)

86d 87b

DynDlist

85a.

87b

in lguns irunstnis es muy til poder eliminr un elemento queD semosD pertenee l seueniX mtodos pblicos DynDlist<T> 85b + (85a) 87a 87c void remove(T & data) { Dnode<T> * p = data_to_node(data); p->del(); delete p; num_elem; }
Uses

Dnode

83a.

87c

n primitiv esenil pr el desempeo y elegni de lgunos lgoritmos es swap()F gomo todo el trjo y fue implntdo desde l lse DlinkD nuestr primitiv slo se remite tiper e invorX mtodos pblicos DynDlist<T> 85b + (85a) 87b 87d void swap(DynDlist & l) { std::swap(num_elem, l.num_elem); this->Dlink::swap(&l); }
Uses

DynDlist

85a.

87d

ytr form de modi(in de un list dinmi es l prtiin equittivF isto puede herse desde el mtodo Dlink::split_list()X mtodos pblicos DynDlist<T> 85b + (85a) 87c 88a void split_list(DynDlist & l, DynDlist & r) { Dlink::split_list(l, r); l.num_elem = r.num_elem = num_elem/2;
if (num_elem % 2 == 1) // es num_elem impar? l.num_elem++; }
Uses

num_elem = 0;
DynDlist
85a.

88

2. Secuencias

2.4.9.1

Iterador de

DynDlist<T>

88a

rst el presenteD l inserinD eliminin y otrs operiones de modi(in estn restringids los extremos de l listF i un pliin requiere modi(in en posiiones diferentesD entones st puede servirse de un iterdor undo operiones espeiles sore el elemento tulX mtodos pblicos DynDlist<T> 85b + (85a) 87d 91a class Iterator : public Dnode<T>::Iterator { DynDlist * list_ptr; // puntero a la lista int pos; // posicin del elemento actual en la secuencia mtodos iterador de DynDlist<T> 88b };
Uses

Dnode

83a and

DynDlist

85a.

88b

v lse gurd un puntdor l list on el propsito de mntener el ontdor de elementosY de est mner se puede tulizr el ontdor undo se ejeuten operiones sore el iterdor que modi(quen l ntidd de elementosF il triuto pos re)ej l posiin ordinl dentro de l seueni del elemento tul y puede oservrse medinteX mtodos iterador de DynDlist<T> 88b (88a) 88c const int & get_pos() const { return pos; } r mntener orretmente el estdo de este vlor deemos sorergr ls funiones de vne del iterdor de mner tl que tulien su vlorX mtodos iterador de DynDlist<T> 88b + (88a) 88b 88d const int & next() { Dnode<T>::Iterator::next(); pos++; return pos; }
Uses

88c

Dnode

83a.

88d

il mnejo de l posiin del elemento tul del iterdor tmin requiere sorergr los mtodos reset_first() y reset_last()F r rer un iterdor slo se requiere un list o por opi de otro iterdorX mtodos iterador de DynDlist<T> 88b + (88a) 88c 89a Iterator(DynDlist<T> & _list) : Dnode<T>::Iterator(_list), list_ptr(&_list), pos(0) {}
Iterator(const Iterator & it) : Dnode<T>::Iterator(it), list_ptr(it.list_ptr), pos(it.pos) {} Iterator() : list_ptr(NULL) {} Iterator & operator = (const Iterator & it) { Dnode<T>::Iterator::operator = (it); list_ptr = it.list_ptr; pos = it.pos; return *this;

2.4. Listas enlazadas

89

}
Uses

Dnode

83a and

DynDlist

85a.

89a

has_current() se hered de l lse se DlinkF Dnode<T> trj en funin de nodos y nuestro iterdor dee trjr en funin de elementos de tipo TF or es rzn deemos sorergr get_current()X mtodos iterador de DynDlist<T> 88b + (88a) 88d 89b
T & get_current() { return Dnode<T>::Iterator::get_current()->get_data(); }
Dnode
83a.

Uses

89b

v inserin y supresin medinte el iterdor de Dnode<T> es diret porque Dnode<T> mnej elementos de tipo Dnode<T> que poseen sus propis primitivs de inserin y supresinF in nuestro so no es posile herlo porque mnejmos elementos genrios de tipo TF es puesD requerimos que el iterdor exporte funiones que permitn insertr y eliminrF v inserin l presentmos jo ls misms forms que DynDlist<T>X mtodos iterador de DynDlist<T> 88b + (88a) 89a 89c void insert(const T & _data) { Dnode<T>::Iterator::get_current()->insert(new Dnode<T>(_data)); ++list_ptr->num_elem; } void append(const T & _data) { Dnode<T>::Iterator::get_current()->append(new Dnode<T>(_data)); ++list_ptr->num_elem; }
Uses

Dnode

83a.

89c

vs otrs mners de insertr son lists enters prtir del elemento tulX mtodos iterador de DynDlist<T> 88b + (88a) 89b 89d void insert_list(const DynDlist & list) { Dnode<T>::Iterator::get_current()->insert_list(&list); list_ptr->num_elem += list.num_elem; list.num_elem = 0; } void append_list(const DynDlist & list) { Dnode<T>::Iterator::get_current()->append_list(&list); list_ptr->num_elem += list.num_elem; list.num_elem = 0; }
Uses

Dnode

83a and

DynDlist

85a.

89d

v supresin l vemos omo l supresin del elemento tulX mtodos iterador de DynDlist<T> 88b + (88a) T del() { Dnode<T> * ptr = Dnode<T>::Iterator::get_current();

89c 90a

90

2. Secuencias

}
Uses

T ret_val = ptr->get_data(); Dnode<T>::Iterator::next(); ptr->del(); delete ptr; list_ptr->num_elem; return ret_val;


Dnode
83a.

90a

v operin del() puede ser muy restritiv en el sentido de que vnz el iterdorY demsD lo he en un solo sentidoF xos onvieneD puesD ofreer l primitivs de eliminin ontextulesD es deirD el predeesor o suesor del elemento tulX mtodos iterador de DynDlist<T> 88b + (88a) 89d 90b T remove_prev() { Dnode<T> * curr_ptr = Dnode<T>::Iterator::get_current(); Dnode<T> * ptr = curr_ptr->remove_prev(); T ret_val = ptr->get_data(); delete ptr; list_ptr->num_elem; return ret_val; } T remove_next() { Dnode<T> * curr_ptr = Dnode<T>::Iterator::get_current(); Dnode<T> * ptr = curr_ptr->remove_next(); T ret_val = ptr->get_data(); delete ptr; list_ptr->num_elem; return ret_val; }
Uses

Dnode

83a.

90b

v ltim operin de modi(in de un list dinmi medinte un iterdor puede ser muy til en lgunos sosY se trt del orte de un list prtir de l posiin tul del iterdorX mtodos iterador de DynDlist<T> 88b + (88a) 90a size_t cut_list(DynDlist & list) { list_ptr->Dnode<T>::cut_list(Dnode<T>::Iterator::get_current(), &list); list.num_elem = list_ptr->num_elem - pos; list_ptr->num_elem -= pos; return list.num_elem; }
Uses

Dnode

83a and

DynDlist

85a.

90c

il iterdor permite un mner onis y expresiv de opir listsX copiar lista 90c (91) for (typename DynDlist<T>::Iterator itor(const_cast<DynDlist&>(list)); itor.has_current();itor.next())
this->append(itor.get_current());
Uses

DynDlist

85a.

2.4. Listas enlazadas

91

91a

vo que permite implntr l signin y el onstrutor opiX mtodos pblicos DynDlist<T> 85b + (85a) 88a DynDlist<T> & operator = (const DynDlist & list) { while (not this->is_empty()) // vaciar this this->remove_first();

91b

copiar lista 90c


}
Uses

return *this;
DynDlist
85a.

91b

hel mismo modoD el onstrutor opiX mtodos pblicos DynDlist<T> 85b + DynDlist(const DynDlist & list) : Dnode<T>(list) { this->reset(); num_elem = 0;
}
Uses

(85a)

91a 91c

copiar lista 90c


83a and

Dnode

DynDlist

85a.

91c

v llmd this->reset() es indispensle pr segurr que l list est lgimente vF i no se hiier sD entones el vlor de thisD que funge de nodo eerD orreE sponder l opi de listF i l ondiin de list imposiilit el eso direto sus elementosD efetos de interfz puede ser ltmente desele disponer del operdor de eso por posiinX mtodos pblicos DynDlist<T> 85b + (85a) 91b T & operator [] (const size_t & n) { typename DynDlist<T>::Iterator it(*this); for (int i = 0; i < n and it.has_current(); i++, it.next()) ; return it.get_current(); }
Uses

DynDlist

85a.

2.4.10

Aplicacin: aritmtica de polinomios

91d

gonsideremos un eh que modelie polinomios y sus operiones sisF l eh est relizdo en el rhivo polinomFg 91d D el ul se de(ne ontinuinX polinom.C 91d class Polinomio {
};

Miembros privados Polinomio 93c interfaz de Polinomio 91e

Implementacin de mtodos Polinomio 94f

91e

ry vris mners de rer un polinomioD l primer es por omisinX interfaz de Polinomio 91e (91d) 92a Polinomio();

92

2. Secuencias

92a

iste onstrutor re el polinomio 0x0 F r onstruir un polinomio ulquierD el punto de prtid ser un polinomio de un solo trminoX interfaz de Polinomio 91e + (91d) 91e 92b Polinomio(const int& coef, const size_t & pot); iste onstrutor instni el polinomio coef xpot Y por ejemploX
Polinomio p(20, 7);

92b

snstni un polinomio on vlor 20x7 F i queremos onstruir un polinomio ms omplejoD entones podemos sumr vrios trminos medinte el operdor de sumX interfaz de Polinomio 91e + (91d) 92a 92c Polinomio operator + (const Polinomio&) const; or ejemploD pr onstruir el polinomio 20x7 + 3x3 + x2 + 20 podemos efeturX
Polinomio p(Polinomio(20, 7) + Polinomio(3, 3) + Polinomio(1, 2) + Polinomio(20, 0));

92c

or rzones de e(ieni que disutiremos posteriormenteD es onveniente ofreer l siguiente versin de l sumX interfaz de Polinomio 91e + (91d) 92b 92d Polinomio& operator += (const Polinomio&); wedinte este operdorD el polinomio nterior puede onstruirse omo sigueX
Polinomio p(20, 7); p += Polinomio(3, 3) + Polinomio(1, 2) + Polinomio(20, 0);

92d

il produto de dos polinomios se espei( medinte el operdor *X interfaz de Polinomio 91e + (91d) 92c 92e Polinomio operator * (const Polinomio&) const; ytrs operiones que se delegn ejeriios sonX interfaz de Polinomio 91e + Polinomio operator - (const Polinomio&) const;
Polinomio operator / (const Polinomio&) const; Polinomio operator % (const Polinomio&) const;
(91d) 92d 92f

92e

92f

ists operiones orresponden l sustrinD divisin y residuoF vs pliiones que utilien polinomios requerirn un form de eder sus trmiE nosF r ello deemos proveer un onjunto mnimo de primitivsF n triuto esenil de un polinomio es onoer l ntidd de trminosX interfaz de Polinomio 91e + (91d) 92e 92g const size_t & size() const; equerimos onoer d uno de los trminosY esto lo podemos her medinteX interfaz de Polinomio 91e + (91d) 92f 93a size_t get_power(const size_t & i) const;

92g

2.4. Listas enlazadas

93

93a

get_power() retorn l poteni orrespondiente l iEsimo trmino diferente de ero sumiendo que los trminos del polinomio estn ordendos desde l myor hst l menor poteniF il oe(iente se otiene medinteX interfaz de Polinomio 91e + (91d) 92g 93b
const int & get_coef(const size_t & i) const;

93b

il grdo del polinomio puede onsultrse medinteX interfaz de Polinomio 91e + const size_t & get_degree() const;
2.4.10.1 Implementacin de polinomios

(91d)

93a

n primer tentin omo estrutur de dto pr representr un polinomio es un rregloF r un polinomio de grdo n se reserv un rreglo de dimensin n + 1D el ul ontiene los oe(ientesF xo es neesrio lmenr l poteniD pues st se represent medinte el propio ndie del rregloF in prieniD el rreglo ofree ventjs fenomenlesY por ejemploD l sum es diretE mente l sum de vetoresF vmentlementeD el rreglo puede desperdiir un ntidd de espio impresionnteY por ejemploD el polinomio 20x100 requiere un rreglo de 101 elementos pr lmenr un solo oe(ienteY un desperdiio del 997F vos polinomios son muy diversosF v multipliin y divisin rrojn polinomios de grdos diferentes sus operndosF in un miente donde se efeten muhs operionesD es de esperr que dos polinomios tengn sus grdos diferentesF in didurD muhs vees un polinomio es espridoD es deirD vrios de sus oe(ientes son nulosF or ests rzonesD un list enlzd que slo lmene trminos diferentes de ero es l estrutur idne pr representr un polinomioF v (gur PFIS ilustr l representin on lists dolemente enlzds del polinomio 6 4x + 2x3 1x2 + x + 7F v list est ordend desde l myor hst l menor poteniF il orden es esenil pr filitr l e(ieni de los lgoritmosF
4 6 2 3 -1 2 1 1 7 0

pigur PFISX epresentin de 4x6 + 2x3 x2 + x + 7 on lists enlzds r representr un polinomio podemos utilizr el eh DynDlist<T>D el ul reie omo prmetro un tipo que lerg los elementos gurdr en l listD es deirD los pres oe(ienteEpoteniX Miembros privados Polinomio 93c (91d) 94a struct Termino { int coef; size_t pot;
};

93c

Miembros Trmino 94b

94

2. Secuencias

Denes:

Termino,

used in chunks 9498.

94a

v list enlzd ontiene entones trminosX Miembros privados Polinomio 93c + DynDlist<Termino> terminos;
Uses

(91d)

93c 94c

DynDlist

85a and

Termino

93c.

94b

ry dos forms de onstruir un trminoX Miembros Trmino 94b Termino() : coef(0), pot(0) {}

(93c) 94d

Termino(const int & c, const size_t & p) : coef(c), pot(p) {}


Uses

Termino

93c.

94c

e nivel privdo es importnte onstruir un Polinomio prtir de un trminoX Miembros privados Polinomio 93c + (91d) 94a 98b Polinomio(const Polinomio::Termino & termino) { terminos.append(termino); }
Uses

Termino

93c.

94d

v sum de trminos se de(ne omo sigueX Miembros Trmino 94b + Termino& operator += (const Termino & der) { coef += der.coef; return *this; }
Uses

(93c)

94b 94e

Termino

93c.

94e

v multipliin forzosmente dee produir un nuevo trminoD por es rzn deeE mos implntr estritmente el operdor *X Miembros Trmino 94b + (93c) 94d Termino operator * (const Termino & der) const { return Termino(coef*der.coef, pot + der.pot); }
Uses

Termino

93c.

94f

he(nid l onstruin de un trmino podemos de(nir l onstruin de polinomiosX Implementacin de mtodos Polinomio 94f (91d) 95a Polinomio::Polinomio(const int & coef, const size_t & pot) { terminos.append(Termino(coef, pot)); } Polinomio::Polinomio() { /* empty */ }
Uses

Termino

93c.

2.4. Listas enlazadas

95

Suma de polinomios

v sum de dos polinomios P1 =

n i i=0 ci x

y P2 =

m j j=0 dj x

se de(ne omoX

max(n,m)

P1 + P2 =
k =0

(ck + dk )xk .

95a

is fil otener un lgoritmo e(ienteD pues ls lists estn ordends por poteniF in este sentido es preferile implementr el operdor +=D pues s nos horrmos el rer nuevos trminos pr el polinomio resultdoF he este modoD el operdor + podemos esriirlo en funin de += omo sigueX Implementacin de mtodos Polinomio 94f + (91d) 94f 95b Polinomio Polinomio::operator + (const Polinomio & der) const { Polinomio ret_val(*this); // valor de retorno operando derecho ret_val += der; // smele operando derecho return ret_val; } v sum es extremdmente simple porque suye en l llmd l operdor +=D el ul posee l siguiente estruturX Implementacin de mtodos Polinomio 94f + (91d) 95a 98a Polinomio & Polinomio::operator += (const Polinomio& der) {
} return *this;

95b

Implantacin de Polinomio::operator += 95c

95c

entes de efetur l sum omo tlD deemos veri(r que ninguno de los dos poliE nomios orrespond l elemento neutroX Implantacin de Polinomio::operator += 95c (95b) 95d if (der.terminos.is_empty()) return *this;
if (terminos.is_empty()) { *this = der; return *this; }

95d

i mos polinomios no son nulosD entones deemos reorrerlosF r ello usmos un iterdor por d polinomio operndoX Implantacin de Polinomio::operator += 95c + (95b) 95c 95e DynDlist<Termino>::Iterator it_izq(terminos); DynDlist<Termino>::Iterator it_der(const_cast<DynDlist<Termino>&>(der.terminos));
Uses

DynDlist

85a and

Termino

93c.

95e

v (gur PFIT ejempli( el polinomio 6x6 + 7x5 x4 + 3x2 + 4x omo operndo izquierdoD y 8x8 + x6 2x2 + 2 omo operndo derehoF ehor reorreremos ls lists de trminos hst que uno de los iterdores lne su (n de listX Implantacin de Polinomio::operator += 95c + (95b) 95d 97b while (it_izq.has_current() and it_der.has_current()) {
}

Procesar trminos actuales 96a

96

2. Secuencias

itor_izq

6x6

7x5

x 4 2x2

3x2

4x

8x8

x6

itor_der

pigur PFITX um de polinomios

96a

en izq y der ls potenis de los trminos tules de los iterdores izquierdo y dereho respetivmenteX Procesar trminos actuales 96a (95e) 96b const size_t & izq = it_izq.get_current().pot; const size_t & der = it_der.get_current().pot;

izq y der deen proesrse segn los siguientes sosX


IF i l poteni del izq es menor que derD entones der estr presente en el resultdoF gomo l list est ordendD es seguro que this no ontiene un trmino on l mism poteni de derF ist es l situin on los trminos 6x6 y 8x8 de los polinomios izquierdo y dereho respetivmenteF heemos rer un nuevo trmino opi de der e insertrlo en this @el polinomio izquierdoAF v opi de der dee preeder izq en thisD pues el resultdo dee estr ordendoF vs iones nteriores se trduen l siguiente digoX
96b

Procesar trminos actuales 96a +

(95e)

96a 96c

if (izq < der) { // insertar a la izquierda del actual de it_izq it_izq.append(Termino(it_der.get_current().coef, der)); it_der.next(); // ver prximo trmino de polinomio derecho continue; }
Termino
93c.

Uses

append() sore it_izq grntiz que el nuevo trmino se predeesor del tul izquierdoF vuegoD vnzmos el iterdor derehoD pues el trmino de poteni der y h sido proesdoF pinlmenteD repetimos el proedimientoF
PF i ls potenis son igulesD entones deemos sumr los oe(ientesD vnzr mos iterdores y repetir el proedimientoF ist es l situin on los trminos 6x6 y x6 de los polinomios izquierdo y dereho respetivmenteF
96c

Procesar trminos actuales 96a +

(95e)

96b 97a

if (izq == der) { // calcular coeficiente resultado it_izq.get_current() += it_der.get_current(); // += Termino

2.4. Listas enlazadas

97

}
Uses

it_der.next(); // avanzar a sig trmino polinomio derecho if (it_izq.get_current().coef == 0) // suma anula trmino? { // s, borrarlo de polinomio izquierdo (coeficiente 0) it_izq.del(); continue; }
93c.

Termino

QF in el ltimo so @izq > derAD izq ser prte del resultdoF uesto que izq y pertenee thisD simplemente vnzmos el iterdor izquierdo y repetimos el proedimientoF ist es l situin on los trminos 7x5 y 2x2 de los polinomios izquierdo y dereho respeE tivmenteF
97a

Procesar trminos actuales 96a +


it_izq.next();

(95e)

96c

97b

il proeso itertivo nterior ulmin undo lguno de los iterdores lnz el (nl de un de ls listsF in este so qued por reorrer un listF i l list por reorrer es l izquierdD no deemos her ndD pues sus elementosD que son prte del resultdoD y estn inluidos en thisF iD por el ontrrioD l list que rest por reorrer es l derehD entones deemos opir todos sus trminos restntes e insertrlos seuenilmente en l list izquierdX Implantacin de Polinomio::operator += 95c + (95b) 95e while (it_der.has_current()) { // copia trminos restantes derecho a izquierdo terminos.append(Termino(it_der.get_current().coef, it_der.get_current().pot)); it_der.next(); }
Uses

Termino

93c.

Multiplicacin de polinomios

v multipliin de dos polinomios P1 =


n

n i i=0 ci x m

y P2 =

m j j=0 dj x

se de(ne omoX

P1 P2 =
i =0

ci xi
j =0

kj xj

ist expresin sugiere un lgoritmo sdo en sum de produtos prilesD el ul puede resumirse omo sigueX
Algoritmo 2.1 (Multiplicacin de dos polinomios)
n m j j v entrd son dos polinomios P1 = i=0 ci x y P2 = j=0 dj x de grdos n y m respetivmenteF v slid es un polinomio R orrespondiente l produto P1 P2 F

IF snstnie un polinomio nulo RF PF epit pr i = 0 hst n

98

2. Secuencias

@A R = R + R

@A e R = ci xi P2

98a

ehor podemos odi(r el operdor * ompletmente reminisente del lgoritmo PFIX Implementacin de mtodos Polinomio 94f + (91d) 95b Polinomio Polinomio::operator * (const Polinomio & der) const { Polinomio result; if (terminos.is_empty() or der.terminos.is_empty()) return result;
for (DynDlist<Termino>::Iterator it_izq(const_cast<DynDlist<Termino>&>(terminos)); it_izq.has_current(); it_izq.next()) result += der.multiplicado_por(it_izq.get_current()); }
Uses

return result;
DynDlist
85a and

Termino

93c.

98b

il if veri( que si lguno de los polinomios es nuloD entones el produto es nuloF il for es extmente l versin odi(d del lgoritmo PFIX d trmino del polinomio izquierdo se multipli entermente por el polinomio dereho y el resultdo es umuldo en el polinomio resultF il frgmento der.por_termino(it_izq.get_current() orresE ponde l multipliin de un polinomio por un trminoD operin que de(nimos ontinuinX Miembros privados Polinomio 93c + (91d) 94c Polinomio multiplicado_por(const Termino & term) const { Polinomio result; if (terminos.is_empty() or term.coef == 0) return result;
for (DynDlist<Termino>::Iterator it((DynDlist<Termino>&) terminos); it.has_current(); it.next()) result.terminos.append(Termino(it.get_current().coef * term.coef, it.get_current().pot + term.pot) ); return result;
DynDlist
85a and

}
Uses

Termino

93c.

il lgoritmo es senilloF e instni un polinomio result on vlor iniil igul l polinomio nuloF vuegoD por d trmino del polinomio se multipli por el trmino operndo y el resultdo se insert ordendmente en resultF

2.5 Pilas
n pil es un strin de )ujo onsistente de un seueni de elementos en l ul ls operiones de inserinD onsult y eliminin se ejeutn por un solo extremoF v

2.5. Pilas

99

propiedd esenil es que el ltimo elemento en insertrse siempre ser el primer elemento en eliminrseF l propiedd se onoe omo i @ltimo en intrrD rimero en lirA15 F
push pop

tope
8 7 6 4 3 2 1

pigur PFIUX estrin de un pil qr(mente podemos ver un pil omo un reipiente on un sol entrd tl omo en l (gur PFIUF gundo se insert un elementoD los elementos previmente insertE dos se empujn hi joF or es rznD l operin de inserin se denomin omnmente pushF il extremo del reipienteD por donde entrn y slen los elementos se denomin topeD el ul es el nio punto de mnipulin de l pilF elegrimente hlndoD undo se tiv un supresinD el resorte empuj los eleE mentos hi rri y el elemento situdo en el tope slt hi fuerF or es rznD l supresin de un pil se le denomin omnmente popF n pil se utiliz undo se requiere un )ujo de proesmiento de elementos inverso l seueni de oservin o de entrdD es deirD desde el ms reientemente oserE vdo hst el ms ntigumente oservdoF gulquier ptrn de proesmiento que visite elementos de un onjunto en este orden es suseptile de implntrse on un pilF v vid rel ofree lgunos ejemplos de l disiplin pilF gulquier de nosotros hr experienido el refrn populr que rez los ltimos sern los primerosF il lvdo mnul de pltos en un fregdero domstio sigue l disiplin pilF roE lementeD los pltos se piln segn el orden de ulminin de l omidD es deirD el tope de l pil ontiene el plto de l ltim person en ulminr su omidF gundo lvmos los pltosD los enjonmos y los pilmos en el segundo reipiente del fregderoF osteriormenteD enjugmos los pltos y los pilmos en el esurrideroF iste ejemplo utiE liz tres pils y re)ej un tipo de proesmiento en el ul lo importnte es ulminr e(zmente el trjo y no el orden en que los pltos son proesdosF
2.5.1 Representaciones de una pila en memoria

ry dos mtodos pr representr un pilX rreglos y lists enlzdsF in ms reE presentionesD los elementos se disponen seuenilmente segn el mismo orden de l pilF in un rreglo se requiere mntener el ndie l ltimo elementoF v primer entrd lmen el elemento ms ntiguoD mientrs que el ndie refereni el tope ms unoF v (gur PFIV ilustr un pil de 5 elementos ontenid en un rreglo de 11 elementosF in un list enlzd requerimos mntener un puntdor l primer nodoF uesto que slo nos interes el topeD l seueni de l list est invertidY es deirD el primer nodo
15
En ingls LIFO (last in, rst out).

100

2. Secuencias

0 1 2 3 4 5 6 7 8 9 10 T0 T1 T2 T3 T4 Elemento ms antiguo tope

pigur PFIVX epresentin de un pil medinte un rreglo de l list lmen el tope y el ltimo lmen el ms ntiguoF v (gur PFIW ilustr l representinF v selein de representin depender de ls irunstnisF in lo que te l esE pioD quiz un ftor onsiderle es l mxim ntidd de elementos que pued ontener l pilD l ul depende de l pliinF vs lists rren un soreoste por elemento deido l puntdor diionlF i se onoe l mxim ntidd de elementos y l pliin l provehD entones est lro que el rreglo es ms ompto que l listF
tope

Elemento ms antiguo

pigur PFIWX epresentin de un pil on lists enlzds ytro ftor evlur es l vriin mxim del tmo de l pilF odemos onoer el mximoD pero si ste es muy poo proleD entonesD en promedioD puede ser ms rto en espio un representin on lists que enfoque el tmo promedioF v selein se efetur onsiderndo l desviin tpi del tmo de l pilF e l el tmo promedio de l pilD l l desviin tpiD lmax el tmo mximo que puede lnzr l pilD Ts el espio oupdo por un elemento de l pil y ps el espio oupdo por un puntdorD entonesD si @PFPHA (l + l )(Ts + ps ) lmax Ts , entonesD en promedioD l list oupr menos espio que el rregloF in lo que onierne el tiempo de ejeuinD el rreglo es l representin ms rpidF uesto que los elementos del rreglo son seueniles en memoriD l lolidd espil y temporl es provehd y el he del omputdor logr su ometidoF iste no es el so on ls lists donde los nodos estrn en direiones de memori diferentesF or otr prteD undo se insert o se suprime un elemento en un list enlzdD puede invorse l mnejdor de memoriF il mnejo de memori impone un soreoste diionl en un list respeto l rregloF v e(ieni del mnejdor de memori pr prtr un loque es muy vrile y puede ser proporionl l ntidd de loques prtdF v mism onsiderin es vlid undo se lier un loqueF n pil puede instrumentrse diretmente medinte el tipo DynDlist<T> de(nido en PFRFW @gF VRAF i mirmos el primer elemento de l list omo el topeD entones push(item) equivle insert(item)D pop() remove_first() y top() get_first()F

2.5. Pilas

101

2.5.2

El TAD

ArrayStack<T>

(pila vectorizada)

101a

il desempeo de un pil implntd medinte un rreglo es tn exelente que vle l pen her explito el menismo de implntinF ArrayStack<T> dispr exepiones undo se exede l pidd del rreglo o undo se intent eder el tope de un pil vF hisprr ests exepiones tiene un ligero oste en desempeo que puede ser importnte si l pil se utiliz muy menudoF ixisten muhs pliiones en ls ules se puede onoer el tmo mximo de l pil y en ls que es inneesrio onsiderr el desordeF or otr prteD un desorde negtivo es un error de progrmin veri(r en ls primers etps de un proyetoF or es rznD el eh FixedStack<T> modeliz ls misms primitivs que ArrayStack<T> on l difereni de que no se efetn veri(iones y no se disprn exepionesF he est mnerD pliiones que onozn el mximo tmo de pil se ene(in de l gnni en veloidd dd por l useni de veri(ionesF ils implntds on rreglos se de(nen en el rhivo tplrrytkFr 101a D el ul export dos tipos priniplesX ArrayStack<T> y FixedStack<T>X tpl_arrayStack.H 101a template <typename T, const size_t dim = 100> class ArrayStack {
}; template <typename T, const size_t dim = 100> class FixedStack
Denes:

miembros privados de pila vectorizada 101b miembros pblicos de ArrayStack<T> 101c

ArrayStack, FixedStack,

used in chunks 101c, 110, 118e, 24648, and 509b. used in chunks 180c, 473b, and 492b.

101b

vos dos tipos de dtos poseen los mismos triutosY stos sonX miembros privados de pila vectorizada 101b T array[dim]; size_t head;

(101a)

101c

array es un rreglo esttio de elementos de tipo T on dimensin dimF dim es un prmetro de l plntill que represent l dimensin del rreglo y on un vlor por omisin de 100F head es el ndie de l prxim entrd disponileF min indi l ntidd de elementos de l pilF head - 1 es el ndie del elemento topeF v onstruin de un pil slo requiere iniilizr headX miembros pblicos de ArrayStack<T> 101c (101a) 101d
ArrayStack() : head(0) { /* empty */ }
ArrayStack
101a. Uses

101d

r insertr un elemento se us el mtodo push()X miembros pblicos de ArrayStack<T> 101c + T & push(const T & data) {
}

(101a)

101c 102a

push data 101e

101e

push data 101e

(101d)

array[head++] = data; return array[head - 1];

102

2. Secuencias

102a

in lguns pliiones se requiere prtr espio en l pil sin que n se onozn los vlores de inserinF i ien esto puede logrrse medinte un serie onseutiv de pushes de dtos vosD es ms e(iente ofreer un sol operinF l operin se denomin pushn() y se implnt omo sigueX miembros pblicos de ArrayStack<T> 101c + (101a) 101d 102c T & pushn(const size_t & n = 1) {
}

apartar n elementos 102b

102b

e prtir del topeD el usurio de ArrayStack<T> puede referenir los n elementos insertdos que no hn sido iniilizdos y s signrles su vlor undo se neesrioF prtr n elementos 102b es muy simple on un rregloY st on inrementr headX apartar n elementos 102b (102a) head += n; return array[head - 1]; r sr un elemento de l pil utilizmos pop()X miembros pblicos de ArrayStack<T> 101c + T pop() {
}
(101a) 102a 102e

102c

pop data 102d

102d

pop data 102d

(102c)

return array[head];

102e

or rzones de e(ieniD tmin es desele ofreer un primitiv que liere vrios elementos en un sol operinX miembros pblicos de ArrayStack<T> 101c + (101a) 102c 102g T popn(const int & n) {
}

liberar n elementos 102f

in lgunos ontextosD est operin se le llm multipopF


102f

liberar n elementos 102f


head -= n; return array[head];

(102e)

102g

ry vris forms de onsultr l pilY tods se efetn respeto l tope y retornn un refereni un elemento dentro de l pilF v primer form es l del elemento en el topeX miembros pblicos de ArrayStack<T> 101c + (101a) 102e 103a T & top() {
}

retornar referencia al tope 102h

102h

retornar referencia al tope 102h


return array[head - 1];

(102g)

2.5. Pilas

103

103a

ytro tipo de onsultD menos freuente pero posile en lguns pliionesD es onoer el iEsimo elemento respeto l topeX miembros pblicos de ArrayStack<T> 101c + (101a) 102g 103d T & top(const int & i) {
}

referencia al i-simo respecto a tope 103b

103b

n vez vliddo el rngo de esoD el elemento es edido medinteX referencia al i-simo respecto a tope 103b (103a) return array[head - i - 1]; in lguns osiones un pil es reutilizle ondiin de que st se previmente vidF ir l pil implntd on un rreglo es un operin extremdmente rpidX vaciar pila 103c (103d) head = 0; ist filidd meree ofreerse en un primitivX miembros pblicos de ArrayStack<T> 101c + void empty() { vaciar pila 103c }
(101a) 103a 103e

103c

103d

103e

odemos onsultr un predido que nos dig si l pil est o no vX miembros pblicos de ArrayStack<T> 101c + (101a) 103d 103g bool is_empty() const { pila vaca? 103f }

103f

pila vaca? 103f

(103e)

return head == 0;

103g

v ntidd de elementos de l pil es diretmente el vlor de headX miembros pblicos de ArrayStack<T> 101c + (101a) 103e const size_t & size() const { return head; } e nivel de interfzD FixedStack<T> es idnti ArrayStack<T>F or rzones de omptiilidd es preferile de(nir ls misms exepiones de ArrayStack<T> en ls primitivs de FixedStack<T>F he este modoD FixedStack<T> es plile en d sitio donde se utilie ArrayStack<T>F e nivel de implntinD FixedStack<T> es muy similr ArrayStack<T>F v diE fereni prinipl reside en que FixedStack<T> no efet veri(in de desorde ni dispr exepionesF he restoD d primitiv de FixedStack<T> es idnti su pr en ArrayStack<T>F
2.5.3 El TAD

ListStack<T>

(pila con listas enlazadas)

103h

il eh ListStack<T> modeliz un pil implntd medinte lists enlzdsF el onoE er el tipo de implntinD el usurio onoe los ostes en espio y tiempoD s omo ls gnnis en verstilidd imprtids por l nturlez dinmi de ls lists enlzdsF ListStack<T> se s en el eh Snode<T>D el ulD en eseniD ontiene todo lo neeE srio pr mnejr ls listsF ListStack<T> se de(ne en el rhivo tpllisttkFr 103h Y tpl_listStack.H 103h template <typename T> class ListStack : private Snode<T> {

104

2. Secuencias

};
Uses

atributos de ListStack<T> 104a mtodos pblicos de ListStack<T> 104b


Snode
68b.

wedinte derivin de Snode<T>D this funge de nodo eer de l list uyo primer elemento siempre ser el nodo tope de l pilF
T:class

Snode

T:class

ListStack
-num_nodes: size_t +ListStack() +push(node:Node*): void +pop(): Node* +top(): Node* +is_empty(): bool +size(): size_t

T:class

DynListStack
+top(): T& +push(_data:const T&): T& +pop(): T +~DynListStack(): virtual

pigur PFPHX higrm wv de ls lses vinulds ListStack<T>

104a

ListStack<T> posee un triuto nioX atributos de ListStack<T> 104a


size_t num_nodes;

(103h)

104b

el ul ontiliz l ntidd de nodos que posee l pilF ListStack<T> export dos sinnimos de nodoX mtodos pblicos de ListStack<T> 104b typedef Snode<T> Node;
Uses

(103h) 104c

Snode

68b.

104c

e nivel de interfzD ls operiones de ListStack<T> mnejn nodos de l pilF Item es un sinnimo ofreido por omptiilidd on versiones nterioresF il onstrutor ListStack<T> slo se remite iniir el ontdor de nodosX mtodos pblicos de ListStack<T> 104b + (103h) 104b 104d ListStack() : num_nodes(0) {} v operin push() se de(ne en funin de un ListStack<T>::NodeX mtodos pblicos de ListStack<T> 104b + (103h) 104c 105a void push(Node * node) { ++num_nodes; this->insert_next(node); }

104d

push() no gener ningun exepinD pues su ni responsilidd es enlzr el nodo l listF uesto que this es l eerD insert_next() siempre insertr node l frente de l listD el ul siempre se orresponde on el topeF

2.5. Pilas

105

105a

uprimir el tope equivle suprimir el nodo del frente de l listF isto es direto segn l interfz de Snode<T>X mtodos pblicos de ListStack<T> 104b + (103h) 104d 105b Node * pop() { num_nodes; return this->remove_next(); } il tope puede onsultrse medinteX mtodos pblicos de ListStack<T> 104b + Node * top() const { return static_cast<Node*>(this->get_next()); }
2.5.4 El TAD
(103h) 105a

105b

DynListStack<T>

il eh ListStack<T> mnej pils en funin de nodos de un list enlzdF isto olig l usurio ontrolr y veri(r detlles del mnejo de memoriF v responsilidd de ListStack<T> es el mnejo de los nodosY l del liente es prtr y lierr los nodosF gomo hemos prendido en osiones nterioresD mnejr los enlesD tipos y memori puede herse jo un solo ehD derivdo de eh ms senillosF il eh DynListStack<T> umple el ometido meniondo en el prrfo nteE riorF DynListStack<T> de(ne un pil implntd on lists enlzds simples y on mnejo de memori inluidoF DynListStack<T> est de(nido en el rhivo tpldynvisttkFr 105c X
105c

tpl_dynListStack.H 105c

template <typename T> class DynListStack : public ListStack<T> { mtodos de DynListStack<T> 105d };
DynListStack,
used in chunks 106c, 188, 645b, 647b, 649, 650, 652b, and 764b.

Denes:

105d

DynListStack<T> lmen dtos del tipo genrio TF el derivr plimente de ListStack<T>D DynListStack<T> hered grn prte de su implntin y de su interfzF il mnejo de lists lo port entones ListStack<T>F vs primitivs que no dependen del tipo TD is_empty() y size()D se heredn diretmenteF vs otrs primitivsD que s dependen de ListStack<T>D deen sorergrse pr que mnipulen dtos de tipo TF gomenzmos por ls primitivs ms senillsX mtodos de DynListStack<T> 105d (105c) 106a
T & top() const { return ListStack<T>::top()->get_data(); }

top() onsult el nodo tope de l lse se y retorn un refereni l dtoF

106

2. Secuencias

106a

push() dee insertr un dto de tipo TF isto requiere prtr el nodoD opirle el dto e invor l push() de ListStack<T>X mtodos de DynListStack<T> 105d + (105c) 105d 106b T & push(const T & item) { typename ListStack<T>::Node *ptr = new typename ListStack<T>::Node (item); ListStack<T>::push(ptr); return ptr->get_data(); } push() retorn un refereni l dto ontenido en el topeF v lor de pop() es extrer el nodo de ListStack<T>D opir el dto retornr y lierr l memoriF ist ondut se espei( omo sigueX mtodos de DynListStack<T> 105d + (105c) 106a 106c
T pop() { typename ListStack<T>::Node* ptr = ListStack<T>::pop(); T retVal = ptr->get_data(); delete ptr; return retVal; }

106b

uesto que DynListStack<T> es responsle del mnejo de memoriD DynListStack<T>::DynListStack dee lierr tod l memoriF es puesD nos segurmos de vir tod l pil en tiempo de destruinX
106c

mtodos de DynListStack<T> 105d +


virtual ~DynListStack() { while (not this->is_empty()) pop(); }
DynListStack
105c.

(105c)

106b

Uses

xotemos que is_empty() pertenee ListStack<T> mientrs que pop() DynListStack<T>F

2.5.5

Aplicacin: un evaluador de expresiones aritmticas injas

in el dominio de l mtemti hy vris mners de representr un operin inriF gd un sume un onvenin er de l posiin del operdor y los operndosF in notin prejaD el operdor preede los operndosF in notin suja16 D el operdor suede los operndosF in notin injaD el operdor se pone entre los dos operndosF or ejemploD podemos representr l sum de dos operndos x e y omo sigueX  re(jX +xy  u(jX xy+  sn(jX x + y
16
En ingls es traducido como

post(x.

De all que algunos textos la denominen postja.

2.5. Pilas

107

v notin pre(j se proxim ls mtemtis trdiionlesF il resultdo de evlur un funin f on dos operndos x e y se denot omnmente omo f(x, y)F hel mismo modoD l omposiin funionl se denot omo h(f(x, y)F vs notiones pre(j y su(j permiten un ntidd ritrri de operndosF ist es un grn ventj pr denotr funiones multivriles de ndole ulquierF edemsD undo hy vris operionesD ls notiones pre(j y su(j permiten expresr tods ls operiones sin neesidd de prntesisF or ejemploD l form su(j de x (y + z) es yz + xF r evlur un expresin pre(j o su(j se utiliz un pilF il lgoritmo pr evlur expresiones su(js se desrie omo sigueX v entrd del lgoritmo es un seE ueni onteniendo un expresin su(j ompuest por operdores y operndos numriE osF v slid es el vlor orrespondiente l resultdo (nlF il lgoritmo utiliz un pil pr gurdr resultdos priles y un vrile llmd (h tul o simplemente l (hF v (h ontiene el smoloD operndo u operdorD que se est proesndoF
Algoritmo 2.2 (Evaluacin de expresin suja) Algoritmo

IF epit mientrs l (h no est l (nl de l seueniF @A i l (h es un operdor = sque dos vlores de l pilD efete l operin dd por el operdor ledo y lmene el resultdo en l pilF @A he lo ontrrioD si l (h es operndo = mtlo en l pilF PF gundo se lne el (nl de l seueniD el resultdo lmendo en l pil es el resultdo de l expresinF i l pil est v o st ontiene ms de dos vloresD entones l expresin su(j onten lgn errorF n lgoritmo similr puede deduirse pr evlur expresiones pre(jsF v notin su(j junto on el lgoritmo PFP es omn en lguns luldors de olsilloD ntiguos proesdores y lgunos lengujes de progrminF or supuestoD l notin in(j es l ms fmilirD pero st slo permite lo sumo dos operndosF in didurD l preedeni de ls operiones puede requerir el uso de prntesisF e us de estoD expresiones omplids son normlmente ms lrgs en form in(j que sus equivlentes pre(jo o su(joF iste heho sugiere que mnipulr y evlur expresiones in(js es ms ostoso en espio y en tiempo que en ls otrs dos notionesF osilemente por est rznD lgunos frintes de luldors de mno pre(eren l notin su(jF ixiste un lgoritmo muy e(iente pr evlur un expresin in(jD el ul requiere dos pilsF n pil lmen operndos y resultdos priles y l otr lmen operdores y prntesis que representn l preedeniF entes de explir el lgoritmo requerimos lgun mquinri de se que efete el proesmiento de l den de rteres y que nos indique si estmos en preseni de

108

2. Secuencias

108a

un operndo u operdorF r ello de(nimos los posiles vlores de (hs que pueden enontrrse en un denX tipo de cha 108a enum Token_Type { Value, Operator, Lpar, Rpar, End, Error };

108b

Value represent un operndoD Operator represent uno de los operdores +, , , o /D Lpar y Rpar representn los prntesis izquierdo y dereho respetivmenteD End represent el (n de l den yD (nlmenteD Error indi que se enontr un smolo que no puede ser onsiderdo operndo ni operdorF ehor podemos de(nir un rutin que le l den y nos indique qu tipo de (h se est leyendoX rutina lectora de chas 108b
Token_Type lexer(char *& str, size_t & len) {

cuerpo de lexer 108c

108c

lexer() inspeion seuenilmente l den de rteres ontenid en str prtir del smolo str + lenF el (nl de l llmdD str punt l primer smolo de l (hF il vlor de str puede modi(rseD pues puede her espios en lno que no deen proesrseF lexer() retorn el tipo de (h que se h detetdoF il prmetro len se modi( pr indir l longitud en rteres de l (h tul enontrdF vos vlores de los prmetros se iniin del siguiente modoX cuerpo de lexer 108c (108b) 108e
str += len; len = 1;

ignorar espacios en blanco 108d

108d

or de(niinD l inspein omienz en str + lenF el iniioD l longitud de l (h que se enuentre ser l menos de un uniddF sniid l inspeinD l rutin dee ignorr los espios en lnosF isto se de(ne filmente omoX ignorar espacios en blanco 108d (108c) while (isblank(*str)) str++;

108e

isblank() es un extensin qx de l iliote estndr del lenguje g y retorn un vlor diferente de ero si el smolo de prmetro orresponde un lno o tuldorF or simpliiddD nuestro evludor slo ept los operdores +D D y /D los ules representn ls operiones ritmtis lsisF he l mism mnerD los operndos slo son nmeros enterosF lvo un operndoD l longitud de un (h es unoF eri(mosD puesD si el smolo enontrdo orresponde un operdorX cuerpo de lexer 108c + (108b) 108c 109a
switch (*str) { case '(': return Lpar; case ')': return Rpar; case '+': case '-': case '*':

2.5. Pilas

109

case '/': return Operator; case '\0': return End;

109a

i el )ujo sle del switchD entones l ni posiilidd orret es enontrr un operndoF xos eriormos entones de que l den orrespond un operndoX cuerpo de lexer 108c + (108b) 108e 109b if (not isdigit(*str)) return Error;

109b

isdigit() es un funin de l iliote estndr del lenguje g y retorn un vlor diferente de ero si el smolo de prmetro orresponde un dgitoF i el )ujo no retorn errorD entones ontilizmos l ntidd de dgitos por l dereh y retornmos el digo de (h ValueX cuerpo de lexer 108c + (108b) 109a
char* base = str + 1; while (isdigit(*base++)) len++; return Value;

109c

gundo lexer() retorn un operdorD deemos tomr iones segn l preedeni del operdorF r ello elormos un funin queD ddo un operdorD determine su preeE deniX funcin de precedencia 109c unsigned precedence(const char & op) // $ < ( < +- < */ { switch (op) { case '$': return 0; case '(': return 1; case '+': case '-': return 2; case '/': case '*': return 3; } }

109d

precedence() tiene omo prmetro un smoloF uesto que los operdores son de un solo smoloD podemos identi(r l ourreni del operdor medinte inspein diret de l denF ry un operdor (tiioD 6D on l menor preedeniD uyo rol se explir ms deE lnteF il prntesis izquierdo se onsider un operdor en el siguiente nivel de preedeniF v sum y rest oupn el prximo nivel de preedeniF pinlmenteD los operdores on ms preedeni son el produto y l divisinF i lexer() retorn ValueD entones neesitmos otener un den de rteres que onteng el nmeroF l funin l efetumos del siguiente modoX funcin convertir cha a cadena 109d
char * str_to_token(char * token_str, const size_t & len) { static char buffer[256]; strncpy(buffer, token_str, len); buffer[len] = '\0';

110

2. Secuencias

return buffer;

110a

str_to_token() extre un opi del nmero ontenido en token_strF il lgoritmo de evluin usr dos pils omo sigueX pilas de evaluacin 110a (111a)
ArrayStack<int> val_stack; ArrayStack<char> op_stack;
ArrayStack
101a. Uses

110b

il lgoritmo efet operiones en lne onforme nliz l den de entrdF v operin fundmentl es sr dos operndos de l pil val_stack y un operdor de l pil op_stackY luegoD efetur l operin yD (nlmenteD lmenr el resultdo de nuevo en l pil val_stackF iste ptrn se modulriz en l siguiente rutinX funcin de ejecucin de operacin en pilas 110b void apply(ArrayStack<int>& val_stack, ArrayStack<char>& op_stack) { const char the_operator = op_stack.pop(); const int right_operand = val_stack.pop(); const int left_operand = val_stack.pop(); int result; switch (the_operator) { case '+': result = left_operand + right_operand; break; case '-': result = left_operand - right_operand; break; case '*': result = left_operand * right_operand; break; case '/': result = left_operand / right_operand; break; } val_stack.push(result); }
Uses

ArrayStack

101a.

110c

apply() sume que el operndo dereho fue insertdo en l pil despus del izquierdoF isto es lo norml si l den de entrd se nliz de izquierd derehF ehor disponemos de ls herrmients neesris pr desrrollr un rutin que evle un expresin in(jF xuestr rutin se llmr eval() y tendr l siguiente estruturX funcin de evaluacin de expresin inja 110c int eval(char* input) {
while (true) {

variables de eval 111a inicializacin de eval 111b

switch (current_token) { case Value: case Lpar:

leer prxima cha 111c

procesar operando 111d procesar parntesis izquierdo 112b

case Operator:

procesar operador 112a

2.5. Pilas

111

case Rpar: case End: } }

procesar parntesis derecho 112c procesar n de entrada 112d

111a

input es l den de rteres que ontiene l expresin in(jF eval() requiere siguientes vrilesX variables de eval 111a
Token_Type current_token; size_t token_len = 0;

pilas de evaluacin 110a

(110c)

111b

current_token es l (h tul oservd en l den de entrd y token_len es l longitud de l (h en rteresF sniilmente no hy ningun (hD por lo que token_len dee ser eroF v pil de operdores requiere un entinel espeil que se de l menor preedeni posileF l entinel es el vlor 6 que se insert iniilmente en op_stackX inicializacin de eval 111b (110c)
op_stack.push('$');

111c

hespus de l iniilizinD l rutin omienz iterrF il uerpo itertivo lee ls (hs presentes en l entrd y luego proes l (h segn su tipoF veer l (h onsiste simplemente en un invoin lexer()X leer prxima cha 111c (110c) current_token = lexer(input, token_len); gundo l (h es un operndoD lo introduimos en l pil de operndosX procesar operando 111d (110c) { const int operand = atoi(str_to_token(input, token_len)); val_stack.push(operand); break; } revimente hy que efetur l onversin de l den de rteres su representin numriF odemos introduir el operdor en l pilD pero ntes podemos ejeutr tods ls operiones que estn en l pil de operdores on myor o igul preedeni que el operdor tulF ist lterntiv es preferile porque disminuye el onsumo en espio de ls pilsF r ejempli(rD onsideremos l expresin 100 20 5 + 7 y supongmos que l (h tul es el operdor de restF in este momentoD val_stack ontiene < 100 > y op_stack < $ > y no podemos efetur ningun operin porque el operdor (tiio 6 tiene menor preedeni que el operdor F gundo enontrmos el operdor D tmpoo podemos efetur ningun operin porque el produto tiene myor preedeni que l restF piE nlmenteD undo nos enontrmos el operdor +D val_stack ontiene < 100, 20, 5 > y op_stack < $, , >F equ efetumos el produtoD pues ste tiene myor preedeni que l sumD lo que nos dej ls pils en los estdos < 100, 100 > y < $, > respetivmenteF osteriormenteD efetumos l restD pues st tiene l mism preedeni que l sumF el

111d

112

2. Secuencias

112a

trmino de est operin introduimos el operdor + en l pil lo que nos dej el estdo de ls pils en < 0 > y < $, + >F v ondut nterior se modeliz entones jo l siguiente formX procesar operador 112a (110c) { while (precedence(op_stack.top()) >= precedence(*input)) apply(val_stack, op_stack); op_stack.push(*input); // introducir operador en op_stack break; } vos prntesis en l expresiones in(js son utilizdos pr modi(r l preedeni por omisin de los operdoresF gundo l (h se un prntesis izquierdoD lo introduimos en l pil de operdoresX procesar parntesis izquierdo 112b (110c) { op_stack.push(*input); // introducir parentesis en op_stack break; } il prntesis dereho indir el (nl de un expresin que dee ser evludF gundo enontremos el prntesis derehoD ejeutremos tods ls operiones entre los prntesisF r ello llmmos suesivmente apply() hst que el prntesis izquierdo se enontrdo en el tope de l pilX procesar parntesis derecho 112c (110c) { while (op_stack.top() != '(') apply(val_stack, op_stack); op_stack.pop(); /* saca el parentesis izquierdo */ break; } il (n de l entrd lo indi lexer() undo retorn el vlor EndF in este momentoD si l expresin fue orretD nos flt evlur ls operiones que se enuentrn en l pil de operndosD lo ul se de(ne de l siguiente mnerX procesar n de entrada 112d (110c) { while (op_stack.top() != '$') apply(val_stack, op_stack); op_stack.pop(); // debe ser '$' const int ret_val = val_stack.pop(); return ret_val; }
2.5.6 Pilas, llamadas a procedimientos y recursin

112b

112c

112d

no de los usos ms trsendentles de l pil es l gestin de llmds proedimientos de un progrmF gonsideremos el siguiente frgmento de digoX
int fct_1(int i) { /* ... */ } int fct_2(int i) {

2.5. Pilas

113

} int fct_3(int j) { int x; x = fct_2(j); ... } void main() { int y; y = fct_3(3); ... }

int x; x = fct_1(i); ...

ehor exminemos los eventos involurdos l llmd fct_3() desde main()F gundo se lnz l llmd fct_3()D el )ujo de ontrol slt hi l direin de memori de fct_3() y omienz ejeutrlF osteriormenteD undo se lnz l llmd fct_2()D y el )ujo de ontrol slt de nuevo hi l direin de fct_2()F pinlmenteD se lnz l funin fct_1() y el )ujo slt de nuevo hi l direin de fct_1()F gundo fct_1() (nlizD el )ujo de progrm reorre el mino inverso hst main()F lnteemosD entonesD ls siguientes preguntsX  vs funiones fct_2() y fct_3() tienen prmetros de nomre i y vriles loles de nomre xF gmo se diferenin entre si los prmetros y vrilesc  gmo se gestion l memori pr los prmetros y vriles loles de un proeE dimientoc  gmo he el )ujo de ontrol pr sltr un funin y regresr undo ulmin l llmd l funinc istos prolems son resueltos por el ompildorD el sistem opertivo y el hrdwre trvs de un pilF v myor de los proesdores mnejn dos registros espeiles omnmente denomindos SB y SPF istos registros mnejn l denomind pil del sistemF SB es l direin se de un pil y SP es l direin tul del tope de l pilF gundo se he un push sore l pil del sistemD SP es derementdoF hel mismo modoD undo se he un pop()D SP es inrementdoF gundo el ompildor proes un llmd un funinD por ejemploD fct_1() desde main()D se generD ntes de llmr l funinD l seueni de pseudodigo sore l pil sistem mostrd en el udro PFSFIF il ompildor tmin gener digo diionl l prinipio y l (nl de l funin fct_1() jo el esquem mostrdo en el udroPFSFPF qenerlmenteD un push() equivle restr l registro SP el tmo de lo que se le insertF imtrimenteD un pop() equivle un sumF r ls funiones fct_2() y fct_3()D el ompildor gener digos similres PFSFI y PFSFPF

114

2. Secuencias

IF n push() pr el espio del resultdo que retorn fct_1()F PF rios pushes pr los prmetros de fct_1()F QF n push() pr l direin tul del )ujo del progrmF RF n instruin de slto hi l direin de l funin fct_1()D el ul llev el )ujo de ontrol hi el iniio de l funin fct_1()F SF n vez que fct_1() hy sido ejeutdD el )ujo de progrm regresr l punto posterior donde se efetu el sltoF r elloD el ompildor gener un pop() que reuper l direin de retorno de l pilF el regresr main() se efetn vrios pops orrespondientes l ntidd de pushes que se hizo pr psr los prmetrosF TF pinlmenteD se he un ltimo pop() que reuper el resultdo de fct_1()F

F
Pseudocdigo 2.5.1:

istrutur de digo generd pr l llmd funcion_1()

IF el iniio de l funin se efetn vrios pushes proporionles l nmero de vriles loles de fct_1()F PF il digo de l funin se gener on referenis ls vriles loles prtds en el punto nterior y los prmetros prtdos y opidos en PFSFIF QF il resultdo de l funin tmin se gurd en el espio prtdo en el punto I de PFSFIF RF el (nl de l funinD el ompildor de un ntidd de pops igul l ntidd de pushes usd pr ls vriles lolesF istos pops liern l memori usd por ls vriles lolesF SF e he un pop() que reuper l direin de retorno l invonte de fct_1() y se slt l punto S de PFSFIF
Pseudocdigo 2.5.2:

istrutur de digo generd pr l llmd l funcion_1()

114

v informin pertinente un llmd proedimiento que se gurd en l pil sistem es ontiguF il loque ompuesto por el vlor de retornoD prmetrosD direin de retorno y vriles loles se denomin registro de tivinF il soporte ejeutivo pr ls llmds proedimientos se implnt on un pil porque el progrm )uye trvs de ls funiones jo un disiplin iF n vez que se lnz fct_3()D el progrm dee regresr por el mino inverso main() psndo por fct_2() y fct_1()F eunque l reursin es un tni de progrmin stnte poderosD es imporE tnte prehender que onllev ostes importntes en espio y tiempoF gomo ejemploD onsideremos l funin ftoril implntd reursivmenteX Factorial recursivo 114 int fact(const int & n) { if (n <= 1) return 1; return n*fact(n-1); } v versin reurrente del ftoril es un ml ejemplo del uso ine(iente de l reursinD pues prte de ser extremdmente ine(ienteD l ontrprte itertiv es muy e(iente

2.5. Pilas

115

y ms fil de implntrF in emrgoD efetos didtiosD su odi(in reurrente es muy fil de omprender porque re)ej idntimente l de(niin mtemtiF
SB Resultado 4 Direccin de retorno Resultado 3 Direccin de retorno Resultado 2 Direccin de retorno Resultado 1 Direccin de retorno
fact(4)

fact(3)

fact(2)

fact(1)

SP

pigur PFPIX gp de l pil sistem on l llmd fact(4) v (gur PFPI ilustr el estdo de l pil sistem undo se lnz l llmd fact(1)F gd vez que se efet un llmd reursiv se gst en espio de pil el resultdo de l llmd reursivD el prmetro y l direin de retornoF hel mismo modoD por d llmd se gst en tiempo los tres pushes y los tres popsF
2.5.6.1 Consejos para la recursin

i estmos disendo un lgoritmo y nos es ms fil trjr on l reursinD entones deen tenerse en uent ls siguientes onsiderionesX IF odo lgoritmo reursivo dee tener un so se donde no ourr ningun llmd reursivF PF il lgoritmo dee progresr y onverger en tiempo (nito enontrr l soluinF or d llmd reursivD l entrd dee disminuirF i este no es el soD hy stntes proiliddes de que el rzonmiento suyente l lgoritmo est errdoF QF ivite lulos repetidosF iste es el prinipl peligro de l reursinF n ejemplo notle son los nmeros de pioni uy de(niin mtemti es l siguienteX Fib(n) =

1
Fib(n 1) + Fib(n 2)

si n 1 si n > 1

v odi(in reursiv que lul el iEsimo nmero de pioni se desprende de su de(niin mtemtiX
115

Funcin de Fibonacci 115

int fib(const int & n) { if (n <= 1) return 1; return fib(n - 1) + fib(n - 2); }

xotemos que Fib(n 2) se lul 2 veesF v primer undo se llm explitmente Fib(n 2)Y l segundD dentro de l llmd Fib(n 1)F ist dupliidd de llmds

116

2. Secuencias

fib(5) fib(4) fib(3) fib(2) fib(2) fib(3) fib(1)

fib(2)

fib(1)

fib(1)

fib(0)

fib(1)

fib(0)

fib(1) fib(0)

pigur PFPPX vlmds fib() pr n = 5 se expnde exponenilmente medid que ument nF v (gur PFPP ilustr l ntidd de llmds fib() pr l peque esl n = 5F gundo se dise un lgoritmo reursivo deemos eriorrnos de que no hyn luE los redundntesF or lo generlD l redundni requiere notr los lulos en lgun estrutur de dtos espeilF
2.5.6.2 Eliminacin de la recursin

ry tres mners onoids pr eliminr l reursinD l ules menionremos en los suprrfos susiguientesF
Eliminacin de la recursin cola

116a

i un proedimiento P(x) tiene omo ltim instruin un llmd P(y)D entones es posile reemplzr P(y) por un signin x = y y un slto l iniio del proedimientoF or ejemploD el reorrido in(nito de los nodos de un list enlzd podr de(nirseD reursiv y errnementeD del siguiente modoX Recorrido recursivo de lista enlazada 116a template <typename T> void recorrer(Snode<T> * head, void (*visitar)(Snode<T>*)) { if (head->is_empty()) return; (*visitar)(head->get_next()); recorrer(head->get_next()); }
Uses

Snode

68b.

116b

iste proedimiento puede trnsformrse medinte eliminin de l reursin ol enX Recorrido no-recursivo de lista enlazada 116b template <typename T> void recorrer(Snode<T> * head, void (*visitar)(Snode<T>*)) { start: if (head->is_empty()) return; (*visitar)(head->get_next()); head = head->get_next(); goto start;

2.5. Pilas

117

}
Uses

Snode

68b.

117

wuhs vees es posile eliminr l reursin ol un si l ltim instruin no es un llmd reursivF or ejemploD l ltim instruin de l versin reursiv del ftoril ptoril reursivo 114 no es l llmd fact(n - 1)D sino l llmd returnF in este so podemos eliminr l reursin ol y otener l siguiente versinX Factorial no recursivo 117 int fact(const int & n) { int result = 1; start: if (n <= 1) return result; result *= n; n; goto start; }
Emulacin de los registros de activacin

odemos suprimir l reursin si emulmos ls llmds reursivs y los registros de tivinF r ello deemos de(nir un pil on los siguientes triutosX IF vos vlores de los prmetrosF in so de que se trte de un funinD se inluye el vlor de retornoF PF vos vlores de ls vriles lolesF QF n indiin que sele l direin de retornoF gd vlor de indiin dee orresponder un punto de retorno en el proedimiento reursivoF n vez de(nid l pilD se modi( el proedimiento reursivo omo sigueX IF e de l fse de iniio l delrin e iniilizin de l pilF PF e ponen etiquets de slto en los puntos de slid de ls llmds reursivsF QF e l exepin de l fse de iniilizinD el uerpo de l funin se envuelve on un lzo repetitivo uy ondiin de prd es que l pil est vF RF vos puntos donde hy llmds reursivs se sustituyen por un push() de lo que ser el registro de tivin y un slto l iniio del lzoF SF vos puntos donde el proedimiento reursivo retorne se sustituyen por un pop() seguido de un switch que determinD segn l indiin de slto del registro de tivinD l direin de sltoF

118

2. Secuencias

118a

or ejemploD pr el lulo del iEsimo nmero de pioni modi(mos l punin de pioni 115 del siguiente modoX Versin recursiva mejorada de Fibonacci 118a int fib(const int & n) { if (n <= 1) return 1; const int f1 = fib(n - 1); const int f2 = fib(n - 2); return f1 + f2; } ist form filit l eliminin de l reursinF he(nimos l siguiente estrutur pr el registro de tivinX Registro activacin 118b # define P1 1 # define P2 2
struct Activation_Record { int n; int f1; int result; char return_point; };
Denes:

118b

(118d)

Activation_Record,

used in chunk 118e.

118c

gon mirs l lriddD el eso ulquier de los mpos se efet trvs de lguno de los siguientes mrosX acceso registro activacin 118c (118d) # define NUM(p) ((p)->n) # define F1(p) ((p)->f1) # define RESULT(p) ((p)->result) # define RETURN_POINT(p) ((p)->return_point) v versin no reursivD on pilD que lul el iEsimo nmero de pioniD l de(E nimos en el rhivo (stkFg 118d uy de(niin es l siguienteX b_stack.C 118d
int fib_st(const int & n) { }

118d

Registro activacin 118b acceso registro activacin 118c cuerpo de b_st 118e

118e

gindonos l mtodoD lo primero es de(nir el premulo de l rutinX cuerpo de b_st 118e (118d) ArrayStack<Activation_Record> stack; Activation_Record * caller_ar = &stack.pushn(); Activation_Record * current_ar = &stack.pushn(); NUM(current_ar) = n;

emulacin de recursin 119a

2.5. Pilas

119

Uses

Activation_Record

118b and

ArrayStack

101a.

119a

e lo lrgo de l rutin mnejremos dos puntdoresF caller_ar represent el regisE tro de tivin del invonteF equerimos este registro de tivin porque deemos gurdr el resultdo de l llmd tul que emulmosD el ul se gurd en el registro de tivin del invonte y no del invodoF current_ar es el registro de tivin de l llmd tulF ehor emulmos el uerpo del proedimiento reursivoF r ello omenzmos por olor el digo mostrdo en ersin reursiv mejord de pioni 118a y luego sustituimos por segmentos de digo que emuln l reursinX emulacin de recursin 119a (118e) start:
p1: /* punto de retorno de fib(n - 1) */ p2: /* punto de retorno de fib(n - 2) */ return_from_fib:

caso base de recursin 119c llamada a b(n - 1) 120a

retorno desde b(n - 1) 120b llamada a b(n - 2) 120c retorno desde b(n - 2) 120d retornar desde b 120e

histinguimos utro etiquets de slto del )ujo de ejeuinX IF start es por donde se inii el mtodoF gd vez que se emule un llmd reursiv se tulizn los punteros los registros de tivin y se slt hi este puntoF
119b

llamada recursiva a b 119b

(120)

caller_ar = &stack.top(1); current_ar = &stack.top(); goto start;

iste segmento de digo sume que un nuevo registro de tivin h sido previmente insertdo en l pilF or es rzn tulizmos los puntdores los registros de tivin ntes de sltr l iniio del progrmF v primer lne del progrm reursivo proes el so seD el ul es muy similr en l versin no reursivX
119c

caso base de recursin 119c

(119a)

if (NUM(current_ar) <= 1) { RESULT(caller_ar) = 1; goto return_from_fib; }

el igul que en l versin reursivD l ondiin se evl sore el prmetro n del registro tulF i emos l so seD entones ponemos el resultdo en el registro de tivin del invonte y envimos el )ujo de progrm hi l prte que emul el retornr desde l funin reursivF

120

2. Secuencias

i no se e en el proeso seD entones hy que emulr l llmd fib(n - 1)D l ul se reliz omo sigueX
120a

llamada a b(n - 1) 120a

(119a)

RETURN_POINT(current_ar) = P1; NUM(&stack.pushn()) = NUM(current_ar) - 1; // crea reg. act.

llamada recursiva a b 119b

v primer lne mr l direin de retornoF v segund prt el registro de tivin de l nuev llmd e inii su prmetro n segn l llmd fib(n - 1)F PF gundo se hy luldo fib(n - 1)D retornr desde ( 120e inspeionr el vlor RETURN_VALUE del registro tul de tivin y se pertr de que hy que sltr el )ujo hi l etiquet p1F in este momento deemos emulr l signin int f1 = fib(n - 1)X
120b

retorno desde b(n - 1) 120b

(119a)

F1(current_ar) = RESULT(current_ar);

vuegoD emulmos l llmd fib(n - 2)X


120c

llamada a b(n - 2) 120c

(119a)

NUM(&stack.pushn()) = NUM(current_ar) - 2; // crea reg. act. RETURN_POINT(current_ar) = P2;

llamada recursiva a b 119b

llmd (@n E PA 120c es si idnti llmd (@n E IA mi es que el vlor del prmetro n orresponde n 2F

120a

F vo nio que

QF n vez luldo fib(n - 2)D retornr desde ( 120e sltr el )ujo hi p2F in este momento emulmos l signin int result = f1 + f2X
120d

retorno desde b(n - 2) 120d

(119a)

RESULT(caller_ar) = F1(current_ar) + RESULT(current_ar);

RF pinlmenteD return_from_fib es el punto donde se emul l instruin return del proE edimiento reursivoF l emulin onsiste enX
120e

retornar desde b 120e

(119a)

stack.pop(); /* cae en el registro del invocante */ if (stack.size() == 1) return RESULT(caller_ar); caller_ar = &stack.top(1); current_ar = &stack.top(); switch (RETURN_POINT(current_ar)) { case P1: goto p1; case P2: goto p2; }

2.5. Pilas

121

gd vez que se retorn de un funin se elimin un registro de tivinD ese es el ometido del pop()F i l pil ontiene un registroD entones el )ujo est terminndo l llmd iniil y el resultdo de(nitivo se enuentr en RESULT(caller_ar)F he lo ontrrio se tulizn los puntdores los registros de tivin y se determin donde se dee retornrF v rutin nterior exhie un desempeo inferior su versin reursivF he entrdD el eh ArrayStack<T> de un soreoste de vlidin de desorde que no tiene l versin reursivF ry otrs fuentes de soreosteD l indiin de slto es un que no tiene l versin reursivF odemos efetur mejors sore l versin no reursivF in primer lugr podemos eliE minr el mpo f1 del registro de tivin y utilizr resultF he este modo disminuimos l ntidd de pushesF ytr mejor es disminuir l ntidd de oserviones l pil Einstruin top()EF v prte llmd reursiv ( 119b podr de(nirse omoX
caller_ar = current_ar; ++current_ar; goto start;

uesto que el registro del invonte psr ser el tulD no hy neesidd de oservr l pilF uesto que l pil est implntd on un rregloD el siguiente registro de tivin ser el veino de current_arY por eso lo inrementmosF n optimizin (nl onsiste en olor direiones reles de slto en lugr de etiE quetsF iste mtodo eliminr el switch y el if de retornr desde ( 120e D pues el )ujo sltr diretmente l direin ddF hesfortundmenteD ni el lenguje C ni el C++ poseen menismos que permitn lmenr direiones de slto17 F endrmosD entones que progrmr lguns prtes de l rutin en ensmldorF
Eliminacin total de la recursin

gomo y hemos vistoD eliminr l reursin no es trivilF v experieni indi que es muy difil otener un versin no reursiv que se ms e(iente que su equivlente reursivoF or es rznD l eliminin de l reursin de un lgoritmo nturlmente reursivo slo dee herse si l prte reursiv est dentro del mino rtio de ejeuin y es vitl umentr el desempeoF in l myor de ls osiones es preferile trjr on l versin reursivF ixisten situiones en ls que el tmo de l pil del sistem es pequeoF in estos sosD l reursin es peligrosD pues ument ls posiiliddes de desorde de pilF ituE iones de este tipo son progrms empotrdosD de tiempo rel o pliiones prlels on vrios )ujos @thredsA de ejeuinF in este soD (n de proteger l pil del sistem es justi(le Elguns vees esenilE disponer de un versin no reursiv que mneje su propi pilF in l prtiD el uso de l reursin es un uestin de omodiddF i los oneptos inherentes l lgoritmo son reursivosD entones es preferile trjr en trminos reurE sivosD pues hy ms seguridd de entendimientoF i por rzones de desempeo o espio se
17
A la excepcin del ensamblador, el autor no conoce ningn lenguaje que posea este mecanismo. Las primitivas

longjmp() y setjmp() de la biblioteca estndar del lenguaje C permiten guardar direcciones de

ujo y saltar a ellas. Lamentablemente, a nuestros efectos, sus costes en tiempo y en espacio son superiores que el guardar indicaciones.

122

2. Secuencias

he neesrio eliminr l reursinD entones es preferile formulr oneptos itertivosD en lugr de eliminr l reursin de un lgoritmo reursivoF n ejemplo notle es l mism funin ftoril uy de(niin itertiv esX
n

n! =
i=1

i .

ist de(niin nos ondue un versin itertiv sin ningn rzonmiento reursivoF elguns vees se puede enontrr un soluin nltiF or ejemploD omo deE mostrremos en TFRFP @gF RVQAD el iEsimo nmero de pioni puede de(nirse omoX

1 Fib(n) = 5

1+ 5 2

1 5 2

n lgoritmo sdo en est expresin no requiere ningun iterin ni reursinF in de(nitivD lo ms simple es menudo lo idneoF i pensr reursivmente es ms simpleD entones trnse por lgoritmos reursivosF i l versin reursiv es muy ine(ienteD el ftoril o los nmeros de pioniD por ejemplosD entones usque soluiones que disminuyn los lulos repetidos o utilie oneptos itertivos que le onduzn hi lgoritmos itertivosF

2.6 Colas
n ol es un seueni on dos extremos de esoF v inserin se efet por un extremoD l supresin por el otroF il extremo de inserin se denomin omnmente ol o trsero oD en sus formsD sjons rer o tilF il extremo de supresin se llm ezD frente oD en sus forms sjonsD front o hedF
cola trasero rear put
Tn Tn1 Tn2 T2 T1

cabeza frente front get

pigur PFPQX isin strt de un ol v (gur PFPQ ilustr un visin strt de un olF vos elementos entrn por el extremo izquierdo medinte l operin put()F hel mismo modoD los elementos slen por el extremo dereho medinte l operin get()F emos extremos son oservlesF il trsero de un ol denot el elemento ms reientemente insertdo y el frente el menos reientemente insertdoF ist noin de reiente es fundmentl en lgunos lgoritmos y se denomin i @rimero en intrrD rimero en lirA oD en inglsD pspy @pirst snD pirst yutAF odemos deir que los elementos de l ol estn ordendos desde el ms joven hst el ms ntiguoF iste ptrn rteriz los ontextos lgortmios en los ules un ol puede usrseF el igul que on ls pilsD ls ols son muy omunes en l vid relF inontrmos ejemplos tpios en ls ols de esper de muhos serviios de nuestr soieddF gundo vmos l ine deemos her un ol pr omprr l entrdY igulmente deemos her

2.6. Colas

123

otr ol pr ingresr l slF gundo vmos l no deemos her olF gundo onduimos un rro y rrimos un semforo se form un olF
2.6.1 Variantes de las colas

n vrinte ms generl del orden pspy onsiste en ver el orden desde el ms reienteE mente edido hst el menos reientemente edidoF il orden de inserin y extrin es el mismoD pero hy un operin diionl de eso o onsultF gulquier elemento de l ol puede ser edidoD pero este eso us que el elemento se desple hi el trseroF he este modoD el frente es el elemento que tiene ms tiempo sin referenirseD mientrs que el trsero es el que tiene menos tiempoF ist polti or importni en prolems que mnipuln onjuntos de dtos de rdinlidd (nitF gundo se ingres un nuevo elemento en un onjunto llenoD hy que seleionr un elemento suprimirF i el eso l onjunto exhie lolidd temporlD lo ul suede en muhos ontextos pliE tivosD entones el mejor elemento suprimir es el menos reientemente utilizdoF in un ol que mneje el orden de esoD este elemento se enuentr en el frenteF ytr vrinte importnte es permitir l inserin y supresin por los dos extremosF ist vrinte es denomind diol o dipolo 18 F in iert medidD un diol es un form generl de pil y de olF gulquier de ls dos estruturs puede modelizrse medinte un diolF v fmili en torno l eh Dlink @ PFRFU @gF UPAA es un dipoloF
2.6.2 Aplicaciones de las colas

in generlD los sistems progrmdos utilizn ols pr tender soliitudes jo l just disiplin pspyF or ejemploD un servidor if puede enolr soliitudes de squed de pgin segn el orden de llegdF wuhos sistems de ontrol de trnsiones enoln ls soliitudes de serviiosY por ejemploD trnsiones (nniersF il rol fundmentl del softwre de red es trnsmitir pquetes de informin entre los diversos nodos de un redF il progrm enrgdo de est trnsmisin se denomin enrutdor o enmindorF qenerlmenteD un enrutdor proes sus pquetes segn un disiplin pspyF vos sistems opertivos tmin utilizn ols pr omprtir reursos entre diversos usuriosF rdiionlmenteD proesos que rrien un sistem se insertn en un olF il proeso en el frente se extre y se ejeut durnte un tiempo llmdo untumF gundo el untum expirD el proeso se insert de nuevo en l ol y el sistem opertivo extre el siguiente proeso de l olF ixiste tod un rm de l mtemtiD onoid omo teor de olsD l ul modeliz entiddes strts que se enoln pr soliitr lgn serviioF eunque l mtemti rroj resultdos nltios muy tilesD lgunos modelos son tn omplejos que es neesrio simulrlosF les sistems de simulin usn intensivmente olsF
2.6.3 Representaciones en memoria de las colas

el igul que l pilD un ol es un seueni de elementos de lgn tipoF gomo tlD hy dos forms sis de representr un olX on un rreglo o on un listF
18
En ingls, dequeue.

124

2. Secuencias

v implntin de l ol on un rreglo es similr l pilF v difereni estri en que deemos mnejr los dos extremosD ergo deemos mntener dos ontdoresX uno pr l olD otro pr l ezF v (gur PFPR ilustr un ol implntd medinte un rregloF
0 1 2 3 4 5 6 7 8 9 10 T0 T1 T2 T3 T4 cabeza cola

pigur PFPRX gol implntd medinte un rreglo r insertrD opimos el elemento e inrementmos l olF r eliminrD opimos el vlor de retorno e inrementmos l ezF v ol est llen undo l ntidd de elementos es igul l dimensin del vetorF xotemos que l eliminin de elementos puede dejr espios disponiles l izquierd del ndie ezF es puesD l inserin y supresin deen onsiderr est irulriddF isto puede mnejrse medinte un if que veri(que si el ndie no se enuentr en el orde del rregloD o medinte l funin mduloF r ls ols es preferile que l list se irulrD pues podemos eder l frente y el trsero medinte un solo puntdorF i se trt de un list simplemente enlzdD ordenmos los elementos desde el frente hst el trsero y mntenemos un puntdor l ltimo elemento @(gur PFPSAF he este modo podemos insertr y eliminr desde el puntero l olF
rear

pigur PFPSX gol implntd medinte un list simple vs lists dolemente enlzds pueden ser un uen esogeni pr ls ols ordeE nds segn el tiempo de eso y pr ls diols @ PFTFI @gF IPQAAF v ventj es que l supresin de un elemento es diret on un nodo doleD mientrs que en un list simple hr que mntener el puntero l predeesorF il tipo DynDlist<T> estudido en PFRFW @gF VRA nos proporion un mner diret de implementr un olF i vemos el ltimo elemento omo el trseroD entones l operin get() se implnt medinte return remove_first()Y y put(item) medinte append(item)F il trsero y el frente se oservn trvs de get_last() y get_first()D respetivmenteF
2.6.4 El TAD

ArrayQueue<T>

(cola vectorizada)

in est sein desrrollremos un implntin de ols medinte rreglos esttiosF smplntremos dos eh muy similresX ArrayQueue<T> y FixedQueue<T>F emos tipos son si idntios slvo que FixedQueue<T> no efet veri(iones de desordeF

2.6. Colas

125

125a

vos tipos se de(nen en el rhivo tplrryueueFr tpl_arrayQueue.H 125a template <typename T> class ArrayQueue {

125a

de l siguiente mnerX

}; template <typename T> class FixedQueue


Denes:

atributos de cola vectorizada 125b mtodos privados de cola vectorizada 126d mtodos pblicos de ArrayQueue<T> 126c observadores de cola vectorizada 128g

ArrayQueue,

used in chunks 126c and 251c.

ems lses modelizn ols de elementos genrios de tipo T implntds medinte un rreglo esttioF ArrayQueue<T> veri( desordes undo el rreglo est vo o llenoF n desorde provo un exepinF FixedQueue<T> no efet ningun veri(in ni gener ningun exepinF v useni de ests veri(iones onllev un liger gnni en desempeoF v dimensin del rreglo interno est restringid un poteni ext de 2F
125b

atributos de cola vectorizada 125b


const size_t two_pow; const size_t dim; T * array;

(125a) 125c

125c

il puntero array ontiene los elementos de l olF dim represent l dimensin del rreglo internoD el ul es un poteni ext de 2 tl que dim == 2two_pow F il frente de l ol est ddo porX atributos de cola vectorizada 125b + (125a) 125b 125e size_t front_index; /* index of oldest inserted item */

125d

front_index es el ndie del elemento ms ntiguo en l olY es deirD array[front_index] ontiene el frente de l olX frente de la cola 125d (127g)
array[front_index]

125e

il trsero de l ol est indido porX atributos de cola vectorizada 125b + size_t rear_index;

(125a)

125c 126a

rear_index indi l posiin de l primer eld disponile pr insertrY es deirD array[rear_index - 1] ontiene el elemento ms reiente en l olF
0 1 2 3 4 5 6 7 T0 T1 T2 T3 T4
front_index rear_index

pigur PFPTX yrgnizin del rreglo en ArrayQueue<T> vos vlores de front_index y rear_index se iniin en eroF v (gur PFPT ilustr el estdo del rreglo y de los ndies despus de insertr los primeros ino elementos en un rreglo de 8 elementosF

126

2. Secuencias

126a

nto pr insertrD omo pr eliminrD st on inrementr el ndie orresponE dienteF i queremos insertrD inrementmos rear_indexY si queremos eliminrD inremenE tmos front_indexF gundo lguno de los ndies lnz l dimensin del rreglo lo iniimos de nuevo en eroY esto simul l irulriddF r esto st poner un if despus del inremento que veri(que si se lnz l dimensinY si tl es el soD entones reiniimos el ndie en eroF odemos evitr el if si d vez que inrementmos un ndie lulmos el mdulo de l dimensin del rregloF he este modoD el vlor del ndie siempre estr omprendido entre 0 y dim 1F iste mtodo lineliz el digoD pero es ms lento que on el ifF is pr solventr este prolemD que forzmos l dimensin que se poteni ext de 2D puesD en este soD el mdulo puede lulrse muy rpidmente trvs de un and lgioF or tntoD uno de los triutos ser un msr de its pr lulr el mduloX atributos de cola vectorizada 125b + (125a) 125e 126b const size_t mask; is tentdor lulr el nmero de elementos medinte el vlor soluto de rear_index front_indexF vmentlementeD tenemos un migeddD pues l rest es ero undo l ol est llenF xo hy otr lterntivD entonesD que ontilizr diretmente l ntidd de elementos en un triutoX atributos de cola vectorizada 125b + (125a) 126a size_t num_items; vos triutos de l ol se iniin omo sigueX mtodos pblicos de ArrayQueue<T> 126c (125a) ArrayQueue(const size_t & tp = 8) : two_pow(tp), dim(1two_pow), array(NULL), front_index(0), rear_index(0), mask(dim - 1), num_items(0) { array = new T [dim]; }
Uses 127b

126b

126c

ArrayQueue

125a.

126d

v operin de inrementr un ndie y luego lulr el mdulo ser efetud por los modi(dores de l olF is muy importnteD puesD segurrnos de herl orretmenteF r elloD l modulrizmos y l islmos en un sol operinX mtodos privados de cola vectorizada 126d (125a) 127a void increase_index(size_t & i, const size_t & inc = 1) const { i += inc; i &= mask; }

increase_index() inrement i en inc uniddes y lul el mdulo medinte l msrF il mtodo del mdulo puede plirse tmin on rests en lugr de sumsF gundo se derement un entero sin signo on vlor eroD el desorde negtivo us que el entero dquier el myor vlorF uesto que l dimensin es poteni de dosD el mdulo dr omo resultdo l dimensin menos unoF heemos segurrnosD emperoD de que ls rests se pliquen sore enteros sin signo yD por supuestoD de que l ritmti se inriF i se dese onsultr el trseroD entones es neesrio eder array[rear_index - 1]F uesto que est operin puede rrojr un desorde

2.6. Colas

127

negtivoD l islmos en un sol funin que nos grntie un operin orretX


127a

mtodos privados de cola vectorizada 126d +

(125a)

126d

T & rear_item(const size_t & i = 0) { return array[static_cast<size_t> ((rear_index - i - 1) & mask)]; }


(125a) 126c 127d

127b

mtodos pblicos de ArrayQueue<T> 126c +


T & put(const T & item) { }

put en cola vectorizada 127c

127c

put() gener l exepin std::overflow_error si se intent insertr en un ol llenF v inserin omo tl es omo sigueX put en cola vectorizada 127c (127b)
array[rear_index] = item; T & ret_val = array[rear_index]; increase_index(rear_index); num_items++; return ret_val;

127d

in lugr de insertr un elemento es posile prtr espioD jo disiplin pspyD pr n elementosF isto es tn rpido trvs de un rreglo que vle l pen exportr l funionlidd en el siguiente mtodoX mtodos pblicos de ArrayQueue<T> 126c + (125a) 127b 127f T & putn(const size_t & n) {
}

putn en cola vectorizada 127e

127e

v primer prte veri( el desorde y l segund se remite inrementr rear_indexX putn en cola vectorizada 127e (127d) increase_index(rear_index, n); num_items += n; return rear_item();

127f

mtodos pblicos de ArrayQueue<T> 126c +


T get() { }

v supresin es si simtri put()X

(125a)

127d 128a

get en cola vectorizada 127g

127g

donde l supresin onsiste enX get en cola vectorizada 127g num_items; T ret_val = frente de la cola 125d ; increase_index(front_index); return ret_val;

(127f)

128

2. Secuencias

128a

v ontrprte de putn() es getn()D es deirD lierr n elementos por el frente de l olX mtodos pblicos de ArrayQueue<T> 126c + (125a) 127f 128c T & getn(const size_t & n) throw(std::exception, std::underflow_error) {
}

getn en cola vectorizada 128b

128b

getn en cola vectorizada 128b

(128a)

num_items -= n; increase_index(front_index, n); return array[front_index];

128c

v onsult por el frente se he medinteX mtodos pblicos de ArrayQueue<T> 126c + T & front(const size_t & i = 0) {
}

(125a)

128a 128e

retornar i-simo elemento del frente 128d

128d

retornar i-simo elemento del frente 128d


return array[front_index + i];

(128c)

128e

v onsult por el trsero tmin es simtriX mtodos pblicos de ArrayQueue<T> 126c + T & rear(const size_t & i = 0) {
}

(125a)

128c

retornar i-simo elemento del trasero 128f

128f

retornar i-simo elemento del trasero 128f


return rear_item(i);

(128e)

128g

pinlmente tenemos los lsios oservdoresX observadores de cola vectorizada 128g const size_t & size() const { return num_items; }
bool is_empty() const { return num_items == 0; } const size_t & capacity() const { return dim; }

(125a)

v implntin de FixedQueue<T> es muy similr ArrayQueue<T>F v ni difereni ser que FixedQueue<T> no veri( desordesF
2.6.5 El TAD

ListQueue<T>

(cola con listas enlazadas)

128h

il eh ListQueue<T> modeliz un ol implntd medinte un list simpleE mente enlzd irulrF ListQueue<T> est espei(do e implntdo en el rhivo tpllistueueFr 128h X tpl_listQueue.H 128h template <typename T> class ListQueue { Node de ListQueue<T> 129a

2.6. Colas

129

};

Atributos de ListQueue<T> 129b Mtodos pblicos de ListQueue<T> 130a


used in chunks 12931.
rear_ptr

Denes:

ListQueue,

pigur PFPUX gol implntd medinte Snode<T> vs operiones de ListQueue<T> se espei(n en funin de nodos simples de tipo ListQueue<T>::NodeX Node de ListQueue<T> 129a (128h) typedef Snode<T> Node; typedef ListQueue Set_Type; typedef Node * Item_Type;
Uses

129a

ListQueue

128h and

Snode

68b.
T:class

ListQueue
-rear_ptr: Node * -num_nodes: size_t +ListQueue() +put(node:Node *): void +get(): Node* +front(): Node* +rear(): Node* +size(): size_t +is_empty(): bool

T:class

DynListQueue
-Node: ListQueue<T>::Node +put(data:const T&): T& +get(): T +front(): T& +rear(): T& +~DynListQueue(): virtual

pigur PFPVX higrm wv de ls lses vinulds ListQueue<T> v list est ordend desde l ez hst l olF he este modoD mnteniendo un puntero pr l ol podemos eliminr en tiempo onstnteF v (gur PFPU muestr un disposiin de ol implntd medinte lzos simples de tipo Snode<T>F v on(gurin de l (gur PFPU es generl slo undo l list no est vF is inevitleD puesD tener que mnejr dos sosX uno generl y uno undo l ol est vF ehor podemos omenzr introduir los triutos de ListQueue<T>X Atributos de ListQueue<T> 129b (128h) 129c Node * rear_ptr;

129b

129c

rear_ptr ser el puntero l ol irulr de elementos de tipo Snode<T>F il otro triuto es el nmero de elementos que posee l olX Atributos de ListQueue<T> 129b + (128h) 129b
size_t num_nodes;

130

2. Secuencias

130a

vos vlores nteriores requieren ser iniidos por el onstrutorX Mtodos pblicos de ListQueue<T> 130a (128h) ListQueue() : rear_ptr(NULL), num_nodes(0) { /* empty */ }
Uses

130b

ListQueue

128h.

130b

enemos dos modos de ser si un ol est vX si rear_ptr == NULL o si num_nodes == 0F v inserin posee l siguiente estruturX Mtodos pblicos de ListQueue<T> 130a + (128h) 130a 130c void put(Node * node) { if (num_nodes > 0) rear_ptr->insert_next(node); num_nodes++; rear_ptr = node; }

130c

put() no dispr ningun exepin porque no hy mnejo de memoriF is imposile que put() frse si el nodo fue orretmente prtdoF v eliminin es un poo ms omplid porque dee veri(r desorde negtivo y que l ol deveng vX Mtodos pblicos de ListQueue<T> 130a + (128h) 130b 130d
Node * get() Node * ret_val = rear_ptr->remove_next(); num_nodes; if (num_nodes == 0) rear_ptr = NULL; return ret_val; }

130d

v onsult se de(ne de dos formsX Mtodos pblicos de ListQueue<T> 130a + Node * front() const { return rear_ptr->get_next(); } Node * rear() const { return rear_ptr; }

(128h)

130c

front() retorn el nodo por el frente y rear() el nodo por l olF


2.6.6 El TAD

DynListQueue<T>

(cola dinmica con listas enlazadas)

il eh DynListQueue<T> modeliz un ol implntd trvs de un list simpleE mente enlzd irulrF DynListQueue<T> est espei(do e implntdo en el rhivo tpldynvistueueFr 131 F DynListQueue<T> hered prte de l interfz e implntin de ListQueue<T>F il nio rol de DynListQueue<T> es mnejr l memori y mnipulr dtos de un tipo genrio T en lugr de nodos de un list enlzdF uesto que este proeso y lo hemos

2.7. Estructuras de datos combinadas - Multilistas

131

131

puesto en prti pr ls lists y ls pilsD pondremos en est sein tod l implntin diret de DynListQueue<T>X tpl_dynListQueue.H 131 template <typename T> class DynListQueue : public ListQueue<T> { typedef typename ListQueue<T>::Node Node; T & put(const T & data) { Node * ptr = new Node (data); ListQueue<T>::put(ptr); return ptr->get_data(); } T get() { Node * ptr = ListQueue<T>::get(); T ret_val = ptr->get_data(); delete ptr; return ret_val; } T & front() const { return ListQueue<T>::front()->get_data(); } T & rear() const { return ListQueue<T>::rear()->get_data(); } virtual ~DynListQueue() { while (not this->is_empty()) get(); } };
Uses

ListQueue

128h.

2.7 Estructuras de datos combinadas - Multilistas


gonsideremos un list de estudintes de un urso de estrutur de dtosF vos nomresD pellidos y dul de identidd pueden representrse medinte dens de rteresF vs nots pueden representrse medinte enterosF od est informin l estruturmos en un registro y usmos un rreglo de registros pr representr l listF ist mner de orgnizr los dtosD que posilemente y nos se nturlD es un ejemplo de ominiones entre diverss estruturs de dtosF egn los requerimientos del prolemD un seueni de elementos puede representrse omo un rreglo o omo un listF gomnmenteD un mtriz se represent omo un rreglo de rreglosF odemos her lo mismo on listscD es deirD podemos tener un list de listsc o rreglo de listsc o un list de rreglosc vs respuests son (rmtivsF in lenguje gD un mtriz se represent medinte un rreglo de (lsD en el ul d (l es tmin un rregloF es puesD podrmos delrr lo siguienteX
DynSlist<int> mat[5];

132

2. Secuencias

equ tenemos un rreglo de lists donde d mat[i] re(ere un list enlzdF min podrmos delrrX
typedef int Arreglo[5]; DynSlist<Arreglo> mat;

vo que nos de(ne un list enlzd de rreglos de dimensin 5F sgulmente podemos delrrX
DynSlist< DynSlist<int> > mat;

pr de(nir un list de listsF vos ejemplos nteriores pueden modelizrse prtir de eh onoidosF is posile que tengmos que jr de nivel y mnejr diretmente ls listsF gomo ejemploD onsidere un pliin que mnipule mtries de muy lt eslD del orden de millones de (ls y olumnsF les pliiones son omunes en prolems de progrmin linel y enter de l vid relF v esl de ests mtries got l memori de ulquier omputdorF ist lro que no tenemos espio pr lmenr un mtriz de illones de elementos jo l representin lsiF imperoD unque ls mtries son enormesD l myor de ls vees sts poseen muhsimos elementos nulosF odemosD puesD plir el mismo prinipio que en los polinomiosX slo gurdmos los elementos diferentes de eroF fjo este linemientoD imginmos el siguiente tipo espeil de nodoX

i j dato

Puntero a la prxima columna

Puntero a la prxima la

que nos represent un entrd de un mtriz mat[i, j] on los siguientes triutosX  ndie de (lY es deir el vlor de i  ndie de olumnD es deirD el vlor de j  lor del dto diferente de ero ontenido en mat[i, j]  untero l siguiente mat[i + x, j] on vlor diferente de ero  untero l siguiente mat[i, j + y] on vlor diferente de ero he est mnerD l mtrizX

1 5 0 0 0 0 0 0 0 0

0 0 10 1 2 0 0 1 0 , 0 0 0 0 1 0

puede representrse omo en l (gur PFPWF gomo vemos en l (gur PFPWD tenemos 5 lists de (ls y 5 lists de olumnsF gd list posee un nodo eerD el ulD pr mejorr l rpidez de esoD onviene uir en un rregloF es puesD tendrmos un rreglo de 5 eers pr ls (ls y otro de 5 eers pr ls olumnsF

2.8. Notas bibliogrcas

133

0 0

10

1 2

pigur PFPWX n mtriz esprid representd medinte multilists hdo un nodo ulquierD el elemento hi l dereh indi l prxim entrd en l mism (l on un vlor diferente de 0Y l olumn es verigud por el ndie de l olumnF hel mismo modoD el elemento hi jo indi l prxim entrd en l mism olumn on un vlor diferente de eroY l (l es verigud por el ndie de l (lF v representin de l (gur PFPW ompens on rees si el nmero de entrds nuls es muy grndeF or ejemploD un mtriz 104 x104 oupr 400 106 de ytes en un rquitetur de 32 itsF i un 47 de los elementos es diferente de eroD que represent 4 millones de elementosD l representin on multilists oupr (4 + 4 + 4 + 4 + 4) 0, 04 1006 = 80 106 ytesF v sumD rest y divisin de mtries son files de progrmr on mtries sds en l estrutur de l (gur PFPWF r otrs operiones puede ser ms onveniente tener lzos l (l y l olumn predeesorsF il lgoritmo ndido pr multiplir mtries n n es ioF isto signi( que su tiempo de ejeuin es proporionl n3 F gon millones de olumns y (ls no hy muhs espernzs de otener un uen desempeo si esogemos l representin seuenilF ore mtries esprids representds on multilists el tiempo es muho menorD pues ls entrds de ls mtries son visitds en el mismo orden de ls lists y no hy neesidd de insertr eros en l mtriz resultdoF in de(nitivD l durin depende de l ntidd de elementos diferentes de eroF

2.8 Notas bibliogrcas


vos orgenes de ls estruturs sis se remontn medidos de los os QH del siglo durnte los desrrollos de progrms pr los primeros omputdoresF ist po es tn rn este redtor que ste no se siente utorizdo pr ofreer un disurso histrio sore el origen de ls estruturs de dtos que representn seuenis ni lguns de ls tnis de squed trtds en este ptuloF r oservr un hermoso pnorm de

134

2. Secuencias

est psionnte historiD esrito por uno sus protgonistsD reomendmos nuevmente l letur de l sein histri ontenid en el primer volumen de unuth WU @pgins RSUE RTSAF or su rter seuenil inntoD l noin de rreglo fue mnejd desde los primeros progrms de omputdorF in didurD el rreglo tiene su equivlente vetor en mtemtiF or lo nteriorD ser muy venturdo triuir lgun utor exlusivF imperoD e selr el portrn IP omo el primer lenguje de progrmin y el primero en soportr rreglos trvs del propio lengujeF il enfoque de diseo de l jerrqu de lses Dlink est primigenimente inspirdo en utilitrios disedos pr el miroEnleo Chorus ISID sistem sore el ul este redE tor urs sus estudios dotorlesF elguns iliotes de progrmin usn enfoques similresD entre los ules e destr net.datastructures reportd en TQF in el mismo sentido de lo rreglosD ls lists enlzds fueron desuierts indeE pendiente y seprdmente en los primigenios y y rnos ontextos omputionlesF in emrgoD e selr l sv @snformtion roessing vngujeA IQP omo el primer lenguje que inorpor ls lists un lenguje de progrminF v lsi pitorizin onsistente de retngulos pr representr loques de memori y de )ehs pr los punE terosD pree en un rtulo de xewell y hw sore progrmin on sv IQIF vos rreglosD listsD pils y ols y son prte de los lengujes de muy lto nivel modernosD entre los que e selr Perl IUU y Python IUPF stos se irunsrien en los llmdos de sriptingD trmino mdurdo por tohn uF yusterhout IQT en un lere y visionrio rtulo meniondo en l sein iliogr( de este ptuloF v squed inri es un prinipio de squed milenrioD el ulD segn unuth WUD se remont hst l mism wesopotmiD preursor de l ivilizin y hoy en d miseE rlemente niquild en nomre de l propi ivilizinF gonsltese el trjo histrio de ohr wnn nd ihrd ldinger sore los orgenes de l squed inri IITF eprte sus ndots histris WU es un de ls ms slids referenis formles en el mpo de lgoritmos y estruturs de dtosF vs estruturs lineles son trtds de mner muy forml y on pliiones relesF v primer ediin fue redtd en un po en que el poder omputionl de un mquin n er muy jo y el lenguje ensmldor er l ni lterntiv seri pr progrmr pliiones de lto desempeoF or est rznD el texto de unuth ontiene un mpli gm de truos utilizr on estruturs linelesF il lsio y ntiguo texto de irth IVP fue esrito durnte los os UH del siglo F e pesr de su eddD hoy en d este texto ontinu stnte vigente y present un exposiin de ls estruturs lineles superior l normF edemsD irth onsgr un exelente y ompleto ptulo l reursinF il liro de edgewik ISS est repleto de lgoritmos on estruturs linelesY por ejemploD lgoritmos de ordenmiento de listsF e nivel prtioD st esD en nuestr opininD l mejor refereniF ge menionr empero que los lgoritmos que usn estruturs lineles estn distriuidos lo lrgo del texto en ptulos que no neesrimente trtn de estruturs linelesF vewis y henenerg IHV presentn lgunos truos interesntes on lists enlzdsF v tni de lse intermediri @roxyAD utilizd por BitArray y DynArray<T> pr distinguir los esos de letur de los de esriturD l nliz intensivmente ott weyer IPSF

2.9. Ejercicios

135

il prolem de tos es nltimente trtdo por qrhmD unuth y tshnik TRF v ritmti de polinomios explid en PFRFIH @gF WIA es mplimente desrE rolld por ehoD roproft y llmnWF n lterntiv puede enontrrse en el texto enilopdio de gormenD veiserson y ivest QPF il lgoritmo de evluin de expresiones in(js desrrolldo en PFSFS @gF IHTA fue tomdo de un texto sore progrmin de sistems de eter glingert PUF iste liro est tn mgistrl y onismente esrito que lo reomendmos on rees pr un introduin l mpo de l progrmin de sistemsD ompildoresD ensmldores y rgdoresF

2.9 Ejercicios
IF or qu l squed inri no dee utilizrse pr elementos ordendos en un rhivo lmendo en memori seundric PF smplnte entermente el prolem fundmentl de estrutur de dtos estudido en IFQ @gF IUA medinte rreglos desordendosF QF smplnte entermente el prolem fundmentl de estrutur de dtos estudido en IFQ @gF IUA medinte rreglos ordendosF RF ixplique mo es el menismo de eso direto los elementos de un mtrizF SF in generlD explique mo es el menismo de eso direto los elementos de un rreglo nEdimensionlF TF hisee e implnte un eh que modelie rreglos n dimensionlesF UF isri un implntin lo ms e(iente posile de l rutin DynArray<T>copy() segn ls indiiones dds en PFIFRFQ @gF RRAF VF isri un lgoritmo e(iente que efete l inserin ordend en un DynArray<T>F WF isri un lgoritmo e(iente que efete l eliminin ordend en un DynArray<T>F IHF upong un proeso on un memori totl disponile de M ytes y un mximo perE mitido por un llmd new de S ytesF gonsidere un rreglo dinmio de elementos de tmo T F eleione los tmos de diretorioD segmento y loque que mximien l dimensin de un DynArray<T>F IIF isri l sorerg del mtodo DynArray<T>::cut(l, r)D el ul lier tod l memori entre [0..l - 1] y r+1..dim @dimA es l dimensin tul del rregloF IPF v iliote ALEPH implnt un prototipo del eh de l iliote stdc++ llmdo vector<T>D el ul export un rreglo dinmioF il tipo en uestin se enuentr en el rhivo Vector.HF @A evise minuiosmente l implntin en Vector.HF ruelD usque erroresD eventulmente deprel y eventulmente mejore su e(ieniF @A gompre rtimente Vector.H on otrs implntiones de stdc++F

136

2. Secuencias

IQF isri un lgoritmo e(iente que inviert un rregloF ABCDEFG se dee rrojr GFEDCBAF

or ejemploD l invertir

IRF isri un lgoritmo que elimine los elementos duplidos de un rreglo ordendoF ISF isri un lgoritmo que elimine los elementos duplidos de un rreglo desordendoF ITF hdo un rreglo desordendo de n 1 elementos enteros omprendidos entre 1 y nD disee un lgoritmo que no onteng ilos niddosD o seD de un sol psdD que determine el elemento fltnte @CAF IUF gonsidere l operin de rotin de un rregloF or ejemploD rotr 3 vees hi l izquierd el rreglo ABCDEFGHI rroj omo resultdo DEFGHIABCF hisee un lgoritmo generl que no onteng ilos niddos @slo ilos de un sol psdAD que rote m vees un rreglo de dimensin n @CCAF IVF upong un seueni S =< s1 , s2 , . . . sn >F v operin void rotar_derecha(S, n) rot S n posiiones hi l derehF or ejemploD

rotar_derecha(< 1, 2, 3, 4, 5, 6, 7 >, 3) =< 5, 6, 7, 1, 2, 3, 4 >


esumiendo seuenis implntds on lists irulres dolemente enlzds que utiE lizn nodo eerD esri un lgoritmo que implnte rotar_derecha(S, n) en tiempo proporionl l tmo del rreglo y sin usr espio que rez en funin del rregloF in otrs plrsD no dee usr lists o rreglosF IWF hd un den de rteres que ontiene plrsD supong un operin de jusE ti(in de l den de rteres un mximo de nF or justi(r se entiende que se oloquen tods ls plrs posiles en extmente n rteres interlndo proporionlmente lnosF or ejemploD l denX
Esta es una prueba de justificacin

tiene un longitud de QP rteresF i se justi( QH rteresD entones el resultdo esX


Esta es una prueba de

hisee un lgoritmo que justi(que un den de rteres un mximo n menor que l longitud de l denF il lgoritmo dee tener dos slidsX l den justi(d y l den extrd por l derehF PHF gonsidere n elementos enterosD lmendos en un rregloD omprendidos entre 0 y m, m nF @A se el tipo BitArray pr diser un lgoritmo que determine lgn elemento fltnteF @A upong que m es su(ientemente pequeo pr que todos los nmeros quepn en memoriF hisee un lgoritmo que onstruy un rreglo que onteng los elementos fltntesF

2.9. Ejercicios

137

@A upong que n es muy grndeD pero que el rreglo n e en memoriF upong ondiiones muy restritivs de memoriX no es posile usr un rreglo de its niD en generlD ulquier otr estrutur de dtoF impero s es posile utilizr rhivos en modo ppendD es deirD slo se puede insertr l (nl del rhivoF iF se el prinipio de squed inri pr diser un lgoritmo que determine lgn elemento fltnte @CCCAF iiF se el prinipio de squed inri pr diser un lgoritmo que onstruy un rhivo on los nmeros fltntes @C Eluego de resolver nteriorEA F PIF gonsidere l selein letori de un elemento ontenido en un rreglo de n elementos enterosF @A hisee un lgoritmo que esoj letorimente un elemento del rregloF @A upong hor que no se onoe n y que el (nl del rreglo orresponde un elemento entinel on vlor genrio FINF hisee un lgoritmo e(iente que seE leione letorimente un elemento del rregloF @A ehor sum que los enteros estn lmendos en un list simplemente enlzdF hisee un lgoritmo que efete un sol psd y seleione letorimente un elemento de l list @CCAF PPF gonsidere el siguiente prototipo de funinX
template <typename T> int select(T a[], size_t n, int i);

il ul retorn el ndie de iEsimo menor elemento en el rreglo desordendo a[] que ontiene n elementosF isri un implntin que no modi(que l permutin del rreglo ni utilie rreglos uxilires @CAF PQF ixtiend el eh DynArray<T> pr mnejr mtriesF uponiendo que el eh es llmdo DynMatrix<T>X @A uede implntrse este eh prtir del eh DynArray<T>c @A uede usrse un implntin independiente ms e(ientec @A gmo ser l form y ules ls funiones de l lse proxy sore el eh DynMatrix<T>c PRF ixtiend el eh DynArray<T> pr mnejr rreglos multidimensionlesF PSF v myor de los eh que mnejn lists no utilizn memoriF xinguno de estos eh veri( si l direin de un ojeto que insert o elimin es vlidF hisee un mtodo que veri(que si un direin de ojeto es vlid @CAF PTF in el mismo espritu de l pregunt nteriorD disee un mtodo queD dems de veri(r si el puntero es vlidoD veri(que que l direin orrespond un ojeto del tipo esperdo por l funin @CCAF PUF ispei(que ules yuds podr ofreer un ompildor pr filitr l implntin genrimente de l onversin de un Slink l registro que lo inluy @CCCAF

138

2. Secuencias

PVF ispei(que ules yuds podr ofreer el lenguje de progrmin pr implntr genrimente l onversin de un Slink l registro que lo inluy @CCCAF PWF isri un lgoritmo que uente el nmero de nodos en un list simplemente enlzdF QHF istudie y disut el diseo de los eh Slist<T> y DynSlist<T>F he ules forms pueden extenderse o mejorrsecD ules son sus prolemscD estn ompletosc QIF smplnteD en detrimento del tiempo de ejeuinD un eh llmdo Single_Link que teng extmente los mismos mtodos que l lse DlinkF QPF isri un lgoritmo que uente el nmero de ourrenis de un elemento x en un list simplemente enlzdF QQF hdo un puntdor ptr un nodo de un list enlzdD esri un lgoritmo que determine l posiin ordinl de ptr dentro de l listF hisee su lgoritmo pr que funione on lists simples y dolesF QRF hisut revemente lterntivs pr implntr l sustrin de polinomiosF QSF hisut revemente mo implntr los lgoritmos de divisin y residuo de polinomiosF herive expresiones del tiempo de ejeuinF QTF smplnte el eh olinomioD explido el PFRFIH @gF WIAD medinte lists simpleE mente enlzdsF se el eh Snode<T> o SlinkF QUF gonsidere dos lists de enteros dolemente enlzdsD irulresD on nodo eerD denominds l1 y l2 respetivmenteF gonsidere l operinX
const bool similar(Dnode<int> & l1, Dnode<int> & l2)

v ul retorn true si ls lists ontienen extmente los mismos enterosD flse en so ontrrioF isri lgoritmos que implnten l operin pr ls siguientes situionesX @A vs dos lists estn ordends del menor l myor entero @A vs lists no estn ordends QVF hiseeD instrumente e inorpore l eh Slink ls operiones del eh Dlink insert_list()D append_list() y concat_list @CAF QWF gonsidere el siguiente prototipo de funinX
void permutar_pares(Dlink * lista);

v funin tom d pr dentro de l seueni e los intermiF or ejemE ploD si l =< 1, 2, 3, 4, 5, 6, 7, 8, 9 >D entonesD luego de permutar_pares(l)D l =< 2, 1, 4, 3, 6, 5, 8, 7, 9 >F isri l funin en uestinF RHF gonsidere el siguiente prototipo de funinX

2.9. Ejercicios

139

void conmuta_pares(Dlink * l1, Dlink * l2);

v funin intermi los elementos de posiin pr de l1 on los de posiin pr de l2F or ejemploD si l1 =< 1, 2, 3, 4, 5, 6, 7 > y l2 =< a, b, c, d, e >D entonesD luego de conmuta_pares(l1, l2) ls lists devienen en l1 =< a, 2, c, 4, e, 7 > y l2 =< 1, b, 3, d, 5 >F isri l funin en uestinF RIF isri un lgoritmo itertivo que lule el iEsimo nmero de pioniF RPF isri un lgoritmo reursivo que ompute el iEsimo nmero de pioni y que no redunde lulos @CAF RQF isri un versin del lgoritmo on pil desrrolldo en PFSFTFP pr lulr el iEsimo nmero de pioni que no redunde en lulos @CAF RRF isri un lgoritmo reursivo que onviert un den de rteres que ontiene un entero su representin enterF in otrs plrsD esri un rutin que onviert un entero lmendo en un char* un entero de tipo intF RSF in un tlero de jedrez de n n esques19 D se sit un llo en ls oordends x0 , y0 F isri un lgoritmo que enuentreD si existeD un reurimiento ompleto del tlero de n2 1 movimientos tl que d esque se visitdo extmente un vez @CCAF RTF hdo un tlero de jedrez de 8 8 esques esri un lgoritmo que distriuy oho reins en el tlero de mner tl que ningun rein pued menzr ulquier de ls otrs @CCAF RUF esuelv el prolem nterior de ls oho reins pr enontrr tods ls soluiones diferentes @CAF RVF El problema del morral hdo un ojetivo O y un olein de pesos P = {p1 , p2 , . . . , pn , pi } N D se pide determinr si existe un selein de pesos P P tl que pi P =)F

iste prolem es onoido omo el prolem del morrl porque legoriz el seleionr ules rgs llevr en un morrl de mner tl que no se porte ms O kilogrmosF r el prolem del morrlX @A isri un lgoritmo reursivo @A ilimine l reursin del lgoritmo nterior @A isri un lgoritmo itertivo que no utilie pil @CCA

RWF hd un olein de ojetos S = {s1 , s2 , . . . , sn , si } on pesos P = {p1 , p2 , . . . , pn , pi } R y vlores V = {v1 , v2 , . . . , vn , vi } RD se pide enontrr un suonjunto S SD que mximie el vlor totl sS vi restringido un piE dd de pesos sS pi CD es deirD que todos los ojetos quepn en un morrl de pidd CF
19
En la jerga ajedrecstica, un escaque es uno de los cuadros del tablero.

140

2. Secuencias

hisee un lgoritmo que resuelv est vrinte del prolem del morrl @CCAF SHF isri un lgoritmo reursivo que genere ls n! permutiones de n elementos x1 , x2 , . . . , xn on un onsumo de espio onstnteD que no rez segn n @CCAF SIF v funin de ekermn A(m, n) est de(nid de l form siguienteX
n + 1 A(m, n) = A(m 1, 1) A(m 1, A(m, n 1)) m=0 m > 0, n = 0 m, n > 0

@A isri un rutin reursiv que lule l funin de ekermnF gul es l omplejidd de tiempo de l funinc @CA @A isri un funin itertiv que lule l funin de ekermnF gul es l omplejidd de tiempo de l funinc @CA SPF en A y B dos lists enlzds ordendsF gonsidere l mezl ordend de A y BD uyo resultdo es un list fusiond y ordend de los nodos de A y BF isri un lgoritmo que mezle dos listsX @A implemente enlzds @A holemente enlzds SQF smplemente un iliote que efete tods ls veri(iones de tipo en tiempo de ejeuin tl omo fue plntedo en ejeriio PT @CCAF SRF smplnte el onstrutor opi y el operdor de signin pr l lse DynArray<T> de(nid en PFIFR @gF QRA @CAF SSF ispei(queD disee e implnte totlmente el eh DynMatrix<T> meniondo en el prolem PQF STF hisee e implnte un eh que mneje rreglos de its y que utilie el eh DynArray<T>F SUF hisee e implnte un eh que mneje mtries de itsF SVF smplnte un eh llmdo DynArrayStack<T>D el ul mnej pils implntds on rreglos dinmiosF il rreglo dee ser ontrdo dinmimenteF SWF smplnte un eh llmdo DynArrayQueue<T>D el ul mnej ols implntds on rreglos dinmiosF il rreglo dee ser ontrdo dinmimenteF THF smplnte l sustrin de polinomiosF TIF smplnte l divisin de polinomios @CCAF TPF smplnte l operin residuo produto de l divisin de dos polinomios @CCAF TQF wodi(que el eh Polinomio pr que hg los trminos visiles l usurio y permit ederlos e(zmente medinte un iterdorF

2.9. Ejercicios

141

TRF smplnte un funin que lule l derivd de un polinomioF TSF smplnte un funin que lule l integrl de un polinomioF TTF wodi(que el eh polinomio pr que utilie oe(ientes en punto )otnteF TUF smplnte un funin que evle un polinomioF TVF isri un lgoritmo de un sol psd que enuentre el menor elemento de un list enlzdF TWF hd un list irulr dolemente enlzdD esri un lgoritmo que oloque los nodos que estn en posiiones impres despus de los que estn en posiiones presF e dee preservr el orden reltivo entre los nodosF UHF gonsidere l eliminin de los elementos repetidos de un listF hisee un lgoritmo que (ltre los elementos repetidos de un listF elie pr los siguientes sosX @A v list es simplemente enlzdF @A v list es dolemente enlzdF in mos sosD el resultdo dee omponerse de dos listsF n orrespondiente l (ltrdoY l otr orrespondiente los elementos suprimidosF UIF upong dos lists simplemente enlzds A y B y ls operiones de unin e interseE inF isri lgoritmos que lulen l unin e intersein siX @A vs lists estn ordendsF @A vs lists no estn ordendsF enlie el desempeo de d uno de los lgoritmosF UPF upong dos lists enlzds A y BF gonsidere l operin de fusin uyo resultdo ser un sol list uyos primeros elementos orresponden l list A seguid por los elementos de l list BF isri un lgoritmo de fusin pr d uno de los siguientes sosX @A vists simples no irulresF @A vists simples irulresF @A vists doles no irulresF @dA vists doles irulresF UQF gonsidere el prolem de invertir los elementos de un list en un sol psdD sin usr un estrutur de dto diionl y sin opir los ontenidos de los nodosF isri lgoritmos prX @A n list simplemente enlzdF @A n list simplemente enlzd irulrF @A n list dolemente enlzdF ropong l menos dos lgoritmosF

142

2. Secuencias

@dA n list dolemente enlzd irulrF ropong l menos dos lgoritmosF URF upong l situin siguienteX
0 1 2 3 4 5 6 7 8 9

@A ixplique un lgoritmo que determine si l list en uestin tiene o no un ilo yD si existe un iloD ul es el nodo de omienzo y ul es su longitudF hisut el desempeo de su mtodoF @A esum que es imposile mntener lgun estrutur de dto o esriir sore los nodosF lo es posile lguns elds de memoriF iF wenione lgn esenrio rel donde ests restriiones se plirnF iiF gon ls restriiones ddsD explique un mtodo que oupe espio onstnte y que determine si existe un iloD en ul nodo y de unt longitudF iiiF gul es el desempeo del mtodo nteriorc USF smgine l siguiente situinX
x

il prolem onsiste en determinr ul es el nodo de interseinD untos nodos preeden x en d listD y untos nodos sueden xF @A uponiendo que se puede mrr ulquier nodoD disee un lgoritmo que no onteng ilos niddosF @A e prtir de hor sum que no se puede mrr lgn nodoF hisee un lgoE ritmo ndido sdo en dos ilos niddosF il lgoritmo puede oupr espio proporionl l nmero de nodosF @A hisee un lgoritmo sdo en dos ilos niddos que oupe espio onstnteF @dA hisee un lgoritmo sdo en ilos simplesD no niddosD que oupe espio onstnteF UTF gonsidere l operin de prtiin de un list en dos lists de igul tmoF v primer list orresponde los n/2 primeros elementos y l segund los n/2 elementos restntesF isri lgoritmos sdos en ilos simples pr prtiionrX @A n list simplemente enlzdF @A n list simplemente enlzd irulrF @A n list dolemente enlzdF @dA n list dolemente enlzd irulrF UUF isri un proedimiento generlD sdo en ilos simplesD que efete un mE prtiinF is deirD despus de l operinD l list es prtid en m lists de tmo n/mF

2.9. Ejercicios

143

UVF isri un progrm que muev el menor elemento de un list l primer posiinF UWF isri un progrm que muev el myor elemento de un list l ltim posiinF VHF gon se en los dos ejeriios previosD esri un progrm que ordene un list doleE mente enlzdF VIF hisee e implnte un eh que modelie un pil implntd on rreglos dinmiosF hisut tods ls opionesD ventjs y desventjs de su diseoF VPF hisee e implnte un eh que modelie un ol implntd on rreglos dinmiosF hisut tods ls opionesD ventjs y desventjs de su diseoF VQF gonsidere un list irulr de form tl que l list pued reorrerse e(zmente en ms direionesF @A gonsidere un funin f(p1 , p2 ) = p3 tl que f(p1 , p3 ) = p2 , f(p2 , p3 ) = p1 , pi , pj , pk N , pi = pj = pk F hdo un nodo on un solo mpo pr un direin de memoriD explique un mtodo que utilie un funin omo l nterior pr reorrer l list en los dos sentidos n undo un nodo ontiene un solo puntdor @CCAF @A inuentre operiones que puedn usrse pr implntr l funin f de l preE gunt nterior @CAF @A gon se en ls respuests nterioresD disee e implnte un eh que modelie un list irulr reorrile en mos sentidos y que use un solo puntdor por nodo @CCAF VRF smplnte los mtodos pushn()D popn() y empty() de(nidos en ArrayStack<T>D pr l lse ListStack<T>F or qu no hn sido implntdos diretmente dentro de l lsec VSF ixplique omo implntr un pil medinte dos olsF VTF ixplique omo implntr un ol medinte dos pilsF VUF r onvertir un nmero en se IH se divide suesivmente entre dos hst que el oiente deveng en ero y en d divisin se lmen el restoD el ul es un dgito del equivlente en se inriF or ejemploD 3710 puede lulrse en inrio omoX

37 18

mod 2 = 1 mod 2 = 0

9 mod 2 = 1 4 mod 2 = 0 2 mod 2 = 0 1 mod 2 = 1


he este modoD 3710 = 1001012 F smplnteD usando una pilaD l rutinX

144

2. Secuencias

void imprime2(const int & n);

v ul imprime el equivlente inrio del prmetro nF VVF isri un progrm que evle un expresin pre(jF VWF isri un progrm que evle un expresin su(jF WHF ixpnd el evludor de expresiones in(js pr que efetu operiones de exponenE iinD trigonometr y logritmosF WIF wodi(que el evludor de expresiones in(js pr queD en lugr de evlur l expresinD genere l expresin su(jF snluy ls operiones de exponeniinD trigonometr y logritmosF WPF wodi(que el evludor de expresiones in(js pr queD en lugr de evlur l expresinD genere l expresin pre(jF snluy ls operiones de exponeniinD trigonometr y logritmosF WQF hisee e implnte un eh que modelie diols implntds on rreglosF WRF hisee e implnte un eh que modelie diols implntds on listsF WSF hisut ls lterntivs de diseo de un eh que modelie mtries esprids repreE sentds on multilistsF ixplique mo se relizrn ls operiones de sumD restD multipliin e inversinF WTF glule los ostes en espio de un mtriz representd medinte multilistsF roporE ione un expresin nlti en funin de l dimensin de l mtriz y del porentje de elementos nulosF WUF hisee e implnte un eh que modelie mtries esprids representds on multiE listsF smplnte ls operiones de sumD restD multipliin e inversin @CCAF

Crtica de algoritmos
in este ptulo estudiremos lguns tnis de nlisis y veri(in de orretitud uyo (n es ritir lgoritmosF gritir proviene del griego @ritiosAD que sigE ni( el que ritiD el ulD su vezD deriv del vero griego @rinoA y onnot seprrD disernirD distinguirD rir1 F gritir onsisteD puesD en seprrD seleionr l os de inters efetos de estudirlF eroD pr qu l estudimosc nto desde ls perspetivs del ornte omo desde ls de los ene(irios de l orD l rti se he on pretensin de mejorr el ienF ry dos mners de ver un rtiF n se onentr en lo interno 2 y te l proeso de hehur de l orF iste tipo de rti es ms propio entre los orntes @prtintesA que entre los ene(irios que reien @usnA l orF e l otr fet de l rti se le denomin extern y te l preiin soil de l orD es deirD mo el entorno o soiedd prei o desprei el ien de l orF v rti extern es fundmentl y primri respeto l internD pues st te l destino de l orF v rti extern se onentr en el qu es l orD lo que st represent soilmente omo ienD mientrs que l rti intern se onentr en el mo se llev o l orF v ieni modern suele usr el trmino nlisis pr referir un estilo tnio de estudio interno en l ul l os de estudio se divide en prtes pr estudirls por seprdoF enlisis proviene del griego @nlisisA y en ltim instni del vero D el ul tmin signi( soltr @ AD distintivmenteD por prtesD y seprr @ AD lo ul orresponde on su primer epin en el hFFeFiFX distinguir y seprr ls prtes de un todo F heemos lrr vehementemente que ritir es muho ms que nlizr yD pr prehender elloD quiz lo mejor se mirr el ntnimo de nlisisD ul es sntesis D proveniente del griego @sntesisA queD hFFeFiF dixitD signi( omposiin de un todo por l reunin de sus prtes F gomo deemos preir en este ontextoD omponer progrmsD o seD sintetizrlosD tiene ms sentido pr nosotros que desomponerlosD es deirD que nlizrlosF urge entones l siguiente preguntD que dejremos iertX undo progrmmosD nlizmos o sintetizmos o mosc lntedo de otro modoX remos progrms prtir de un todo que luego desomponemos o prtir de prtes que despus omponemosD ms oss o ningunc vs rtis suelen ser lsi(ds en onstrutiv o destrutivF roy se og
1 2
Una criba es una especie de colador con que antiguamente se limpiaba el trigo del polvo y otras Segn [113]. impurezas. Quiz por esta acepcin sea ms aceptable decir que criticar no signica dividir.

IRS

146

3. Crtica de algoritmos

por que l rti se onstrutiv y no destrutivF or qu estos djetivoscD qu se onstruye o destruyec ws en prtiulrD por qu un rti podr ser destrutivc is orreto deir que un or se onstruyeD sentido por el ul un rtiD sore todoD undo st revel erroresD uys suniones y enmiends mejorn l orD puede onE siderrse onstrutivF eunque hemos diho queD etimolgimenteD el ritir onllev romperD no deemos eptr que un rti destruy literlmente un orY todo lo ontrrioD unto ms gud y preis se un rtiD ms onstrutiv esD pues st permite mejorr l orF vo nterior es orreto inlusive si un rti revel que no tiene sentido onstruir l orD puesD l (n y l oD ste es un onoimiento prtioF gmo es entones que un rti puede li(rse de destrutivc yurre que l rzn de l rti de est po se entr en el individuoD o seD en l personlidd del ornteD quien es el ritidoD y del ritinteD en lugr de onentrrse sore l or omo un todoF in este mroD undo el ornte de est po esuh un rtiD es muy posile que en lugr de onsiderrl hi el sentido de l orD qu es ell y mo se llev oD se onfund on quin es el ornte y mo es l omo utorF or l misms rzonesD menudoD el ritinte inurre en el mismo yerroX onentr su rti @si so hor se le puede llmr sA en l personlidd del ornteD es deirD en el utorD en detrimento del sentido de l or y su instrumentinF in el mro hedonistD l rti es onstrutiv si se logr interpretr omo elogioD mientrs que es destrutiv undo se entiende omo reproheF il prolem es que l onfundir el qu se he on el quin heD oD el mo se he on el mo es quien lo heD se pierde el vlor esenil de l rtiD ul no es otro que mejorrD perseguir l exeleni yD en ltim instniD el ien en el ul trsiende l orF eoremos el ojeto de estudio de este ptulo desde dos perspetivsX l e(i y l e(ieniF v e(i onierne que se logre el efetoD es deirD que el lgoritmo lne el (n de resolver el prolem pr el ul fue destindoF isto es l orretitudF v e(ieni te qu tn ien un lgoritmo o progrm lnz su soluinD lo ul impli deir que pr poder hlr de e(ieniD previmente dee herse sido e(zF odemos deir entones que l e(ieni te mo se puede ser mejor e(zF i un progrm no es orretoD entones posilemente no teng sentido hlr de e(ieniF or eso l orretitud prim l e(ieniD pues de nd vle l ltim si no se lnz el efetoD es deirD si no se resuelve el prolemF r estudir l e(ieni se hen nlisisF in este sentido en pregunts omoX unto dur el progrmcD untos reursos omputionles onsumec il sentido rtio sore est lse de pregunts determinr l ftiilidd de un progrm y ls irunstnE is en que ste pued o de usrseF hurnte un nlisisD es muy posile que se revelen otrs forms o vrintes pr elE orr el lgoritmo o progrmD lguns de ells lo mejorrnD otrs lo empeorrn y otrs develrn lgoritmos muy distintosF or didurD el entrenmiento en el nlisis de lgoritmos requiere su ompresin lF gonseuentementeD nlizr lgoritmos es un de ls mejores mners de gnr onoimiento sore su diseoF gundo se tiene lro el prolemD un nlisis puede indiir spetos de orretitudF emos un ejemplo extremoX un durin nulD que no tiene sentido onretoD podr indiir no slo un error en el nlisisD sino en el lgoritmo mismoF in lo que sigueD entonesD ordremos dos tems priniplesX el nlisis de lgoritmos

3.1. Anlisis de algoritmos

147

y su orretitudF emos ten l rti internD l ul @no deemos olvidrloAD no tiene sentido sin un perspetiv de rti externF

3.1 Anlisis de algoritmos


sntuitivmente hy dos mtris fundmentles y elementlesD ls ulesD en teorD perE miten unti(r l lidd de un lgoritmoX IF v durin de l ejeuinD omnmente llmd tiempo de ejeuinD l ul onsiste en medir el tiempo desde que se inii el progrm hst que se ulminF in este sentidoD unto menos dure un progrmD mejor es steF PF v ntidd de onsumo de otros reursos3 Y en prtiulrD l memoriF wedimos los ytes de memori y de otros reursos que oup un progrm durnte su ejeuinF intre dos progrms omprrD el que onsum menos reursos es el mejorF nto l durin omo el onsumo de reursos dependen de l on(gurin de l enE trdF no de los ftores ms importntes de est on(gurinD pero no el nioD es el tmo de l entrdD pues unto myor es stD posilemente myor es l ntidd de dtos proesr y myores duriones y ntiddes de reursos hy que gstrF in este orden de idesD en lo que sigue nos referiremos T (n) omo un funin que desrie el omportmiento de un lgoritmoD segn su durin o su onsumo de reursosD l tmo de l entrd nF

Td1 (n)

Td2 (n)

0 n1 n2 n

pigur QFIX n ejemplo de Td il tmo n es un prte de l on(gurinD l ulD en sD onsiste en el orden o permutin en que le pree l entrd l progrmF uesto que onoer tods ls permutiones posiles de un entrd es muy lorioso @y sujetivoAD en el nlisis de un lgoritmo se suelen empler lgunos estdstiosD de los ulesD los priniples son el promedio o esprnz y el mximoF vs oserviones nteriores suponen que el tmo de l entrd puede expresrse en funin de un sol vrileD lo ul no siempre es el soF in lguns irunstnisD
3

otros porque el tiempo de ejecucin puede tambin considerarse como un recurso.

148

3. Crtica de algoritmos

el tmoD u otr unti(in er de l entrdD se de(nen medinte un funin multivrileF istos sos sonD por supuestoD ms omplejos que el univrileF hdos dos lgoritmos A1 y A2 D que resuelven el mismo prolemD ul de los dos es mejorc yjetiv e idnemente hlndoD podemos lulr prioriD o seD sin ejeutr los lgoritmosD ls funiones de durin Td1 (n) y Td2 (n) y ls funiones de onsumo de espio Te1 (n) y Te2 (n)F i tuvisemos ests funionesD entones tendrmos riterios stnte ojetivos y preisos pr deidirF or ejemploD si Td exhiiese ls forms mxims de l (gur QFID entones srmos que pr entrds myores n2 Td2 (n) es mejor que Td1 (n)D pues est ltim es l que tiene myor durinF il nlisis nterior slo es posile si se pueden onoer priori ls forms de Td1 (n) y Td2 (n)F vmentlementeD sumir tl posiilidd no es nd relistD pues pr el so generl es extremdmente difil lulr priori Td (n)F r prehender el porqu de est di(ultd es neesrio omprender que lulr Td (n) requiere ontr l ntidd de instruiones que ejeutr l seueni (nit denomind lgoritmoF efortundmenteD no es onveniente onoer on preisin Td (n)D puesD l postreD l durin rel depender de ftores sujetivos que modi(rn l form ext de Td (n)F in efetoD Td (n) tendr forms diferentes segn ls irunstnis de ejeuin del lgoE ritmoF intre tles irunstnis e destr ls siguientes rterstisX  Caractersticas materiales del computadorX existen muhs rquiteturs diferenE tes de omputdoresF elguns rquiteturs se prestn mejor pr un lse de proleE ms que otrsF osilementeD un lgoritmo tendr duriones distints en rquiteturs distintsF eun entre rquiteturs homognes existen diferenis dds por l veloidd del relojD ntidd de memoriD sistem opertivo y nmero de proesos que tulmente lergue el omputdorD entre otros ftores que iniden en l durin de un progrmF  Caractersticas de la codicacinX un lgoritmo se instrument en lgn lenguje de progrminF vengujes diferentes que odi(quen el mismo lgoritmo produirn progrms on duriones diferentesF or didurD los progrmdores tmin di(eren en sus estilos de odi(inF n lgoritmo implntdo por dos progrmdores en un mismo lenguje y ejeutdo en un slo omputdorD prolemente exhiir diferenis en el tiempo de ejeuinF  Caractersticas del cdigo generado por el compiladorX los ompildores di(eren en l trduin del digo fuente l ojetoF is stnte prole que dos ompildores diferentes generen trduiones diferentes de un mismo progrm yD por tntoD dihos progrms exhiirn tiempos de ejeuin diferentesF istos ftoresD entre otros msD heterogneos entre sD hen ms rduo Edems de imprtioED onoer no slo l form ext de T (n)D sino expresr el tiempo de ejeuin de un progrm en lgun unidd espe( y preisF heemosD puesD indgr un riterio de nlisis que elud los ftores meniondosF
3.1.1 Unidad o paso de ejecucin

gomo y selmosD nlizr un lgoritmo onsiste en ontr l ntidd de instruiones o psos de ejeuin que ste ejeutF u es un pso de ejeuinc in prinipio podemos

3.1. Anlisis de algoritmos

149

149a

deir que es l mnim instruin que se puede ejeutrF ist noin estlee un grno mnimo que nos permite unti(r l durin de un lgoritmo sin onsiderr el tiempo soluto de ejeuinF u se onsider un mnim instruinc vs onsideriones nteriores re)ejn lo difil que es sentr este umrlF or tl rznD onsiderremos un pso de ejeuin omo ulquier seueni de ejeuin uy durin se onstnteF rnsmos por lo onstnte sin ser ul es l durin relF ropiiemos el entendimiento medinte lgunos ejemplosF v siguiente instruinX ejemplo 1 paso de ejecucin 149a (149e) x = y; se onsider un pso de ejeuinF gd vez que el )ujo pse por est instruinD su ejeuin tendr un durin mxim onstntemente otdF in el mismo sentido ejemplo 2 paso de ejecucin 149b (149e) x = y + z; uy durin es myor que el ejemplo I pso de ejeuin 149a D tmin est onstnE temente otdY por tntoD el ejemplo P pso de ejeuin 149b tmin se onsider un pso de ejeuinF n seueni de instruiones tl omo l siguienteX ejemplo 3 paso de ejecucin 149c (149e) x = h; if (x < y) { x = y + z; a = b*c; } else { x = p + q + r; a = b + c; } puede onsiderrse ms ostos que ejemplo P pso de ejeuin 149b D sin emrgoD independientemente del vlor del predido y de lo lrg que pued ser l ejeuin de ulquier de los loquesD ejemplo Q pso de ejeuin 149c es un pso de ejeuinD pues ste tiene un durin que puede otrse por un onstnteF il loque repetitivo ejemplo 4 paso de ejecucin 149d (149e) for (i = 0; i < 100000; i++) a[i] = b[i] + c[i]; tmin tiene un durin onstnte y se onsiderD onseuentementeD un pso de ejeE uinF pinlmenteD l ejeuin seuenil de todos los loques nteriores ltimo ejemplo paso de ejecucin 149e

149b

149c

149d

149e

ejemplo 1 paso de ejecucin 149a ejemplo 2 paso de ejecucin 149b ejemplo 3 paso de ejecucin 149c ejemplo 4 paso de ejecucin 149d

150

3. Crtica de algoritmos

tmin es un pso de ejeuinD pues su durinD pesr de que omprend l de todos los loques nterioresD tmin es onstnteF e prtir de este momentoD un unidad de ejecucin se dene como una secuencia de instrucciones cuya duracin es constanteF isto onllev erroresD pero reordemos que el tiempo de ejeuin vr segn irunstnis jens l lgoritmoF gulquier que se el tmo y l disposiin de l entrdD un )ujo de ejeuin siempre tendr durin onstnte d vez que pse por lgun instruin seuenilF in el mismo espritu de rzonmientoD ulquier seueni de instruiones on durin onstnte tmin se onsider un unidd de ejeuinF is importnte destr el sri(io que impone nuestro onepto de unidd de ejeuE in l onsiderr omo onstnte lo que de heho esD en l myor de los sosD vrileF il onepto equiprD por ejemploD un seueni de diez instruiones on un de un milln pues en mos sos se onoen ls onstntes diez y un millnD respetivmenteF in emrgoD est lro queD muy prolementeD l ejeuin de l primer seueni dure 105 vees menos que l segundF fjo l onieni del sri(io nteriorD l ventj del onepto es que el rter onstnte no se pierde on lo vrile de l entrdF in plrs ms simplesD seuenis de ejeuin uys longitudes sen distints pero onsE tntesD siempre tendrn duriones onstntes no fetds por el tmo de l entrdF isto ltimo es lo preile del oneptoF
3.1.2 Aclaratoria sobre los mtodos de ordenamiento

in este ptulo nos serviremos de lgunos mtodos de ordenmiento pr ilustrr el nlisis de lgoritmosD pues stos plnten nturlmente el tmo de l entrd on se en l ntidd de elementos ordenrF or didurD l permutin de l seueni de entrd inide en el desempeo de l myor de los mtodos de ordenmientoF or est rznD undo se nliz un mtodo de ordenmiento hy que onsiderrD por lo generl on riterios estdstiosD l form de l permutinF eprte de fungir omo un uen vehulo de ensenz pr el nlisis y diseo de lgoritmosD los mtodos de ordenmiento son prte de los onoimientos eseniles de todo uen progrmdorF in efetoD el ordenmiento se us en un mpli gm de prolems ms omplejosF or ejemploD en grfosD mito que estudiremos en el ptulo UD vees se requieren ordenr reliones omo preproesmiento lgunos lgoritmosF ytro ejemplo notle se enuentr en el srn onvexoD prolem de l geometr omputionl que onsiste en enontrr un polgono que envuelv un onjunto de puntosF n lgoritmo simple y e(iente pr este prolem requiere ordenr los puntos segn sus oordendsF vos mtodos de ordenmientoD s omo otros utilitrios reliondosD residen en el rhivo tpl_sort_utils.HF
3.1.3 Ordenamiento por seleccin

rgmos nuestro primer nlisis trvs de l noin de pso de ejeuinF e tl (nD onE sideremos el mtodo de ordenmiento de seleinD el ul puede plsmrse pitrimente omo sigueX

3.1. Anlisis de algoritmos

151

swap[a[i], a[j])

Orden absoluto i

Desorden j desde i hasta n 1 para encontrar el menor elemento j

151a

in est lse de digrmD el retngulo prinipl represent el rregloF vos suE retngulos internos representn pedzos del rreglo que oniernen su estdo de orE denmientoF vs )ehsD junto on lgn nomre de vrileD indin un ontdor o iterdor junto on su sentido de iterinF xuestr implntin del ordenmiento por selein se estrutur del siguiente modoX uy implntin esX Mtodos de ordenamiento 151a 151c template <typename T, class Compare = Aleph::less<T> > inline void selection_sort(T * a, const size_t & n) { for (int i = 0, min, j; i < n - 1; ++i) {
if (Compare () (a[min], a[i])) std::swap(a[min], a[i]);

Sea min el ndice menor entre i + 1 y n - 1 151b

}
151b

v squed del menor elemento se he seuenilmente de l siguiente mnerX Sea min el ndice menor entre i + 1 y n - 1 151b (151a) for (min = i, j = i + 1; j < n; ++j) if (Compare () (a[j], a[min])) min = j; il myor oste del if inluido en el loque e min el ndie menor entre i C I y n E I 151b es que el predido se iertoF i este fuese el soD l durin del if n permnee onstntemente otdF gonluimosD puesD que el loque dentro del for tom un unidd de ejeuinF or lo tntoD el loque e min el ndie menor entre i C I y n E I 151b ejeut n i 1 psos de ejeuinD el ul puede proximrseD on un ligero errorD n iF he este modoD el mtodo tomX
n2 n1 n1

T (n) =
i=0

ni=
i=1

n
i=1

i = (n 1)n

n(n 1) n(n 1) = sos de ejeuin 2 2

@QFIA

151c

isto nos revel que independientemente de que tengmos un omputdor muy rpido o muy lentoD y dems idiosinrsis presentds en QFIFID el tiempo de ejeuin ree udrtimente segn el nmero de elementos que estemos ordenndoF uede enonE trrse lgn mtodo ojetivo que rterie el tiempo de ejeuin sin onsiderr los spetos reltivosc v respuest es (rmtiv y l ordremos en l siguiente suEseinF ixtmente el mismo lgoritmo puede instrumentrse pr ordenr lists dolemente enlzds uyo nodo eer se de tipo DlinkF ero pr eso es onveniente instrumentr un rutin que usque el menor elemento de un list enlzdX Mtodos de ordenamiento 151a + 151a 152 template <class Compare> inline Dlink * search_min(Dlink & list) { typename Dlink::Iterator it(list);

152

3. Crtica de algoritmos

Dlink * min = it.get_current(); for (it.next(); it.has_current(); it.next()) { Dlink * curr = it.get_current(); if (Compare () (curr, min)) min = curr; } return min;

Denes:

search_min,

used in chunks 152 and 156b.

is extremdmente importnte notr que el mtodo de ordenmiento reie el tipo DlinkD desde el ul no se puede onoer genrimente el tipo dto que permite her ls ompriones que onduirn l ordenmientoF tustmenteD este es el (n de l lse CompareD l ul dee implntr el operdor bool Compare::operator () (Dlink *, Dlink *) y que se enrg de omprr dos nodos puntdos por vriles Dlink*F odrmos implntr el ordenmiento de lists prtir del tipo Dnode<T>D desde ul y onoermos un tipo de seF ero est deisin exluir el ordenmiento de lists sds en otros usos de DlinkY por ejemploD supongmos l siguiente estrutur de nodoX
struct Nodo { Dlink enlace_lista_1; Dlink enlace_lista_2; Dlink enlace_lista_3; D1 d1; D2 d2; D3 d3; };

ist lse de nodo no podr ordenrse por un rutin genri de ordenmiento sd en un Dnode<T>D pues el tipo ejemplo Nodo no es un Dnode<T>F or didurD Nodo tiene tres enles que se endenn lists diferentesF gmo ordenmos genrimente segn ulquier de ls tres listsc v respuest onsiste en delegr l omprin bool Compare::operator () (Dlink *, Dlink *)F or ejemploD si desemos ordenr l list 1 segn el triuto d1D podemos herlo omo sigueX
struct Comparar_D1 { bool operator () (Dlink * l1, Dlink* l2) { Nodo * n1 = Dlink::dlink_to_Node(l1); Nodo * n2 = Dlink::dlink_to_Node(l2); return n1->d1 < n2->d1; } }

152

enlogmenteD podemos relizr ompriones pr los tipos D2 y D3 y s ordenr por los enles enlace_lista_2 y enlace_lista_3F gon lo nterior en menteD el ordenmiento por selein se expli por s mismoX Mtodos de ordenamiento 151a + 151c 153a template <class Compare> inline void selection_sort(Dlink & list)

3.1. Anlisis de algoritmos

153

}
Uses

Dlink aux; while (not list.is_empty()) { Dlink * min = search_min <Compare> (list); // menor de list min->del(); // saque menor de list aux.append(min); // insrtelo ordenado en aux; } list.swap(&aux);
search_min
151c.

ist versin expres mejor el prinipio del mtodoX usr el menor elemento e insertrlo en un listF v list resultnte estr ordendF il mtodo es el mismo que plimos undo ordenmos rjsF il usrX
bool Compare::operator () (Dlink *, Dlink *)

omo riterio generl de omprin pretende servir pr tods ls irunstnis de ordenmiento de lists enlzdsF in emrgoD en l myor de ls irunstnisD se trtr de ordenr un list de Dnode<T>D en l ul s se onoe el tipoF r endulzr el sunto diseremos l versin genriX
bool Compare::operator () (Dnode<T> *, Dnode<T> *)

153a

l ul ser el riterio de omprin por omisinX Mtodos de ordenamiento 151a + template <typename T, class Compare> class Compare_Dnode { bool operator () (Dlink * l1, Dlink * l2) const { Dnode<T> * n1 = static_cast<Dnode<T>*>(l1); Dnode<T> * n2 = static_cast<Dnode<T>*>(l2); return Compare () (n1->get_data(), n2->get_data()); } };
Denes: Uses

152 153b

Compare_Dnode, Dnode 83a.

used in chunks 153b and 165a.

153b

he este modo podemos exportr un espeilizin de selection_sort() que onsider un riterio de omprin de los ontenidos de los nodosX Mtodos de ordenamiento 151a + 153a 154a template <typename T, class Compare = Aleph::less<T> > inline void selection_sort(Dnode<T> & list) { selection_sort < Compare_Dnode<T, Compare> > (list); }
Uses

Compare_Dnode

153a and

Dnode

83a.

154

3. Crtica de algoritmos

3.1.4

Bsqueda secuencial

154a

entes de psr estudir un orpus ojetivo pr nlizr lgoritmosD presentemos uno de los spetos que menudo omplin el nlisis o selein de un lgoritmosX el zrF r eso nos vldremos de uno los lgoritmos ms simplesD populres y tilesX l squed seuenilF gomenemos por un rregloD uy squed puede plsmrseD sin neesidd de expliin previD de l siguiente mnerX Mtodos de ordenamiento 151a + 153b 154b template <typename T, class Equal = Aleph::equal_to<T> > inline int sequential_search(T * a, const T & x, const int & l, const int & r) { for (int i = l; i <= r; i++) if (Equal () (a[i], x)) return i; return Not_Found; }
Denes:

sequential_search,

used in chunks 15b, 31b, 154, and 155.

154b

sequential_search() us seuenilmente en el rreglo aD entre los ndies l y rD el elemento xF i l squed es exitosD entones se retorn el ndie ontentivo del elementoY de lo ontrrioD se retorn Not_FoundF sequential_search() emple omo riterio de iguldd el operdor () de l lse prmetrizd EqualF guntos psos de ejeuin onsume este lgoritmoc v sutilez de su nlisis es que l durin de ejeuin depende de dos ftoresX @IA l permutin del rreglo aD y @PA del vlor de squed xF emoslo desde l perspetiv del vlor de xF i x no est ontenido en el rregloD entonesD independientemente de l permutinD el for se ejeutr ompletmenteD rzn por l ul el lgoritmo onsume r l = n psos de ejeuinF he lo ontrrioD entonesD l durin depender de l permutinY espe(menteD de l posiin en donde se enuentre x dentro del rregloF i se enuentr en l primer posiinD entones l durin es un pso de ejeuinF i se se enuentr en l ltim entones son n 1F gul esogerc xo lo semosD pero s podemos tener un expettiv de lo que v sueder y st l expres el onepto de espernz estdstiF i l permutin es letoriD entones l espernz ser por el entroF v durin r esperd ser l+ 2 F gulminemos est sein on ls versiones genris de l squed sore listsX Mtodos de ordenamiento 151a + 154a 155a
template <typename T, class Equal = Aleph::equal_to<T> > inline Dnode<T> * sequential_search(Dnode<T> & list, const T & x) { for (typename Dnode<T>::Iterator it(list); it.has_current(); it.next()) { Dnode<T> * curr = it.get_current(); if (Equal () (curr->get_data(), x)) return curr; } return NULL; }
Dnode
83a and

Uses

sequential_search

154a.

3.1. Anlisis de algoritmos

155

155a

is fil dptr ests squeds l eh DynDlist<T>Y Mtodos de ordenamiento 151a + 154b 156a template <typename T, class Equal = Aleph::equal_to<T> > inline T * sequential_search(DynDlist<T> & list, const T & x) { Dnode<T> * ret = sequential_search<T, Equal>((Dnode<T>&) list, x); return ret != NULL ? &ret->get_data() : NULL; }
Uses

Dnode

83a,

DynDlist

85a, and

sequential_search

154a.

3.1.5

El problema fundamental y los arreglos dinmicos

155b

uiz l mner ms simple y verstil de instrumentr el prolem fundmentl de(nido en IFQ @gF IUA se herlo medinte el tipo DynArray<T>F in este soD trnsmos por un rreglo desordendo que puede reer y dereer dinmimenteF v ventj del desorden es que no requerimos rir y errr rehs nte inseriones y eliminionesF v desventj es que l squed dee ser seuenilX tpl_dynarray_set.H 155b template <typename T, class Equal = Aleph::equal_to<T> > class DynArray_Set : public DynArray<T> { T & insert(const T & item) { (*this)[this->size()] = item; return this->access(this->size() - 1); } T * search(const T & item) { int i = Aleph::sequential_search<T, Equal>(*this, item, 0, this->size() - 1); return (i >= 0 and i < this->size()) ? &this->access(i) : NULL; } void remove(T & item) { item = access(this->size() - 1); this->cut(this->size() - 1); } };
Uses

DynArray

34 and

sequential_search

154a.

v rutin sequential_search() llev oD omo homnimmente se in(ereD un squed seuenil sore el rreglo dinmio4 F glrmenteD l inserin es summente rpidD pues equivle un pso de ejeuinF v squed depende l suerteD pero en el peor de los sosD undo se trte de un fllidD tomr n psos de ejeuin @n es l ntidd de elementosAF pinlmenteD l eliminin tom un pso de ejeuinD pero se requiere onoer un refereni l elemento que desemos eliminrD lo ul menudo exige un squed exitos que est otd por n psos de ejeuinF
4
Vase 3.1.4 (Pg. 154) para ms detalles.

156

3. Crtica de algoritmos

3.1.6

Bsqueda de extremos

156a

n so espeil de l squed es l determinin de un vlor extremo de un seueniY es deirD el vlor mnimo o mximoF e trvs de l lse de omprin genriD esto puede resolverseD pr rreglosD del siguiente modoX Mtodos de ordenamiento 151a + 155a 156b template <typename T, class Compare = Aleph::less<T> > inline int search_extreme(T * a, const int & l, const int & r) { T extreme_index = l; for (int i = l + 1; i <= r; i++) if (Compare () (a[i], a[extreme_index])) // se ve un nuevo menor? extreme_index = i; // s return extreme_index; }

156b

search_extreme() us el elemento extremo segn el riterio de omprin CompareF in emrgoD on est sintxis no qued semntimente lro que se trt de usr el mnimo o el mximoF r lrr el sunto usremos dos distints funionesX Mtodos de ordenamiento 151a + 156a 156c
template <typename T, class Compare = Aleph::less<T> > inline int search_min(T * a, const int & l, const int & r) { return search_extreme<T, Compare> (a, l, r); } template <typename T, class Compare = Aleph::greater<T> > inline int search_max(T * a, const int & l, const int & r) { return search_extreme<T, Compare> (a, l, r); }
search_min
151c.

Uses

156c

gul es l difereni on l squed prtiulr que estudimos en l susein preeE dentec v estrutur es prtimente l mismX un lzo de r l = n psosY l difereni rdi en l deteninF r un permutin letoriD l squed exitos es proporE ionl n en promedioD mientrs que l squed de un extremo requiere siempre exmiE nr l totlidd de l seueniF gonseuentementeD l durin de search_extreme() es proporionl n pr todos los sosF r ompletr est susein deemos progrmr search_extreme() pr ls lists sds en DlinkD lo que se plnte del siguiente modoX Mtodos de ordenamiento 151a + 156b 163a template <class Compare> inline Dlink * search_extreme(Dlink * list) { typename Dlink::Iterator it(*list); Dlink * curr_min = it.get_current(); for (it.next(); it.has_current(); it.next()) { Dlink * curr = it.get_current(); if (Compare () (curr, curr_min)) curr_min = curr; }

3.1. Anlisis de algoritmos

157

return curr_min;

ist funin se espeiliz pr el resto de ls lses de l jerrqu derivd desde DlinkF


3.1.7 Notacin

v noin de pso de ejeuin nos permiti enontrr un proximin de Td (n) pr el ordenmiento por seleinF eullD en l oquedd de ls inmensiddes de Td (n)D podemos enontrr un ptrn de onstni er de lo que D en l ejeuin onret de un lgoritmoD se mide omo vrileF in el horizonte de quell lejn tiene sentido l siguiente de(niinF
Denicin 3.1 (Notacin

O) en dos funiones T (n) y F(n)F intones se die que T (n) es O(f(n))D denotdo omo T (n) = O(f(n))D si y slo si c, n1 | T (n) cn2 , n n1 F

gundo deimos que T (n) = O(f(n)) estmos proximndo el omportmiento de T (n) un funin diferente yD pr que teng sentido prtioD ms senillF e(rmemosD por ejemploD que T (n) = n2 + n + 1 = O(n2 )F i esto es orretoD entones c, n1 | T (n) cn2 F eleionemos c = 1 e intentemos demostrr l (rminF r pror que n2 + n + 1 = O(n2 ) plntemos l ineuin n2 + n + 1 cn2 , n n1 = (1 c)n2 + n + 1 0F vo que rroj omo res

n=

1 4(1 c) . 2(1 c)

i seleionmos c = 7/4 tenemos omo res n0 = 2/3, n1 = 2F es puesD c = 7/4, n1 = 2 on(rmn que n2 + n + 1 = O(n2 )F hemostrr que T (n) = O(f(n)) pr lgun funin f(n) no impli que no existn otrs funiones que stisfgn l de(niinF he hehoD es posile deir que hy mejores funiones que otrsF or ejemploD son demostrles ls siguientes (rmionesX
n i=1 n i=1 n i=1

i2 = O(n4 ) i2 = O(n3 ) i2 = O(n2 )

@QFPA @QFQA @QFRA

pero l ltim (rmin es l ms preis de ls tresF uesto que hy dos ingnits @c, n1 A y un sol desigulddD demostrr T (n) = O(f(n)) puede ser difil en lgunos sos mtemtiosD peroD por lo generl en el nlisis de lgoritmosD l demostrin es senillF in lgunos sos puede ser til pre(jr un vlor de l onstnte c y resolverX
n

lim T (n) c f(n) 0

@QFSA

v (rmin T (n) = O(f(n)) slo tiene un direin respeto l igulddF xo es orreto deir O(f(n)) = T (n)D pues no re)ej l desiguldd de l de(niinF

158

3. Crtica de algoritmos

vo idneo undo se (rme que T (n) = O(f(n))D es que f(n) ote sinttimente l funin T (n)F e nivel sinttioD l mejor proximin es que l sntot de f(n) se prlel l de T (n)F ry sos en que se puede demostrr que f(n) no es sinttimente prlel T (n) y esto se expres medinte l siguiente de(niinF
Denicin 3.2 (Notacin

o) en dos funiones T (n) y F(n)F intones se die que T (n) es o(f(n))D denotdo omo T (n) = o(f(n))D si y slo si c, n1 | T (n) < cf(n) , n n1 F
cT (n)

g (n) f (n)

T (n)

n1

n2

Asntotas

pigur QFPX ijemplo generl de funiones que se otn sinttimente v ide de estudir un lgoritmo medinte operiones O es otener l proximin sintti ms ern l tiempo de ejeuinF odemos trjr on un proximin y no on un resultdo exto porque lo que nos onierne es l tendeni de T (n) en el lgoritmo en sD sin onsiderr los detlles sujetivos irunstniles pertinentes l tipo de hrdwreD ompildor y otros ftores previmente meniondosF odemosD puesD sumir que l onstnte c stre ls diferenis irunstniles de ejeuinF vs diferenis de desempeo dds por otros ftores representn diferentes onstntes uyo vlor no nos onierneF in el mismo sentidoD l form ext de T (n) no es relevnteD sino l tendeni sintti prtir de l onstnte n1 F in lgunos sos pueden onvenirnos ls de(niiones pr los equivlentes inferiores de O(f(n)) y o(f(n))Y es deirD sntots que estn por dejo de T (n)F
Denicin 3.3 (Notacin

) en dos funiones T (n) y F(n)F intones se die que T (n) es (f(n))D denotdo omo T (n) = (f(n))D si y slo si c, n1 | T (n) cf(n) , n n1 F
Denicin 3.4 (Notacin

) en dos funiones T (n) y F(n)F intones se die que T (n) es (f(n))D denotdo omo T (n) = (f(n)) si y slo si c, n1 | T (n) > cf(n) , n > n1 F

3.1. Anlisis de algoritmos

159

r indir que l proximin sintti O(f(n)) es prlel T (n) enunimos l siguiente de(niinX

) en dos funiones T (n) y F(n)F intones se die que T (n) es (f(n))D denotdo omo T (n) = (f(n))D si y slo si T (n) = O(f(n)) y T (n) = (f(n))F odemos deir tminD T (n) = (f(n)) T (n) = O(f(n)) y f(n) = O(T (n))F
Denicin 3.5 (Notacin

v (gur QFP pitoriz T (n) y lguns funiones que l otn sinttimenteD por jo y por rriF sdenti(quemos en primer lugr l funin T (n)D l ul desrie hipottimente el tiempo de ejeuin de un lgoritmoF in l (gurD l funin g(n) est por enim de T (n) pr todo n n1 D es deirD T (n) = o(g(n))F v de(niin de o QFP nos permite multiplir T (n) por lgun onstnte c de modo que T (n) se myor que g(n)F ero eso es irrelevnte en l oquedd de lo in(nitoD pues l pendiente de g(n) @vnse sus puntos de orteA es myor que l de T (n)F gonseuentementeD no import unt se l enormidd de l onstnteD en lgun lejnD g(n) siempre sorepsr T (n)F il mismo estilo de rzonmiento puede usrse pr onsttr T (n) = (f(n))F in el horizonte de los grndes nmerosD T (n) sorepsr f(n)F ehor estmos preprdos pr omprender el sentido del onepto de D el ul puede preirse en l (gur QFQF

c1 f (n) T (n)

c2 f (n) Asntotas

n1

pigur QFQX ijemplo generl de urv sinttimente prlel yservemos primero l urv c2 f(n)D uy sntot es prlel l de T (n)F n ierto vlor de onstnte c2 he que T (n) = (f(n))F ehor ienD str on multiplir f(n) por un onstnte c1 > c2 pr que T (n) = O(f(n))F or tntoD T (n) = (f(n))
3.1.7.1 lgebra de

in el mundo de lo in(nitoD lo que he l difereni es l tendeni que lleve l urvF ums y produtos de onstntes son desrtles en el dominio de l notin OF isto posiilit un lger sore l notin O que simpli( onsiderlemente el nlisis de un lgoritmoF r elloD permtsenos enunir ls siguientes regls sisD uys

160

3. Crtica de algoritmos

demostriones se delegn ejeriiosX

O(f(n)) + O(g(n)) = O(max(f(n), g(n))) O(O(f(n))) = O(f(n)) c O(f(n)) = O(f(n))

@QFTA @QFUA @QFVA @QFWA @QFIHA @QFIIA @QFIPA

O(f(n)) O(g(n)) = O(f(n) g(n)) T (n) = n + n


k k 1

O(f(n) g(n)) = f(n) O(g(n)) + + n + c = O (n )


log n = O(n)
k k

in osiones tenemos que omprr funiones on el ojeto de determinr ul es l myorF e efetos del rigorD o si l omprin es difil de estleerD plntemos el rdio o rzn entre ls funiones omo riterio de omprin y onseuente deisinF he este modoX f(n) = o(g(n)) 0 = f(n) lim = = g(n) = o(f(n)) @QFIQA n g(n) c = f(n) = (g(n))
3.1.7.2 Anlisis de algoritmos mediante

gomo y hrto hemos reldoD en progrminD (n de uents todo es seueniF enlizr un lgoritmo requiere entonesD o desenrollr l mxim seueni de ejeuin posileD o desenrollr l seueni de ejeuin proleF r entender el sentido de desenrollrD onsideremos el siguiente uleX
for (int i = 0; i < 3; ++i) printf("Prueba %d\n", i);

hesenrollr este ule equivle esriir l ejeuin omo un seueniX


int i = 0; if (i < 3) printf("Prueba %d\n", i); ++i; if (i < 3) printf("Prueba %d\n", i); ++i; if (i < 3) printf("Prueba %d\n", i); ++i; if (i < 3) ;

xotemos que slo en el ltimo if el predido i < 3 es flsoD por lo que l impresin siempre se ejeut yD en este so prtiulrD el if ompleto se onsider un pso de ejeuin5 F uesto que fue posile desenrollr el ule en 11 instruiones de durin onstnteD el ule en s es de durin onstnteF or lo tntoD el ule onform un pso de ejeuin y su tiempo de durin es O(1)F
5
Esa es la razn por la cual la instruccin dentro del

if

no se coloca indentada.

3.1. Anlisis de algoritmos

161

in el dominio OD el rte de nlizr un lgoritmo onsiste en identi(r seuenis de ejeuin que omporten funiones de durin diferentes y plir regls de onteoY sore todo ls de l sum y del produtoF in el sentido de lo rein explido son pliles ls siguientes regls pr los lsios loques de progrmin proedurlX IF Instrucciones secuenciales: l ejeuin de dos instruiones seueniles on tiempo T1 (n) = O(f1 (n)), T2 (n) = O(f2 (n)) tomn l sum T1 (n) + T2 (n)D l ulD por l regl @QFTA @de l sumAD tom O(max(f1 (n), f2 (n)))F PF Instrucciones de decisin: summos omo so generl l siguiente estruturX

if @ O(f1 (n)) A O(f2 (n)) else O(f3 (n))


in este soD el tiempo de ejeuin estr ddo por O(f1 (n)) + max(O(f2 (n)), O(f3 (n)))F equ estmos onsiderndo lo peorY es deirD l ejeuE in del loque ms ostosoF iventulmenteD segn l distriuin de ertitud del predido del ifD puede onsiderrse l espernzF QF Instrucciones de repeticin: l ejeuin de un repetiin on l siguiente estruE turX

for @ O(f1 (n)) A O(f2 (n))


se rige por l regl del produtoF il tiempo de ejeuin estD puesD determiE ndo por O(f1 (n)) vees l ejeuin del loque interno de oste O(f2 (n))D es deirD O(f1 (n)) O(f2 (n)) = O(f1 (n) f2 (n))F

r nlizr un repetiin nidd deen estudirse sus dependenis on los ilos externosF ixisten diverss formsD ls ules no neesrimente orresponden on l estrutur nteriorF in lnes generlesD el truo pr nlizr un repetiin onsiste en verigur l ntidd de vees que st se efetF or lo generlD el nlisis de un repetiin se he desde el ule ms interno hst el ms externoF v durin de un lgoritmo se remite identi(r sus seuenis de ejeuin y desenrollrls en un solF euenis de longitud (jD es deirD psos de ejeuinD son O(1)F euenis de longitud proporionlmente vrile son O(n)F euenis de seuenis de longitud proporionlmente vrile son O(n2 )F euenis de longitud udrtimente vrile son O(n3 )F iguiendo est seueni de rzonmiento no es difil intuir que el onjunto de posiles funiones desriptors del tiempo de ejeuin de un lgoritmo est irunsrito un peque fmiliD uys urvs se ilustrn en l (gur QFRF in ls suseiones susiguientes estudiremos un lse de lgoritmo denomind diE vidirGominrD l ul divide l entrd en dos prtes proximdmente igulesF hentro de est lse de lgoritmoD quellos que trjn sore slo un de ls prtes dividids

162

3. Crtica de algoritmos

1e+12 1e+10 1e+08 1e+06 10000 100 1 1 O(n) O(n2 ) 100 10000 n O(n3 ) O(2n ) O(lg(n)) O(n lg(n)) 1e+06 1e+08 O ( n) O(1) 1e+10

pigur QFRX gurvs de lg(n),

n, n, n lg(n), n2 , n3 , 2n esls logrtmis

dejndo l otr sin proesr son O(lg(n))D mientrs que quellos que requieren proesr linel y entermente ls dos prtes son O(n lg(n))F ixiste otr lse de prolem uy soluinD por lo generl muy simpleD onsiste en lulr y nlizr tods ls permutiones de seuenis soluin posilesF gundo los elementos no estn repetidosD el nmero de permutiones de un seueni es n!F gundoD por el ontrrioD lo estnD es mn D donde m es l ntidd de elementos y n l longitud de l seueniF ems situiones estn otds sinttimente por l funin f(n) = 2n D l ul no es polinmiF or es rznD lgoritmos uyo tiempo de ejeuin es O(2n ) son denomindos noEpolinomiles oD rnimmenteD xF xo se se si pr los prolems x existen lgoritmos orretos on soluiones polinmisF in todo soD hst que no se demuestre lo ontrrioD los prolems x son intrtles en el sentido de queD un pr un peque eslD no existen reursos omputionles que permitn ejeutr el lgoritmoF or es rznD los prolems x son tilddos de intrtles o herleosF
3.1.8 Ordenamiento por insercin

ongmos en prti l teor de l notin O medinte el diseo y nlisis de desempeo de otro mtodo de ordenmientoD denomindo de inserinD uyo esquem generl se osquej del siguiente modoX
a[j] = tmp tmp = a[i]

j
A[j] >= A[i]

Desorden

Orden relativo i

rimeroD el elemento en l entrd a[i] se gurd en tmpF ri l izquierd del ndie i tenemos orden reltivoD es deirD los elementos estn ordendos ms no neesrimente en su posiin de(nitivF vuegoD el ndie j retroede prtir de i - 1 hst enontrr un elemento menor o igul que tmpY en el nterin de l iterinD d elemento se v opindo hi l dereh de mner tl de ir dejndo un rehF gundo j es de iterrD a[j] tiene un reh donde olomos el vlor de a[i] memorizdo en tmpF

3.1. Anlisis de algoritmos

163

163a

n implntin es omo sigueX Mtodos de ordenamiento 151a + 156c 164a template <typename T, class Compare = Aleph::less<T> > inline void insertion_sort(T * a, const size_t & l, const size_t & r) { for (int i = l, j; i <= r; ++i) { T tmp = a[i]; // memorice a[i], pues ser sobre escrito
} a[j] = tmp; // inserte tmp en la brecha

Abra una brecha a[j] donde insertar tmp 163b

e difereni del mtodo nteriorD l interfz de insertion_sort() tom los ndies izquierdo y dereho entre los ules se dese ordenr el rregloF ist interfz ser til pr ominr este mtodo on otros ms so(stidosF in lo que sigueD sumiremos l = 0 y r = n - 1F
163b

Abra una brecha a[j] donde insertar tmp 163b

(163a)

for (j = i; j > l and Compare() (tmp, a[j - 1]); j) a[j] = a[j - 1]; // desplazar hacia la derecha

il ilo externo efet r l + 1 = n iterionesF or lo tntoD ste es O(n)F r estudir el ilo interno de er un reh j donde insertr tmp 163b requerimos onoer el nmero de vees que ste iterF ist ntidd depende del vlor del predido j > l and Compare() (tmp, a[j - 1])D uyo resultdo depende de l perE mutin de los elementos en el intervlo [l, i 1]F in este sentido deemos onsiderr vris posiiliddesX IF i el intervlo [l, i 1] est ordendoD entones no se efet ningun repetiin y el ilo es O(1)F in este soD el mtodo es O(n) O(1) = O(n)F PF i el intervlo [l, i 1] est ordendmente invertidoD es deirD sus elementos estn ordendos desde el myor hst el menorD entones el ilo iter i l = i veesD lo que nos d O(i)F uesto que i depende de nD podemos deir diretmente que el ilo es O(n)F gonseuentementeD el mtodo es O(n) O(n) = O(n2 )F vs situiones plnteds onsidern dos esenrios de ejeuinX el mejor soD undo el rreglo est ordendoD y el peorD undo el rreglo est ompletmente invertidoF i l disposiin del rreglo es letoriD entonesD d uno de los esenrios tiene un 1 proilidd de ourreni de n ! Y un muy j proilidd undo n es grndeF es puesD en un so o en el otroD el nlisis pe de exgerdmente optimist o pesimistD on el onseuente peligro de ser irrelist l momento de expresr el desempeo del mtodoF r predeir lo que sueder deemos onsiderr el so esperdoF i onsidermos l seueni omo un permutin letoriD entones el vlor del ndie de reh j tiene un proilidd uniforme entre l e i 1F il nmero esperdo de iteriones del ilo er un reh j donde insertr tmp 163b ser l espernz l +1 de un distriuin uniforme disret entre l e i 1 y el ilo repetir r2 veesF isto es O(n)D lo que nos d omo onlusin de desempeo del mtodo O(n) O(n) = O(n2 )Y el mismo resultdo del peor soF

164

3. Crtica de algoritmos

gompremos el mtodo de inserin on el de seleinF gul es el mejorc i exmiE nmos ligermente el resultdoD entones podemos onluirD errnementeD que son equivE lentes Eque lo sonD sinttimenteEF imperoD el lzo interno del mtodo de selein @ e min el ndie menor entre i C I y n E I 151b A siempre iter n i + 1 veesD indepenE dientemente de l permutin a[i+1 .. n -1]Y mientrs que l ntidd de iteriones del lzo interno del de inserin @ er un reh j donde insertr tmp 163b A deE pende de l permutin a[l .. i - 1]6 F r prehender este hehoD es onveniente profundizr el nlisis del mtodo de inserin pr el so promedioF i proximmos el i D entones tenemos omo desempeoX nmero de repetiiones del lzo interno 2
n 1 i =1

i n(n 1) = ; 2 4

164a

que es equivlente l mitd de tiempo del mtodo de seleinF i ien ls urvs de mos mtodos son udrtisD l del de inserin es inferior l del de seleinF or su simpliidd de implntinD su jo oste onstnte y su uen desempeo pr permutiones usiEordends @O(n)AD el mtodo de inserin es un exelente lterntiv pr ordenr seuenis pequesF v versin pr lists es ms senillD pues no se requieren mnejr ndiesY tn solo reorrer l list e ir insertndo ordendmente en otr list d nodo oservdoF ist tividd justi( l preseni de l primitiv siguienteX Mtodos de ordenamiento 151a + 163a 164b template <class Compare> inline void insert_sorted(Dlink & list, Dlink * p) { typename Dlink::Iterator it(list); while (it.has_current() and Compare () (it.get_current(), p)) it.next(); if (it.has_current()) it.get_current()->append(p); // insertar antes de current else list.append(p); }
Denes:

insert_sorted,

used in chunk 164b.

164b

insert_sorted() insert el nodo p en l list ordend list segn el riterio de omE prin CompareF gon est primitivD el ordenmiento por inserin qued onismente de(nidoX Mtodos de ordenamiento 151a + 164a 165a
template <class Compare> inline void insertion_sort(Dlink & list) { Dlink aux; while (not list.is_empty()) insert_sorted<Compare>(aux, list.remove_next()); list.swap(&aux); }
insert_sorted
164a.

Uses

Note que tiene sentido comparar

efecto, por cada permutacin probabilidad.

a[i+1 .. r] con a[l .. i - 1] en cada uno de los mtodos. En a[i+1 .. r], existe otra complementaria a[l .. i - 1] que tiene la misma

3.1. Anlisis de algoritmos

165

165a

insert_sorted() ejeut un sol iterin de seuenis onstntesF v durin de l iterin depender de l permutin de l seueni list y del vlor lmendo en el nodo pF ist es l mism situin que on l versin pr rreglosF il tiempo de insert_sorted() es entones O(n) pr el peor so y pr el esperdoF v inserin es llmd desde otro loque itertivo uyo tiempo esD on ertitudD O(n)D pues hy que reorrer tod l listF es puesD omo es de esperrseD el mtodo es O(n2 )F xos rest exportr espeiliziones por omisin pr el tipo Dnode<T>X Mtodos de ordenamiento 151a + 164b 169 template <typename T, class Compare = Aleph::less<T> > inline void insertion_sort(Dnode<T> & list) { insertion_sort < Compare_Dnode<T, Compare> > (list); }
Uses

Compare_Dnode

153a and

Dnode

83a.

3.1.9

Bsqueda binaria

165b

il nlisis del mtodo de inserin o de selein trvs de operiones O es simple y diretoF in muhs osionesD sore todo en lgoritmos reursivosD se dee plnter un euin de reurreniF slustremos est ide medinte l versin reursiv de l squed inri sore un rreglo ordendoX Mtodos de bsqueda 165b template <typename T, class Compare = Aleph::less<T> > inline int binary_search_rec(T * a, const T & x, const int & l, const int & r) { const int m = (l + r) / 2; if (l > r) return m;
if (Compare() (x, a[m])) return binary_search_rec<T, Compare>(a, l, m - 1); else if (Compare() (a[m], x)) return binary_search_rec<T, Compare>(a, m + 1, r); } return m; // encontrado

il lgoritmo us reursivmente un ourreni del elemento x en un rreglo que est ordendo entre l y rF i l > rD entones el rngo de squed est vo y tenemos l ertitud de que el elemento x no se enuentr dentro del rngoF he lo ontrrio insE peionmos el elemento situdo en el entroY si ste ontiene el vlor xD entones m es el resultdoF i noD deidimosD segn el orden de xD en ul de los dos surngos deemos usrX el izquierdo o el derehoF esummos que el rngo [l, r] es de rdinlidd nF gundo n 0 el lgoritmo termin en tiempo onstnte O(1)F iD por el ontrrioD existen elementos dentro del rngoD entones pueden ourrir dos ossX o el elemento se enuentr en el entroD o hy que usr reursivmente en lgun de ls prtiionesF uesto que l prtiin ourre extmente por el entroD el resto del tiempo se onsume

166

3. Crtica de algoritmos

sore proximdmente l mitd de l entrdF lntemosD puesD l siguiente euin reurrenteX O(1) si n 0 T (n) = . @QFIRA T (n/2) + O(1) si n 1

xotemos que existe un ligero error en l reurreniX l llmd reursiv ourre soE re T ((n 1)/2) y no sore T (n/2)D omo se expres en @QFIRAF iste errorD que filit mnipulr T (n)D es despreileD pues un pso de ejeuin de menos no lterr el omE portmiento sinttio de T (n)F ifetuemos l trnsformin n = 2k = k = lg(n)Y esto sume que n es un poteni ext de 2D lo ulD si muhs vees no ser el soD s es vlido en el dominio de l notin OF v reurreni @QFIRA se expres entonesX

T (2k ) =

T (2k1 ) + 1

O(1)

si k = 0 si k > 0

@QFISA

vo interesnte de l trnsformin es que expres diretmente l reurreni omo un sumtoriF in efetoD expndindol tenemosX

T (2k ) = T (2k1 ) + 1 = T (2k2 ) + 1 + 1 = T (20 ) + 1 + + 1 + 1 = k + 1


ehor hemos l trnsformin inversX @QFITA

T (n) = lg(n) + 1 ,

@QFIUA

l ulD lrmenteD es O(lg(n))Y un e(ieni espetulrF v squed inri esD en el peor soD O(lg(n))F e requiere duplir l entrd pr que el lgoritmo demore un unidd de tiempo de msF
3.1.10 Errores de la notacin

ry dos onddes stnte notles de l notin OF in primer lugrD ell ojetiz l impreisinF odemos interpretr que ls onstntes de l de(niin c y n1 soren ls idiosinrsis sujetivs que y hemos seldo @tipo omputdorD FFFAF in segund instniD l notin permite estudir funiones T (n) del tiempo de un lgoritmo jo un mtodo onsiderlemente ms senillo que el onteo y el lger trdiionlF ero tod ojetizin rre un preioD por ierto stnte ojetivo y generl tod ojetizinD ul es el oultmiento de quello sujetivo que no slo en muhos sos puede ser importntsimoD sino serle esenilsimoD pues se rriesg ese ien supremo llmdo verddF hespus de nlizr el mtodo de inserin y omprrlo on el de seleinD podemos resltr que l notin O slo rroj l form de T (n) pr entrds muy grndesF he hehoD l impreisin de l notin O desehD entre otros spetosD los que se resumen en ls siguientes oservionesX IF xo se onsidern los ostes onstntes del lgoritmoX l propi de(niin de O desrt ls operiones que tomn tiempo onstnte en O(1)F

3.1. Anlisis de algoritmos

167

PF vos ostes vrilesD pero inferiores l urv dominnteD tmpoo se onsidernF or ejemploD supongmos un lgoritmo udrtio on un fse iniil de preproeE smiento O(n)D luegoD un fse O(n2 ) donde se ejeut el lgoritmo en s yD (nlmenteD un fse (nl de postproesmiento O(n)F in este soD el tiempo de ejeuin estr ddo por O(n) + O(n2 ) + O(n) = O(n2 )F ehor ienD el resultdo (nl O(n2 ) oult ompletmente dos ostes onsiderles soidos l lgoritmoX el pre y el postproeE smientoD los ulesD un undo son linelesD pueden ser ostossimos si onllevn un onstnte muy ltF QF il rter rel de T (n) se esonde totlmente por l otin O(f(n)) puesD en l myor de ls veesD T (n) = f(n)X en este sentido e selr que O(f(n)) slo tiene sentido pr entrds myores que l onstnte n1 plnted en l de(niin QFIF in otrs plrsD (rmr que T (n) = O(f(n)) desonoe el omportmiento de T (n) ntes de n1 F v gr( QFS selD rtesinmente hlndoD el dominio donde l notin O es onD ertitudD verddX v notin O es ertermente preis en el dominio de lo in(nito

Dominio exacto de la notacin O

Realidad

n1

pigur QFSX slustrin gr( del dominio de l notin O @o de l eterniddAD pero este dominio puede ser muy strto y lejno de lgun relidd onretF or esoD omo en todo lo ojetivoD hy que ndr on sumo uiddoF gostes muy grndesD inordlesD pero onstntesD pueden quedr ompletmente oultos por un nlisis OF vo mismo puede sueder on otros ostes sinttimente inferiores pero onstntemente superioresF or didurD el oultmiento totl de l form de T (n) puede rrer sorpress si l ejeuin slo tiene sentido pr esls inferiores l ot sintti n1 de l de(niin QFIF uiz lo peorD poltimente hlndoD es que un vez pulido un nlisis OD el onoimiento de quellos ostes y seldos tiend sepultrse pr siempreF
3.1.11 Tipos de anlisis

gomo y reitertivmente hemos dihoD hy lgoritmos que no slo dependen del tmo de l entrdD sino tmin de l form en que se presente l entrdF il mtodo de inserin ofree un uen ejemploF

168

3. Crtica de algoritmos

or lo generlD undo se nliz un lgoritmo se onsidern dos perspetivsF v primer onsiste en nlizrlo pr l entrd que use l peor ejeuinY l segund pr l entrd esperdF gsi siempre se requiere el nlisis pr l peor entrdD pues ste plnte un ot de ejeuinF il peor so nos ofree un espeie de grnt er del tiempo de ejeuinD pues ulquier otr entrd diferente l peor ser mejorF ist grnt es preile undo se requieren lgoritmos on requerimientos de ejeuin duros que no se pueden )exiilizrD y en los ules no se puede tener el lujo de tener un ml ejeuinF il nlisis pr l entrd esperd plnte un prediinD un expettiv er del tiempo de ejeuin ms proleF e trt de un espernzD es deirD de lo que se esper que sued muhs veesD pero no siempreF v proporin de vees que el lgoritmo se omportr omo lo esperdo depender de l vrinz de l entrdF fsimenteD este tipo de nlisis se puede plnter en dos situionesF v primer undo l entrd esperd se stnte proleD es deirD undo l vrinz de l entrd se pequeF v segund situin undo se plntee omo requerimiento stisfer l promedio de sos sin importr lguns mls ejeuiones usds por un ml entrdF in ms situiones es importnte onoer l vrinzF

3.2 Algoritmos dividir/combinar


n tni elegnte pr resolver un prolem onsiste en dividirlo en dos prolems equiE ttivosD uys omplejiddesD menudo expresds en funin de l eslD son menores que ls del prolem iniilF il proeso de divisin se repite reurrentemente on d un de ls prtes hst lnzr omplejiddes prtiulres uy soluin se onoidF e prtir de este momento se omin un pr de soluiones pr enontrr l soluin l prolem generl primigenimente divididoF e l ominin de dos soluiones pr otener l soluin omplet se le denomin ominin o onquistF r plir est tni se requiere @IA ser dividir el prolem y @PA ser ominrF ist es l prte sujetivsim en el diseo de un lgoritmo dividirGominrF or ontrsteD l estrutur y nlisis de est lse de lgoritmos tiene un esquem muy ojetivoF hdo un prolem P on entrd de tmo nD un lgoritmo dividirGominrD uy durin se desrie por l funin T (n) y que resuelve P se estruturD de mner generl y ojetivD en ls prtes siguientesX IF Identicacin de un problema particular y su solucinX est prte identi( un soluin prtiulr del prolem pr un tmo prtiulr de entrd n < nb F in est fse se requiere onoer mo resolver el prolem pr l ourreni de entrd prtiulrF e est prte se le llm seF esummos que l soluin se uest T (nb )F uesto que nb es onstnteD lo ms prole es que T (nb ) se onstnteD por lo queD l myor de ls veesD el oste de T (nb ) = O(1), n nb F PF DivisinX en est prte se divide el prolem en dos prtiiones equittivs de tmos n1 n2 n 2F esummos que l divisin uest O(fd (n))F

3.2. Algoritmos dividir/combinar

169

QF RecursinX est prte onsiste en resolver reursivmente d prtiin y otener soluiones s1 (n1 ) y s2 (n2 )F uesto que ourren llmds reursivsD el oste es desonoido hst tnto no se onoz el oste del so se y de l omininF imperoD menudo el oste puede expresrse reursivmente omo T (n1 ) + T (n2 )D pues ls llmds reursivs se orresE ponden on l mism funin de durinD pero pr entrds menoresF RF CombinacinX en est fse se ominn ls soluiones s1 (n1 ) y s2 (n2 ) resultntes de ls llmds reursivs en un soluin de(nitiv l prolemF egn lo expresdoD l durin de un lgoritmo dividirGominr se formul medinte l siguiente reurreniX , n nb O(fb (n)) @QFIVA T (n) = O(fd (n)) + T (n1 ) + T (n2 ) + O(fc (n)) , n > nb
divisin primera particin segunda particin combinacin

esummos que l ominin uest O(fc (n))F

wuy menudoD l estrutur de un lgoritmo dividirGominr se prest filmente su mnejo onurrenteD es deirD ls prtiiones pueden trtrse por hilos o proesos de ejeuin distintosF i estos hilos son ejeutdos por proesdores mteriles distintosD entones los suEprolems pueden resolverse simultnemente yD de este modoD ms rpE idmente que un solo proesdorF v veloiddD por supuestoD depende de l ntidd de proesdores que se dispongD de l ndole del lgoritmo prlelizr y de ls virtudes del disedor o progrmdor que hg l prlelizinF
3.2.1 Ordenamiento por mezcla

169

ijempli(quemos el diseo y nlisis de un lgoritmo dividirGominr medinte un lgoE ritmo de ordenmiento denomindo de mezlD el ul se desrie ontinuinX Mtodos de ordenamiento 151a + 165a 172
template <typename T, class Compare = Aleph::less<T> > inline void mergesort(T * a, const int & l, const int & r) { if (l >= r) return; const int m = (l + r)/2; mergesort<T, Compare>(a, l, m); mergesort<T, Compare>(a, m + 1, r); }
Uses

mezcla de arreglos 171

merge<T, Compare>(a, l, m, r);


merge
171 and

mergesort

173a.

il lgoritmo se orresponde extmente on el ptrn dividirGominrF v fse de ominin l efet el proedimiento merge()D el ul se enrg de mezlr dos prtiiones ordendsF entes de indgr el tiempo de ejeuin requerimos onoer mo se efet l mezl y nlizr su desempeoF

170

3. Crtica de algoritmos

3.2.1.1

Mezcla (merge)

v mezl sume dos seuenis ordendsD en los intervlos [l, m] y [m + 1, r]F i tuviseE mos dos rreglos ordendosD entones podrmos mezlrlos en un terero por rridoF e d iterinD omprmos el elemento tul de d rregloD opimos el menor de los dos l rreglo resultdo y vnzmos el elemento tul en el rreglo que onten el menor elementoF in nuestr situin tenemos un rreglo prtiiondo en dos prtes equittivs que y estn ordendsF il proeso de mezl opir el rreglo a[] hi uno uxilir que llmremos b[]F xo es posile evdir el uso de un rreglo diionlF gon mirs simpli(r l mezl hremos l opi del rreglo a hi el segundo rreglo b segn el siguiente esquemX
l
a

m a[l..m] a[m + 1..r ]

Copia primera mitad arreglo 170a Copia invertida segunda mitad arreglo 170b
l
b

m a[l..m] a[m + 1..r ]

170a

is deirD entre 0 y m opimos el rreglo normlmenteD mientrs que entre m + 1 y r lo invertimosF he est formD undo se efete l mezlD los myores elementos fungirn de entinels nturles que nos horrrn un segund repetiin junto on un if que deid sore ul de ls dos mitdes hy que relizr el resto de l opiF Copia primera mitad arreglo 170a (171) for (i = l; i <= m; i++) b[i] = a[i];

170b

Copia invertida segunda mitad arreglo 170b


for (j = r, i = m + 1; i <= r; i++, j) b[i] = a[j];

(171)

n vez opids ls prtiiones en el rreglo bD proedemos mezlrls en el rreE glo a omo sigueX
l
b

m a[l..m]
i

r a[m + 1..r ]
j

l
a

min(b[i], b[j])

170c

vo ul se implnt del siguiente modoX mezclar mitades 170c for (k = l, i = l, j = r; k <= r; k++) if (Compare() (b[i] < b[j])) a[k] = b[i++]; else a[k] = b[j];

(171)

3.2. Algoritmos dividir/combinar

171

171

y que omplet todo lo neesrio pr progrmr l rutin merge()X mezcla de arreglos 171 (169) template <typename T, class Compare = Aleph::less<T> > inline void merge(T * a, const int & l, const int & m, const int & r) { int i, j, k; T b[r - l + 1];

Copia primera mitad arreglo 170a Copia invertida segunda mitad arreglo 170b mezclar mitades 170c
used in chunk 169.

Denes:

merge,

il prmetro m es el entro de l prtiinF


3.2.1.2 Anlisis del mergesort

r nlizr el mergesort() usmos l euin @QFIVA y plntemosX

T (n) =

2T (n/2) + O(fc (n))

O (1)

,n 1 ,n > 1

@QFIWA

honde O(fc (n)) es l omplejidd de tiempo de l fse de omininD o seD de l funin merge()F glrmenteD los loques gopi primer mitd rreglo 170a y gopi invertid segund mitd rreglo 170b onsumen n/2 psos de ejeuinD lo que los he O(n)F il loque mezlr mitdes 170c onsume extmente n uniddes de ejeuinD lo que lo he tmin O(n)F or tntoD merge() onsume O(n) + O(n) + O(n) = O(n)F he este modoD @QFIWA se plnte omoX

T (n) =

O(1)

2T (n/2) + O(n)

,n 1 ,n > 1

@QFPHA

ist reurreni tmin puede resolverse sumiendo n = 2k = k = lg(n)D o seD sumimos que n es un poteni ext de 2F r n > 1D @QFPHA se plnte omoX

T (2k ) = 2T (2k1 ) + O(2k ) = @dividimos tod l euin entre 2k A T (2k1 ) T (2k ) = + O(1) 2k 2 k 1 T (2k2 ) = + O(1) + O(1) = O(1) + + O(1) +O(1) 2 k 2
k veces

= O(k) + 1
el regresr l plno n tenemos que @QFPIA se plnte omoX

@QFPIA

T (n) = O(lg(n)) + O(1) = n T (n) = O(n lg(n)) + O(n) = O(n lg(n)) ;

@QFPPA

pr n = 2k F il ul est sinttimente otdo por O(n lg(n))F in el in(nitoD l mulE tipliidd de n no fet el omportmiento sinttioD pues st no fet l reurreniF

172

3. Crtica de algoritmos

in otros trminosD el que n se o no poteni ext de dos no mir el heho de que T (n) se O(n lg(n))F il mtodo por mezl es O(n lg(n)) pr todos los sosX mejorD peor y promedioF xotemos que el lgoritmo en s no distingue l form de l entrdY siempre uest O(n lg(n))D independientemente de l disposiin de los elementos en el rregloF
3.2.1.3 Estabilidad del mergesort

hd un tl de registrosD es deirD un rreglo on olumns de tipos igules o diferentesD un lve primri es un que no se repite en un (lF or ejemploD el nmero nio de identidd nionl no est disedo pr repetirseF n lve seundri es un que puede repetirse en dos o ms (lsY ejemplosD los nomres y pellidosF fjo l de(niin nteriorD un mtodo de ordenmiento se li( de estle siD l ordenr por lve seundri un seueni de registros previmente ordend por lve primriD ls lves seundris repetids se onservn entones ordends segn l lve primriF in el sentido de lo nteriorD el mtodo mergesort es estleF
3.2.1.4 Coste en espacio

il onsumo de memori es otro oste que siempre dee onsiderrse l momento de nlizr un lgoritmoF in este sentidoD el ordenmiento de rreglos por mezl es un uen ejemploD pues l rutin merge() requiere un rreglo proporionl nD lo ul impli que el mtodo en uestin requiere espio proporionl O(n)F es puesD si se dese utilizr este mtodoD entones dee segurrse el disponer del espio diionl requerido pr su ejeuinF
3.2.1.5 Ordenamiento por mezcla de listas enlazadas

172

il ordenmiento por mezl fue oneido muy otrorD undo h muy po memori y los medios de lmenmiento seundrio ern ints mgntis lentsimsF in quellos tiemposD ordenr requer l mezl de vris intsF eunque hoy en d disponemos de muy extenss memoris y de medios de lmeE nmiento msivo no seuenilesD el ordenmiento por mezl no es pr nd osoletoF odo lo ontrrioD es un mtodo on grnt O(n lg(n)) que permite ordenr efetivE mente lists enlzds y queD por didurD no requiere espio diionlF l mezl se espei( omo sigueX Mtodos de ordenamiento 151a + 169 173a template <class Compare> inline void merge_lists(Dlink & l1, Dlink & l2, Dlink & result) { while (not l1.is_empty() and not l2.is_empty()) if (Compare () (l1.get_next(), l2.get_next())) result.append(l1.remove_next()); else result.append(l2.remove_next());
if (l1.is_empty()) result.concat_list(&l2);

3.2. Algoritmos dividir/combinar

173

else result.concat_list(&l1);

in onsonni on su rter de seueniD el ordenmiento por mezl de un list enlzd tiene extmente l mism estrutur que su versin pr rreglosF
173a

Mtodos de ordenamiento 151a +

172 173b

template <class Compare> inline void mergesort(Dlink & list) { if (list.is_unitarian_or_empty()) return; Dlink l, r; list.split_list(l, r); mergesort <Compare> (l); mergesort <Compare> (r); } // dividir en dos listas // ordenar la primera // ordenar la segunda

merge_lists <Compare> (l, r, list); // mezclarlas

Denes:

mergesort,

used in chunks 169 and 577b.

v iliote de(ne espeiliziones pr ls otrs lses de lists medinte l utiE lizin de l lse Compare_DnodeF
3.2.2 Ordenamiento rpido (Quicksort)

gonsideremos un rreglo desordendo a[] y l invoin pivot = partition(a, l, r)D l ul prtiion el rreglo en dos prtes generles omo se pitoriz en l siguiente (gurX
l r

Todo menor o igual que a[pivot]

pivote Todo mayor o igual que a[pivot] pivot

173b

v ejeuin pivot = partition(a, l, r) efet lguns operiones sore el rreE glo y retorn un ndie pivot tl que el rreglo stisfe l prtiin segn el esquem pitorizdoF is deirD despus de invor partition()D el elemento a[pivot] se enuentr en su posiin de(nitiv dentro de lo que ser l seueni ordendY o seD l entrd a[pivot] orresponde l pivotEsimo menor elemento del rregloF il rreglo h sido diE vididoD segn a[pivot]D en dos prtes desordendsD que pueden ordenrse reursiv e independientemente omo sigueX Mtodos de ordenamiento 151a + 173a 177 template <typename T, class Compare = Aleph::less<T> > inline void quicksort_rec(T * a, const int & l, const int & r) { if (l >= r) return;
const int pivot = partition <T, Compare> (a, l, r);

174

3. Crtica de algoritmos

}
Uses

quicksort_rec <T, Compare> (a, l, pivot - 1); quicksort_rec <T, Compare> (a, pivot + 1, r);
partition
175b.

iste proedimiento es el mejor mtodo de ordenmiento hst hoy onoidoF u rendimiento es tn espetulr que su desuridor 7 D gFeFF rore UID lo uE tiz quiksort  IVPD o seD ordenmiento rpidoD oD revidmenteD en stellnoD el rpidoF v eseni del mtodo suye en l mner de efetur l prtiinD pero ntes de estudirl es interesnte fundmentr el nlisis del lgoritmoF gonviene notr que l estrutur dividirGominr del quiksort di(ere ligermente de su trdiionl orden ojetivoF vs llmds reursivs ourren l (nl de l rutin sin que se note explitmente un fse de omininF he hehoD es en l propi prtiin del rreglo undo ourre l omininD pues un vez efetud l prtiinD d prte puede ordenrseD independientementeD por seprdoF il tiempo de ejeuin se rteriz por l siguiente euin reurrenteX

T (n) =

O (1)

O(fp (n)) + T (pivot l) + T (r pivot)

,n 1 ,n > 1

@QFPQA

donde O(fp (n)) rteriz l durin de partition()F pivot es el ndie del elemento en torno l ul se efet l prtiinF
3.2.2.1 Particin

v prtiin es l prte ms delid y omplid del quiksortF esummos un elemento pivot que representr l elemento de prtiin y que de lgun formD que expliremos ms delnteD se ui en a[r]F sniiemos nuestro estudio medinte oservin de l siguiente (gurX
swap(a[i], a[j])

++i
<
pivot

j
while a[j]

j
>
pivot

r
pivot

while a[i]

avance i hasta primer elemento mayor que pivot 174

avance j hasta primer elemento menor que pivot 175a

174

v (gur represent el rreglo entre l y rF i es un ndie por el ldo izquierdo del rreglo y j es por el ldo derehoF i se mueve hi l derehD lo que impli que dee inrementrseY mientrs que j se mueve hi l izquierdD por lo que se dee derementrF vos vlores iniiles de estos ndies se olon en un posiin previ su primer esoY es deirD i en l - 1 y j en rF vuego de iniidos los ndiesD l rutin entr en un lzo uyo uerpo onsiste en usr un inversin reltiv l pivoteD es deirD un pr de elementos que estn invertidos en orden respeto l pivoteF il primero de estos elementos se us por l izquierdX avance i hasta primer elemento mayor que pivot 174 (175b) // avance mientras a[i] < a[pivot] while (Compare() (a[++i], pivot)) { /* no hay cuerpo */ }
7
En la cita original Wirth emplea el trmino inventor.

3.2. Algoritmos dividir/combinar

175

175a

in l instruin a[++i]D l rg de a[i] se efet despus del inrementoF or tntoD el primer eso ourre sore a[l]F il desplzmiento de i jms sorepsr rD pues el pivote funge de entinel y l omprin es por desiguldd estritF or tntoD i nun eder un ndie fuer del rngo [l, r]F v squed del elemento de inversin del ldo dereho es similrD pero qu no tenemos un entinelD por lo que deemos veri(r que j no sorepse lX avance j hasta primer elemento menor que pivot 175a (175b) while (Compare() (pivot, a[j])) // avance mientras a[pivot]< a[j] if (j == l) // se alcanz el borde izquierdo? break; // s ==> hay que terminar la iteracin i i y j no se ruzn @i < jAD entones existe un inversin que se orrige intermE indo a[i] on a[j]F iD por el ontrrioD los ndies i y j se ruzn @i >= jAD el proeso de prtiin ulmin y el ndie i onstituye el punto de prtiinF in este momento se intermi on el pivote e i divide l rreglo en dos prtesY l izquierd ontiene lves menores o igules l pivoteD mientrs que l dereh ontiene lves myores o igulesF is posile que el rngo [l, i] onteng lves igules l pivoteY esto suede si j ruz iD es deirD si no se enuentr un lve del ldo dereho que se menor que el pivote e i qued posiiondo en un lve igul l pivoteF gon ls expliiones nteriores propidsD estmos listos pr mostrr l prtiinX Denicin de particin de arreglo 175b template <typename T, class Compare> inline int partition(T * a, const int & l, const int & r) {
T pivot = a[r]; // elemento pivot int i = l - 1, // ndice primer elemento a la izquierda > que pivot j = r; // ndice primer elemento a la derecha > que pivot while (true) {

175b

Seleccionar pivote 180b

avance i hasta primer elemento mayor que pivot 174 avance j hasta primer elemento menor que pivot 175a

if (i >= j) break; // En este punto hay una inversin a[i] > a[pivot] > a[j] std::swap(a[i], a[j]); // Eliminar la inversin

} std::swap(a[i], a[r]); return i;

Denes:

partition,

used in chunks 173b, 177, 180c, 182b, 184, and 186a.

v rutin tom omo prmetros el rreglo y los lmites izquierdo y derehoD denominE dos l y r respetivmenteF v primer lne del mtodo es un pso fundmentl en el desempeo del quiksort y onsiste en seleionr un elemento que funj de prtiiondor del rregloF l eleE

176

3. Crtica de algoritmos

mento se denomin pivoteF or horD summos que seleionmos el ltimo elementoD es deirD a[r]F ixisten otrs forms de esoger el elemento pivote que son ms ostoss en tiempo onstnteD pero que mejorn l espernz de durin del ordenmientoF gulquier que se el mtodoD nos remitiremos olor el pivote en el extremo derehoF he este modoD un modi(in del enfoque de selein de pivote no fet el resto del lgoritmo de prtiinF
3.2.2.2 Anlisis del quicksort

il nlisis del quiksort requiere resolver l euin @QFPQAD l ulD su vezD requiere del nlisis de l prtiinF gulquier se l disposiin del rregloD el while ms externo rompe undo se ruen los ndies i y jF r que esto sued tienen que ourrir extmente r l + 1 inrementos y derementosF or tntoD si n = r l + 1D entones el tiempo de ejeuin es O(n)F ustituyendo este tiempo en l euin @QFPQA puede proximrse X

T (n) =

O(n) + T (pivot l) + T (r pivot)

O(1)

,n > 1

,n 1

@QFPRA

i suponemos un permutin letoriD entones l espernz sore el punto de r prtiin se sit en l+ 2 D o seD en el entro del rregloD por lo que l euin @QFPRA puede proximrse omoX

T (n) =

O(1)

O(n) + 2T (n/2)

,n 1 ,n > 1

@QFPSA

l ul es O(n lg(n))F il desempeo del quiksort es O(n lg(n)) pr el so esperdo y pr el mejor soF il peor so puede ourrir undo el pivote se justmente el myor de todos los elementos entre i y jF in est desfortund situinD l prtiin izquierd es de longiE tud r l 1D mientrs que l de l dereh es 0F in otrs plrsD no se logr dividir efetivmenteF v euin @QFPRA se expres omoX

T (n) =

O (1)

O(n) + T (n 1)

,n 1 ,n > 1

@QFPTA

l ul es O(n2 )F il quiksort devieneD en el peor soD el lento IVPF gun prole es que ez lo peorc el igul que en l vidD muy pooF r intuir este hehoD plnteemos lgunos muy mlos sosF n muy ml so est ddoD prdjimenteD undo el rreglo est ordendoF in est situinD el pivote siempre es el myor elementoD el ul y se enuentr en su posiin de(nitivY l prtiin izquierd es de longitud n 1 mientrs que l dereh es nulF v 1 proilidd de este infortunio es n ! D pues slo existe un posiilidd entre ls n! posilesF n so ligermente peor que el nterior se d undo el rreglo est ordendmente invertidoF ist disposiin us un prtiin izquierd nul y un dereh de longiE 1 tud n 1F v proilidd es idnti l so nteriorX n !F

3.2. Algoritmos dividir/combinar

177

u tn prole es tener un ml soc in estdstiD est respuest l d l vE rinzF i l permutin es letoriD entones l prtiin vrir segn un distriuin 2 uniformeD es deirD (rl+21) 1 D por lo que el punto de prtiin se desvir dentro del rngo
1 de(nido por (n) 12 D lo ul rroj un error esperdo de 297 proximdmenteF in otros trminosD un espeie de ml so esperdo de prtiin es que st se de proporin 1/3Y proporin que n divide el rreglo de mner efetivF edemsD est desventur tenE dr que ourrir on l myor de ls prtiionesY uestin ltmente improle si ls permutiones se distriuyen segn un densidd uniformeF
2

3.2.2.3

Anlisis de consumo de espacio del quicksort

vos lgoritmos reursivos onllevn un oste en espio deido l pilF in este sentidoD un lgoritmo dividirGominr onsume espio de pil undo memoriz un de ls divisiones efetos de proesr reursivmente l otrF he este modoD onforme umentn ls divisionesD myor memori se requiereF il quiksort puede ser muy ostoso en espio si ourren mls prtiiones suesivsF eprehendmos esto mirndo el peor de todos los mlos sosD el ul ourre undo el rreglo est inversmente ordendoF in est situinD segn he(niin de prtiin de rreglo 175b D el rreglo siempre se prtiion enX
pivot quick_sort_rec<T, Compare>(a, l+1, r-1) quick_sort_rec<T, Compare>(a, r+1, r)

Orden invertido
l r

177

vo ulD segn l implntin de quicksort_rec()D us ls llmds reursivs @olods on prmetros relesA quicksort_rec(a, l, r-1) y quicksort_rec(a, r+1, r)D justo en ese orden respetivoF xotemos que este orden de llmds empil l prtiin ms peque mientrs se efeE t l llmd reursiv sore l prtiin ms grnde uyo tmo es r l 1F e su vezD puesto que el resto del rreglo est inversmente ordendoD l siguiente invoE in quicksort_rec(a, l, r - 1) us de nuevo l peor prtiinD por lo que se vuelve empilr l prtiin v mientrs se llm reursivmente l prtiin de tmo r l 2F iste proeso de mls prtiiones ontin hst que se ordene enterE mente el rregloF il peor so del quiksort slo empil prtiiones vsF r preisr el oste en espio de ests llmds vns hy que ontr l ntidd de vees que se llm reursiE vmente l quiksortD l ul esD extmenteD el nmero de elementos nD o seD O(n)F n muy ml so del quiksort puede filmente usr un desorde de pilF r evitr esto deemos segurrnos que l primer llmd reursiv se efete sore l prtiin ms pequeD de modo tl que se empile menosD pues menor tmo de prtiin ourrir un menor ntidd de llmds reursivsF he est mnerD un muy liger vriin de quicksort_rec()D que minimiz el onsumo de pilD se enuni omo sigueX Mtodos de ordenamiento 151a + 173b 180a template <typename T, class Compare = Aleph::less<T> > inline void quicksort_rec_min(T * a, const int & l, const int & r) { if (r <= l)

178

3. Crtica de algoritmos

return; const int pivot = partition<T, Compare>(a, l, r); if (pivot - l < r - pivot) // cual es la particin ms pequea? { // particin izquierda ms pequea quicksort_rec_min<T, Compare>(a, l, pivot - 1); quicksort_rec_min<T, Compare>(a, pivot + 1, r); } else { // particin derecha ms pequea quicksort_rec_min<T, Compare>(a, pivot + 1, r); quicksort_rec_min<T, Compare>(a, l, pivot - 1); }
partition
175b.

}
Uses

ist versin invo l reursin desde l menor hst l myor prtiinD lo ul grntiz un onsumo de pil mnimoF he unto se trt este onsumoc r responder l uestinD deemos primero identi(r ul es el mximo tmo que puede tomr un menor prtiin y sumir que ello ourre reursivmente en d llmd reursivF il mximo de que hlmos se present undo l prtiin ourre extmente por el entroD el ulD no sorprendentementeD es el mejor so de prtiin en veloidd de ordenmiento y ourreD lo sumoD O(lg(n)) veesD que es l myor proporin de vees que podemos dividir l rregloF or tntoD quicksort_rec_min() tiene un onsumo de espio O(lg(n)) en el peor soD oste perfetmente mnejle un pr pils pequesF il nlisis preedente tmin nos d uent er del nmero de invoiones reurE sivs que ourrirn en el mejor so del quiksortD es deirD undo tods ls prtiiones ourrn por el entroF in este soD d llmd l quiksort osion dos llmds reursivs sore prtiiones del mismo tmoF or tntoD el totl de llmds reursivs que tomr el mejor so del quiksort estr ddo porX
lg(n)

2i 2lg(n)+1 1 ;

@QFPUA

donde n es l ntidd de elementosF v sumtori ext ourrir si n = 2k 1D o seD si n + 1 es un poteni ext de 2F in este soD tods ls prtiiones osionds siempre son extmente del mismo tmoF v (gur QFT pitoriz tods ls llmds reursivs que ourren pr n = 15 en un estrutur denomind rolD l ul ser estudid en el ptulo S @gF QUWAF restemos tenin espeil l digrm QFT e identi(quemos l primer llmd qs(0, 14)8 F ist llmd gener ls llmds qs(0, 6) y qs(8, 14)F il lgoritmo seleE ion qs(0, 6) pr ontinur l reursin y empil qs(7, 14)F e su vezD qs(0, 6) empil qs[4, 6] y prosigue reursivmente sore qs(0, 2)F gundo se lleg por primer vez l so seD l pil ontiene ls llmds qs(0, 14)D qs(7, 14)D qs(4, 6)D qs(2, 2) pendientes por herF
8
El nombre del mtodo ha sido abreviado por economa de espacio.

3.2. Algoritmos dividir/combinar

179

qs(0,14)

qs(0,6)

qs(8,14)

qs(0,2)

qs(4,6)

qs(8,10)

qs(12,14)

qs(0,0)

qs(2,2)

qs(4,4)

qs(6,6)

qs(8,8)

qs(10,10)

qs(12,12)

qs(14,14)

pigur QFTX istrutur de ls prtiiones y llmds reursivs pr el mejor so del quiksort y IS elementosF v mxim ntidd de llmds empilr est dd por l mxim profundidd del rol desde qs(0, 14) hst ulquier so se qs(i, i)F gulquier que se el vlor y tmo de l entrdD si se proes primero l prtiin ms pequeD entones el onsumo en pil no soreps O(lg(n))F
3.2.2.4 Seleccin del pivote

i l permutin del rreglo es letoriD entonesD l selein del pivote por l dereh del rregloD tl omo hst el presente l hemos trtdoD tmin es letoriF or tntoD pr permutiones letorisD nuestr versin del quiksort dee omportrse O(n lg(n)) en el so esperdoF or didurD l vrinz @297A indii que en so de ml suerteD el quiksort n es rpidoF il rzonmiento nterior presume que l permutin se distriuye uniformementeY uestin plusile e idne en el mundo ojetivo de l estdstiD pero que puede per de ndid en el mundo relF odo depende de qu es lo que se orden y desde dnde proviene l seueniF in l vid ourre que los qu y los desdeD si siempre son sesgdosF or otr prteD el peor so del quiksort es tn severmente lmitoso que ningun pliin seri puede suyer sore l si el desempeo es lo rtioF vo nterior justi( onsumir un poo de tiempo onstnte pr forzrD en l medid posileD que ourrn uens prtiionesF v mejor mner de eliminr un sesgo es letoE rizr explitmenteF v ide es forzr que ulquier se l permutinD l selein del pivote oedez un riterio letorioD el ulD tl omo lo rgimosD proilstimente use uenos sosF in este orden de idesD un primer estrtegi onsistir en letorizr l prtiinD es deirD en sorter letorimente l selein del ndie del pivoteF il ndie pivote ser entones un nmero letorio entre l y rF he este modoD l letoriedd y no depende de modo lguno del vlor de l permutinF v tni nterior es uenD pero no evit l posiilidd de que el pivote letorio use un ml prtiinF n tni pr disminuir est posiilidd es sorter vrios ndies y seleionr omo pivote el vlor de l medinF isto onllev l di(ultd de que hy que veri(r que los sorteos no se repitnD lo que es lgortmimente engorroso yD en durin onstnteD ostosoF or es rzn es preferile no veri(r repiteni y simplemente seleionr l medinD s ourrn repitenisF ued por deidir untos sorteos se deen herF gunto myor se est ntiddD myor posiilidd se tendr de

180

3. Crtica de algoritmos

180a

otener un uen pivoteD pero tmin se tendr myor onsumo de tiempo onstnte y myor impto en el desempeoF v letorizin es un prinipio lgortmio tendiente disminuir l ml suerte o fvoreer l uenF il prinipio hor esonoido jo el rtulo de lgoritmos letoriE zdos y onstituye tod un rm de l lgortmiF in este texto se estudirn diverss lses de letorizinF n esquem que no requiere generr ndies letorios es tomr los ndies extremos lD r ms el ndie del entro y esoger ls medin de ls tres entrdsF i ienD omo siempreD l letoriedd depende de l permutinD tendr que her permutiones sesgds por los tres ldos pr que ourr un muy ml soD lgo poo prole de oneir pero suseptile de ourrir o de ser dredemente provodo9 F in este sentidoD l siguiente rutin seleion el pivote segn lo rein explidoX Mtodos de ordenamiento 151a + 177 180c template <typename T, class Compare> inline int select_pivot(T * a, const int & l, const int & r) { if (l - r <= 2) return r;
const int m = (r + l) / 2; // ndice del centro const int p = Compare () (a[l], a[m]) ? m : l; // p=max(a[l],a[m]) } return Compare () (a[r], a[m]) ? r : p; // retornar min(a[r], a[m])

180b

v rutin nterior permite ompletr el mtodo de(nitivo de prtiin de l siguiente mnerX Seleccionar pivote 180b (175b) const int p = select_pivot <T, Compare> (a, l, r); std::swap(a[p], a[r]);
3.2.2.5 Quicksort sin recursin

180c

gonoido el ptrn de demnd de espio del quiksortD result trtivo efetos de liE gerr l rg por lulo onstnteD intentr otener un versin no reursiv del mtodoF esimismoD el ptrn del lgoritmo itertivo y se onoe desde el diseo de l versin itertiv de l squed inri @ PFIFIFP @gF QHAAF il quiksort dee usr un pil pr reordr un prtiin mientrs orden l otrF ist es l difereni on l squed inri itertivD l ul no requiere un pil porque no se requiere reordr l prtiin que se desrt despus de l divisinF es puesD usremos un pil de pres que ontengn los ndies izquierdo y dereho de l prtiinD uy pidd mxim @de l pilA ser de 32 prtiionesD tmo su(iente si siempre ordenmos de primero l prtiin ms pequeF he restoD ondiiond l estdio de un propid redin y de un responsle estudioD l siguiente rutin no dee plnter prolems de omprensinX Mtodos de ordenamiento 151a + 180a 181 template <typename T, class Compare = Aleph::less<T> > inline
9
En seguridad de sistemas, una tcnica de denegacin de servicio, llamada ataque por complejidad algortmica, consiste en explotar malos casos del algoritmo. En este sentido podra ocurrir una situacin en la cual, deliberadamente, se le d a un sistema malas particiones a efectos de causar su colapso.

3.2. Algoritmos dividir/combinar

181

void quicksort(T * a, const int & l, const int & r) { typedef typename Aleph::pair<int, int> Partition; FixedStack<Partition, 32> stack; stack.push(Partition(l, r)); // todo el arreglo como particin inicial while (stack.size() > 0) { const Partition p = stack.pop(); const int pivot = partition <T, Compare>(a, p.first, p.second); if (pivot - p.first < p.second - pivot) // cul ms pequea? { // particin izquierda ms pequea stack.push(Partition(pivot + 1, p.second)); stack.push(Partition(p.first, pivot - 1)); } else { // particin derecha ms pequea stack.push(Partition(p.first, pivot - 1)); stack.push(Partition(pivot + 1, p.second)); }

}
Uses

FixedStack

101a and

partition

175b.

3.2.2.6

Quicksort sobre listas enlazadas

181

he todos los lgoritmos de ordenmientoD quiz el ms simple de expresrse se el quiksort sore lists enlzdsF v siguiente rutin lo indiiX Mtodos de ordenamiento 151a + 180c 182b template <class Compare> void quicksort(Dlink & list) { if (list.is_unitarian_or_empty()) return;
Dlink * pivot = list.remove_next(); Dlink smaller, bigger; // listas de menores y mayores que pivot

particionar lista 182a


quicksort <Compare> (bigger); quicksort <Compare> (smaller); list.concat_list(&smaller); // restaurar listas ordenadas en list list.append(pivot); list.concat_list(&bigger);

v estrutur del lgoritmo no es nd misteriosD pues se orresponde on el esquem del lgoritmoX prtiionr l seueni en el ptrn smallerpivotbiggerF v list

182

3. Crtica de algoritmos

182a

smaller slo ontiene los elementos menores que pivotD mientrs que l list bigger inluye los myoresF ehor nos flt espei(r l prtiinD l ul es onsiderlemente ms senill que on los rreglosX particionar lista 182a (181 185)
while (not list.is_empty()) { Dlink * p = list.remove_next(); if (Compare () (p, pivot)) smaller.append(p); else bigger.append(p); }
Mejoras al quicksort

3.2.2.7

182b

evisemos el proedimiento de prtiin he(niin de prtiin de rreglo 175b y los ordenmientos de selein e inserin presentdos en QFIFQ @gF ISHA y QFIFV @gF ITPA respetivmenteF n primer mird indii que estos mtodos de ordenmiento tienen menos instruiones que el proedimiento de prtiin del quiksortF n revisin ms uios revel que los mtodos de ordenmientoD que son O(n2 )D ontienen menos ifD menos llmds Compare() y menos ompriones de ndies que el proedimiento de prtiinF vos omentrios nteriores justi(n l oservin empri de que los mtodos de selein e inserin son ms rpidos que el quiksort pr rreglos pequeosF gmo es posile estoc eordemos que l notin O oult los ostes onstntes y que st slo rige despus de un vlor de entrd espe(oF re quD en el quiksortD un uen so de quellos ostes que oult l notin OF n mejor sustnil l quiksort onsiste en onmutr otro mtodo de ordeE nmiento pr tmos de prtiin pequeosF vo lo ms grnde que pued ser lo pequeo depende simente del hrdwre y del ompildorF uesto que el mtodo de inserin exhie mejores tiempos onstntes que el de seleinD lo integrremos l siguiente verE sin mejord del quiksortX Mtodos de ordenamiento 151a + 181 184 template <typename T, class Compare = Aleph::less<T> > inline void quicksort_insertion(T * a, const int & l, const int & r) { if (r <= l) return;
const int pivot = partition<T, Compare>(a, l, r); const int l_size = pivot - l; // const int r_size = r - pivot; // bool left_done = false; // true bool right_done = false; // true tamao particin tamao particin si particin izq si particin der izquierda derecha est ordenada est ordenada

if (l_size <= Aleph::Insertion_Threshold) { // ordene particin izq por insercin insertion_sort<T, Compare>(a, l, pivot - 1);

3.2. Algoritmos dividir/combinar

183

left_done = true; } if (r_size <= Aleph::Insertion_Threshold) { // ordene particin der por insercin insertion_sort<T, Compare>(a, pivot + 1, r); right_done = true; } if (left_done and right_done) return; // ambas particiones ordenadas por insercin if (left_done) // particin izq ordenada por insercin? { // s; slo resta ordenar recursivamente particin der quicksort_insertion<T, Compare>(a, pivot + 1, r); return; } if (right_done) // particin der ordenada por insercin? { // s; slo resta ordenar recursivamente particin izq quicksort_insertion<T, Compare>(a, l, pivot - 1); return; } // aqu, ambas particiones no fueron ordenadas por insercin if (l_size < r_size) // ordenar primero particin ms pequea { // particin izquierda ms pequea quicksort_insertion <T, Compare> (a, l, pivot - 1); quicksort_insertion <T, Compare> (a, pivot + 1, r); } else { // particin derecha ms pequea quicksort_insertion <T, Compare> (a, pivot + 1, r); quicksort_insertion <T, Compare> (a, l, pivot - 1); }
partition
175b.

}
Uses

il vlor exto de Insertion_Threshold es reltivo y depende de ls ondiiones mteriles y opertivsF n vlor entre 20 y 30 es su(iente en el momento de redin de este texto10 F
3.2.2.8 Claves repetidas

eunque el lgoritmo de prtiin he(niin de prtiin de rreglo 175b funion deudmente pr lves repetidsD podr provehrse el proeso de prtiin pr onsiderr repiteni y relizr un prtiin on l form siguienteX
l
Elementos menores que pivot Elementos iguales pivot Elementos mayores que pivot

e este tipo de prtiin se le denomin de l triple form o nder holndes en honor l nionlidd de idsger F hijkstrD el primer homre que se onoe her reportdo
10
En enero 2006, procesadores i686 a 3 Ghz, con 2Mb de cache L2.

184

3. Crtica de algoritmos

el desurimiento del mtodoF v ventj de este esquem es que tods ls lves repetids quedn l entro y ls invoiones reursivs se efetn sore onjuntos ms pequeos que no ontienen repitenisD lo ul eler el ordenmientoF v prtiin dee modi(rse de mner tl que ls repitenis se vyn olondo por los extremos en un esquem similr l siguienteX
l
igual p menor i desorden j mayor q igual

vuegoD undo los ndies se ruenD se hen los intermios neesrios pr dejr el rreglo triplemente prtiiondoF vos detlles del lgoritmo se dejn omo ejeriioF
3.2.2.9 Quicksort concurrente o paralelo

in el quiksort on lists enlzds es muy filmente prensile su filidd de prlelizinF in efetoD omo luego de l prtiin el pivote y se enuentr en su posiin de(nitiv dentro del orden solutoD ls prtiiones pueden ordenrse indepenE dientementeD por seprdoD por distintos lgoritmosD vrintes yD en lo que onierne l propsito de est oservinD por proesdores diferentesF gomo mner ms fmilir de prehender el suntoD onsideremos un mzo de rjs ordenr y tres personsD un pr prtiionr y ls dos restntes pr ordenrF wientrs l primer efet l prtiinD ls dos restntes deen esperrD pero un vez que l prtiin est ulmindD entones ls persons enrgds de ordenr pueden llevr o el ordenmiento sin que interE (ern entre ells y on el orden (nl del mzoF gundo ls prtiiones estn ordendsD el prtiiondor junt los mzosD on lo que tiene un mzo ompletmente ordendoF v oservin es idnti pr el ordenmiento on rreglosD unque un poo ms difil de entenderD ddo el rter de opi que se requiereF
3.2.2.10 Bsqueda aleatoria de clave

184

gundo intentmos resolver el prolem fundmentl medinte rreglos nos enontrmos on un disyuntivF i ordenmosD entones podemos empler l e(iente squed iE nriD pero tenemos un inserin y supresin O(n)F or el ontrrioD si mntenemos l seueni desordendD entones tenemos un inserin muy rpid O(1)D pero un squed y supresin lents O(n)F in l myor de ls osionesD l rzn de ser de resolver el prolem fundmentl es l squedD rzn por l ul podrmos ordenr de vez en undo o undo estemos seguros de que no hrn ms inserionesF ero eso n es ostoso y limit l soluin un espetro pequeo de situionesF n lterntiv de squedD hrid entre el orden y el desordenD que permite imE plntr el onjunto fundmentl medinte seuenisD se sirve de l prtiin del quiksort explid en QFPFPFI @gF IURAF in efetoD podemos servirnos del mtodo desrrolldo en he(niin de prtiin de rreglo 175b @ QFPFPFI @gF IURAA pr implntr l squed sore un rreglo desordendoX Mtodos de ordenamiento 151a + 182b 185 template <typename T, class Compare= Aleph::less<T> > inline int random_search(T * a, const T & x, const int & l, const int & r)

3.2. Algoritmos dividir/combinar

185

if (l > r) return Not_Found; const int pivot = partition<T, Compare>(a, l, r); if (Compare() (x, a[pivot])) return random_search<T, Compare>(a, x, l, pivot - 1); else if (Compare() (a[pivot], x)) return random_search<T, Compare>(a, x, pivot + 1, r);

}
Uses

return pivot; // elemento encontrado en el ndice x


partition
175b.

185

v ide del lgoritmo es prtiionr letorimente el rreglo y otener el punto de prtiin pivotF eordemos que el pivote siempre se enuentr en su posiin de orE den de(nitivF or tntoD el orden de x respeto pivot determin en ul de ls dos prtiiones se ontin reursivmente l squedF or supuestoD segn el nlisis de QFPFPFI @gF IURAD el lgoritmo reorre entermente el rregloD rzn por l ul es fil ver que l squed generl no podr poyrse entermente en random_search()F ero s podrD emperoD mntener un list ordend de pivotes prtir de l ul her squeds seueniles que sern onsiderlemente ms orts que reorrer entermente l rregloF il nlisis forml de este lgoritmo se deleg omo ejeriioF v squed letorizd es perfetmente plusile on lists enlzdsF il prinipio @y el lgoritmo resultnteA es el mismoX prtiionr l list segn el pivote y luego deidir en ul de ls dos prtiiones ontinur l squedX Mtodos de ordenamiento 151a + 184 186a template <typename T, class Compare> inline Dnode<T> * dlink_random_search(Dlink & list, const T & x) { if (list.is_empty()) return NULL;
Dnode<T> item(x); Dnode<T> * item_ptr = &item; // puntero a celda que contiene a x Dlink smaller; // lista de los menores que pivot Dlink bigger; // lista de los mayores que pivot Dnode<T> * pivot = static_cast<Dnode<T>*>(list.remove_next());

particionar lista 182a

Dnode<T> * ret_val = NULL; if (Compare () (item_ptr, pivot)) ret_val = dlink_random_search <T, Compare> (smaller, x); else if (Compare () (pivot, item_ptr)) ret_val = dlink_random_search <T, Compare> (bigger, x); else ret_val = pivot; list.swap(&smaller);

186

3. Crtica de algoritmos

}
Uses

list.append(pivot); list.concat_list(&bigger); return ret_val;


Dnode
83a.

or eonom de digoD dlink_random_search() sume que se us sore un list de DlinkF isto requiere que el usurio surt un lse de omprin que onsidere ojetos de tipo Dlink y no Dnode<T>D lo ul he l sunto lgo engorrosoD pues el usurio dee onvertir los punteros del tipo Dlink Dnode<T>F gomo y explimos en QFIFQ @gF ISQAD l lse genri Compare_Dnode nos posiilit l implntin de random_search() pr ojetos de tipo Dnode<T> y derivdosF
3.2.2.11 Seleccin aleatoria sobre secuencia desordenadas

186a

fjo el mismo fundmento del lgoritmo nteriorD es posile implntr l selein letoE riD es deirD usr el iEsimo menor elemento dentro de l seueniF isto se llev o de l siguiente mnerX Mtodos de ordenamiento 151a + 185 186b template <typename T, class Compare> static inline const T & __random_select(T * a, const int & i, const int & l, const int & r) { const int pivot = partition<T, Compare>(a, l, r); if (i == pivot) return a[i];
if (i < pivot) // est en particin izquierda? return __random_select<T, Compare>(a, i, l, pivot - 1); else return __random_select<T, Compare>(a, i - (pivot - l + 1), pivot + 1, r);
partition
175b.

}
Uses

186b

smportnte selr que qu el prolem s se resuelve ms rpido on random_select() que medinte l mer squed seuenilF in efetoD en ltimo soD l selein ser O(n2 )11 F is onveniente veri(r que el vlor de i se irunsri l rngo [l, r]F e efetos de horrr durin de lulo ponemos l veri(in un sol vezD dentro de l interfz pliD en lugr de herlo d llmd reursivF he este modoD l rutin pli se de(ne sX Mtodos de ordenamiento 151a + 186a 187b
template <typename T, class Compare = Aleph::less<T> > const T & random_select(T * a, const int & i, const int & n) { return __random_select(a, i, 0, n - 1); }

r l selein letori on lists enlzds deemos dir l proeso prtiionr list 182a l ontilizin de ls rdinliddes de ls dos prtiiones resultntesF isto
11
Vase ejercicio 22 de captulo 2 (Pg. 27).

3.3. Anlisis amortizado

187

187a

se puede her de l siguiente mnerX particionar lista y contar 187a while (not list.is_empty()) { Dlink * p = list.remove_next(); if (Compare () (p, pivot)) // p < pivot? { smaller.append(p); ++smaller_count; } else { bigger.append(p); ++bigger_count; } }

(187b)

187b

Mtodos de ordenamiento 151a +

186b

template <class Compare> Dlink * dlink_random_select(Dlink & list, const size_t & i) { if (list.is_empty()) return NULL; Dlink smaller; // lista de los menores que pivot Dlink bigger; // lista de los mayores que pivot size_t smaller_count = 0, // cantidad de elementos de smaller bigger_count = 0; // cantidad de elementos de bigger Dlink * pivot = list.remove_next();

particionar lista y contar 187a

Dlink * ret_val = NULL; if (i == smaller_count) ret_val = pivot; else if (i < smaller_count) ret_val = dlink_random_select<Compare>(smaller, i); else ret_val = dlink_random_select<Compare>(bigger, i - (smaller_count+1)); list.concat_list(&smaller); list.append(pivot); list.concat_list(&bigger); return ret_val;

3.3 Anlisis amortizado


gonsideremos un situin en l ul queremos estudir el desempeo de un eh o un estrutur de dtosF v notin O nos proporion un menismo senillo y ojetivo pr nlizr l tendeni de l urv de durin de un lgoritmoF in emrgoD undo nlizmos el desempeo de un eh deemos onsiderr otros spetos diionlesX  n eh tiene vris operiones uyos desempeos pueden ser diferentes y que pueden srse en lgoritmos distintosF or tntoD nlizr un eh puede requerir nlizr distintos lgoritmosF

188

3. Crtica de algoritmos

 or lo generlD un eh suye en un estrutur de dtosF in este sentidoD su nlisis requiere onsiderr el estdo tul de l estrutur de dtosD pues steD muy proleE menteD teng relin diret on el desempeo de l operinF  il estdo de l estrutur de dtos depende de l permutin de operiones que se sued sore el ehF euenis de operin distints produirn tiempos distintosF el respetoD unto demorr efetur n operiones sore un ehcD podemos estleer un ot independiente del vlor de l permutinc es ls ossD vemos los prolems del mero uso de l notin O l nlizr un ehF r esoD exminemos el eh DynListStack<T> @ PFSFR @gF IHSAA y un seueni ulquier de operiones sore este ehY en prtiulrD onsideremos ls seuenis posiles que omporten pushes y popsF i rememormos l implntin de DynListStack<T>D entones podemos prehender que tnto push() omo pop() tomn O(1)F or tntoD ulquier seueni de n operiones sore DynListStack<T> tom nO(1) = O(n)F emos de her nuestro primer nlisis sore el omportmiento de un eh omo un todoF ehor dmos l eh DynListStack<T> l operin popn(n)D l ul extre n elementos de l pil12 F l operin puede herse del siguiente modoX pushn para DynListStack<T> 188 template <typename T> void popn(DynListStack<T> & stack, const size_t & n) { for (int i = 0; i < n and stack.size() > 0; ++i) stack.pop(); }
Uses

188

DynListStack

105c.

i l pil ontiene n elementosD entones el oste de popn() es O(n) pr el peor soF upongmos que reiimos l versin extendid del eh DynListStack<T> on ls siE guientes espei(iones de rendimiento sds en el nlisis trdiionl13 X
xomre de operin i(ieni peor so
O (1) O (1) O(n)

push(item) pop() popn(n)

gunto uest un seueni de n operiones onseutivs sore un ojeto DynListStack<T>c r responder por el peor so tommos l operin popn()D que es l ms ostosD y lulmos el oste de ejeutrl n vees onseutivsF e trvs de este rzonmiento llegmos l onlusin de que el oste totl es n O(n) = O(n2 )F ero este rzonmiento no es justoD pues el desempeo de popn() depende de l ntidd de elementos en l pilF n llmd popn(n) tom O(n)D pero ls siguientes tomrn O(1)D pues se ejeutn sore un pil v3F il nlisis nteriorD ms sujetivoD que onsider ls irunstnis de invoin popn()D nos revel que ulquier seueni de n operiones esD en promedioD O(n)F
12 13
Operacin que fue denida para el TAD El resto de las operaciones

ArrayStack<T>
y

desarrollado en 2.5.2 (Pg.

101) y que

toma

O ( 1) .

size(), is_empty()

top()

se omiten porque tienen tiempo constante y

no producen modicaciones sobre la estructura de datos.

3.3. Anlisis amortizado

189

n tni de vngurdi que intent on ierto xito ojetizr el nlisis de tipos strtos de dtos se denomin nlisis mortizdoF v ide es ponderr los ostes de operiones de un eh trvs de un potenil strto o de rditosF
3.3.1 Anlisis potencial

in est lse de nlisis deemos enontrr un funin potenil : D RD donde D represent l estrutur de dtos suyente l eh y R es el onjunto de los nmeros relesF D se de(ne omo D = {D0 } {D1 , D2 , . . . , Dn }D donde D0 es el estdo iniil de l estrutur de dtos y {D1 , D2 , . . . , Dn } son los estdos suseuentes resultntes de un seueni de operiones sore el ehF he qu mner puede usrse l funin potenil pr nlizr un ehc r ordr l preguntD plnteemos l siguiente ide de oste mortizdo pr l iEsim operin sore un ehX @QFPVA ci = ti + (Di ) (Di1 )
Diferencia de potencial: i

ti es l durin de ejeuin de l iEsim operinD mientrs que i es l diferenE i de potenil entre l operin tul y l nteriorD l ul represent el onsumo o l ompensin de energ segn que el diferenil se positivo o negtivoF in este soD el potenil denot un espeie de energ que se gst o se gn entre un operin y otrF il oste mortizdo modeliz el heho de que lguns operiones uesten ms que otrsD pero tmin el que otrs operiones umenten el potenil de l estruE tur de dtos de mner tl de que dispongn de energ undo tenF v euin @QFPVA nos ondue de(nir el oste totl de n operiones de l siguiente formX

T(n) =

ti

=
i=1 n

ci ci

((Di ) (Di1 ))
i n n

i=1

=
i=1

i=1

(Di ) +
i=1

(Di1 ) =

@QFPWA

C=

ci

=
i=1 n

ti

+
i=1

(Di )
i=1

(Di1 )

i=1

=
i=1 n

ti + ti

(D1 ) + + (Dn ) (D0 ) + + (Dn1 )

=
i=1

+ (Dn ) (D0 )

@QFQHA

r que el potenil teng sentidoD es menester de(nir de mner tl queD pr tod permutin posile de operionesD (Dn ) (D0 )D es deirD que l difereni potenil totl entre el estdo iniil de l estrutur de dtos y l ltim operin siempre se positivoD pues si noD en lgn momentoD l estrutur de dtos reer de potenilD lo ul pree no tener sentido en nuestro ontexto terrenlF odemos sumir que (D0 ) 0D pues l ide de un estrutur de dtos es dr poteni ls futurs operionesF fjo

190

3. Crtica de algoritmos

est suninD (Dn ) (D0 ) 0D lo ulD en funin de @QFQHAD nos ondue (rmr l desiguldd siguienteX
n n

T(n) =
i=1

ti

ci
i=1

@QFQIA

fjo ls premiss plntedsD l desiguldd @QFQIA nos demuestr que C(n) ot suE periormente T(n)D rzn por l ul podemos trjr on seguridd medinte C(n) y los peores sos de ti segn d un de ls operiones del eh y ls posiles permutiones de seuenis de operinF gonsideremos l versin extendid del eh DynListStack<T> y de(nmos : D R omo l ntidd de elementos que tiene l pil l trmino de un operinD por lo que (D0 ) = 0F istudiemos lo que ourre on los poteniles mirndo lgun seueni de operin prtiulrD por ejemploD l mostrd por l tl siguienteX
i

yperin E push() push() push() pop() push() popn(3)

ti
E 1 1 1 1 1 3

( D i ) 0 1 2 3 2 3 0

i = (Di ) (Di1 )

ci = ti +
E 2 2 2 0 2 0

H I P Q R S T

E 1 1 1 1 1 3

el (nl de un push()D el tmo de l pil se inrement en unoD por lo que siempre se umpleX ci = 1 + 1 ;
ti i

si l iEsim operin es push()F el (nl de un popn(k)D (Di ) = Ni1 k donde Ni1 es l ntidd de elementos ntes de efetur popn()F he este modoD luego de ejeutdo un popn(k)D el oste mortizdo serX ci = k + Ni1 k Ni = 0 ;
k i

d vez que l iEsim operin se popn(k)F xotemos que el oste de pop() es equivE lente popn(1)F in sntesisD independientemente de l permutin de l seueni de operinD los ostes mortizdos del eh DynListStack<T> son los siguientesX
xomre de operin

c
2 0 0

push(item) pop() popn(n)

ehor estudiemos el oste totl de n operiones onseutivs sore el eh DynListStack<T>F odemos dividir ls operiones en n1 push() y n2 popn() @reordeE mos que pop() popn(1)AF or tntoX T(n) C(n) = O(n1 ) 2 + O(n2 ) 0 = O(n1 ) = O(n)

3.3. Anlisis amortizado

191

es puesD el oste promedio por operin entre ulquier permutin de n operionesD est ddo porX C(n) O(n) ti = = O(1) n n
3.3.2 Anlisis contable

in un nlisis mortizdo ontleD d operin se le sign un ntidd onstnte llmd rditoD esogid uiddosmente segn l nturlez de l operinD l ul no neesrimente se orresponde on el oste rel en durinF i el oste en durin de l iEsim operin es ti D y ci su oste rditoD entones requerimos stisferX
n n

C=
i =1

ci T(n) =

ti
i=1

@QFQPA

pr ulquier seueni posile de n operiones sore el eh o estrutur de dtosF il oste mortizdo del eh o estrutur de dtos pr un seueni de n operiones esX C=
n i=1 ci

@QFQQA

v desiguldd es l mism que l expresd en @QFQIAD pero sumiendo que el oste mortizdo ci es onstnte pr d operin @lo ul result el so pr el eh DynListStack<T>AF in emrgoD el rzonmiento pr l selein del rdito de d operinD unque inspirdo en l ide de potenilD est prestdo del rgot merE ntilF v ide es que siempre de her rdito pr oster ulquier seueni de operinF in este sentidoD los rditos de d operin deen seleionrse de modo tl que (nnien on rditos otrsF he iert mnerD l signin de rditos puede interpretrse omo un funin poE tenil disret y por prtes segn l operinF or ejemploD signemos l eh extendido DynListStack<T> los siguientes rditos mortizdosX
xomre de operin grditos
2 0 0

push(item) pop() popn(n)

r rindr sentido l rzonmiento que nos ondue est selein de rditos deemos oservr que no puede her un pop() si ntes no huo un push()F he este modo podemos deir que undo se efet un push() se dejn dos @2A rditosD uno orrespondiente l oste en durin y otro dejdo en prstmo o grnt pr oster l durin de extrin del elemento undo se efete su pop()F uesto que ls operiones hn sido osteds por delntdo por el push()D pop() y popn() no tienen rditosD pues sus ostes hn sido mortizdos por el push()F gon los ostes mortizdos nteriores podemos lulr un ot pr el oste mortiE zdo del eh DynListStack<T>D el ul no exeder deX C

2n = 2 = O (1) n

192

3. Crtica de algoritmos

il trmino rditoD proveniente del vero ltino r ed ere D signi( reerD on(rD dr fe en un personF roy en dD el mundo eonmio emple el trmino rdito pr referir un ntidd de dinero que se otorg en prstmoY tl pree que l presunin de uen es unti(le oD por didurD est vinuld l poder eonmio14 F il trmino mortizr se us en el mundo nrio y es desde ll que proviene l metfor on este tipo de nlisisF guriosmenteD mortizr proviene del frnsD el ulD su vezD proviene del ltn medievl dmortizreF il pre(jo d indi proximiddD mientrs que mortis signi( muerteF emortizr signi(r entones l proximidd de l muerteD pero el trmino se us desde l idd wedi pr onnotr l proximidd de l muerte de un deudF
3.3.3 Seleccin del potencial o crditos

r que un nlisis mortizdo teng sentidoD es esenil enontrr un uen funin potenil o logrr interpretr ls operiones en funin de su trjo y l mner en que ells mortizn o onsumen rditos entre sF he un iert formD el nlisis mortizdo es sujetivo en el sentido de que deleg en l funin potenil l sujetividdes del eh y de su estrutur de dtosF is entones durnte el estudio y selein de l funin potenil @o de los rditos por operinA undo se trtn tles sujetividdesF or lo generlD l funin potenil dee ponderr el estdo de l estrutur de dtosF in el so de un seueniD el tmo es menudo un uen esogeniF n mner de filitr el nlisis mortizdo de un operin onsiste en dividirl en etps seuenilesD nlizr d un por seprdo y luego sumrlsF upongmos que un seueni de operiones y un operin efetud en l iEsim vez on oste morE tizdo ci entre el estdo Di1 y Di F ehor supongmos que l fse Di1 Di puede dividirse en ls fses D1 , D2 , . . . Dk D de mner tl que Di1 = D0 y Di = Dk F e tj el oste de psr del estdo Dj1 Dj D entonesX
k

ti =
j=1

tj

@QFQRA

egn @QFPVAD el oste mortizdo de ti puede de(nirse omoX


k k

cj =
j =1 j=1 k

(tj +(Dj ) (Dj1 ))


tj + (Dk ) (D0 )
j=1

= ti +(Di ) (Di1 ) = ci
14

@QFQSA

El premio Nobel de la Paz de 2006 fue conferido al profesor bengal Muhammad Yunus, fundador del

Banco Grameen (banco rural). El banco en cuestin concede microcrditos a prestatarios muy pobres materialmente, sin ninguna garanta o crdito econmicos, permitindoles confrontar su pobreza material. No sorprendentemente, el 90% de los prestatarios reintegran completamente el prstamo, aunque tambin el 95% de los prestatarios son mujeres.

3.4. Correctitud de algoritmos

193

or tntoD el oste mortizdo de l operin es l sum de los ostes mortizdos de sus etpsF edems de los onoimientos sore l estrutur de dtos y de l tni de nlisisD en l squed y selein de un funin potenil intervienen l experieniD el rte y l suerteF

3.4 Correctitud de algoritmos


gundo hlemos er de l orretitud de un lgoritmo o progrm nos referimos que ste logre el (n pr el ul fue destindoF uesto de otro modoD l orretitud onierne lo que l prinipio de este ptulo denominmos e(iD lo ulD en el so de un progrmD equivle deir que ste no rroje mls respuestsF e menudoD esto no es senillo de determinr porque hst que el progrm est opertivo no se puede veri(r si es o no orretoF v e(i queD reordemosD no es lo mismo que l e(ieniD se juzg por ompletitud y minimliddF or ompletitud deimos que el efetoD o seD el (nD se lne lE menteF or minimlidd deimos que no se efete lgo diionl l (nD lo que en el lenguje tenortio se denomin efeto olterlD expresin que omnmente indi que l onseuin del (n rre efetos diionles que freuentemente son indeselesF il R de julio de IWWT se lnz por vez primer el ohete europeo erine SF snmedito l lnzmientoD el ohete empez desvirse de su tryetori vertil y dei destruirse RH segundos despusF vs investigiones ulteriores revelron que un rutin trt nmeros en punto )otnte omo si estuviesen representdos en ritmti enterF v versin nterior del ohete erine R mnej enteros y l rutin en uestin no se veri( exhustivmente pr l nuev versin del oheteF v rutin er inorret UPD VSF
3.4.1 Planteamiento de una demostracin de correctitud

n interpretin de orretitud estri en determinr si el progrm rroj respuests orrets pr tods ls entrds posilesF in funin de estoD puesto que en l myor de ls osionesD los vlores posiles de entrd son o muy grndes o in(nitosD un prue de orretitud requiere lsi(r l entrd en todos los suonjuntos posiles que onformn l entrdF vo nterior puede plnterse formlmente omo sigueF e I el onjunto dominio de entrd de un progrm y R el onjunto resultdoF intonesD un prue de orretiE tud dee exminr el lgoritmo y determinr en funin del mismo @ifurionesD lzosD etterAD los suonjuntos de entrd I = I1 I2 In D junto on sus suonjuntos de slid R = R1 , R2 , . . . , Rn F xotemos que los suonjuntos resultdo pueden solprse entre sD o seD que los resultdos no tienen por que ser exluyentesF v prue de orretitud onsiste entones en veri(r si pr d suonjunto Ii el lgoritmo o progrm rroj l slid Ri F uesto que menudo Ii y Ri son muy grndes o in(nitosD l prue se efet on los vlores fronter de los suonjuntosF or ejemploD un inspein ms profund del ordenmiento por selein estudido en QFIFQ @gF ISHA revel que el loque e min el ndie menor entre i C I y n E I 151b siempre enuentr el mnimo entre i+1 y n-1D pues todo el rngo (i..n) es

194

3. Crtica de algoritmos

inspeiondoF or tntoD e min el ndie menor entre i C I y n E I 151b es orretoF or otr prteD el for ms externo reorre todo el rreglo entre [0..n 1)Y slo flt el ltimo elemento del rregloD el ul ser inspeiondo por e min el ndie menor entre i C I y n E I 151b F or tntoD todos los elementos del rreglo son inspeiondos pr deterE minr el mnimoF il lgoritmo pree serD puesD orretoF il onjunto de entrd fue I = {ods ls permutiones posiles} y el de slid R = {ods ls permutiones ordends}F
3.4.2 Tipos de errores

n error en un progrm puede ometerse durnte ls siguientes fsesX


Diseo:

premiss inorretsD sumids durnte el diseo de un lgoritmoD muy posileE mente onduzn resultdos inorretosF veesD l orretitud de un lgoritmo no es senill de demostrrF in este sentido hy dos lses generles de errores en l prueX IF ue ls instnis posiles de entrd no estn ompletmente uiertsD so en el ul no se sr si el lgoritmo es orreto o no pr l lse de entrd usenteF PF ue lgun o ms de ls prues est errdF osilementeD los errores en l prue de orretitud son los ms seriosD pues induen lo que se denomin omo fls perepinY el lgoritmo podr o no estr orretoD pero (rmmosD sin ertitudD que lo esF

Prueba de correctitud del algoritmo:

Codicacin:

los lgoritmos deen trduirse un lenguje de progrminF ist fse se llm odi(in y durnte ell se esogen ls representiones de los dtos jo l form de estrutur de dtosD s omo ls representiones de ls seuenis de ejeuin del lgoritmo segn los modelos del lenguje @whileD forD ifD etterAF gomo menionremos posteriorE menteD pr evlur orretitud se emplen diversos tipos de progrmsF in este sentidoD un urt lse de error puede induirse por el heho de que uno de los progrms usdos pr veri(r orretitud se inorretoF

Ejecucin y falla de programas de vericacin:

ente ests perspetivs de l orretitudD undo l heho de que st en s se prehende undo se ejeute el progrm y se resuelv el prolemD un progrmdor dee sumir permnentemente un titud de dud respeto l orretitudF
3.4.3 Prevencin y deteccin de errores

ry dos enfoques omplementrios entre s pr lidir on l orretitud de un progrmX IF reveninX mo evitr ometer un errorc

3.4. Correctitud de algoritmos

195

PF heteinX omo detetrlo lo ms pronto posilecX v prevenin requiere un titud rti por prte del progrmdor en el sentido de que prend de sus errores y usque mners de no volver ometerlosF v inorretitud siempre es ostos en el sentido de que de lgun mner rre prdidsD pero hy situiones en ls ules es demsido ostosF or ejemploD un fll en un progrm ontroldor ejeutndose en un omputdor industril puede usr un prd de plnt que detiene l den produtivY ms ostoso es un fll en un progrm de misin rtiD un stliteD por ejemploF v detein requiere forzosmente un nlisis inspetivo del lgoritmo o progrmF gundo el nlisis se llev o sin ejeutr el progrm en uestinD se le denomin esE ttio F enlogmenteD undo el nlisis se vle de l ejeuin del progrm se le llm dinmio F e l pregunt de ul es mejorD l respuest es que unto ntes se detete un error menos ostoso es steF gonseuentementeD pree oligtorio efetur nlisis esttio ntes de instrumentr un progrmF r proximr el entendimiento de este suntoD onsideremos l gr(15 de l (gur QFUF
Costo de correccin de un error

Produccin Pruebas

Codificacin

Diseo estructura de cdigo Diseo arquitectural Requerimientos

Tiempo de desarrollo de un sistema

pigur QFUX gostes de orrein de errores en funin de l etp de desrrollo de un proyeto de softwre v (gur QFU pitoriz ls diferentes etps del llmdo ilo de desrrollo de softwreF hurnte ls tres primers fses se tomn deisiones de diseo de lgoritmos y menismos de sistemD mientrs que durnte ls tres restntes es undo tpimente se detetn los erroresD siendo los de diseo los ms ostososF odemos deir que el oste de un error y su orrein es diretmente proporionl l momento en que se detetF gonsiguientementeD unto ms trde se detete un errorD ms impto en ostes ste tieneF
15
Esta grca est inspirada del curso sobre Promela/Spin, impartido el 11 de abril de 2002, por Theo C. Ruys, en Grenoble, Francia, durante el Para ms detalles, vase:

pin PHHP orkshop.


y

 http://wwwhome.cs.utwente.nl/~ruys/  http://www.spinroot.com/

196

3. Crtica de algoritmos

he l re)exin nterior se dee desprender un fuerte sentido de preuin que se dee sumir durnte ls tres primers etps del ilo de desrrolloF il prolem sioD y est es l trmp l que suumen muhos ingenieros y progrmdoresD es que undo se llev o un nuevo sistem y se tomn deisiones de diseoD no se onoen ules sern sus onddes en e(i y e(ieniF ehor ienD muhs vees se e en l trmp de tomr deisiones de diseo sin onoer priori sus onddesF gonseuentementeD muhs vees se enuentrn errores de diseoD que son de los ms ostososD durnte l fse de instrumentinF gmo se puede disminuir este riesgoc v respuest es hiendo modelos de diseo y veri(ndolos ntes de su implementinD tl omo se ostumr her en otrs rms de l ingenierF
3.4.3.1 Disciplina de programacin

fuens son ls ostumresD uens deen ser ls orsF n ostumre es un hito dquirido de onoimientos prtiosD omprodosD desuiertos durnte hehurs de uens orsF in progrminD omo en ulquier otr prtiD los prtintes forjn ostumresD uens ostumresD porque si no se les morir l prtiF gundo un ostumre deviene omn entre todos @o l myor prte deA los prtintesD entones st deviene en normF v oservni de un ostumreD ms n de un normD requiereD segn se se prendiz o mestroD de un esfuerzo onsiente de voluntd por reordr l pliin de l norm y de un fuerz de rter por no trnsgredirlF e este esfuerzo y fuerz se le denomin disiplinF roy en dD ls uens ostumres se les llm uens prtisD pero l redundni de este li(tivo plnte un migedd on l noin de prtiD rzn por l ul seguiremos usndo ostumre oD undo st se ojetiv entre los prtintesD normF gules son ls ostumres de progrmin que suyen detrs de progrms orreE tosc xumerososD voluminosos e interesntes textos hn sido esritos sore este suntoF xo hyD puesD espio en est susein pr presentr y disutir todo lo inherente l disiplin de progrminF ero s podemos remitirnos l siguiente delogo de qerE rd roltzmnn UQ pr l esritur de progrms orretos rtiosF
Declogo de Holtzmann [73]

goto, longjmp o recursin directa o indirecta lvo lguns exepiones prtiulresD l instruin goto h sido olid desde he uns unts dds porque v ontr l legiilidd de digoF or didurD los nE lizdores esttios tienen seris di(ultdes pr interpretr qu suede on un gotoF vo mismo ourre on el onjunto de instruiones longjmp de l iliote estndr CF utins reursivsD diret o indiretmenteD son tmin muy difiles de nlizr por nlizdores esttiosF edemsD l reursin us implitmente l pil del sistemD uy gestin es difil de otrF ryD por supuestoD exepionesF wuy en prtiulrD en este textoD on l reursin diretF in ese sentido podemos deir que slo dee utilizr reursin pr funiones uy orretitud hy sido demostrd y uyo onsumo de pil se grntie estr otdoF in esos sosD l funin reursiv puede sustituirse por un trono o indirse un nlizdor que l funin en uestin es orretF
1 No usar

3.4. Correctitud de algoritmos

197

2 Siempre asegurar que todo lazo termine

gunts vees no hemos ejeutdo un progrm que no terminc in el so geneE rlD los progrms no terminn Eundo estn disedos pr terminrE porque en en lzos eternos16 F v regl onsiste entones en evidenir grnt de que d lzo del progrm @whileD do-whileD o forA termineF gd vez que se progrme un lzoD pregntese y respndse mo se segur que ste siempre termineF v ni exepin est regl es undo se esrie un lzo que jms dee terminrF xormlmenteD esto ourre en progrms itertivosD por ejemploD un servidorF in este soD l regl es segurr queD en efetoD el lzo nun termineF
3 No utilizar memoria dinmica despus de haber inicializado el programa

in el espritu de este textoD l regl esX independizar toda abstraccin del uso de in otrs plrsD ulquier lgoritmo o estrutur de dtos dee oneirse sin dependeni en memori dinmiF or memori dinmi entendemos llmds malloc()/free()D new/deleteD sbrk()D alloca() yD en generlD ulquier otr primitiv de mnejo de memoriF or iniilizin entendemos l primer fse de un progrm en l ul se delrn ls estruturs de dtos y dems lses de vriles y se les signn sus vlores primigeniosF v rzn de ser de est regl es doleF in primer lugrD l inmens myor de menismos de dministrin de memori no ofreen ots onstntes sore el tiempo de ejeuinF e medid que se gestion ms memoriD ms frgmentin ourre en el espio de direionmientoD lo ul degrd el desempeo y l proilidd de xito de reservinF gonseuentementeD unto ms dure un progrmD ms prole es que l reservin de un loque de memori flleF ist fuente potenil de fll he imposile ofreer un grnt de orretitud @desde l perspetiv de mnejo de memoriAF in segundo lugrD el mnejo de memori es origen de un grn proporin de erroresD rzn por l ulD un form de evdir este potenil de error onsiste simplemente en no usr memori dinmiF yservemos que el uso de un reoletor de sur @grge olE letorA no evde este prinipioD sino que ms lo ien justi(D pues l gestin de memori sd sore un reoletor exhie muh ms inertidumre y tiene menos desempeo que un mnejdor trdiionlF vos errores de mnejo de memori sern revemente trtdos en QFRFQFQ @gF PHUAF rogrms disedos pr prtr sus reursos omputionles durnte su iniiliE zinD no slo son ms files de segurr orretitudD sino que tienden exhiir ms desempeoF in funin de est reglD nos est veddo el uso de memori dinmic v respuest es reltivF xotemos en primer lugr que los diseos de lgoritmos y estruturs de dtos que trtmos en este texto se ogen en su myor est reglF he hehoD hst el presente hemos plido el prinipio (nEE(n presentdo en IFRFPD uy oservni ondue D primeroD strer sin onsiderr el mnejo de memoriY omo en efeto lo hemos heho y hremos trvs de este textoF vos eh dependientes de memori @on pre(jo en nomre
memoria dinmicaF
16
A menudo, la expresin es lazo innito. Sin embargo, en matemtica, as como en otros dominios, el adjetivo innito se usa en el sentido de proporcin, sentido para el cual, en la opinin del autor, no encaja el tiempo. Para el tiempo en s existe el adjetivo eterno.

198

3. Crtica de algoritmos

de lse hynAD derivn de un versin independiente del mnejo de memoriF ry prolems uys soluiones son lrgs en durin y pr los ules es ineludile el mnejo de memoriF in est lse de prolems enjn los grfos y otrs lses de pliionesF
4 Mximo, 60 lneas por rutina

v visin y omprensin humn de un rutin omo un unidd de progrm se remite lo visile en un hoj de ppelD o seD proximdmente TH lnesF utins que exedn est longitud se frgmentn en vris hojs @o pntllsA yD por supuestoD tienen ms proilidd de frgmentr l omprensinF
5 Mnimo dos invariantes (o asertos) por funcin

n invrinte es un ondiin que siempre deer de umplirseF u inumplimiento denotrD entonesD un errorF vs estdstis industriles de prue de progrms indiin ourreni de error entre IH y IHH lnes de digoF or tntoD el uso de invrintes omo preondiionesD postondiE iones e invrintes que se deen mntener en lzosD undo l regl inmeditmente nteriorD dee fvoreer l lidd del digo por disminuin de ls proiliddes de ourreni de error y de umento de su deteinF vs invrintes no fetn el efeto de un rutinD unque s su desempeoF or est rznD menismos de invrintes pueden deshilitrse o herse de lto rendimientoF ws delnteD en QFRFQFQ @gF PHRAD hlremos sore el uso de invrintesF
6 Declare e inicialice objetos lo ms cerca posible de su primer uso

v orrupin de dtos es otr de ls ourrenis priniples de errorF gunts vees no nos hemos enontrdo en l situin misterios en l que un vrile no tiene el vlor esperdoc n de ls virtudes del oultmiento de informin es que limit l orrupin l mito de uso del dtoF i se trt de un ehD ien disedoD por supuestoD l orrupin de uno de sus triutos slo puede deerse uno de sus mtodosF elgo preido en el mito de los ojetos de uso interno de un rutinF or tntoD delrr un ojeto lo ms er posile de su primer usoD fvoree que el ojeto slo exist en su mito de usoF or otr prteD l iniilizin inmedit l delrin elimin l posiilidd de orrupin entre l delrin y su primer utilizinF
7 Siempre vericar valor de retorno de una funcin, as como sus parmetros de entrada y salida

in plrs ms preissD d punto invonte de un funin dee veri(r perteE neni l dominio del vlor de retorno s omo de sus prmetros de slidF hel mismo modoD d funin dee veri(r que los prmetros reiidos tmin estn dentro de su dominioF
8 Minimice el uso del preprocesador a inclusin de archivos y especicacin de macros simples

eunque los preproesdores son muy poderosos omo medios d ho pr extender el

3.4. Correctitud de algoritmos

199

lengujeD no son ompildoresF n preproesdor no veri( el sistem de tipos yD por didurD puede generr instruiones que ompilnD que orrientemente funionenD pero que estn totlmente oults l mird del progrmdorF gonseuentementeD se dee evitr l ontenin de nomresD los prmetros vE riles y los mros reursivosF v exepin de l regl es pr spetos que no pued implntr el lengujeD en uyo so se dee usr prntesis por d unidd de expnsin del mroF eordemos que C y C++ tienen funiones inline que son equivlentes en funionlidd y desempeo l myor de los mrosD on el vlor dido de que usn el sistem de tipos del ompildorF
9 Restrinja el uso de apuntadores a no ms de un nivel de dereferencia

n derefereni es un eso lo que ontiene el punteroF in este sentidoD l regl estlee que no se pueden usr dos o ms dereferenisD por ejemploD lgo omo **ptr = ...F r omenzrD ms de un nivel es omplido de omprender n pr los ms virtuE osos progrmdoresF in segundo lugrD tmin es difil de estudir por los nlizdores esttiosF or supuestoD hy sos en que l delrin de punteros punteros es neesriD pero esto no rre neesrimente violin de l reglF r un ejemplo de seguimiento de est reglD vse l implntin de DynArray<T> presentd en PFIFR @gF QRAF
10 Siempre compile con todos los alertas del compilador habilitados y use analizadores de cdigo

v myor prte de los ompildores modernos efet veri(iones de errores tpiosF or qu rzn hrn de desrtrse ess veri(ionesc v rud respuest es que muhos progrmdores son mlridos y pre(eren sltr un error o lert del ompildor on tl de proseguirD on ms proilidd de error en el futuroD su proyetoF il mismo rzonmiento pli pr los nlizdores esttios o dinmiosF e vees ourre lo que se denomin flso positivoD es deirD un reporte o lert de un error que no existeF or lo generlD estos reportes ourren en ominiones de digo intrinds ls ulesD efetos de l lriddD es preferile modi(rls pr que el omE pildor no rroje mensjes de lert o de errorF
Las preguntas actitudinarias de Van Cleck [173]

e trvs del devenir de l progrmin se h oservdo que trs l orrein de un error se tiende enontrr otro reliondo o uno nuevo introduido por l mism orreinF min se h notdo un resisteni nturlD viiosD por prte del proE grmdor promedioD en mirr minuiosmente el origen del errorF l titud es viios porque no st on orregir el errorD sinoD en so de que detrs del mismo suyz un ml titudD enontrr en qu onsiste tl titud de modo que st pued enmendrse yD onsiguientementeD no repetir l mism lse de errorF om n glekD uno de los priniples desrrolldores de Multics QID IQRD quiz el hito ms importnte en sistems opertivosD se plnte tres pregunts IUQ que un desrrolldor siempre dee herse d vez que detete un error y que lo enminn desurir l titud originri de los erroresF

200

3. Crtica de algoritmos

IF e enontrr el error o l mism lse de error en otr prte del progrmc lnterse est pregunt onllev estleer un ptrn pr el error yD en funin steD usr en el resto del progrm otrs priiones del ptrnF vos hllzgos del ptrn son lugres proles de repiteni del errorF PF gules otros errores estrn reliondos on el enontrdo o on su orreinc rtiendo de l posiilidd de que l orrein introduz un nuevo errorD ordr est pregunt onfront plnter un orrein e interrogr qu sueder un vez que st se hgF e su vezD esto ps por demostrr rigurosmente que l orrein se orretY o seD que no onteng lgn errorF QF u se deer her pr prevenir ometer de nuevo el errorc n vez respondids ls dos pregunts nteriores se dee estleerD en funin del ptrn enontrdoD un protoolo que evite repetir el ometimiento del errorF uiz se est l pregunt ms enriqueedor pr el progrmdorD pues su ordje plnte un ensenzF
3.4.3.2 Anlisis esttico

Compilador y sistema de tipos

il sistem de tipos del lenguje de progrminD en onjunin on el ompildorD efetn un enorme trjo de veri(in de orretitud l vlidr l orrespondenis del progrm respeto l sistem de tipo del lengujeF gomo ejemplo trivilD pero notleD onsideremosX
int x; string s; s = x; // Violacin de tipo. ERROR DE COMPILACIN

vos errores de ompilin hn sido us de ofusin y mldiin entre los progrE mdores noveles y lgunos vnzdosF guntos de nosotros hemos permneido lgun vez loquedos porque un progrm no nos ompilc n mird ms rti del prolem nterior nos permite prehender queD slvo un error del ompildor o del lenguje de progrminD uestin improle pero ftileD un error de ompilin tiene l grn ondd de que nos fuerz enfrentr el ometimiento de un error omo progrmdoresF in el ejemplo nteriorD no tiene sentido signr un entero un den de rteresF or lo generlD los ompildores prmetrizn sus modos de detein y trtmiento de erroresF gonsltese el mnul del ompildor GNU gcc pr ms detllesF in todo soD omo y dit l dim regl de roltzmnnD omplese on tod l detein de errores y lerts hilitdosF xo se prosig hst que el ompildor deje de rrojr lerts y erroresF
Analizadores externos

esult que l squed de errores en el digo fuente de un progrm se puede utomtizr pr vlidr que ste sig los estndres de odi(in del lenguje u otros

3.4. Correctitud de algoritmos

201

estleidos por el grupo trjoF uiz el ejemplo ms reputdo de esto se lint VUD un nlizdor esttio de fuentes pr el lenguje C que h devenido esenil pr el desrrollo de progrms en CD hid uent de l deilidd del sistem de tipos de este lengujeF lint n es mplimente usdoF ry uns unts herrmientsD en su desfortund myor de uso omerilD que hE en nlisis esttio de orretitud de un progrmF vmentlementeD n existen pos herrmients lires que hgn un nlisis esttio l mismo nivel que otrs omerilesF odemos itrD emperoD LC-LINTD omplementrio del lere lint VUD y Flawfinder P y its4 IUS orientdos l squed de errores de seguriddF
Metacompilacin

wetompilin onsiste en ofreer un ompildor extensile en el sentido de que el usurio pued dir nuevs regls de ompilin segn el onoimiento plitivo del usurioF ist ide tiene muho sentido porque el ompildor posee l mquinri neesri pr l veri(in utomtiD pero no posee el onoimiento sore el tipo de pliinF or el ontrrioD el odi(dor s posee quel onoimientoD pero dolee de l flt de quell mquinriF v ide se sD por tntoD en el prinipio (nEE(nF or ejemploD un usurio podr espei(r que l signin entre punteros est proE hiid y que pr tod llmd l operdor new sore un puntero dee enontrrse por lgun prte otr llmd l operdor deleteF hel mismo modoD tl extensin l ompiE ldor podr permitir veri(r esttimente que quel new ourr ntes que el deleteF e pueden provehr tmin ls propieddes trnsformionles del ompildor pr ejeutr iones semntisF or ejemploD que el ompildor implnte l primer regl de roltzmnn y desple l gestin de memori l fse de iniilizinF eportes de ingler et l RSD RT indiin que l metEompilin ser un de los priniples medios de veri(in de orretitud en los os veniderosF wedinte est tniD ingler et l RSD RT y hn enontrdo miles de errores en vinuxD ypenfh y muhos y omplejos sistems omerilesF vmentlementeD los progrms resultntes de ls investigiones de ingler et t RSD RT no son de lire esoF
Exploracin del espacio global de estado

n tni grndios de veri(in de orretitud requiere trduir el progrm un mquin de estdo (nito que represente los diferentes estdos de los progrmsF uesto que no disponemos de espio pr explir formlmente qu es un utmtD lo intuiremos pitrimente medinte un simplsimo utmtD mostrdo en l (gur QFVD que lul el menor entre dos nmeros x, yF gd rulo orresponde un estdoD mientrs que d )eh es un trnsiin entre dos estdosF il mio de estdo ourre undo se ejeut l instruin soid l trnsiinF il estdo iniil se denot on un )eh isld que le llegD mientrs que uno (nl se expres on otr )eh que le sleF n vez otenido el @o losA utmt@sAD un simuldor se enrg de explorr tods ls ominiones de estdos posiles en l squed de errores sinttios y semntiosF n error sinttio se onsider omo un error generl ulquier lse de progrmY por ejemplosD que un progrm jms ejeute lgun porin de su digoD o que el progrm

202

3. Crtica de algoritmos

0 x<y 1 not x<y 2

min=y 3

min=y

ret=min 4

pigur QFVX n utmt que lul el menos entre dos nmeros entre en un estdo de loqueo eterno en el ul se esper por un evento que jms ourE rir @dedlokAD o que se entre en l ejeuin de un lzo in(nitoF n error semntio te l (n del progrm y pr espei(rlo se utiliz por lo generl lgi temporl17 o utE mts de predidos @o de fhiA18 F el proeso de veri(in semnti medinte lgE i temporl @o utmts de fhiA se le denomin Vericacin de modelo @wodel gheking AF es ls ossD l veri(in por este mtodo pree stnte simpleF ero en l reE liddD los utmts resultntes de un progrm rel son extremdmente grndes y no siempre existe un mtodo determinist pr trduir progrms hi utmtsF iste mtodo de veri(in es muho ms interesnte undo se veri(n progrms onurrentesY es deirD progrms ompuestos por vrios progrms que se ejeutn siE multnementeF ero qu se requiere onstruir un utmt glol ompuesto por l ominin de los estdos de todos los utmtsF erimenteD l explorin glol del espio de estdo es pz de detetr ulquier error sinttio y todos los semntios en funin del (n de(nidoF in l prtiD emperoD existe el prolem de que el espio de estdo del utmt glol es explosivo O(2n )F ry tnisD sds en desrrollos teriosD que permiten lidir on este prolemD siendo ls ms importntes ls siguientesX IF elgoritmos simliosX l ide onsiste en sustituir el utmtD o prte de lD por un frmul lgiF or ejemploD pr el utmt nterior ser posile sustituir ls trnsiiones desde el estdo I hi el R por un trnsiin uyo predido ser x < y or not x < y, retaminD pues el )ujo de ejeuin nun se detendr us de ls trnsiiones suprimidsF PF eduin por orden prilX est tniD que se deriv de lgunos resultdos mtemtiosD onsisteD muy grosso modoD en sustituir lrgs dens de trnsiiones seuenilesD que no tienen ifurionesD por un sol trnsiinF il orden pril se pli dinmi y reursivmente undo se trt del utmt glolF or ejemploD el utmt de l (gur QFWE puede sustituirse por el de l (gur QFWE reduido dos estdos y un trnsiin ompuest por ls tres instruiones del utmt extendidoF n simuldor puede dinmimente detetr y efetur est lse de reduinF
17 18
La lgica temporal es una lgica de predicados cuyos cuanticadores consideran al tiempo [145]. Un autmata de predicados es uno cuyas transiciones slo contienen predicados lgicos relacionados

con un autmata resultante del modelo [25, 115].

3.4. Correctitud de algoritmos

203

tmp=x 1

x=y

y=tmp 3

tmp=x x=y y=tmp

Se(b)

(a) cuencia

Se-

cuencia reducida

extendida

pigur QFWX ijemplo de reduin por orden pril QF estrinX en simpleD est tni se s en oservr onjuntos de estdos y E strer su interfz de mner generlF il onjunto onsiderdo se sustituye por un utmt reduido uyo rol es simulr el resultdo generlF vs tnis nteriores permiten reduirD muy onsiderlementeD el espio de estdoF in didurD otr tniD llmd supertrz UUD que exminremos en SFQFP @gF RQRAD sd en el uso de tls hsh sin detein de olisinD permite reduir todv ms el espio glol de estdoF vo nteriorD undo l onoimiento de ls ienis estdstisD indii que es posile explorr si todo oD todo IVQD el espio de estdo si se ejeutn su(ientes simuliones letorisF uiz el exponente ms populr de est lse de veri(in es spin/promela USD UTD URD ISQF promela es un lenguje de espei(in de progrms @no un lenguje de progrminA y spin es su simuldorF il enfoque requiere que el progrm se espei(que en promelaD lo ul de un pso diionl y un fuente potenil de error l trsldr l espei(in en promela hi el lenguje de progrminF v neesidd de este enfoque se dee que n no se onoe generlmente mo se trdue un progrm en un lenguje de progrmin hi un utmt de estdo (nitoF spin es lire desde IWWIF eientemente se hn desuierto tnis efetivs pr trduir un progrm en un lenguje de progrmin un utmt segn l nturlez de l pliinF isto permite utomtizr el proeso de veri(in sin neesidd de psr por l fse de modelizin en otro lengujeF
3.4.3.3 Anlisis dinmico

Sistema operativo

il hrdwre y el propio sistem opertivo tienen medios pr detetr errores durnte l ejeuin de progrmsF in el so del hrdwreD por ejemploD puede detetrse un divisin por eroF in el so omindo de hrdwre y sistem opertivoD puede detetrse un violin de memori @segmenttion fultAD error tmin usnte de desesperiones y mldiiones en los progrmdores novtosD pero en relidd muy fortundoD pues indii el ometimiento de un error y l sunin de su in orretivF

204

3. Crtica de algoritmos

Invariantes

n invrinte o serto es un predido lgio que se introdue en lgn punto de un progrm y uy ertitud veri( si se umplen ls premiss de ejeuin supuests por el disedor del lgoritmo o el progrmdorF v ide es stnte simpleX el predido se evl slo undo el )ujo de ejeuin ps por l invrinteF in ese momento se evl el predido yD si ste es flsoD entones se noti( l progrmdor medinte lgn eventoD por lo generlD el orto del progrmF il evento le permite prehender queD @IA o ls ondiiones requerids pr ejeutr el )ujo en ierto punto no se estn umpliendoD o @PA l ometi un error de rzonmientoF il ulquier de los dos sos se est en preseni de un errorF v mner ms simple de interpretr un invrinte es en form de preondiin o postondiin de un rutinF xotemos que est ide puede plirse ulquier )ujo de ejeuinD es deirD l prinipio de un )ujo estleemos preondiiones que deen umplirse pr que se ejeutdo orretmenteF hel mismo modoD luego de l ejeuin del )ujoD el estdo hr mido de tl form que deen umplirse lguns postondiE ionesF gd preondiin o postondiin no es otr os que un invrinteF elgunos ejemplos pueden lrr l ideF i disermos un primitiv pr lulr l rz udrd x de un nmero relD entones es desele poner omo preondiin el predido x 0F v violin de est preondiin evidenir que en lgun prteD ntes de invor xD se ometi un 2 errorF hel mismo modo podrmos olor omo postondiin x = xD uy violinD ondiin de que l preondiin no hy sido violdD prolemente indiir un error en l instrumentin de xF n eventul uestionmiento ls invrintes es que sts onsumen tiempo de ejeuE inF gonseuentementeD su uso exesivo puede imptr el tiempo de ejeuinF xotemos que este osteD unque onstnteD filmente puede tornrse oneroso siD por ejemploD est ontenido dentro de un lzoF or es rznD muhos progrmdores supeditn el uso de invrintes l digo de desrrollo y no l digo de produinF or lo generlD en C y el C++ D esto se utomtiz medinte mros ondiionlesF v mner tpi es ompilr invrintes si el mro DEBUG est de(nidoF in muhs osiones es importnte dejr ls invrintes en digo de produinD pues rrojn indiios de ourreni de errorF in estos sos no se dee ortr el progrmF v iliote estndr C ontiene un funin llmd assert(predicado)D uy funE in es veri(r un invrinteF xo ostnteD est primitiv es ostos en tiempo de ejeuinD rzn por l ul su uso es uestionle pr digo produtivoF ixisten iliotes espeilizds en el uso de invrintesF uizun de ls ms popE ulres se GNU nana IRRD uys onddesD respeto l assert() trdiionlD pueden reE sumirse enX IF hised pr l e(ieni en durin y espioF he hehoD l veri(in es tn e(E iente que muhs vees no vle l pen eliminr invrintes en el digo de produinF PF v in tomr nte un violin de invrinte es on(gurleF e puedeD entre otrs ossX @A wodi(r l in tomr nte un violin de invrinteY por ejemplosD orE trseD reiniirD envir un depurdor oD simplementeD reportr y ontinurF @A rilitr o deshilitr seletivmente l evluin de invrintesD tnto durnte l ompilin omo durnte l ejeuinF

3.4. Correctitud de algoritmos

205

QF inriqueid on otrs lses formles primitivs que permiten veri(iones de invE rintes ms omplejsF RF wediin preis y porttil del tiempo de ejeuinF emos lguns de ls primitivs de GNU nana ms importntes pr mnejr invE rintesF
Invariantes basadas en asertos

he est lse de invrintesD l prinipl esX


void I(pred)

v ul veri( que pred se iertoD en uyo so negtivo imprime un mensje de error y ortF n form ondiionl de evlur un invrinte es medinteX
void IG (bool pred, bool cond)

v ul evl el predido pred omo invrinte slo si el predido cond es iertoF ist form permite de(nir sos espeilesF e vees es neesrio mntener estdo previoD esto ourre por lo generl on ls postE ondiionesF in este so son de inters ls siguientes primitivsX  void ID (instruccin)X delrin de vrileF  void IS (Asignacin)X jo ID()F permite ejeutr un instruinD normlmenteD un permite relizr un signin un vrile delrd

eunque ID() e IS() son sinttimente similresD el primero dee usrse pr delrr y el segundo pr signrD pues el digo de generin e identi(in sume est funionliddF  void ISG (instruccin, bool pred)X efet un signin ondiionl que el preE dido pred se iertoF or ejemploD un digo que lul l rz udrd de un nmero rel podr plnterse del siguiente modoX raz cuadrada 205 float raz_cuadrada(const float & x) { I(x >= 0); // precondicin exigiendo que x sea positivo
// clculo de la raz de x, el cual se guarda en ret_val I(ret_val*ret_val == x); // resultado igual a x ID(float ret_plus = ret_val + 1); // variable ret_plus I(ret_val < ret_plus*ret_plus); // menor que (ret_val+1)^2

205

206

3. Crtica de algoritmos

hesde el lenguje C es posile poner un seueni de instruiones omo un sol sepE rds por el operdor omF isto es importnte de resltr en este ontexto porque es lo que permite englor un seueni omplet de instruiones en lgun primitiv de invrintesY por ejemploX
ID(int i = 0, j = x + y);
Vericacin por cuanticadores de lgica de predicados

herivdo de l lere progrmin por ontrtos IPRD GNU nana ofree veri(E iones ms re(nds jo l form de unti(dores lgiosF intre los ms importntes podemos indirX  bool A(inicio,condicin,iteracin,pred)X orrespondiente l unti(dor pr todo @AD el ul se orresponde onX
for (inicio; condicin; iteracin) if (condicin) return false; return true;

 bool E (inicio,condicin,next,pred)X orrespondiente l unti(dor de existenE i y que se de(ne sX


for (inicio; condicin; iteracin) if (pred) return true; return false;

is deirD es ierto si l menos en un de ls iteriones se umple el predidoF  long C (inicio,condicin,next,pred)X ontdor de ourrenis de un predido onsistente enX
int count = 0; for (inicio; condicin; iteracin) if (pred) ++count; return count;

 bool E1 (inicio,condicin,next,pred) X veri( que el predido se umpl exE tmente un vezF e puede interpretr de l siguiente mnerX
bool seen = false; for (inicio; condicin; iteracin) if (pred) if (seen) return false; else seen = true; return seen;

3.4. Correctitud de algoritmos

207

207

gomo ejemploD onsideremos veri(r l perteneni exlusiv de un elemento espeE (o un list enlzdX pertenencia a lista enlazada 207 E1(typename DynDlist::iterator<int> it(l), it.has_current(), it.next(), it.get_current() == x);
Uses

DynDlist

85a.

in este punto es menester selr que GNU nana posee los mismos tipos de unti(E dores seldos pr ontenedores de l iliote estndr C++ F GNU nana es un iliote muho ms riD tnto en espei(in de invrintesD omo en otrs funionliddesF vse detenidmente el mnul IRR pr ms informinF
Pruebas

n prue es un experimento onsistente en ejeutr el progrm pr veri(r si funion orretmenteF qrosso modoD existen dos tipos de prueX @IA de j negrD en l ul se estleen entrds y slids orrets veri(rse durnte el experimentoY y @PA de j lnD en l ul se determinn entrds que veri(quen que el )ujo pse por tods ls prtes del progrmF or trdiinD ls pruesD en prtiulr ls j EnegrD ls hen persons distints l odi(dor llmds prodores @testersAF v disiplin imprtid por wguire IIR @ver QFRFQFI @gF IWTAA he ostumre que un progrmdor siempre hg prues j ln pr todo su digoF ixiste tod un ieni pr pror progrms uyo mito y extensin estn fuer de lne en este textoF edems de los dos utores nterioresD l mejor refereni que se este redtor onoe pr el rte de ls prues se titul he ert of oftwre esting por qF tF wyers IPVF
Generacin automtica de prueba

ingler et l hn desrrolldo un tniD primigenimente sd en nlisis esttio del digo fuenteD onsistente en generr entrds l progrm que ejeutn todo los minos de ejeuin posiles del progrm IVTF eprte de enontrr ls entrds que uren todos lo sos posilesD se genern entrds que someten l progrm mximos esfuerzos segn desempeoD ondiiones rtis de onurreniD seguriddD etterD que hn permitido enontrr errores en mnejdores de sistem de rhivo en produin desde he osF
Manejo de memoria

il mnejo de memori dinmi es un fuente de error tn omn que meree onsgrr est suEsein lsi(r y desriir ls lses de errorF
Fugas de memoria (memory leaks)

n fug de memori oD en inglsD memory lekD es un loque que se reserv y que jms en l vid del progrm se lierF or ejemploD si tenemos l siguiente ine(ienteD inelegnte e inorret versin del swap() entre rreglosX
void array_swap(int * a, int * b, const size_t n) { int * tmp = new int [n];

208

3. Crtica de algoritmos

for (int tmp[i] for (int a[i] = for (int b[i] =

i = 0; i < n; ++i) = a[i]; i = 0; i < n; ++i) b[i]; i = 0; i < n; ++i) tmp[i];

entonesD d vez que se invoque array_swap() se dejr prtdoD pr siempreD un rreglo tmp de n elementosF i array_swap() se invo menudoD entones el progrm olpsr en poo tiempo por flt de memoriF v regl pr evitr este error es que todo loque de memori dee lierrse inmediE tmente despus de que ste y no se requierF
Acceso fuera de bloque

wenos freuente que un fug de memoriD tmin omn yD menudoD ms grveD un eso fuer de loque onsiste en l letur o esritur de un zon de memori que no se h prtdoF il so ms tpio es esriir justo despus del (n de un loque de memori reservdo on malloc() o newF or ejemploX
int * tmp = new int [n]; for (int i = 0; i <= n; ++i) tmp[i] = a[i];

iste digo on ertitud esriir un entero de ms en el rreglo tmpF in el mejor de los sosD ourrir un segmenttion fultY en el peorD el error psr temporlmente desperiido hst que tiempo despus @quiz muho despusA presente sntoms tmin errtios en el sentido de que son vrilesD pudiendo serD inlusiveD de ndole heisenerE gino @heisenugA19 F v regl pr evitr este error es lgo vgX siempre revise rigurosmente el eso medinte un puntdorF or es rzn son uens ostumresX IF sr nomres de punteros que indiquen lrmente que se trt de un punteroF il menismo de nomrmiento fvorito es su(jr el nomre on _ptrY de este modoD un herrmient estilo grep puede enontrr ls ourrenis de uso de un puntdor y permitir l progrmdorD o un herrmient utomtizdD nlizr l orretitudF PF esle el uso de punteros omo rreglos en operiones genrisD ergo reuslesD que onentren l veri(in de orretitud en un sol porin de digoF n ejemplo representtivo lo onstituyen ls funiones fill_dir_to_null()D release_segment()D entre otrs espei(ds en PFIFRFP @gF RHAF QF ivitr el uso de ms de un indireionmiento por punteroF or ejemploX
**int_ptr = 5;

no estr permitidoF v exepin est regl es undo se trten rreglos omo punteros y tengmos rreglos de rreglosD tles omo lo hiimosD por ejemplos pr
19
Por el clebre fsico alemn Werner Heisenberg quien descubri el principio homnimo acerca de la imposibilidad de observar el estado real de una partcula atmica, pues la misma observacin cambia el estado.

3.4. Correctitud de algoritmos

209

el mtodo access() de DynArray<T> @ PFIFRFQ @gF RSAA o on los rreglos multiE dimensionles @ PFP @gF SVAAF
Direccin de devolucin invlida

n invoin exitos malloc() o new retorn un puntero l loque reservdoF il menismo de devoluinD medinte free() o deleteD dee reiir extmente el mismo vlor de puntero que entreg malloc() o deleteF vierr un direin de memori que no hy sido retornd por el mnejdor de memori esD puesD un serio error de progrmin que ompromete el estdo de l pliin y uys onseuenis son inierts yD por lo generlD permneen indetetles durnte lgn tiempoF intregr un direin invlid l mnejdor de memori es un error ms omn de lo que podr pensrseF uiz el so ms freuente ourre on punteros sore lses derivds y lguns trnsformiones resultntes del stingF ytr posiilidd suede undo se mnejn multiestrutursD por ejemploD un multilistF
Vericadores dinmicos de memoria

vos errores de memori fueron un perenne dolor de ez en el psdo hst que preieron progrmsD en su myor en form de iliotesD pr detetrlosD siendo los ms populres entre ellos electric fence I y dmalloc IUWF gon este esquem se requiere yud del preproesdorD l ul no est ompletmente disponile en C++ y el endenmiento de un ilioteD l ul interept ls llmds malloc() y free()F n nuevo y verstil progrm de veri(in h preido reientementeX valgrind IQHD IPWD el ul no requiere ilioteD sino que intert sore el ejeutle resultnteF vos menismos de detein son los mismosF in primer lugrD d direin de loque de memoriD junto on su posiin ext de reservinD lne y nomre del rhivoD se not en un tl de mner tl que l (nl del progrm ls entrds en l tl orresponden fugs de memoriF hel mismo modoD un entreg de direin invlid puede detetrse porque l direin no se enuentr en l tlF gundo se soliit un loqueD se prt un poo ms de mner tl de poner rejsD ls ules son zons on vlores espeilesD d ldo del loqueD de po posiilidd de esriturD y uy pitorizin es omo sigueX
ptr

el lierr un loque de memori se revis el vlor de l rejD y si ste es diferente l de iniioD entones puede ser sntom de que se h esrito por fuer de un loqueF vs veri(iones nterioresD en prtiulrD ls rejsD no grntizn detein pr todos los sosF il enfoque de valgrind es lgo similr los sos nteriores pero no interept l iliote en sF in su lugrD valgrind intereptD sore el ejeutleD ls llmds rtis reservin de memori @malloc()D free()D sbrk()D newD deleteD FFFA yD por didurD interept los esos memori y otrs operiones delidsF vuegoD ejeut el progrm yD durnte l ejeuin v veri(ndo y reportndo los eventules erroresF valgrind h disminuido grndiosmente el tiempo de veri(in en lo que onierne l mnejo de memori y otrs lses de erroresF fjo los dos enfoque presentdosD el progrm se ejeut onsiderlemente ms lentoD lo que en irunstnis espeiles puede her su uso omplidoF

210

3. Crtica de algoritmos

Depuradores

e veesD un error no se detet por los nlizdores esttios o dinmios sino que se onoe su preseni porque el progrm rroj resultdos inorretosF u squed es un rte que depende de l experieniD instinto e intuiin del progrmdor pr enontrr prtes que ofrezn pists er del errorF in este orden de idesD un de ls lses de progrms ms tiles que existen son los depurdoresD progrms espeilizdos en oservr l ejeuin del progrm y relionrl l digo fuenteF no de los depurdores ms leres es el GNU gdb ITID junto on lgunos de sus frontles @frontEendsAD tles omo el ddd IVWF

3.5 Ecacia y eciencia


e ests lturs del disursoD deemos tener lro que l e(i prim l e(ieniF el (nl de uentsD de que vle lgo muy e(iente si no es orretocF ues ienD en lgunos prolemsD l e(i puede omprometer l e(ieni y vieversX si se he orretE menteD entones puede ser muy ine(iente yD posilementeD inplileF r prehender l uestin onsideremos un ejemplo mgistrl mostrtivo de ls viisitudes involurds en l resoluin de un prolem y los ompromisos que menudo se presentn entre orreE titud @e(iA y e(ieniF il ejemplo est sdo en teven kien de su exelentsimo liro he elgorithm hesign wnul ISWF gonsideremos un onjunto P = {p1 , p2 , p3 , . . . , pn } de n puntos en el plnoF gd punto se de(ne por sus oordends rtesins (x, y)F il prolem onsiste entones en enontrr un orden de visit entre todos los puntos de mner tl que l longitud del reorrido se mnimF ry vris mners de ordr l soluin de este prolemF uiz l ms ndid se medinte l heursti del veino ms ernoX ddo un punto pi D el prximo punto onetr es el ms erno pi F

pigur QFIHX n disposiin de puntos y l soluin del ilo ms orto medinte l heursti del veino ms erno ISW rfrsendo kien ISWD un lgoritmo sdo en el punto ms erno es sE tnte simpleD fil de omprender y de implementrF odemos deir tmin que el lE goritmo es muy e(ienteD pues su omplejidd es O(n)F vmentlementeD el lgoritmo no es orretoD y pr pertrnos de ello onsideremos este ontrejemploD omenzndo desde el punto 0 plntedo por el propio kien ISWX

3.5. Ecacia y eciencia

211

1
-23

2
-6

3 4
-1 0 1

5
3

7
13

gon est disposiin de puntos l heursti del punto ms ernoD prdjimenteD puede enontrr seuenis muy lrgs y no ls ms ortsFD ytr heursti ms omplejD llmd el pr de puntos ms ernoD tmin selE d por kien ISWD trj on los puntos extremos de minos prilesF il lgoritmo mnej un onjunto de minos priles @iniilmente de un solo puntoAF il lgoritmo onsiste en determinr y onetr el pr de puntos extremos ms ernos de modo tl que l onexin se un mino y no se forme un iloF ist heursti ondue un lgoritmo menos e(iente que on l heursti del mino ms ortoD pero on mejores resultdos pr sos ms diversosF vmentlementeD un lgoritmo sdo en est heursti no es solutmente orreto pr tods ls entrds posilesF v ni soluin orret onoid est dd por el siguiente lgoritmoX
Algoritmo 3.1 (Camino ms corto entre un conjunto de puntos)

lgoritmo es el onjunto P = {p1 , p2 , p3 , . . . , pn }F p1 , p2 , . . . , pn >F il lgoritmo requiere onstruir un onjunto = {1 , 2 , . . . , m } onformdo por tods ls permutiones posiles de los puntos de P F IF distancia = PF resultado = QF e el onjunto de tods ls permutiones de (P) RF @A e c l distni totl otenid de reorrer los puntos en el orden de l perE mutin @A i c < distancia = iF distancia = c iiF resultado = ods los posiles minos se onsidern y slo se esoge el de menor osteF il lgoE ritmo en s es simpleD unque no onsider mo onstruir el onjunto de permutionesD lo ul no es un tre muy senillF il lgoritmo esD puesD orretoF snfelizmenteD tl omo se plnteD es tn ine(iente que slo podr ejeutrse en omputdores divinosF r prehender esto nliemos l e(ieniF il nmero de exploriones que efet el lgoritmo QFI es igul l ntidd de permutiones que existen entre los n puntosD o seD O(2n )D un e(ieni intrtle un pr poos puntosF e veesD l orretitud y l e(ieni representn ontrdiiones inslvlesF eunque kien present este prolem omo un ompromiso entre orretitudD e(ienE i y filidd de progrmin ISWD lo ulD en iert medid es orretoD disrepremos un poo y plnteremos nuestros rgumentos jo ls siguientes oservionesX

v entrd del v slid es un seueni S =<

212

3. Crtica de algoritmos

IF v instni del prolem del vendedor vijero que estmos trtndo es generl en el sentido de que se trt de resolverlo pr todos lo sos posilesF in emrgoD en l vid relD si siempre se dispone de ms informin er de ls lses de entrdF or ejemploD si fuer neesrio resolver el prolem pr plni(r solddurs sore un ole eletrniD entones se se que ls on(guriones de puntos onformn polE gonos montonos y que pr stos l heursti del veino ms erno rroj soluiones orretsF PF in otrs osionesD l difereni entre l soluin ptim y un uenD heurstimente enontrdD no es muy notleF in estos sosD el tiempo de desrrollo y ejeuin de un lgoritmo ueno puede ser menor que el de uno ptimoF in lgoritmos y sistemsD s omo en otros dominios de l ingenierD se pronuni un proverio que rez que lo mejor es enemigo de lo uenoF he lo nterior se desprende que l lein sigue siendo que l e(i prim l e(ieniF
3.5.1 La regla del 80-20

in IWHT el ingeniero frnoEitlino ilfredo reto sel que en stli el VH7 de l riquez se distriu muy injustmente entre el PH7 de l polinF u oservin fue orroord en lguns otrs ltitudes y ontextos jo el rinipio de retoF in lgunos ontextos en los ules se hl de e(ieniD el rinipio de reto h sido plido pr rterizr un relin entre reursos de onsumo o produin y los gentes onsumidores o produtoresF ry indiiones empris de que el prinipio pli los sistems omputionlesF in efetoD se h oservdoD entre otrs ossD queX IF il VH7 de l memori onsumid por un progrm es usd por el PH7 del progrmF PF il VH7 del tiempo de ejeuin es onsumido por el PH7 del progrmF QF il VH7 de los esos diso es relizdo por el PH7 del progrmF RF il VH7 del esfuerzo de desrrollo de un sistem es relizdo sore el PH7 del mismoF in progrminD este ptrn se le denomin l regl del VHEPH F v regl h sido slidmente omprod lo lrgo de l histori de l progrmin y trvs de diversos sistemsX opertivosD de ses de dtosD y vrids pliionesF v regl VHEPH no es un simple rzn numri o proporinF e trt del vliossimo onoimiento que represent el ser que l e(ieni de un progrm est determind por un prte orrespondiente l PH7F or tntoD undo se dese mejorr un progrmD o seD de herlo ms e(ienteD deemos herlo sore quel PH7 y no perdernos en mejorrD ftilmenteD el restnte VH7F
3.5.2 Cundo atacar la eciencia?

vo nterior re(rm que l e(i prim l e(ieniD pues hst que no logremos el efetoD no podemos identi(r ese PH7 del progrm sore el ul deermos de onenE trrnos si desesemos mejorr l e(ieniF ws nD si elormos progrms e(es

3.5. Ecacia y eciencia

213

que stisfen ls expettivsD vle l pen mejorr su e(ienic r responder esto deemos mejor preguntrnosX si tenemos un progrm e(z @orretoAD undo es que hy que tr l e(ienic ry vris ondiionesD siendo ls ms omunes ls siguientesX  il progrm resultnte no omete l soluin en un durin eptle pr su pliE inX disemos un progrmD lo odi(mosD ompromos que es orretoD pero undo lo ejeutmos nos pertmos de que su durin de ejeuin no umple ls expettivsF  gmio en ls ondiiones mientles de uso del progrmX tenemos un progrm orreto que umple ls expettivsF n d ontee un mioD por ejemploD se ument l esl de entrd y el progrm dej de ser e(ienteF  so del progrm omo un omponente de otro progrm o sistemX tenemos un proE grm orreto y e(iente y se nos plnte reusrlo omo prte de otro progrmF in emrgoD el omponente en uestin no tiene l su(iente e(ieni pr segurr l e(ieni glol del progrmF i un progrm ddo enj en lgun de ests ondiionesD entones puede dverrse l neesidd de herlo ms e(ienteF iD l ontrrioD el progrm stisfe tods ls expettivsD entones es preferile evitr el efeto del segundo sistem PRD el ulD itndo frooksX FFF is the most dngerous system mn ever designs PR20 F
3.5.3 Maneras de mejorar la eciencia

n vez dverdo que requerimos her ms e(iente un progrmD tenemos vris lterE ntivsD ominles entre sD pr mejorr l e(ieniF intre ls ms usules tenemosX IF sdenti(in y mejormiento del PH7X uent hid del rinipio de retoD eso tiene muho sentidoD pues eso ene(ir l VH7 del progrmF PF gmio de lgoritmoX veesD sore todo deido l esl de l entrdD es el propio lgoritmo l fuente de ine(ieniF in este so puede dverrse neesrio diser un lgoritmo ms e(iente omputionlmenteF or ejemploD tl vez un proeso rtio de un sistem use lgn mtodo senillo de ordenmiento uy omplejidd es O(n2 )Y en este soD el mtodo podr sustituirse por lguno O(n lg n)D el ul es onsiderE lemente ms e(ienteF QF gmio en l titud de progrminX otr posiilidd de ine(ieni puede deerse un titud por prte de los progrmdores que introduz ine(ieniF e menudoD esto ourre entre progrmdores novelesF n ejemplo notle y rel onstituye el pse de prmetros por vlor en C++ F in efetoD en este lengujeD si no se tiene el uiddo deudoD el oste del pse de prmetros por vlor puede ser ltsimoD pues d invoin funin requiere un opi de d ojeto prmetroD l ulD segn l ndole del ojetoD puede onsumir stnte tiempoF RF gmio mientl dredeX he unos PH osD undo un progrmdor quer logrr lgunos efetos visules espeilesD ument explitmente l veloidd de reloj y
20
Es el ms peligroso sistema que alguien puede disear.

214

3. Crtica de algoritmos

us un ols de hielo sore el proesdor pr tenur el lor produidoF equell limitd y efmer tni permit predeir que proesdores ms veloes Eo dptE iones fsisE drn soluin l prolemF n prolem de e(ieni puede trse fuerz rut umentndo el poder omE putionlF eprte de mios fsios del estilo desrito en el prrfo nteriorD hy vrios ms lolesF in primer lugrD puede sustituirse el ompildor por uno que efeE te optimiziones gresivs espeilesF in segundo lugrD puede dquirirse hrdwre espeilizdo oD simplementeD de myor poteniY veloidd de proesdorD ntidd de memoriD ntidd de disoD tenolog de lmenmientoD nmero de proesdoresD etterF ist esD grosso modoD l lsi(in de ls mners ojetivs en que se puede mejorr l e(ieniF vo demsD y lo que vendrD es de ndole sujetiv y prte del orpus de estudio de este textoF
3.5.4 Perlaje (proling)

hdo un progrm del ul se dese estudir su e(ieniD ules son ls prtes del progrm que representn quel PH7 rtioc eprte del onoimiento del progrmdorD en l determinin de est respuest puede usrse un lse espeil de progrm llmdo per(ldor @pro(lerAF he mner elementlD un pro(ler es un progrm queD osistido por el ompildorD muestre l ejeuin de un progrm y re estdstis sore l posiin de ejeuin del progrmF or lo generlD un pro(ler ofree dos gr(os fundmentlesX IF il per(l plnoD el ul muestr l durin onsumid por d rutin y l ntidd de vees que fue invodF PF il grfo de llmdsD el ul muestrD pr d funinD ules fueron ls funiones que l llmron y unts vees esto ourriF iendo este enfoque de ndole estdstiD l preisin del pro(ler depende de l durin totl del progrmX myor durinD myor preisinF e pesr de este tipo de impreE isinD este enfoque tiene l enorme ventj de que no impt demsido sore l durin permitindole ejeutrse veloiddes erns l tiempo relF il prinipl exponente del pro(ler estdstio es GNU gprofF ry vrios frontEends gr(os que verstilizn l visulizin de los per(les rrojdos por GNU gprofD siendo el ms notle de ellos kprofF Valgrind tmin posee un exelente pro(ler estdstioF ytro enfoque de per(lje ms determinist onsiste en inluir ontdores diretos en d rutin y medidores de tiempoF il enfoque es muho ms preiso que el estdstioD pero tiene el prolem de que ument onsiderlemente el tiempo de ejeuin hinE dolo inplile pr progrms on requerimientos de tiempo relF n prototipo lire de est lse de pro(ler es FunctionCheck IRPF
3.5.5 Localidad de referencia

or lo generlD el eso los dtos por prte de un progrm exhie un ptrn repetitivo denomindo lolidd de refereniF gundo se ede un dtoD existe un lt proE ilidd de que ste se edido de nuevo en un tiempo prximoF e este tipo de lolidd

3.5. Ecacia y eciencia

215

de refereni se le li( de temporlF n muy simple ejemplo es l instniin de un vrileD l ulD sore todo si se siguen uens ostumres de progrminD deer ederse pr letur o esritur en un tiempo muy prximoF ytro ptrn onsiste en eder un dto erno en memori de otro reientemente edidoF e este lse de lolidd de refereni se le li( de espilD y un uen ejemplo lo onstituye el eso vetores y mtriesF v lolidd de refereniD undo l onoimiento de l regl del VHEPHD intuye un menismo muy utilizdo pr mejorr el rendimiento denomindo heY vero frns que signi( esonder y que legoriz l trnspreni del menismoF n he es un onjunto strtoD (nitoD sustentdo en un estrutur de dtosD que se ntepone un onjunto de dtos muho myor y uyo eso es notlemente ms rpido que el onjunto de dtosF gundo se ede por vez primer un elemento del onjuntoD ste se gurd en el heF vos siguientes esos se ejeutn sore el heD que es muho ms rpidoF uesto que el he es (nitoD posilemente ste deveng llenoF in este soD se dee seleionr un entrd del he pr eliminr de mner que pued sustituirse por l nuevF or lo generlD se elimin l entrd que teng ms tiempo sin usrseF ghes son tpimente usdos en ls pltforms de hrdwre pr plir l difereni de desempeo entre el g y l memoriF or l mism rznD los sistems opertivos los usn pr plir el desfse entre l memori y el disoF in ms situiones suele gurdrse en el he no slo el dto rein edidoD el ul ure l lolidd de refeE reni temporlD sino tmin los dtos dyentesD de mner que tmin se ur l lolidd espilF in SFQFQ @gF RQSA estudiremos un enfoque generl de he pr usrse sore onjuntos en memoriF
3.5.6 Tiempo de desarrollo

vos mntes de los grndiosos y modernos lengujes de sripting tles omo PerlD Python y RubyD los ules filitn muhsimo el desrrollo rpido de prototipos y pliionesD tienen el siguiente proverioX el tiempo humno es ms importnte que el tiempo de g 21 F gon esto expresn un elemento de e(i y e(ieni que menudo es desE uiddo eD inlusiveD ompletmente despreidoX el tiempo de desrrollo de un progrmF wodelos y prototipos son fundmentles en ingenierD pero por un extr rznD poos ingenieros de softwre suelen usrlos undo se enuentrn nte diseos de softwre novedoso o que no tienen experieni en herloF in todo soD pree surdo elorr progrms uyo tiempo de desrrollo se muho myor que l vid del progrm en ejeE uin oD inlusiveD lo ul es pttimente ms omnD que no sen e(ientes oD muho peorD ine(esF egn ls onsideriones nterioresD onluymos on ls siguientes reomendiones tendientes elerr el tiempo de desrrolloX IF rime l simpliidd de diseo por el desempeoD puesD omo reiterdmente lo hemos seldoD l e(i prim l e(ieniF or tntoD piense en optimizin slo si se h segurdo el (n y se requiere ms e(ieniF
21
Escuchado por primera vez por este redactor por boca de Francisco Palm.

216

3. Crtica de algoritmos

PF snviert todo el tiempo neesrio en grntizr orretitud de los diseos ntes de proeder l odi(inF in virtud de est reomendinD use modelos y verifquelos exhustivmenteF i exisE ten espei(iones de e(ieniD entones verifquels en los modelosF rototipee rpidmente prototipos de los modelos y veri(dos y onvldelos on ls ondiiones esperds de ejeuinF in este sentidoD es perfetmente plusile usr lengujes que permitn desrrollr efetivmente prototipos eD inlusiveD si l e(ieni es stisftoriD sr el desrrollo de(nitivo en el lenguje de prototipedoF

3.6 Notas bibliogrcas


il ordenmientoD omo orr del homreD se enuentr en tod ultur y po humnF udier deirse que el mtodo de selein es de utor humnD pues no se enuentr el nomre de lgn individuo que se triuy pr s mismo su utorF vos historidores de l omputin triuyen el ordenmiento por mezl tohn von xeumnnY un de ls mentes ms geniles del siglo F il mtodo de inE serin se le triuye uonrd useD quien tmin se triuye el desurimiento del omputdor digitlF il quiksort fue desuierto por ghrles enthony ihrd rore en IWTI UIF hesde entones hst el presenteD el mtodo h sido intensivmente estudidoF unuth WW ofree un muy detlldo estudio s omo un exelente reuento histrio del quiksort y dems mtodos de ordenmientoF oert edgewikD jo l tutor de unuthD onsgr su tesis dotorl l estudio del quiksortF gomo tlD edgewik ISS es un exelente refereni pr el nlisis del mtodo y sus vrintes plitivsF v notin OD fundmento esenil del nlisis de lgoritmosD fue originlmente onE eid por el mtemtio lemn ul fhmnn en IVWR IIF egn rjn ITUD el nlisis mortizdo fue desrrolldo por wF F frownD oert iF rjnD F ruddleston y uF wehlhorn ITUF in su rtuloD rjn triuye el desurimiento del mtodo potenil hniel hF letorD mientrs que el li(E tivo mortizdo se triuye rjn y letor ITUF v ide de veri(in de orretitud sd en invrintes h sido populr desde el mismo iniio de l progrminF in emrgoD l respeto vle l pen destr el trjo de hvid osenlum ISHD IRWF v espei(in y veri(in utomti de progrms fue iniid (nles de los os THD pero no fue sino hst (nles de l dd del UH undo se tuvo lroD on los trjos de (ropulo et l IVVD que el futuro de l veri(in de sistems se hr forml y utomtimenteF i usted lleg ser un progrmdorD entones quiz lgn d emprender l direin de un or omplej en un sistem omputionl que requier l prtiipin de muhos progrmdoresF in ese entones requerir dominr ls uens ostumres y normlizrls entre los progrmdoresF in ese momento deer onoer muy ien er de l sngenier del oftwreF in el nterinD primero domine el ser progrmdor y omiene por leer el primer liroD en tiempo y en exeleniD de sngenier del oftwreX he wythil wnE wonthX issys on oftwre ingineering de predrik F frooks PRF

3.7. Ejercicios

217

il mpo sore disiplin y uens ostumres de progrmin tendientes produir progrms orretos es muy vstoF xo hyD puesD su(iente espio en este texto pr disernir l respetoF in emrgoD nte l posiilidd de frgmentin del letor nte l extens vriedd de fuentesD es esenil responsilidd en est susein menionr explitmente los priniples textos de refereniX IF riting olid gode IIR de teve wguire vers sore mo esriir progrms que no ontengn erroresF eunque prez muy osdoD wguire ense un disiplin que fuerz odi(r progrms orretosF r resumirD wguire lr un mino en torno ls tres pregunts de n glekF PF he rtie of rogrmming WQ de uernighn y ike es un liro sore ls ueE ns ostumres de progrminD esrito on muh utoriddD pues sus utores son prtintes involurdos en exelss ors de softwreF QF feutiful godeX veding rogrmmers ixplin row hey hink IQS editdo por endy yrm y qreg ilsonD present un reopilin de vrios diseos e instrumentE iones de progrms leres y elegntesF pinlmenteD gode gomplete IPP de teve wgonnell es un exelente trtdo eniE lopdio sore uens ostumres en progrminF

3.7 Ejercicios
IF hemuestre ls (rmiones QFP @gF ISUAD QFQ @gF ISUA y QFR @gF ISUAF PF hemuestre tods ls regls lgeris enunids en QFIFUFI @gF ISWAF QF esuelv extmente ls siguientes reurrenisX @A

T (n) =
@A

1,

n=1 n>2

3T (n 1) + 2,

T (n) =
@A

1,

n=1 n 2, n poteni ext de 2

2T (n/2) + 1,
si n = 1

T (n) =
@dA

2T (n/2) + 6n 1,

n 2, n poteni ext de 2
si n 1

T (n) =
RF gonsidere l siguiente funinX

2T (n/2) + lg n si n > 1

218

3. Crtica de algoritmos

unsigned int misterio(unsigned int & n) { if (n == 0) return 0; unsigned int suma = 0; for (unsigned int i = 1; i <= n; i++) suma += 2*i - 1; return suma; }

u retorn l funinc SF hisee un lgoritmo de prtiin triple tl omo el explido en QFPFPFV @gF IVQAF TF hisee el proedimiento desrito en mezl de rreglos 171 de modo tl que el rreglo seundrio slo onsum l mitd del espioF is deirD si el rreglo est entre [l ..

r]D entones l dimensin del rreglo b dee ser

rl1 2

UF hisee un lgoritmo genrio que se sirv del ptrn genrio Iterator y que ordene por selein un seueniF hisee el lgoritmo de form tl que se lo ms e(iente posile en rreglos y lists dolemente enlzdsF VF v mezl de dos seuenis ordends usd en el mtodo de ordenmiento por mezl requiere opir todos los elementos de los rreglos mezlr en un rreglo uxilirF hisee un lgoritmo que disminuy el espio diionl l mitdF WF enlie el tiempo de ejeuin del siguiente pseudoprogrmX
void programa(int l, int r) { if (l >= r) return; O(1) int m = (l + r) / 2; programa(l, m - 1); programa(m + 1, r);

IHF hdo el siguiente progrmX


int programa(int l, int r, int A[]) { if (r < l) return 0; for (int i = l; i < r; i++) x = x + A[i]; int y = 0; y += x + programa(l, r - 1, A); return y; }

3.7. Ejercicios

219

@A enlie el tiempo de ejeuin @A r el rreglo ea IDPDQDRDSDTF u vlor devuelve l llmd programa(3, 5, A)c IIF r d uno de los siguientes progrmsD nlie el tiempo de ejeuinX @A void f() { int i = 0; for(int j = i; j > -1; j++); } @A void g(int n) { for (int j = 2n ; j < i++; }

lg

n; j /= 2)

@A void h(int n) { for (int x = 1; x < n; x += 2) printf("impar: %d", x); } @dA void f(int N) { int n = 1; do { n *= 2; for (z = 0; z < n; z++) printf("%d\n", z); } while (n < N); } IPF gonsidere un rreglo on n diferentes enteros desordendos omprendidos entre 0 y m, m nF e requiere determinr un nmero fltnte entre los enteros on un oste en espio O(1)F vo ltimo signi( que no se pueden utilizr estruturs de dtos uxilires uyo espio rez en funin del tmo del rregloF or ejemploD pr m = 1000 y un rreglo [ 0 1 2 3 37 28 36 273 2721 99 327 7 354 6 84]D 500 / A es un soluinF

@A enlie rigurosmente el lgoritmo nterior pr el mejorD peor y so promedioF

@A ropong un lgoritmo fuerz rut que resuelv el prolemF is deirD i [0..m], 0 i m usque en el rreglo hst no enontrr el vlor de iF @A ropongD explique y disee un lgoritmo que resuelv el prolem en O(n lg m) pr el peor soF

@dA fjo l existeni del lgoritmo de l pregunt nteriorD disut ul y en ules irunstnis un lgoritmo es mejorD el O(n lg m) o el disedo en IPF

220

3. Crtica de algoritmos

IQF glule el tiempo de ejeuin del lgoritmo de multipliin de polinomios deE srrolldo en l susein PFRFIH @gF WIAF IRF ilimine l reursin ol del mtodo quicksort_rec()F ISF hg un estudio estdstio er de los tmos de prtiiones prtir de ls ules el ordenmiento por inserin es ms rpido que el quiksortF ITF smplnte el ordenmiento por selein on lists simplemente enlzds del tipo Snode<T>F IUF smplnte el ordenmiento por inserin on lists simplemente enlzds del tipo Snode<T>F IVF smplnte el ordenmiento por mezl on lists simplemente enlzds del tipo Snode<T>F IWF smplnte un quiksort itertivo que ordene lists simplemente enlzds del tipo Snode<T>F PHF smplnte el quiksort on lists simplemente enlzds del tipo Snode<T>F PIF isri un lgoritmo que prtiione un list simplemente enlzd irulr on nodo eer del tipo Snode<T>F il prototipo es el siguienteX
Snode<T> * partir(Snode<T> & list, Snode<T> & l1, Snode<T> & l2);

sniilmenteD l1 y l2 estn vsF el (nl de l llmd se retorn el elemento pivote de l prtiinY l list list qued v y l1 ontiene los elementos menores que el pivote mientrs que l2 los myoresF PPF hisee e implnte un quiksort no reursivo sore lists doles de tipo Dnode<T>F PQF hisee e implnte un quiksort no reursivo sore lists simples de tipo Snode<T>F PRF hisee e implnte un quiksort sore lists doles on Dnode<T> que seleione l medin entre lgunos de los elementos onstntemente sequiles de l listF PSF isri el quiksort pr lists dolemente enlzds de mner tl que letorie l selein del pivoteF PTF hisee e implnte l siguiente primitiv
int select_pivot(T a[], const int l, const int r, const int n)

v ul sorte l zr n ndies entre l y r y seleion el ndie orrespondiente l medinF xo veri(que repiteni entre los ndiesF PUF wodi(que el quiksort pr lists enlzds presentdo en QFPFPFT @gF IVIA pr que hg un mejor selein del pivoteF PVF istudie el onsumo de espio en pil que osion el mergesort deido ls llmds reursivsF

3.7. Ejercicios

221

PWF wodi(que el quiksort pr lists enlzds presentdo en QFPFPFT @gF IVIA pr que minimie el onsumo de espio en sus llmds reursivsF QHF he los mtodos de ordenmiento presentdos en este ptuloD ul ser el mejor pr ordenr lists enlzdsc QIF il mismo ejeriio que el nteriorD pero est vez no puede her repiteni entre los ndies sortedosF QPF hisee e implnte un lgoritmo que enuentre el iEsimo menor elemento de un list simplemente enlzd desordend @Snode<T>AF QQF hisee e implnte un lgoritmo que enuentre el iEsimo menor elemento de un list dolemente enlzd desordend @Dnode<T>AF QRF hisee e implnte el esquem de triple prtiionmiento explido en QFPFPFV @gF IVQA pr mnejr lves repetidsF QSF enlie rigurosmenteD pr los sos esperdo y peroD el desempeo de l primitiv random_search()F QTF isri el random_search() pr lists simplemente enlzds de tipo SlinkF QUF enlie rigurosmenteD pr los sos esperdo y peroD el desempeo de l primitiv random_select()F QVF smplnte el random_search() on lists simples de tipo Snode<T>F QWF smplnte el random_select() on lists simples de tipo Snode<T>F RHF smplnte el onjunto fundmentl on rreglos desordendos sdo en ls primitiE vs random_search() y random_select()F RIF smplnte el onjunto fundmentl on lists simples de tipo Snode<T> sdo en ls primitivs random_search() y random_select()F RPF smplnte el onjunto fundmentl on lists doles de tipo Dnode<T> sdo en ls primitivs random_search() y random_select()F RQF ixtiend GNU nana pr que mneje los unti(dores que veri(quen ontenedores de l iliote ALEPHF RRF r todos los eh disedos hst el presenteD veri(que l pliin de ls regls de roltzmnn UQ presentds en QFRFQFI @gF IWTAF

rboles
eunque tulmente on tendeni l olvidoD desde he muho tiempoD eso que le rind identidd y sentido un os se le llm eseni o quidF hesde y durnte eddes inmemorilesD nestrles y lejnsD se ree que el quid de lgo se estudi prtir de su ontexto de origenF vo que hor vulgrmente llmmos futuroD nestrlmente se le llm destinoD o seD hi dnde se vF gundo se quer ser qu er @desde dnde vieneA y qu devendr @hi dnde vA un osD se estudi y se riti su genelogD es deirD su origen y devenir prtir de su gnesisF il trmino genelogD que ontiene genusD proviene del ltn genelog iD el ul proviene su vez del griego y signi( el estudio del mino desde el origen @gnesisA hst el presenteF roy en dD l genelog tiende estudirse omo un seuenE i de eventos respeto un movimiento externo y jeno los eventos llmdo tiempoF e este tipo de estudio se le llm por lo generl ristoriF ruo posD sin emrgoD en que lgunos genelogists sentn que el quid de un os no se remit un mer y ni seueni de eventosD sino diverss y vriles seuenis que provenn desde un momento denomindo origenD onvergn hi otro momento llmdo presente y prosegun hi lgo por venir que se llm destinoF equellos genelogists se pertron de que onvivn on testigos que hn ompdo sus sendientes y que les sorevivirn ellos y sus desendientesF esimismo se fsinron por el heho de que ls propis forms de quellos testigos indiin su devenir y eddF el gnero de quel testigo hoy se le mient jo el nomre de rolD y l exepin de l ultur tenolgi de est poD en ls restntes el rol h usdo tnto somro trvs de ls eddes y ltitudesD que h sido l extremo sujeto de venerinF or qu somrc eprte de su ellezD monumentlidd y longeviddD h vris rzonesF n de ls priniplesD de grn inters pr nuestro ontextoD er su estrutur genriD s omo su evoluinF n rol omienz en el mundo omo un semillit que lentmente enrz y ree mirndo y usndo l luz en un trm jerrqui que trz su eddD su genelog y que trnsige imginr su destinoF eunque por lo generlD un rol lo mirmos omo un rolD es deirD omo un todoD en osiones mirmos sus prtesX rzD tronoD rmsD hojsD )oresD FFFF gunto ms er se est de l rzD ms ntigu es l regin del rol que mirmosY nlogmenteD unto ms lt o mpli st esD ms joven es l prte respeto otrs inferiores o ms internsF iste ptrn estruturlD que no se orresponde on un mer seueniD pree en un numersim vriedd de ontextos de nuestr vid de los ules no esp l omputinF e los tos y hehos humnos les llmmos gestosD pues stos gestnF er humno PPQ

224

4. rboles

slo tiene sentido on los otros seres humnosF ws humnos somos en l medid en que ms nos hymos ien reliondo on los otrosF he lgun mner podrmos deir que omo humnos nos distinguimos entre nosotros porque los gestos que reiimos del otro y gestmos pr lD son de lgun mner diferentesF n ntiguo y hermoso proverio hind rezX un gesto gener un titudD un titud gener un rter y un rter gener un destino F i generlizmos nuestr identiddD o l de lgn otroD podemos pensr en el rter y her memori en ls titudes y gestos que ondujeron quells titudesF sndgndo en un rter tenemos ide er de mo se proyet el destinoF xo en ldeD rerlito de que el rter de un homre es su destino F gomo un hipottio y muy reduido ejemplo onsideremos l risD l ulD en iert formD gest legr y su vez gest tmin un rter mistosoF v mistdD undo se irunsrie dentro de un utnti noin de ienD gest un destino enmrdo en l uen vid suyente l ide de ien que en mistd se omprtF v vid humn est plen de muhos ms gestosD l sonrisD el llntoD el gritoD el somro FFF s omo de sus onseuentes titudesD l pirdD l tristezD el enojoD l uriosidd FFFF grteres emergen de quells titudesY el mistosoD el stutoD el deprimidoD el deson(doD el persevernte FFFF hependiendo del devenir y de l suerteD esos rteres onjugdos pueden destinr en un pdreD un poltioD un poetD un guerreroD un (lsofo FFFF odo este disurso puede sintetizrseD de un mner un tnto reduid pero ms prensileD jo el digrm de l (gur RFI in los gestosD los nuestros y los del otroD se gestn nuestros destinosF
risa sonrisa llanto grito asombro

alegra

picarda

tristeza

enojo

curiosidad

amistoso

astuto

deprimido

desconfiado

perseverante

Padre

Poltico

Poeta

Guerrero

Filsofo

Destino

pigur RFIX n rol destinl entes de ordr formlmente el onepto omputionl de rolD emppmosnos un poo ms de l ide strt de rol en un ontexto ms otidinoF in el entorno genelgio de est poD quiz se el rol genelgioD el ul trz sendeniD y uy representin generl se ilustr en l (gur RFPD un ejemplr repreE sentnte ulturl de l estrutur rol y de su similridd pitri y jerrqui on su prngn nturlF e difereni de su estereotipo nturlD en el rol genelgio ls semills @los isueE losA se enuentrn en ls hojsD mientrs que el ltimo desendiente est en l rzF in el mismo sentido genelgioD unque ms individulistD un ptrn seminl ms (el on el rol nturl es el rol dinstioD el ul trz ls desendeni y uy estrutur siD pero no generlD se ilustr en l (gur RFQF

225

Bisabuelo

Bisabuela

Bisabuelo

Bisabuela

Bisabuelo

Bisabuela

Bisabuelo

Bisabuela

Abuelo paterno

Abuela paterna

Abuelo materno

Abuela materna

Pap

Mam

Hijo

pigur RFPX porm generl de un rol genelgio


Individuo

Primognito

Hijo 2

Hijo 3

Nieto 1

Nieto 2

Nieto 3

Nieto 4

Bizn 1

Bizn 2

Bizn 3

Bizn 4

Bizn 5

Bizn 6

Bizn 7

Bizn 8

Bizn 9

biz-biz

pigur RFQX porm si de un rol dinstio

il rol genelgio generl de l (gur RFP es inrio en el sentido de que d miemro tiene extmente dos nestros diretosX el pdre y l mdreF in mioD l numeriidd del rol dinstio depender del rter prol(o de l fmiliF in progrmin se mnej l strin de rol pr representr jerrqus de mputoD rdenes espeiles de dtos o situiones que tn los roles ulturles eD inlusiveD nturlesF he hehoD en IFP @gF IIA introdujimos el onepto de herenE i de lses y su rter genelgioF in omputinD ls pliiones del rol son muy diverss y vn desde l reuE perin e(iente de lves hst l resoluin nlti de expresiones del lulo formlF il rol fundment muhos esquems de reuperin y reonstruin de informinD tnto en memori primri omo en seundriF odo proeso de trduinD por ejemE ploD l ompilin de lgn lenguje de progrminD utiliz el rol omo estrutur fundmentlF il lulo forml utomtioD es deirD el lulo de expresiones nltiE sD por ejemploD lmitesD derivdsD integrlesD etterD us l rol omo estrutur de representin de ls expresionesF n lor de este ptulo ser formrnos on los linemientos sios efetos de umplir los siguientes ojetivosX IF gonoer los oneptos sios y homogeneizr terminologsF

226

4. rboles

PF gomprender los lgoritmos fundmentles y preprr l letor en el desrrollo de lgoritmos ms omplejosF QF reprrnos pr el estudio de estruturs rolD espeilizdsD que sern desrroE llds en otros ptulos de este textoF resentd l ide intuitiv y genelgi del rolD s omo su inters en l omE putinD estmos prestos pr iniir formlmente nuestro estudioF

4.1 Conceptos bsicos


gomenemos por un de(niin mtemtiF
Denicin 4.1 (rbol)

n rol T se de(ne por un onjunto N = {n1 , n2 , . . . , nn } de uno o ms nodos que stisfen ls siguientes ondiionesX IF ixiste un nodo espeil llmdo raiz(T ) N F PF il onjunto N {raiz(T )} puede prtiionrse en m roles T 1 , T 2 , . . . , T m tl queX

{raiz(T )} T 1 T 2 T m = T

T1 T2 Tm =

gd uno de los onjuntos T 1 , T 2 , . . . , T m son subrboles de T F il ontenido de un nodo ni T se represent omo KEY(ni )D l ul menudo se le llm lveF v (gur RFR ilustr un ejemplo donde l rz es el nodo etiquetdo on l letr A y ls res de los suroles de A estn etiquetdos on BD CD D y E respetivmenteF xotemos que el rol diujdo en l (gur RFR est invertidoX l rz est en l prte superior y ls hojs en l prte inferiorF ividentementeD existe todo un rgot genelgio pr desriir un rolF e un nodo diretmente onetdo l rz se le llm hijoF e exepin de l rzD todo nodo tiene un padre F hdo un nodo ni D llmremos padre(ni ) l pdre de ni e hijos(ni ) l onjunto formdo por los hijos inmeditos de ni F hel mismo modoD ddo un nodo nD hijo(n, i) denot l iEsim rm de nF i hijo(n, i) = D entones n no tiene un iEsim rmF e un nodo que no teng hijos se le llm hoja D pues legoriz l hoj de un rol en el sentido de que es un termininF eprte de l rzD l resto de los nodos se les llm descendientes del nodo raiz(T )F n rol ontiene nodos y rosF n nodo soi un elemento de lgn tipo genrio T F n ro represent un relin entre los dos nodos involurdosF henominremos T l onjunto in(nito de todos los roles posilesF n arborescencia se de(ne omo un onjunto de ero o ms roles disjuntosF n camino < n0 , n1 , . . . , nn1 , nn > es un seueni orrespondiente nodos interE onetdos por ros perteneientes l rol tl que hijo(n0 ) = n1 | hijo(n1 ) = n2 | |

4.1. Conceptos bsicos

227

pigur RFRX n rol de ejemplo

hijo(nn1 ) = nn F n mino se denot por Cns ,nt donde ns es el nodo iniio del mino y nt es el nodo (nl del minoF v longitud del camino D denotd omo | Cns ,nt |D es l ntidd de nodos que ontiene el minoF vos ancestros de ni D denotdo omo ancestros(ni )D es el onjunto onformdo por los nodos perteneientes l mino Craiz(T ),padre(ni ) Y es deirD l seueni de nodos predeesores desde l rz hst ni F hdos dos nodos ni , nj T D entonesD nj es nestro de ni si y solo siD nj ancestros(ni )F elgunos disursos utilizn un noin de edad de nodo D l ul est dd por su posiin dentro del mino de sus nestrosF he este modoD ddo un mino Cn0 ,nn =< n0 , n1 , . . . , nn1 , nn >D deimos que ni es ms viejo @o myorA que ulquier ni+c Cni+1 ,nn F hel mismo modo deimos que ni es ms joven @o menorA que ulquier nic Cn0 ,ni1 F hdo un nodo ni Cn0 ,nn =< n0 , n1 , . . . , nn1 , nn >D el onjunto hijos(ni ) es llmdo l iEsim generinF il grado de ni denotdo omo grado(ni )D es l ntidd de suroles que ontiene el nodo ni F il orden o grado de un rol se de(ne omo el nmero mximo de rms que puede tener ulquier nodo del rolF i el grdo de un nodo es igul l orden del rolD entones deimos que el nodo est ompletoF gundo un rol posee muhos nodos inompletos y stos poseen muy pos rmsD entones deimos que el rol es espridoF hel mismo modoD undo hy muhos nodos ompletos deimos que el rol es densoF il nivel de un nodo ni D denotdo omo nivel(ni )D se de(ne reursivmente omo sigueX 0 si ni = raiz(T ) nivel(ni ) = 1 + nivel(padre(ni )) si ni > 0 v altura de un nodo ni D denotd omo h(ni )D se de(ne omo el nmero de nodos menos uno que hy desde ni hst un hoj situd en el ms lto nivelF

228

4. rboles

min puede de(nirse reursivmente omo sigueX

h(ni ) =

0 si ni es un hoj 1 + max(h(hijo1 (ni )), . . . , h(hijom (ni ))) de lo ontrrio

v altura de un rbol T se de(ne omo l ltur de raiz(T )Y es deirD h(raiz(T ))F v cardinalidad de un rbol T D denotd omo |T |D se de(ne por el nmero totl de nodos del rolF slustrremos lgunos de estos oneptos medinte l (gur RFRF v rz es el nodo etiquetdo on A y est situd en el nivel 0F il grdo de raiz(T ) es 4D que tmin orresponde l orden del rolF vos hijos de A son BD CD D y EF padre(B) = padre(C) = padre(D) = padre(E) = AF v ltur de A es 5D que orresponde l longitud del mino ms lrgo desde AF l mino est ddo por CA,U = A, C, H, P, U o CA,V = A, C, H, P, V | |CA,V | = 5F ehor onsideremos un nodo prtiulrD por ejemploD HF enemosX  grado(H) = 3  padre(H) = C  h(H) = 3 = |CH,U | = |CH,V | ijertese on est terminolog onsiderndo d nodo de l (gur RFRF

4.2 Representaciones de un rbol


rdiionlmenteD estos roles strtos se diujn l revs de los nturlesD omo en l (gur RFRF is deirD l rz en l prte superior y sus desendientes en ls prtes inferioresF ist representin es idne en l myor de ls situionesD pero lgunos prolems se prestn pr otrs representiones ms onvenientesF
4.2.1 Conjuntos anidados

B F L E A K S T

C H

U V P Q O I

pigur RFSX gonjuntos niddos in est representinD l rz es un onjunto de nomre raiz(T ) on suroles omo suonjuntosF or ejemploD l (gur RFS ilustr el equivlente en onjuntos niddos del rol de l (gur RFRF ist representin puede fundmentrse sore estruturs de dtos espeilizds en onjuntosF

4.2. Representaciones de un rbol

229

4.2.2

Secuencias parentizadas

vos onjuntos niddos ignorn el orden de priin de los surolesD el ul en lguns situiones puede ser importnteF i se dese mntener este ordenD un re(nmiento onsiste en representr los onjuntos entre prntesisF in este soD l soitividd represent el orden de priin de los surolesF r el rol de ls (gurs RFR y RFS se tiene l siguiente representin prentizdX

(A(B(F(L)(M))(G))(C(H(O)(P(U)(V ))(Q)))(D(I)(J(R)))(E(K(S)(T ))))


ist representin tiene l ventj de que es linel y re)ej on extitud l topolog del rolF gonsideremos l evluin utomti de expresiones lgerisF gomo ejemploD summos est expresin lgeri

3x4 + 3x3 y2 + x2 1 . 4x2 z


/

2
3x4 +3x3 y2 +x2 1 4x2 z

pigur RFTX rol de l expresin in(j

n ompildor podr trduir est expresin l rol de l (gur RFTD el ul dee evlurse de mner sendenteD o seD desde ls hojs hst l rzF iste orden re)ej (elmente ls posiles y vlids mners en que l expresin puede evlurse sin que se pierd su sentido lgerioF in mtemtiD l omposiin de funiones suele esriirse de mner pre(jD es deirD el nomre de l funin u operin pre(jD nteedeD los operndosF or ejemploD f(x, y) represent un funin f on dos operndosF yurre que l seueni prentizd de un rol de expresiones es pre(jF in l ourreniD el rol de l (gur RFT se represent omoX
@G@C@B@QA @ @xA@RAA A @B@QA @ @xA@QAA @ @yA@PAA A @ @xA@PAA @ EI AA @B @RA @ @xA@PA A @zA A A

v linelidd de l representin prentizd puede utilizrse pr l trnsmisin de roles en un redF il sitio origen de l omuniin otiene un representin prentizd que se eml en un mensjeF el reiir el rol prentizdoD el sitio destino ejeut l trnsformin invers EdesemljeE y otiene un opi ext del rolF

230

4. rboles

in l myor de los lengujes de progrminD en rtilugios eletrnios de lulo y en generl en l ingenierD ls expresiones se olon en form in(j y los prntesis se uin en donde quermos modi(r l preedeni de los operdoresF he este modoD l expresin nterior podr esriirse en form in(j omoX
(3*x^4 + 3*x^3*y^2 + x^2 - 1)/ (4*x^2*z)

v ul es l versin resumid de l expresin in(j orrespondiente l rol de l (gur RFTF v expresin in(j es un representin linel del rol y requiere el uso de prntesis pr espei(r el orden de priin de los nodosY extmente de l mism mner en que dee herse on l preedeni en ls expresiones lgerisF
4.2.3 Indentacin

n mner onveniente y rt pr diujr roles pequeosD en l ul no se pierde l estruturD onsiste en indentr por nivelF v ide se expli medinte el siguiente lgoritmoX v entrd del lgoritmo es un rol en su representin gr( lsiF v slid es l representin indentd del rolF il lgoritmo tiene un prmetro llmdo sD de(nido omo el nmero de espios en lno de seprin horizontlF il lgoritmo es reursivo on prototipo void dibujar(Node * x)F v primer llmd dee ejeutrse on l rz pF
Algoritmo 4.1 (Dibujo de un rbol en modo texto)

IF smprimir pF PF y hijos(x) @A sndentr s espios hi l derehF @A dibujar(y); @A sndentr s espios hi l izquierdF QF i x es un hoj = @A lte de lneF il rol de ls (gurs RFR y RFS tiene l siguiente representin indentdX
A B C F G H L M O P Q R S T U V

D E

I J K

4.3. Representaciones de rboles en memoria

231

4.2.4

Notacin de Deway

v estruturin y ontenido de este texto en ptulosD seionesD etterD se orresponde on un roreseni en l ul los ptulos son roles disjuntosF vs seiones de un ptulo son los suroles de l rz yD l vezD ls suseiones son los suroles de un seinF ist estruturin oedee un jerrqu segn el re de estudioF ues ienD el enfoque utilizdo pr enumerr d sein onstituye un mner de representr un rolF il mtodo en uestin se denomin notacin decimal de Deway D por nlog un notin similr usd pr lsi(r liros en iliotesF fsimenteD l notin de hewy es un mner de enumerr e identi(r unvomente d nodo del rolF il rol de ls (gurs RFR y RFS puede representrse medinte los siguientes nmeros de hewyX
(1 : A), (1.1 : B), (1.2 : C), (1.3 : D), (1.4 : E), (1.1.1 : F), (1.1.2 : G), (1.2.1 : H), (1.3.1 : I), (1.3.2 : J), (1.4.1 : K), (1.1.1.1 : L), (1.1.1.2 : M), (1.2.1.1 : O), (1.2.1.2 : P), (1.2.1.3 : Q), (1.3.2.1 : R), (1.4.1.1 : S), (1.4.1.2 : T ), (1.2.1.2.1 : U), (1.2.1.2.2 : V )

il vlor dido de l notin de hewy es que se preserv ntegrmente l form del rol sin neesidd de justrse un orden de seueniF il rol puede resturrse independientemente del orden en que se presenten los nodosF n representin sd en l notin de hewy puede ser muy til en lguns situiones en que l onstruin del rol se ltmente dinmiF min puede deurse pr l trnsmisin remot de roles muy grndes que no tengn id en un solo mensjeF

4.3 Representaciones de rboles en memoria


fsimenteD existen dos mners de representr un rol en memoriX por rreglos y por lists enlzdsF ems representn un intermedio entre veloidd y espioF
4.3.1 Listas enlazadas

in est representinD d nodo se estrutur segn l form siguienteX


clave L_CHILD R_SIBLING

guyos mpos de inters sonX  R_SIBLINGX puntdor l nodo orrespondiente l hermno derehoF  L_CHILDX puntdor su hijo ms l izquierdF vos mpos R_SIBLING onformn un list simplemente enlzd de hermnosF v eer de est list es el nodo ms l izquierdF v entrd est list es el mpo L_CHILD del nodo pdreF vos mpos L_CHILD onformn un list simplemente enlzd de generionesF hdo un nodo xD L_CHILD(x) es su hijo ms l izquierdY L_CHILD(L_CHILD(x)) es el nieto

232

4. rboles

/ + * 3 x 4 * 3 x 3 y 2 x -1 2

* 4 x z 2

pigur RFUX epresentin on lists del rol de l (gur RFT

ms l izquierd de xY L_CHILD(L_CHILD(L_CHILD(x))) es el iznieto ms l izquierd de x y s suesivmente pr el resto de ls generionesF e menudoD l hijo ms l izquierd de un nodo se le tild de primognitoF v (gur RFU ilustr l representin on lists del rol mostrdo en l (gur RFTF i no hy ms hermnos o generionesD entones el puntdor orrespondiente se mr on el vlor espeil NULLF ist representin es ompt y )exileD pues el orden y rdinlidd del rol puede umentrse o disminuirse dinmimenteF il espio oupdo por d nodo es onstnte e independiente del orden del rol y del grdo del nodoF il desperdiio en nodos inompletos @por ls rms no utilizdsA es pequeoX R_SIBLING en el nodo ms l dereh de d list de hermnosD y L_CHILD en el ltimo desendiente de d list de generionesF r eder un nodo de l iEsim generin es neesrio eder ls i 1 generE iones nterioresF r eder l jEsimo hermno es neesrio eder los j 1 hermnos preedentesF i el orden del rol es onoidoD entones el tiempo de eso est otdo y por lo tnto puede onsiderrse onstnteF v verstilidd de l estrutur puede mejorrse si se utilizn lists dolemente enE lzdsF wuhos lgoritmos que requieren regresr sus nestros pueden ene(irse de est extensinF hdo un nodoD un list dolemente enlzd permite reuperr inmeE ditmente el pdreF il enle dole est ddo por el puntero l hijo ms l izquierd y el puntero l pdreF hel mismo modoD l list enlzd puede ser de los hermnosD en uyo so el enle dole est ddo por los punteros l hermno izquierdo y dereho respetivmenteF
4.3.2 Arreglos

hdo un rol de orden mD d nodo ontiene el espio pr el dto y un rreE glo mEdimensionl de puntdores sus m surolesF il vlor NULL indi l useni de l rm orrespondienteF ist representin tiende utilizr ms espio que ls lists enlzdsF il desperdiio de memori en nodos inompletos puede ser importnte si el rol es muy espridoF in l ourreniD en el rol de orden 4 diujdo en l (gur RFVD slo un nodo est ompletoY onseuentementeD el resto de los nodos inompletos desperdii l menos un eld en punteros nulosF v representin es estti en el sentido de que el orden del rol no es fil de modi(rF iste enfoque no es onveniente pr onstruir un rol de orden desonoidoF

4.4. rboles binarios

233

-1

x
y 2

pigur RFVX epresentin on rreglos del rol de l (gur RFT

in muhos sos es onveniente efetur l onstruin on l representin de lists enlzds y onvertirlo luego l representin vetorizdF il eso un generin es equivlente l de ls lists enlzdsD pero el eso ulquier de ls rms es diretoY est rtersti es l que he est representin ms rpid que su ontrprte on lists enlzdsF n lterntiv pr este enfoque es utilizr un rreglo de pres <puntero rmD ordinl de rm>F iste esquem utiliz un espio por nodo proporionl l nmero de rms y puede gnr espio si el rol es stnte espridoF i el nmero de rms es suseptile de ser muy grndeD el rreglo puede estr ordendo por ordinl de rm y l rm puede ser logrtmimente lolizle medinte l squed inriF isto penliz l inserin y l elimininD pues hy que rir y errr rehs en el rregloF

4.4 rboles binarios


ehor proederemos estudir un lse espeil de rol denomind rol inrioF il rol inrio es l se oneptul de un mpli gm de lgoritmos y estruE turs de dtosF
Denicin 4.2 (rbol binario) n rol inrio T es un onjunto (nito de ero o ms nodos de(nido reursivmente omo sigueX

T=

denot el rol inrio vo es el nodo rz n < L(T ), raiz(T ), R(T ) > de lo ontrrio | L(T ) surol izquierdo R(T ) surol dereho

@RFIA

il ontenido de un nodo ni se denot omo KEY(ni )F henominremos B l onjunto in(nito de todos los roles inrios posilesF v de(niin de rol inrio es diferente de l de(niin de rol dd en RFI @gF PPTAF v distinin l he l noin de sentido de l rmF in l ourreniD los roles inrios ilustrdos en l (gur RFW son diferentes jo l de(niin RFPD pero jo

234

4. rboles

l de(niin RFI son igulesF ist difereni de sentido es preismente l rtersti que nos grntizr un orrespondeni unvo entre un rol inrio y uno mErio ulquierF

pigur RFWX hos roles inrios diferentes

4.4.1

Representacin en memoria de un rbol binario

vos roles inrios se representn en memori on rreglosF in emrgoD puesto que l dimensin del rreglo es dosD l representin es prtimente l mism que on lists enlzdsF v (gur RFIH ilustr un ejemploF
G S B H A X Z

pigur RFIHX epresentin en memori de un rol inrio iventulmente puede onvenir un terer puntero por nodo orrespondiente l nodo pdreF
4.4.2 Recorridos sobre rboles binarios

vos roles y los roles inrios representn rdenes jerrquiosF ero reordemos que el omputdor slo proes seuenisD es deirD no puede distinguirD en el mismo sentido de nuestr perepinD que un rol es un rolF gonsideremos el prolem de ontr el nmero de nodos que posee un rol inrioF r esls peques omo seres humnos no estmos restringidos por l topolog del rolF he hehoD podemos orrr tods ls onexiones entre los ros y n somos pes de ontr los nodosF gonsideremos hor l evluin de l expresin (x2 + x + 1)2yD l ul puede representrse medinte un rol inrio similr l de l (gur RFIIF odemos omenzr l evluin sore ulquier de los tres suroles que poseen hojsF or ejemploD podrmos evlur x2 D luego 2yD luego x + 1 y s suesivmenteF xotemos que este orden de evluin no onsider distnis entre rmsD por ejemploD l que hy entre l rm x2 y 2yF xuestr visin nos permite improvisr diverss seuenis de reorrido o proeE smiento sore el rolF in un omputdorD emperoD on l representin de nodo inrio ddD l visin de ste est restringid por ls siguientes ondiionesX IF il primer nodo oservle es l rzF gonseuentementeD si desemos mirr lE gn surol en prtiulrD entones deemos reorrer d generin desendiente

4.4. rboles binarios

235

* + x 2 x + 1 2 * y

pigur RFIIX ixpresin lgeri representd on un rol inrio

desde l rzF PF hesde un nodo ulquier slo se pueden ver sus dos hijos medinte los mpos L(T ) y R(T )F ixisten utro ptrones de seuenis rquetpis o reorridos pr proesr un rol inrioF
Recorrido prejo

IF isite l rzF PF isite l rm izquierd en pre(joF QF isite l rm dereh en pre(joF


Recorrido injo

IF isite l rm izquierd en in(joF PF isite l rzF QF isite l rm dereh en in(joF


Recorrido sujo

IF isite l rm izquierd en su(joF PF isite l rm dereh en su(joF QF isite l rzF


Recorrido por niveles

IF epit desde i a H hst l h(T ) 1 del rol  smprim todos los nodos del nivel i ordendos de izquierd derehF

236

4. rboles

G S B A X Z

pigur RFIPX rol inrio pr ejempli(r reorridos

wuhos textos denominn los reorridos pre(joD in(jo y su(jo omo preordenD enorden y postorden respetivmenteY ngliismos de preorderD inorder y postorderF eplindo ls de(niiones sore el rol de l (gur RFIP tenemos el siguiente reorrido pre(joX G S B X A Z @RFPA rimero visitmos l rz @GAD luegoD el surol izquierdo @S BAD y luegoD el surol dereho @X A ZAF r el reorrido in(jo tenemosX

B S G A X Z

@RFQA

rimero visitmos l rm izquierd en in(jo @B SAD luegoD l rz @GAD y ulminmos on el surol dereho @A X ZAF il reorrido su(jo esX B S A Z X G @RFRA rimero visitmos l rm izquierd en su(jo @B SAD luegoD l rm dereh @A Z XA yD por ltimoD l rz (GAF pinlmenteD el reorrido por niveles esX

G S X B A Z

@RFSA

e menudoD l seueni del reorrido rteriz l topolog del rolF in efetoD los reorridos estn ntimmente reliondos on muhos de los lgoritmos sore roles y rterizn lgo er de su formF gonsideremos el rol de expresiones lgeris mostrdo en l (gur RFIIF u reorrido su(jo esX

x 2 x 1 + + 2 y
que es l expresin su(j de l expresin lgeri @ve PFSFS @gF IHTAAF il reorrido pre(jo esX + x2 + x1 2y

@RFTA

@RFUA

el ul puede evlurse por l dereh de form nlog l evluin de un expresin in(jF ehor onsideremos un lgoritmo de impresin del rol in(joF
Algoritmo 4.2 (Impresin inja, parentizada, de un rbol binario)

lgoritmo es l rz p de un rol inrioF zdo @vse RFPFP @gF PPWAAF il lgoritmo es reursivo on prototipo void imprimir(Node *nodo)D donde nodo es l rz del rol imprimirF v primer llmd dee ejeutrse on l rzF

v entrd del v slid es el reorrido in(joD prentiE

4.4. rboles binarios

237

IF i nodo == NULL termineF PF smprim 4 @4F QF imprimir(LLINK(nodo)); RF smprim el smolo ontenido en nodoF SF imprimir(RLINK(nodo)); TF smprim 4A4F
+

x + 1

pigur RFIQX royein in(j de un rol inrio

r el rol de l (gur RFIID el lgoritmo rroj l seueniX

((((x) (2)) + ((x) + (1))) + ((2) (y))) ;

@RFVA

l ul es un seueni in(jD vlidD de l expresin lgeriF in otrs plrsD el lgoritmo RFP otiene un representin prentizd del rol diferente l representin dd en RFPFP @gF PPWAF ist representin tmin onserv l form del rol y permite reonstruir su form originlF n form visul de interpretr el reorrido in(joD l ul requiere que los nodos estn su(ientemente seprdosD onsiste en imginr l proyein de un luz sore l rzF il reorrido in(jo se proyetr en un plno situdo dejo del rolF v (gur RFIQ esquemtiz l ideF gonsideremos hor un prolem inversoX ddo lgn reorrido ulquierD mo otener el rolc v respuest o(il es que no es posileF v respuest o(ios es que todo depende del tipo de rol inrioF he lgun mnerD un reorridoD undo l onoimiento er del tipo del rolD onllev su(iente informin sore su topologF in l ourreniD el reorrido pre(jo permite identi(r inmeditmente l rz y l rz del surol izquierdoF ero est informin no es por s sol su(iente pr reonstruir el rol originlF e requiere lgo msF ixisten vrios mtodos pr otener l form originlF odos requieren informin diionlF n primer mtodo es dir delimitdores l reorridoY l representin pE rentizd explid en RFPFP @gF PPWA es un ejemploY el lgoritmo RFP de impresin in(j prentizd es otro ejemploF gul es l difereni entre ls representiones prentizds de RFPFP @gF PPWA y l dd por el lgoritmo RFPc r responderD oservemos l representin prentizd del rol de l (gur RFIIX

((+((x)(2))(+(x)(1)))((2)(y)))

@RFWA

238

4. rboles

el eliminr los prntesisD l expresin resultnte es idnti l expresin @RFUAD es deirD es el reorrido pre(joF v representin prentizd de RFPFP @gF PPWA es un versin extendid del reorrido pre(joF hel mismo modoD l representin onstruid por el lgoritmo RFP es un versin extendid del reorrido in(joF ems representiones ontienen informin su(iente pr reonstruir el rol originlF ytr lterntiv pr reonstruir el rol originl onsiste en ominr l informin de dos reorridos diferentes sore el mismo rolD tni st que expliremos en RFRFIQ @gF PSQAF
* + + x 1 x 2 2 * y

pigur RFIRX rol de operiones equivlente l de l (gur RFII gon el reorrido in(jo normlD sin prntesisD no es posile onstruir lgn rol porque es imposile onoer l preedeniF wuhos tipos de roles pueden onstruirse on tn solo el reorrido pre(jo o su(joF ixisten sos en los ules no es neesrio otener un rol idntio l originlD pero s equivlente efetos de l strinF n ejemplo notle est ddo por los roles de expresiones lgerisY por ejemploD el rol de l (gur RFIR es diferente en form pero equivlente en operin l rol de l (gur RFIIF e pesr de ls migeddes es muy importnte prehender queD dd un expresin pre(j o su(jD es posile onstruir utomtimente un rol que represente orretmente l evluin de l expresinF isto es muy importnte porque de lgun mnerD l expresin su(j posee su(iente informin pr onstruir un rolD ergoD pr resolver el prolemF in otrs plrsD en el so de ls expresiones lgeris podrmos optr por onstruir el rol que efete l evluin de izquierd derehF e efetos del prolemD l soluin est dd y l migedd no es importnteF es puesD siempre podrmos trjr on expresiones su(jsD un form e(z y muy ompt de lmenr expresiones lgerisF
4.4.3 Un TAD genrico para rboles binarios

entes de ordr lgoritmos que nos entrenen en el reorrido de roles estleeremos un eh sore el ul fundmentremos l myor de ls estruturs de rol inrio de este textoF wodelizremos e implntremos un menismo genrio pr onstruir nodos inE riosF e lo lrgo de este texto desrrollremos diferentes estruturs de rol inrioF v myor de ells siempre mnejrn tres triutos siosX un lveD un puntero l rm izquierd y un puntero l rm derehF egn el tipo de rolD el nodo puede ontener lgun informin diionl de ontrolF heemos entones enontrr un form de de(nir genrimente nodos inrios de ulquier ndole jo los siguientes requerimientosX

4.4. rboles binarios

239

IF Soporte para atributos generalesX ddo un nodo inrioD dee poder ederse l lve y sus rms desendientesF istos triutos son omunes todos ls lses de nodos inrios posilesF PF Especicacin de atributos opcionalesX eventulmente dee posiilitrse el delrr triutos propios de un lse prtiulr de nodo inrioF QF Soporte opcional para destructores virtualesX el usurio puede trjr opionlE mente on nodos que posen destrutores virtulesF RF Soporte para nodos centinelas especiales1 X normlmenteD el rol vo se sel medinte el vlor espeil NULLF r ierts estruturs de rol es onveniente que este rol vo se represente medinte un instni prtiulr de nodoF hesrrollremos un soluin sd en mros que se expnden lses prmetrizdsF vos mros se de(nen en el rhivo tplinxodeFr (never dened) F tplinxodeFr (never dened) export dos mrosF il primero es el DECLARE_BINNODE(Name, height, Control_Data)D el ul gener dos lses prmetrizds que representn nodos inrios perteneientes lgun lse de rol inrioF il prmetro Name es el nomE re pre(jo de ls lses que se desen generrF il mro se expnde dos lses si idntisX Name y NameVtlF v ni difereni es que NameVtl posee un destrutor virE tulF il prmetro height represent un estimdo de l ltur mxim que puede lnzr el rol inrioF wuhos lgoritmos sore roles inrios son reursivosD por lo que el onsumo de espio en pil es un ftor onsiderrF in este sentidoD el triuto height ofree un proximdo de l ltur mxim del rol inrioD uyo vlor sirve los lgoE ritmos tomr previsiones er del onsumo en pilF pinlmenteD el prmetro Control_Data es un lse que represent informin de ontrol del nodo inrio pertinente un espeilizinD l ul vr segn el tipo de rol inrio que se mnejeF or ejemploD los roles rojoEnegroD que estudiremos en TFS @gF RWHAD lmenn un olorF hestquemos que Control_data no est destind usrse por el usurio (nl wuhos tipos de roles inrios se utilizn pr onstruir mpeos entre lves de lgn dominio y elementos de lgn rngoF in est situinD lo que se requiere es que d nodo lmene un elemento del rngo ddoF uesto que nuestr pretensin es genriD no podemos usr Control_DataD pues si no invlidrmosD por ejemploD un eh rol rojo genrioF n mner de her un mpeo es medinte hereni de interfzF upongmos que requerimos un mpeo medinte roles rojo negroF or ejemploD un mpeo entre nmeros de dul y pellidos puede espei(rse del modo ilustr en l (gur RFISF in este so implntmos un mpeo (jo en el sentido de que este ontendr pres de tipo [int,string]F il int es l lve del nodo inrio y el string se enuentr en l lse derivdF i desemos un mpeo genrioD el ul es ms ompletoD entones l lse derivd dee ser un plntillD lo ulD en el so de nuestro ejemploD puede espei(rse omo se ilustr en l (gur RFITF
1
En ingls, centinela se escribe sentinel; (con s)

240

4. rboles

RbNode<int>
-key: int -lLink: RbNode * -rlink: RbNode * +RbNode(k:const int &) +RbNode(node:const RbNode &) +RbNode() +reset(): void +get_key(): int& +getL(): RbNode*& +getR(): RbNode*&

Persona
+apellidos: string +apellidos(): string +modificar_apellidos(in a:string): void

pigur RFISX etriutos de nodo inrio espei(dos por hereni de un ojeto derivdo de BinNode<Key>
RbNode<Key>
-key: Key -lLink: RbNode<Key> * -rlink: RbNode<Key> * +RbNode(k:const Key &) +RbNode(node:const RbNode<Key> &) +RbNode() +reset(): void +get_key(): Key& +getL(): RbNode<Key>*& +getR(): RbNode<Key>*&

key:class Key data:Data

Mapppig
+data: Data +get_data(): Data

pigur RFITX etriutos de un nodo inrio genrio espei(dos por hereni de un ojeto derivdo de BinNode<Key> vos roles requieren un vlor espeil pr representr el rol voF l vlor se lmen en el triuto esttio Name<T>::NullPtrD el ul dee iniilizrse explitE mente l vlor de rol voF or omisinD DECLARE_BINNODE() sume que el rol vo es el vlor NULLF elguns vees es onveniente que NullPtr punte un nodo entinel prtiulrF in ests situiones deemos usr el segundo mro DECLARE_BINNODE_SENTINEL()D uy sintxis es similr DECLARE_BINNODE()D pero que represent l instni prtiulr desed pr NullPtrF il nodo inrio ms simpleD llmdo BinNode<Key>D se de(ne en un sol lneX clase BinNode<Key> 240 DECLARE_BINNODE(BinNode, 2048, Empty_Node);
Denes:

240

BinNode, used in chunks BinNodeVtl, never used. Uses DECLARE_BINNODE.

319b, 34752, and 509a.

v lse BinNode<Key> espei( el ms simple nodo perteneiente un rol inrioF in onoer el tipo de rol inrio que se trteD su ltur es stnte vrile y depende del orden en que ls lves sen insertdsF or est rznD el tmo de un pil que opere sore un rol inrio dee ser lo su(ientemente grnde pr que permit lturs elevdsF gomo es muy difil determinr l mxim ltur que podr lnzr un rol

4.4. rboles binarios

241

241

inrio generlD l (jmos en un vlor grndeD pero dvertimos que esto no elimin l posiilidd de un desorde de pilF BinNode<Key> no tiene triutos de ontrol espeilesY por esoD olomos l lse v Aleph::Empty_NodeD l ul est de(nid en l lilioteF r filitr l legiiliddD se exportn los siguientes mrosX macros externos de BinNode<Key> 241 # define LLINK(p) ((p)->getL()) # define RLINK(p) ((p)->getR()) # define KEY(p) ((p)->get_key()) hdo un nodo pD el eso l lve se reliz on KEY(p)D el eso l rm izquierd on LLINK(p) y el eso l rm dereh on RLINK(p)F no de los triutos de un nodo inrio ms importntes lo onform el tipo de lveD el ul es genrimente sequile medinte el nomre key_typeF n funin genri puede onoer el tipo de lve de un nodo medinte l instruinX
typename Node::key_type

v ul re(ere l tipo de lve del nodoF wedinte est interfz se puede diser digo genrio sin neesidd de espei(r ni onoer explitmente el tipo de lve que lerg el nodoF upongmos que desemos un nodo que gurde omo triuto de ontrol l ltur del nodoF he(nimos entones un lse que ontiene tl triuto y nos vlemos de los mros de l siguiente formX
class Altura { private: size_t altura; public: Altura() { /* Empty */ } Altura(size_t a) : altura(a) { /* empty */ } size_t dar_altura() const { return altura; } }; DECLARE_BINNODE(Nodo, 255, Altura); SET_BINNODE_NULL_POINTER(NULL, Nodo);

il mro se expnde dos lses plntill denominds Nodo<Key> y NodoVtl<Key>D respetivmenteF vs lses son si idntisD slvo que NodoVtl<Key> de(ne un desE trutor virtulF v estrutur de Nodo<Key> es l siguienteX
template <typename Key, size_t _MaxHeight = 255> class Nodo : public Altura { public: static Nodo * NullPtr; static const size_t MaxHeight = _MaxHeight; typedef Key key_type; private: Key key; Nodo * lLink;

242

4. rboles

Nodo * rLink; public: Key & get_key() { return key; } Nodo *& getL() { return lLink; } Nodo *& getR() { return rLink; } Nodo(const Key & k) : key(k), lLink(NullPtr), rLink(NullPtr) { } Nodo(const Altura & control_data, const Key& k) : Altura(control_data), key(k), lLink(NullPtr), rLink(NullPtr) { } Nodo(const Altura & control_data) : Altura(control_data), lLink(NullPtr), rLink(NullPtr) { } Nodo() : lLink(NullPtr), rLink(NullPtr) { } Nodo(EmptyCtor) { } void reset() { rLink = lLink = NullPtr; } }; template <typename Key, size_t _MaxHeight> BinNode<Key, _MaxHeight> * BinNode<Key, _MaxHeight>::NullPtr = NULL;

vs lses Nodo<Key> y NodoVtl<Key> representn fmilis de nodos inrios on triutos de ontrol de(nidos en l lse Altura y on lve genri KeyF il eso l lve est ddo por get_key() y los esos ls rms izquierd y dereh por getL() y getR()D respetivmenteF Nodo<Key> hered plimente de AlturaF or tntoD un Nodo<Key> es tmin de tipo alturaF he este modoD Nodo<Key> tiene eso tod l interfz pli de AlturaF ry ino mners de onstruir un Nodo<Key> representds por los ino onstruE tores generdos los ulesD exepin del quintoD se explin por s solosF i se reE quiere un nodo entinelD ste se instni medinte el quinto onstrutorD el ul requiere que Node::Node(SentinelCtor) se de(n en l lse AlturaF v plntill Nodo<Key> tiene dos triutos esttiosF Node::NullPtr es el puntE dor l rol voF in l myor de ls situionesD este puntero tendr el vlor nuloY en otrsD Node::NullPtr direionr l nodo entinelF il vlor de Node::NullPtr dee de(nirse explitmente por el invonte de DECLARE_BINNODE medinte el mro SET_BINNODE_NULL_POINTERF iste mro tom omo prmetros el nomre de l lse nodo y el puntero l nodo entinelF il segundo triuto esttio orresponde un vlor estimdo de ltur mximD que puede ser requerido por lgunos lgoritmos pr determinr el tmo de sus pilsF n Nodo<Key> puede reutilizrseF or ejemploD podrmos extrerlo de un rol e insertrlo en otroF in este soD el estdo del nodo dee ser reiniidoF r ello se provee el mtodo reset()F
4.4.4 Contenedor de funciones sobre rboles binarios

wuhs operiones sore roles inrios se enpsuln en un iliote espeE il que ontendr lgoritmos tpios sore roles inrios y que se de(ne en el rhivo tpl_binNodeUtils.HF v iliote ontiene lgoritmos tpios sore roles inriosY por ejemploD ejeuin de reorridosD dupliin de rolesD etterF v myor prte de ls puniones de BinNode_Utils 243a son plntills on l form generl siguienteX

4.4. rboles binarios

243

template <class Node> funcin (...) { ... }

is deirD el tipo prmetrizdo es un nodo inrio genrio NodeF il ontrto mnimo pr que l iliote opere es que Node exporte ls funiones de BinNode<Key> de(nids en tpl_binNode.HF
4.4.5 Recorridos recursivos

v rutin de reorrido se remite su funin siX reorrerF es puesD un rutin de reorrido in(jo tendr el siguiente prototipoX
template <class Node> inline int inOrderRec(Node * root, void (*visitFct)(Node*, int, int))

v funin inOrderRec() reorre en form in(j el rol inrio on rz root y retorn el nmero de nodos visitdosF gd vez que se visit un nodoD se efet un llmd l funin puntd por visitFctD l ul dee orresponderse on el siguiente prototipoX
template <class Node> void visitFct(Node* node, int level, int position)

243a

node es un puntero l nodo visitdoD level es el nivel o l profundidd del nodo respeto l rz y position es su posiin dentro del reorridoF inOrderRec() es un wrpper un funin reursivD esttiD enrgd de efetur el reorridoD l ul se deriv diretmente de l de(niinX Funciones de BinNode_Utils 243a 243b
template <class Node> inline static void __inorder_rec(Node * node, const int& level, int & position, void (*visitFct)(Node *, int, int)) { if (node == Node::NullPtr) return;

__inorder_rec((Node*) LLINK(node), level + 1, position, visitFct); (*visitFct)(node, level, position); ++position; } __inorder_rec((Node*) RLINK(node), level + 1, position, visitFct);

243b

il nivel level se inrement en d llmdD mientrs que l position en d visitF xotemos que position es un prmetro por refereniD pues ste requiere tulizrse en d visitF r que l rutin se onsistenteD l llmd iniil dee relizrse on vlores de level y position igules eroF iste es el trjo de inOrderRec()X Funciones de BinNode_Utils 243a + 243a 244 template <class Node> inline int inOrderRec(Node * root, void (*visitFct)(Node*, int, int)) { int position = 0; __inorder_rec(root, 0, position, visitFct); return position; }

244

4. rboles

244

inOrderRec() retorn el nmero de nodos que ontiene el rolF vos reorridos pre(jo y su(jo se de(nen de mner nlogX Funciones de BinNode_Utils 243a + 243b

245

template <class Node> inline static void __preorder_rec (Node * p, const int & level, int & position, void (*visitFct)(Node*, int, int)) { if (p == Node::NullPtr) return; (*visitFct)(p, level, position); ++position; __preorder_rec((Node*) LLINK(p), level + 1, position, visitFct); __preorder_rec((Node*) RLINK(p), level + 1, position, visitFct);

template <class Node> inline int preOrderRec(Node * root, void (*visitFct)(Node*, int, int)) { int position = 0; __preorder_rec(root, 0, position, visitFct); return position; } template <class Node> inline static void __postorder_rec(Node * node, const int & level, int & position, void (*visitFct)(Node*, int, int)) { if (node == Node::NullPtr) return; __postorder_rec((Node*) LLINK(node), level + 1, position, visitFct); __postorder_rec((Node*) RLINK(node), level + 1, position, visitFct); (*visitFct)(node, level, position); ++position;

template <class Node> inline int postOrderRec(Node * root, void (*visitFct)(Node*, int, int)) { int position = 0; __postorder_rec(root, 0, position, visitFct); return position; }

ods ls primitivs de reorrido de puniones de BinNode_Utils 243a tienen omo primer prmetro l rz del rol inrioF il segundo prmetro es un funin de visit del nodo que provee el liente de l ilioteF v funin ser invod durnte l visit orde su reorridoF xotemos que l ondiin de prd de l reursin es el visitr un nodo nuloF n interfz lternD que segn el ompildor puede ser un poo ms ostos en deE sempeo pero muho ms verstilD onsiste en exportr l interfz jo un lseF in este

4.4. rboles binarios

245

245

soD el reorrido in(jo se instrumentr sX Funciones de BinNode_Utils 243a + template <class Node, class Op> class For_Each_In_Order { static void for_each_inorder(Node * root, Op & op) { if (root == Node::NullPtr) return;
for_each_inorder((Node*) LLINK(root), op); op(root); for_each_inorder((Node*) RLINK(root), op);

244 246

} public: void operator () (Node * root, Op & op) { for_each_inorder(root, op); } }; }; template <class Node, class Op> class For_Each_Preorder { static void preorder(Node * root, Op & op) { if (root == Node::NullPtr) return; op(root); preorder((Node*) LLINK(root), op); preorder((Node*) RLINK(root), op);

public: void operator () (Node * root, Op & op) { preorder(root, op); } void operator () (Node * root, const Op & op) const { preorder(const_cast<Node*>(root), const_cast<Op&>(op)); }

};

template <class Node, class Op> class For_Each_Postorder { static void postorder(Node * root, Op & op) { if (root == Node::NullPtr) return;

246

4. rboles

postorder((Node*) LLINK(root), op); postorder((Node*) RLINK(root), op); op(root);

public: void operator () (Node * root, Op & op) { postorder(root, op); } void operator () (Node * root, const Op & op) const { postorder(root, const_cast<Op&>(op)); }

};

iste ptrn ofree l ventj de que l operin es tod un lse de ojetoD on l posiilidd de espei(r el onstrutor y el destrutor de l lse OpD lo ul permite pre y postproesmientoF
4.4.6 Recorridos no recursivos

246

il estudio de los reorridos es uno de los mejores entrenmientos en lgortmi de rolesD pues otros lgoritmos oedeen ptrones de un reorrido o ominiones de ellosF gomenemos por l versin ms simple del reorrido pre(joX Funciones de BinNode_Utils 243a + 245 247 template <class Node> inline size_t simple_preOrderStack(Node * node, void (*visitFct)(Node *, int, int)) { if (node == Node::NullPtr) return 0;
ArrayStack<Node *, Node::MaxHeight> stack; stack.push(node); Node * p; size_t count = 0; while (not stack.is_empty()) { p = stack.pop(); (*visitFct) (p, stack.size(), count++); if (RLINK(p) != Node::NullPtr) stack.push(RLINK(p)); if (LLINK(p) != Node::NullPtr) stack.push(LLINK(p));

4.4. rboles binarios

247

}
Uses

return count;
ArrayStack
101a.

247

il ptrn itertivo del lgoritmo es simpleX visiteD introduz el rol derehoD luego el izquierdo y sque de l pilF uesto que el rol izquierdo fue introduido despus del derehoD el izquierdo ser el primero extrerse y visitrseF yservemos que el nivel del nodo se orresponde on el tmo tul de l pil ehor ienD segn l de(niin del reorrido pre(joD el rol izquierdo se visit inE meditmente despus de visitr el nodoF odemos entones mejorr el lgoritmo siD en lugr de gurdr en pil el rol dereho gurdmos su pdre y sumimos que todo nodo extrdo de l pil y fue visitdoF iste ptrn ondue l lgoritmo siguienteX Funciones de BinNode_Utils 243a + 246 248a template <class Node> inline size_t preOrderStack(Node * node, void (*visitFct)(Node *, int, int)) { if (node == Node::NullPtr) return 0;
ArrayStack<Node *, Node::MaxHeight> stack; Node *p = node; size_t count = 0; while (true) { (*visitFct)(p, stack.size(), count++); if (LLINK(p) != Node::NullPtr) { stack.push(p); // p y RLINK(p) faltan por visitarse p = LLINK(p); // avanzar a la izquierda continue; // ir a visitar raz rama izquierda } while (true) { if (RLINK(p) != Node::NullPtr) { p = RLINK(p); // avanzar a la derecha break; // ir a visitar raz rama derecha } if (stack.is_empty()) return count; // fin } p = stack.pop(); // sacar para ir a rama derecha

}
Uses

ArrayStack

101a.

he un iert mnerD todo reorrido tiene lgo de pre(joD pues todo rol se ede trvs de ls res de sus surolesF or tntoD es intuitivmente esperle que el

248

4. rboles

248a

reorrido in(jo teng un estrutur similr l pre(joD pues l difereni esenil es el momento en que se visit l rzF il reorrido pre(jo visit l rz ntes de ontinur por l rm izquierdD mientrs que el in(jo lo he despus de venir desde l rm izquierdF hiho esto podemos presentr l versin no reursiv del reorrido in(joX Funciones de BinNode_Utils 243a + 247 249a template <class Node> inline size_t inOrderStack(Node * node, void (*visitFct)(Node *, int, int)) { if (node == Node::NullPtr) return 0;
ArrayStack<Node *, Node::MaxHeight> stack; Node *p = node; size_t count = 0; while (true) { if (LLINK(p) != Node::NullPtr) { stack.push(p); // p y RLINK(p) faltan por visitarse p = LLINK(p); // avanzar a la izquierda continue; // continuar bajando por la rama izquierda } while (true) { (*visitFct)(p, stack.size(), count++); if (RLINK(p) != Node::NullPtr) { p = RLINK(p); // avanzar a la derecha break; // ir a visitar raz rama derecha } if (stack.is_empty()) return count; } p = stack.pop(); // sacar para ir a rama derecha

}
Uses

ArrayStack

101a.

248b

il reorrido su(jo es ms omplejo y ostoso porque l desempilr hy que veri(r si se proviene desde l izquierd o l derehF n mner de distinguir est lse de provenieni onsiste en mrr el nodo empildo on el sentido del reorridoF he este modo podemos de(nir l siguiente pilX Declaracin de pila suja 248b typedef Aleph::pair<Node*, char> Postorder_Pair; ArrayStack<Postorder_Pair, Node::MaxHeight> stack;
Uses

ArrayStack

101a.

4.4. rboles binarios

249

il char de l pil gurd los vlores siguientesX  'i'X sndi que se empil ntes de desender por l rm izquierdF  'l'X sndi que se empil de regreso de l rm izquierdF  'r'X sndi que se empil de regreso de l rm derehF is en este so que se dee visitr el nodoF n reorrido su(jo sdo en estos prinipios est implntdo en l iliote jo el nomE re de postOrderStack()F se el fuente pr myores detlles sore l instrumentin de este lgoritmoF
4.4.7 Clculo de la cardinalidad

rolementeD l pliin ms senill de los reorridos es lulr l rdinlidd de un rol inrioD l ul puede de(nirse reursivmente omoX
|T | = 0 | L(T )| + 1 + | R(T )|

si T =

si T =

@RFIHA

249a

he est de(niin se deriv diretmente el lgoritmoX Funciones de BinNode_Utils 243a + 248a 249b template <class Node> inline size_t compute_cardinality_rec(Node * node) { if (node == Node::NullPtr) return 0; return (compute_cardinality_rec(LLINK(node)) + 1 + compute_cardinality_rec(RLINK(node))); }
4.4.8 Clculo de la altura

eursivmenteD l ltur de un rol inrio T se de(ne omoX


h( T ) = 0 1 + max(h(L(T )), h(R(T )))

si T =

si T =

@RFIIA

249b

he este modo disemos un lgoritmo ompletmente reminisente de l de(niinX Funciones de BinNode_Utils 243a + 249a 250a template <class Node> inline size_t computeHeightRec(Node * node) { if (node == Node::NullPtr) return 0; const size_t left_height = computeHeightRec(LLINK(node)); const size_t right_height = computeHeightRec(RLINK(node));
} return 1 + std::max(left_height, right_height);

250

4. rboles

4.4.9

Copia de rboles binarios

250a

hdo un rol inrio T D opirlo onsiste en otener un rol inrio T uy form y ontenido se orrespond extmente on T F iste lgoritmo puede de(nirse reursivE mente omo sigueX Funciones de BinNode_Utils 243a + 249b 250b template <class Node> inline Node * copyRec(Node * src_root) { if (src_root == Node::NullPtr) return (Node*) Node::NullPtr; Node * tgt_root = new Node(*src_root); LLINK(tgt_root) = copyRec<Node>((Node*) LLINK(src_root)); RLINK(tgt_root) = copyRec<Node>((Node*) RLINK(src_root)); return tgt_root; } in este digo es importnte omentr el mnejo reursivo de tiposF xoteE mos que copyRec() opi roles genrios on nodos de tipo NodeD el ul podr derivr de un lse de nodo de rol inrioF or es rznD l llmd reurE siv copyRec<Node>(LLINK(src_root)) dee espei(r explitmente el tipo NodeD pues si noD en el so de que se trte de un lse derivdD el ompildor invor copyRec() on l lse se l ul orrespondn LLINK(tgt_root) y RLINK(tgt_root)F i l lse Node es distint l lse que retornn LLINK(tgt_root) y RLINK(tgt_root)D entones ourrir un on)ito de tiposF v opi es un lgoritmo fundmentl pr implntr el onstrutor opi y el operdor de signin en tipos strtos que mnipulen roles inriosF
4.4.10 Destruccin de rboles binarios

250b

gulquier eh que mnipule roles inrios dee estr en pidd de destruir todo el rolF is deirD de invor el destrutor y lierr l memori oupd por d nodo del rolF isto se he de l siguiente formX Funciones de BinNode_Utils 243a + 250a 251a template <class Node> inline void destroyRec(Node *& root) { if (root == Node::NullPtr) return; destroyRec((Node*&) LLINK(root)); destroyRec((Node*&) RLINK(root)); delete root; root = (Node*) Node::NullPtr; } u tipo de reorrido exhie este lgoritmoc glrmenteD l form es su(jX l rz se lier luego de lierr ls dos rmsF ytrs vrintes reursivs de este lgoritmoD que se justen los dems reorridosD son posiles y delegds en ejeriiosF
4.4.11 Comparacin de rboles binarios

e vees es neesrio omprr dos roles inriosF fsimenteD hy dos riteriosD los ules presentremos ontinuinF

4.4. rboles binarios

251

4.4.11.1

Similaridad

hdos dos roles inrios T1 y T2 D se die que T1 es similr T2 D y se denot omoX


T1 T2 T1 = T2 = T1 = T2 =

L(T1 ) L(T2 )

R(T1 ) R(T2 )

@RFIPA

251a

ist de(niin sugiere el siguiente digo reursivoX Funciones de BinNode_Utils 243a + 250b 251b template <class Node> inline bool areSimilar(Node * t1, Node * t2) { if (t1 == Node::NullPtr and t2 == Node::NullPtr) return true; if (t1 == Node::NullPtr or t2 == Node::NullPtr) return false; return (areSimilar(LLINK(t1), LLINK(t2)) and areSimilar(RLINK(t1), RLINK(t2))); }
4.4.11.2 Equivalencia

hdos dos roles inrios T1 y T2 D se die que T1 es equivlente T2 D denotdo omo T1 T2 D si y slo siX IF i T1 = T2 = o PF i T1 = T2 = T1 T2 X KEY(raiz(T2 )) L(T1 ) L(T2 ) R(T1 ) R(T2 ) is deirD T1 y T2 son similres y los ontenidos de d nodo son extmente los mismosF v de(niin de equivleni nos rroj l siguiente implntin reursivX Funciones de BinNode_Utils 243a + 251a 251c template <class Node, class Equal> inline bool areEquivalents(Node * t1, Node * t2) { if (t1 == Node::NullPtr and t2 == Node::NullPtr) return true; if (t1 == Node::NullPtr or t2 == Node::NullPtr) return false; if (not Equal () (KEY(t1), KEY(t2))) return false; return (areEquivalents<Node, Equal>(LLINK(t1), LLINK(t2)) and areEquivalents<Node, Equal>(RLINK(t1), RLINK(t2))); }
4.4.12 Recorrido por niveles

251b

251c

in est lse de reorridoD un ol desrie diretmente el orden en que se deen proesr los nodosX Funciones de BinNode_Utils 243a + 251b 253

252

4. rboles

template <class Node> inline void levelOrder(Node * root, void (*visitFct)(Node*, int, bool), const size_t & queue_size) { const size_t two_power = (size_t) (std::log((float)queue_size)/std::log(2.0) + 1); ArrayQueue<Aleph::pair<Node*, bool> > queue(two_power); queue.put(root); for (int pos = 0; not queue.is_empty(); pos++) { Aleph::pair<Node*, bool> pr = queue.get(); Node *& p = pr.first; (*visitFct) (p, pos, pr.second); if (LLINK(p) != Node::NullPtr) queue.put(Aleph::pair <Node*, bool> (LLINK(p), true)); if (RLINK(p) != Node::NullPtr) queue.put(Aleph::pair <Node*, bool> (RLINK(p), false));

}
Uses

ArrayQueue

125a.

is posileD en detrimento de muho ms tiempo ms no del espioD diser un lgoE ritmo reursivo pr reorrer por nivelesF ist versin se deleg en ejeriioF v funin de visit tiene el siguiente prototipoX
(*visitFct)(Node* p, int pos, bool is_left)

p es el nodo visitdoD pos es l posiin del nodo visitdo dentro del reorrido y is_left es un vlor lgio uyo vlor es true si el nodo es izquierdoF n de ls pliiones tpis del reorrido por niveles es pr el diujdo de rolesD en uyo so es til ser si p es o no un hijo izquierdoF v lgi del lgoritmo es provehr l propiedd pspy de l ol pr grntizr el orden de visit requeridoF ist lro que el primer nodo visitr es l rzD por lo que l metemos en l ol y omenzmosF gd vez que se visite un nodoD todos sus omperos de nivel o generin deen ser los siguientes extrer de l olF isto se grntiz porque d vez que visitmos un nodo introduimos en l ol su hijo izquierdo y luego su hijo derehoF istos hijos vn estr en l ol despus de los nestros de su nivel nterior y despus de sus omperos de nivel que estn del ldo izquierdoF in l (gur RFIUD los prximos nodos en l ol son los hermnos derehos del tulD y fueron introduidos undo se est en el nivel unoF hespus vienen los nodos del nivel tres que fueron introduidos undo se proesron los hermnos izquierdos del nodo tulF iste reorrido es el ms ostoso de los utroD pues puede her flt lmenr muhsimos nodos en l olF i ls hojs del rol tienden estr en el mismo nivelD entonesD por d nivel que se desiend se requerir lmenr el dole de l ntidd de nodos hst llegr l nivel donde se enuentren ls hojsF upongmos que l ntidd de nodos de d nivel es poteni ext de dosY o seD d nivel del rol est llenoF intonesD sumiendo ltur onoid h podemos expresr

4.4. rboles binarios

253

actual

Frente Trasero

pigur RFIUX istdo de l ol undo se proes el nodo indido on )eh

1 i h1 nodos lmendos en l l ntidd de nodos n omo h i=0 2 F is deirD tendremos 2 ol undo nos toque proesr el ltimo nivelF uesto que l form de un rol puede ser stnte ritrriD l primitiv levelOrder() reie omo prmetro el tmo mximo de l ol y deleg l liente el estimr un tmo deudo segn su pliinF

4.4.13

Construccin de rboles binarios a partir de recorridos

253

gonsideremos el prolem de lmenr en un seueni un rol representdo en memoE riF iste prolem es de lto inters en situiones donde requirmos gurdr el rol en un rhivo o trnsmitirlo en un mensje2 F gulquier tni que seuenilie un rol @lo lmene en un seueniA est sd en sus reorridosF in RFRFP @gF PQRA estudimos lguns tnis que permiten reE onstruir un rol inrio prtir de uno de sus reorridosF xos st on un slo reorrido porque onomos el (n del rolF i este onoimiento no es sequileD o si queremos seuenilizr de mner generlD entones hy dos mners de slvr el rolF n onsiste el lulr su seueni digo y luego lmenr ls lves en pre(joY tE ni que se revelr y estudir en RFVFHFU @gF QHPAF v segund onsiste en gurdr dos reorridos ulesquier y prtir de ellos reonstruir el rol originlF uesto que y hemos estudido los reorridosD nos dee ser senillo vislumrr rutins que tomen un rol y lo seuenilienF vo que quiz no sen tn fil es l inversinY es deirD reonstruir el rol prtir de sus seuenisF v siguiente rutin reonstruye un rol inrio prtir de sus reorridos pre(jo e in(joX Funciones de BinNode_Utils 243a + 251c 254b template <template <class> class Node, typename Key> inline Node<Key> * build_tree(DynArray<Key> & preorder, const int & l_p, const int & r_p, DynArray<Key> & inorder, const int & l_i, const int & r_i) { if (l_p > r_p) // est vaco el recorrido? return Node <Key> ::NullPtr;
Node<Key> * root = new Node <Key> (preorder[l_p]); // crear la raz if (r_p == l_p)
2
Ntese que segn la equivalencia entre rboles y rboles binarios es suciente con estudiar los binarios.

254

4. rboles

return root; // recorrido de longitud 1

Calcule en i la posicin de preorder[l_p] en inorder[] 254a


LLINK(root) = build_tree <Node, Key> (preorder, l_p + 1, l_p + i, inorder, l_i, l_i + (i - 1)); RLINK(root) = build_tree <Node, Key> (preorder, l_p + i + 1, r_p, inorder, l_i + i + 1, r_i); return root;
DynArray
34.

}
Uses

254a

preorder[] es un rreglo que ontiene el reorrido pre(jo entre los ndies l_p y r_pF hel mismo modoD inorder[] es un rreglo que ontiene el reorrido in(jo entre los ndies l_i y r_iF v rutin retorn l rz del nuevo rol inrioF v lgi del lgoritmo es simpleF il primer elemento de un reorrido pre(jo es l rz del rolD l ul usmos en el reorrido in(jo y otenemos el desplzmiento iF il ndie i divide el reorrido in(jo en dos prtesX los elementos l izquierd que son l_i .. i - 1 y que perteneen l rm izquierdD mientrs que los elementos l dereh son i + 1 .. r_i y que perteneen l rm derehF emos tipos de reorrido no vnzn visitr l rm dereh hst que no se hy visitdo l totlidd del surol izquierdo y l rzF or tntoD justo ntes de omenzr visitr l rm derehD mos reorridos hn visitdo l mism ntidd de nodos @l rm izquierd y l rzAF isto evideni que los reorridos pre(jo e in(jo de l rm dereh estn ontenidos en mos rreglos entre l_p + i + 1 y r_pF v detein de rol vo se he undo los reorridos son vosD es deirD undo los ndies de los reorridos se ruznF v prte ms delid es usr l posiin reltiv de l rz dentro del reorrido in(joF isto lo efetumos uiddosmente medinte inspein seuenilX Calcule en i la posicin de preorder[l_p] en inorder[] 254a (253)
int i = 0; for (int j = l_i; j <= r_i; ++j) if (inorder[j] == preorder[l_p]) { i = j - l_i; break; }

4.4.14

Conjunto de nodos en un nivel

254b

in lguns situiones es neesrio onoer ules son los nodos de un rol que se enE uentrn en un determindo nivel iY por ejemploD undo se diujn rolesD efetos de justr ls posiiones de los nodos en un nivel determindoF v siguiente rutin reorre reursivmente el rol on rz root y gurd en l list level_list los nodos que se enuentren en el nivel levelF il prmetro current_level denot el nivel del nodo que se est visitndo 3 X Funciones de BinNode_Utils 243a + 253 255 template <class Node> inline static void
3
Equivale a la profundidad recursiva.

4.4. rboles binarios

255

__compute_nodes_in_level(Node * root, const int & level, const int & current_level, DynDlist<Node*> & level_list) { if (root == Node::NullPtr) return; if (current_level == level) { level_list.append(root); return; // no vale la pena descender ms } __compute_nodes_in_level(LLINK(root), level, current_level + 1, level_list); __compute_nodes_in_level(RLINK(root), level, current_level + 1, level_list); }
Uses

DynDlist

85a.

255

il rol se reorre en pre(jo y los nodos se gurdn en l list por nivel de izquierd derehF e difereni del reorrido por nivelesD no es neesrio usr un olF v rutin nterior dee llmrse por l que fungir de interfzD l ul se espei( de l siguiente formX Funciones de BinNode_Utils 243a + 254b 259a template <class Node> inline void compute_nodes_in_level(Node * root, const int & level, DynDlist<Node*>& list) { __compute_nodes_in_level(root, level, 0, list); }
Uses

DynDlist

85a.

4.4.15

Hilado de rboles binarios

is fil deduir que un rol inrio de n nodos onsume 2n puntdoresF ero quiz no se tn fil prehender que pr ulquier rol inrio l ntidd totl de punE teros on el vlor NULL siempre es myor que l ntidd de punteros signdosF ws delnte @proposiin RFP @gF PUUAA demostrremos l veridd de est (rminF esumiendo verz l (rmin nteriorD lgunos hn uestiondo el desperdiio de esE pio usdo por los punteros nulosF e tenor del horre pueden onsiderrse ls siguientes perspetivsX IF odemos tener tres tipos de nodosX ompletoD inompleto y hojF gd nodo oupr el espio exto segn el tipo de nodoF or supuestoD d nodo tendr que tener un mpo diionl que indique su tipoF ist soluin es un lterntiv importnte y pelle si hy requerimientos rtios de espioF edolee sin emrgo de esttismo en el sentido de que si el rol mi dinmimenteD entones el tipo de nodo puede mirF min ls operiones sore estos roles son ms omplejs porque sts deen distinguir los tipos de nodosF PF tilizr los puntdores nulos pr lmenr informin diionlF equ surge ls pregunts ul informincD pr quc

256

4. rboles

erlis y hornton IRI Ereportdo por unuth WUE desurieron un uso ingenioso de los punteros nulosF il mtodo onsiste en reemplzr punteros nulos por hilos que vyn hi otrs prtes del rolF v ide es filitr el reorrido yD onseuentementeD los lgoritmosF hdo un nodo pD inompleto u hojD el prinipio est ddo por ls dos regls siguientesX  LLINK(p) punt l nodo predeesor in(joF  RLINK(p) punt l nodo suesor in(joF
T D C B A
. . . . . . . . . . . . . . . . . . . . .. . .. . . . .. . . . .. . . .. . . .. . . ... . . .. . . . . . . . . . . . . . . . . . . . . . .. . . .. . . .. . . . .. . . ... . . . ..... . . . . . . . . . . . . . . . . . . . . .. . . .. . . . .. . . .. . .. . . .. . ... .. .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E . . . . . . . . ... . . . . . ... . . . . .. . . . . . . . . . .. . . . . . . . . . .. .... . . .... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . F . . . . . . . ... . . .. . . . . . . . .. . . . .. . . . ... . . . ... ..... ..... . . . . . . . . . . . . . . . . . . . . . . . . . . . . W . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . .. . . . . . . . . . . . .. . R V . . . . . .. . . . .. . . . .. . . . . . . . .. . .. . . . . . . . .... . . . . . . .. . . . . . . . . . .. . . . . . . . . ... . . . . . .. ... . . . . . ... . . . . . . . . . . . . ... .. . . ..... . . . . ....... . . U . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . ... .. . . . . . . . .. . . . . ... . . . ... . . . . .. . . . ... . . . .. . . . . ... .. .. . . . . . . .... ... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q . . . . . . . . . . . . . .. .... . . . . . . . . . . . .. . ... . . .. . . . . . .. . ... . . . ... . ....... . . ... . ... .... .... ..

N I H
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G . . . . . . . . . . . . .. .... . . . . . . .. . . . . . ... . . . . . . . . ... . . . . .. . . . . . . ... . . . ...... ... .. .... . . . . . . . . . . . . . . . . . . . .. . . . .. . . .. . . . ... . . . .. . . . .. . ..... . . . . . . . . . . . . K . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . J . . . . . . . . . . . . . . . . . . ... .... . . . . . . . . ... . . .. . . . . . . .. . .. . . . . . . ... .. . . . . . . . . . . . . . ... . . .. .... . ... . . L .... . . . . . . . ... . . .. . . . . . . . .. . . .. . . ... .... ..... . . . . . . . . . . . . . . . . . . . . . . . . . . . P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . .. . . . . . . . O . . . . . . . . . . . . . .. . . . . . ... .. . .. . . . . . . . . . ... . . . . .. . . . . . . .. . . . . ... . . . . . . . . . .. . ..... . . .. .... . . . M . . . . .... . . . . . .. . . . ... . . . . . . .. . . . . .. . . . . .. . . . ... . . . . . .. .. . . ... . . . ...... . .. . . .. . . .. . . .. . . .. . . .. . . ... . . ..

pigur RFIVX ijemplo de rol hildo v (gur RFIV ilustr el hildo de un rolF vos hilos son representdos medinte lnes ortdsF ehor estudiemos mo dee relizrse el reorrido in(joF r ello vemos un lgoE ritmo que usque el suesor in(joF v entrd del lgoE ritmo es un puntdor p un nodoF v slid es el suesor in(jo de pF
Algoritmo 4.3 (Bsqueda del sucesor en un rbol hilado)

IF i RLINK(p) es un hilo = retorne RLINK(p)F PF i RLINK(p) es el vlor entinel (n de reorrido = retorne xvvF QF p = RLINK(p) RF epit mientrs que LLINK(p) no se un hilo  p = LLINK(p) SF etorne p v ventj del hildo es l filidd pr reorrer el rolF il reorrido in(jo requiere determinr el primer elemento del reorridoD luego en llmr suesivmente el lgoritmo RFQ hst llegr l ltimo elementoF

4.4. rboles binarios

257

il hildo requiere distinguir si un puntdor es un hijo o un hiloF eunque un it por puntero es su(iente pr espei(r tl distininD los sistems de memori de los omputdores modernos trjn por ytesF e requiere l menos un yte pr utilizr los dos its neesriosF vs mquins gsg purs no restringen el tmo de un loque de memoriY es posileD puesD prtr el yte extrF in mquins sgD los registros y sus mpos deen estr linedos l tmo de l plr de memoriF in onseueniD dir un yte extr puede signi(r un inremento l tmo del registro myor un yteD pues hr que liner el yte extr hi un direin que se deud l tmo de l plrF n tni pr reonoer hijos de hilos onsiste en efetur un trnsforminD inversileD que lleve el vlor de un puntdor un vlor omprendido dentro de ls zons externs l mnejdor de memoriF gundo se exmin un puntdorD se veri( si ste se enuentr dentro del rngo vlidoY si tl es el soD entones se trt de un puntdorY de lo ontrrio se trt de un hilo yD por supuestoD dee herse l trnsformin invers ntes de referenir el puntdorF n ostulo est tni es l portilidd entre diferentes pltforms de hrdwreD sistem opertivoD ompildor y lengujeF v trnsformin trdiionl onsiste en restr un direin un vlor que segure que l rest estr dentro de l zon de dtos o digo oD por desordmientoD dentro de l zon de l pilF v rest es posile slo si el tmo de l zon de memori es menor o igul l sum de ls otrs zonsF e veesD esto no es posileF
Nodo cabecera

G S X

pigur RFIWX epresentin en memori de un rol inrio hildo elguns ntigus mquins gsg tenn el it ms signi(tivo reservdo pr el signoF gomo los puntdores utilizn inneesrimente este signoD pues ls direiones negtivs no tienen sentidoD este it pod utilizrse pr denotr si el puntdor er o no un hiloF vs mquins moderns son sgD y ls pos gsg que existen tienen muhs funionliddes sgF roy en dD l linein de ls direiones de memori es un de ls funionliddes omunes entre los dos tipos de mquinF v linein impli que ls direiones de memori Elos vlores de los puntdoresE siempre estn linedos l tmo de l plr de memoriF in l myor de rquiteturs modernsD l longitud de l plr en its siempre es poteni ext de dosD es deirD puede expresrse omo 2n D que n es igul 2n 28 ytesF isto impli que todo puntdor vlido siempre tendr los n 3 its menos signi(tivos olodos en eroF istos its pueden utilizrse pr lmenr informin diionlY en l ourreniD el it menos signi(tivo de un puntdor puede fungir omo indidor que sele si el puntdor es o no un hiloF ry vris mners de mnipulr el it menos signi(tivo de un puntdorF uiz l ms senill es medinte operiones lgis sore el puntdor omo sigueF Determinar si un apuntador es un hilo 257

257

258

4. rboles

template <class Node> inline bool isThread(Node * p) { return (Node*) (((long) p) & 1); }
258a

Convertir un apuntador en un hilo 258a

template <class Node> inline Node * makeThread(Node * p) { return (Node*) ( ( (long)p) | 1); } template <class Node> inline Node * makePointer(Node * p) { return (Node*) (((long) p) & -2); }

258b

Convertir un hilo en apuntador 258b

he lgun mnerD el hildo plnte un nlog equivlente l difereni entre l lists enlzds irulres y ls no irulresF in este sentidoD un rol hildo se pree un list dolemente enlzdF el igul que en ls lists irulresD es stnte desele utilizr un nodo eerF il lzo izquierdo del nodo eer puntr l primer nodo in(joF il lzo dereho puntr l rzF il hilo izquierdo del primer nodo in(jo y el lzo dereho del ltimo nodo in(jo puntrn l nodo eerF v (gur RFIW ilustr un ejemplo de l representin en memori de un rol hildo utilizndo un nodo eerF r notr l reminiseni on un list enlzdD tome el rol por los nodos B y Z y estireF
4.4.16 Recorridos pseudohilados

i ien l representin hild de roles tiene sus onddes sore el rendimiento de los reorridosD el hildo es ms difil de implntr que l representin trdiionlF i optsemos por l representin trdiionlD existir n lgun form de provehr los punteros nulos desperdiidosc v respuest es (rmtivX los punteros nulos pueden usrse omo hilos temporlesF hdo un rol inrio on rz rD uiquemos ul es su predeesor in(joF isto es equivlente determinr ul es el ltimo nodo que se visit en in(jo de su rm izquierdF odemos determinr tres sosX  i L(r) = NULL = r no tiene predeesorF  i L(r) = NULL = tenemos dos sosX IF i R(L(r)) = NULL = L(r) es predeesorF i L(r) no tiene rm derehD entones L(r) es el predeesor de rF
r
Predecesor
. . . . . . . . . . . . . . . . .... . . . .. . .... . . . . .. . .... . . ..... . . ......... .......

L(r)

R(r)

L(L(r))

4.4. rboles binarios

259

PF i R(L(r)) = NULL = el predeesor es el desendiente ms l dereh de L ( r) F


r L(r) R(r) L(L(r)) R(L(r))
Predecesor

il predeesor de l rz de un rol inrio es el nodo ms l dereh de su surol izquierdoF or simetrD el suesor de l rz de un rol inrio es el nodo ms l izquierd de su surol derehoF hdo un rol inrio de rz rD el reorrido in(jo puede diserse on los siguientes linemientosX IF entes de desender hi l rm izquierdD determine el predeesor rp F PF rg R(rp ) = rD es deirD pong un hilo dereho rp pr que punte l rz r @que es el suesor de rp AF QF rp es el ltimo nodo en in(jo de l rm izquierd de rF gundo lo visiteD reupere r medinte el vlor de R(rp )F entes de visitr rD segrese de resturr R(rp ) l vlor nuloF istmos en pidd de ordr un lgoritmo in(jo que use hilos priles y uy form generl ser l siguienteX Funciones de BinNode_Utils 243a + 255 278a template <class Node> inline void inOrderThreaded(Node * root, void (*visitFct)(Node*)) { if (root == Node::NullPtr) return; Node *p = root, *r = Node::NullPtr, *q;
}

259a

recorrido injo hilado 259b

p ser el nodo que se visit o un nodo de regreso pr ir hi l derehF q es l direin de un nodo sore el ul existe un hilo temporlF r es un puntero l pdre de pF
259b

recorrido injo hilado 259b

(259a)

while (p != Node::NullPtr) { q = LLINK(p); if (q == Node::NullPtr) { // No hay rama izq ==> visitar p (*visitFct)(p); r = p; p = RLINK(p); continue; }

260

4. rboles

if (q != r) // tiene p un predecesor? { // si ==> dejar un hilo para luego subir a visitar p RLINK(q) = p; // Aqu se coloca el hilo p = LLINK(p); // Seguir bajando por la izquierda continue; } (*visitFct)(p); RLINK (q) = Node::NullPtr; // Borrar hilo r = p; p = RLINK(p); // avanzar a la rama derecha

sea q el predecesor injo de p 260

il menismo del lgoritmo no es trivilF r preir ompletmente su funE ionmientoD es neesri un ejeuin mnulD l ul se deleg l letorF
260

sea q el predecesor injo de p 260

(259b)

// avanzar hacia el nodo ms a la derecha de la rama izquierda while (q != r and RLINK(q) != Node::NullPtr) q = RLINK(q);

il hildo pril es muy importnte porque puede usrse en lgoritmos sore roles en los ules se delido utilizr pil o reursinD pues nos horr espio en pilD lo ul nos grntiz un reorrido seguroD sin preoupin por desorde de pilF gonsiguientementeD el hildo dee ser l opin esoger si l ltur del rol es desonoidF ry sin emrgo tres prolems on el hildoF il primero es que l lgortmi es ms omplidF il segundo lo onstituye el eventul onsumo de tiempo requerido pr enontrr el nodo predeesor ntes de jr un nivel l izquierdF pinlmente el ltimo prolem es que los lgoritmos que utilien hildo pril no son reentrntesY es deirD no pueden ejeutrse onurrentemente sore el mismo rolF
4.4.17 Correspondencia entre rboles binarios y

m-rios

ixiste un mtodo generl pr representr un roreseni omo un rol inrio y vieversF il proedimiento se expli en el siguiente lgoritmoX
Algoritmo 4.4 (Conversin de un rbol

m-rio a uno binario equivalente) v entrd es un rol mErio Tm T F v slid es un rol inrio T B equivlente Tm

IF T = F PF ni Tm plique ls siguientes reglsX @A il hermno inmeditmente l dereh de ni en Tm es el hijo dereho de ni en T F iste lgoritmo produe un rol inrio equivlente l mErio ddoF uesto que l rz de un rol Tm no tiene hermnosD l rz del rol inrio resultnte nun tiene hijo derehoF @A il hijo ms l izquierd de ni en Tm es el hijo izquierdo de ni T F

4.4. rboles binarios

261

pigur RFPHX n roreseni

ist oservin nos ondue extender el lgoritmo RFR pr que mneje roresenisD lo ul onsiste simplemente en onsiderr ls res de los roles de l roreseni omo hermnos de un primer rz (tiiF in este so se dee doptr un riterio pr determinr el orden en que los roles de l roreseni se proesn y que onsiste en mirrlos de izquierd derehF ry un mner visul de interpretr el lgoritmo RFRD l ul es omo sigueX IF indene en un list enlzd los hijos de d fmiliF PF ilimine los ros exepto el que v hi el hijo ms l izquierdF
A D E

pigur RFPIX epresentin on lists de l roreseni de l (gur RFPH il rol inrio equivlente ontiene l mism ntidd de ros que el mErioF or d lzo vertil elimindo existe un lzo horizontl didoF v (gur RFPI ilustr el rol inrio equivlente l roreseni de l (gur RFPH luego de ejeutr l interpretin visul del lgoritmo RFRF il rol inrio equivlente de l (gur RFPI es extmente l representin meE dinte lists enlzds de l roreseni esquemtizd en l (gur RFPHF hdo un nodo

262

4. rboles

ulquier en l representin on lists enlzdsD el puntdor hi l list de hijos funge de puntdor l surol izquierdoF enlogmenteD el puntdor hi los hermnos funge de puntdor hi el surol derehoF i se siente inrduloD gire l (gur RFPI unos 45 en el sentido horrio y estire un poquitn los lzosF hee ver un rol on l form de l (gur RFPPF
A B F L M G O P U V Q H R C I J S T K D E

pigur RFPPX rol inrio equivlente l rol de l (gur RFPH v orrespondeni es inyetivY l onversin de un rol mErio rroj un nio rol inrioF min es inversile y su lgoritmo filmente deduileF uesto que T y Tb (T ) son equivlentes pr todo T D ls mnipuliones que se hen sore un rol mErio pueden perfetmente relizrse sore su equivlente inrioF hd un roreseniD existen dos mners elementles de reorrerlsX
Recorrido prejo

IF isite l rz del primer rol @el ms l izquierdAF PF eorr en pre(jo los suroles del primer rolF QF eorr en pre(jo los roles restntes de izquierd derehF
Recorrido sujo

IF eorr en su(jo los suroles del primer rol @el ms l izquierdAF PF isite l rz del primer rolF QF eorr en su(jo los roles restntes de izquierd derehF ehor lulemos el reorrido pre(jo de l roreseni de l (gur RFPHX

A B F L MG C H O P U V Q D I J R E K S T

@RFIQA

iste reorrido orresponde extmente l reorrido pre(jo del rol inrio equivE lente de l (gur RFPPF hespus de todoD el reorrido pre(jo es l mner topolgimente nturl de listr los nodos en un rolF

4.4. rboles binarios

263

il reorrido su(jo de l roreseni de l (gur RFPH esX

L M F G B O U V P Q H C AI R J D S T K E ,

@RFIRA

el ul no orresponde l reorrido su(jo del rol inrio equivlente @(gur RFPPAF in su lugrD l seueni @RFIRA orresponde l reorrido in(jo del rol inrio equivlente de l (gur RFPPF ist equivleni de reorridos @su(jo en un roreseni in(jo en su equivlente inrioA es un gnni lgortmiD pues el reorrido su(jo es ms ostoso de implntr que los reorridos pre(jo e in(joF in resumenD dd un roreseni y el rol inrio equivlente luldo segn el lgoritmo RFRD tenemos ls siguientes orrespondenis entre los reorridosX IF il reorrido pre(jo de l roreseni orresponde l reorrido pre(jo del rol inrio equivlenteF PF il reorrido su(jo de l roreseni orresponde l reorrido in(jo del rol inrio equivlenteF in un roreseniD los reorridos in(jo y por niveles no pueden de(nirse on preE isinF glrmenteD hy vris mners de de(nir el reorrido in(jo sore un roresenE iD pues existen vris mners de olor l rz entre sus surolesF hel mismo modoD hy vris forms de de(nir el reorrido por niveles en un roreseniF v equivleni entre roresenis y roles inrios es de sum importni prE tiF gulquier prolem representdo on roresenis puede representrse y resolverse en el plno de los roles inriosY el enfoque inverso tmin es posileF gomo disedores y progrmdores podemos esoger l representin ms deud en funin de onddes tles omo l omprensin del prolemD l e(ieni de ejeuinD l simpliidd de l soluin y l reutilizin de lgoritmos y de digos existentesF
A B F L
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . M . . . . . . . . . . . . . . ... . . . . . . . . . . . . . ... . . . . . . . . . .. . . . .. . . . . . . . . . ...... ... .. ....... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . G . .. . . . .. . . . . ... . . ... . . . . . .. . .. . . . . . . . .. ... . . . . . . ... . . .. . . . . . . ... . . . ... .... . .... ... . . ... O ..... . . . . . . . . .. . . . . . ... . . . . . . . . . . . . . . . . . . . . . .. . ... .... . . . ........ . . . . . . . . . . . . . . U . . . . . . . . .. . . . ... . . . . . . . . ... . . ... .... .... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C . . . . . ... . . ... . . . ... . . . .. . . ... .. ... .. ...... . . . . . . . . . . . . . . . . . . . . . . . . . . . . I . . . . . . . . .. . . . . . . ... . . . . . .. . . . . . . . . . .. . . . . . ... ... . . . .... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . R . . . . . . ... . . . . . . .. . . .. . . . . . . . . . ... . . . . . . . . ... . . . .. . . . . . . ... .. ..... .......

D
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . J .. . . . . .. ... . . . . ... . . . . .. . ... . . .. . . . . ... . .. . . .... ... . S . ... . . . . . . .. . . . ... . . . . . . . . . . . . .. .... ... . .. .....

E K
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . T . . . . . . . . . . . . . ... . . . . .. . . . . . .. . . .. . . . . . . . . . .. . . . .. . . . . . . . ... .. ...... ....... . . . . . . . . . . . . . . . . . ... . . . .. . . ... . . .. . . . .. . ... .. ..

H
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q . . . . . . . . . . .. . . . . ... .. . . . . . . .. . .. . . . . . . . . ... . . . . . ... . ... ..... ... ... ... .... ... ..

. . . . . . . . . . . . . . . . . ... . . . .. . .. . . .. . . ... . . . ... .. ..

P
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V . . . . . . . . . . ... . . . .. . . . . . . . . .. . . .. . . . . . . . . ... . . . . . . . . . . . ... . . ....... .... ... ...

pigur RFPQX rol inrioD hildoD equivlente l rol de l (gur RFPH il hildo del rol inrio equivlente puede ser til en ierts lses de prolemsF v (gur RFPQ muestr el rol inrio hildo equivlente l roreseni de l (gur RFPHF il diujr est representin on lists nos permitir prehender y orroorr el signi(E do de los hilos y su utilizin pr regresr sore los nestrosF r eso reordemos

264

4. rboles

que el reorrido in(jo en el rol inrio equivlente se orresponde on el reorrido su(jo en l roreseniF or lo tntoD l exepin de los nodos ms l izquierd y ms l dereh del rol inrio equivlenteD podemos onluir on ls siguientes oserviones generles sore los hilos y su sentido respeto l rol mErioX IF n hilo dereho punt siempre su pdreD pues ste es el suesor su(jo en l roresE eniF PF n hilo izquierdo denot que el nodo es hoj en el rol mErioY esto se dedue diretE mente de l equivleniF il nodo destino del hilo orresponde on el predeesor su(jo en el rol mErioF equ tenemos dos sosX @A i l hoj es el nodo ms l izquierd en el rol mErioD que puede identi(rse en el equivlente inrio porque es un hijo izquierdoD entones el hilo punt un to primognito en lgun generinF xotemos que puede trtrse de un to direto o de un to en generiones nterioresD segn l profundidd de l hojF @A in el so ontrrioD si l hoj no es el ms l izquierd en rol mErioD entonesD el hilo punt siempre su hermno izquierdoF

4.5 Un TAD genrico para rboles


vos roles inrios nos permiten resolver un mpli vriedd de prolemsF xo ostnteD en lguns osiones puede preferirse un rol de lgn orden ddoF in este sentidoD est sein trtr sore el diseo e implntin de un eh que modelie un rolF il eh en uestin se enuentr en el rhivo tpltreenodeFr 264a 4 D uy estruE tur generl es omo sigueX tpl_tree_node.H 264a template <class T> class Tree_Node { Atributos de Tree_Node 264b Mtodos privados de Tree_Node 265c Mtodos pblicos de Tree_Node 264c };

264a

Mtodos utilitarios de rboles 270a

264b

il eh Tree_Node modeliz un nodo de un rol generlD el ul gurd un triuto genrio de tipo T espei(do de l siguiente formX Atributos de Tree_Node 264b (264a) 265a T data; il ul puede ederse medinteX Mtodos pblicos de Tree_Node 264c T & get_key() { return get_data(); } T & get_data() { return data; } typedef T key_type;
4
Brito (maestra) y Juan Fuentes (pregrado). (264a) 265b

264c

En la elaboracin de este TAD se cont con las valiosas ayudas de los para la poca estudiantes Jos

4.5. Un TAD genrico para rboles

265

265a

xuestr primer deisin de diseo onsiste en esoger l representin en memoriF uesto que pretendemos verstilidd y generliddD trnsremos por l representin on listsD pues st ofree ms dinmismo que su ontrprte on rreglosF gonsiguienteE menteD requerimos dos enles dolesX Atributos de Tree_Node 264b + (264a) 264b 265e Dlink child; Dlink sibling;

265b

child enlz los hijos ms l izquierd y sibling enlz los hermnosY su eso est ddo por los siguientes mtodosX Mtodos pblicos de Tree_Node 264c + (264a) 264c 266a
Dlink * get_child_list() { return &child; } Dlink * get_sibling_list() { return &sibling; }

265c

wuhs veesD luego de otener un puntero Dlink o desde child o siblingD neeE sitremos onvertirlo un Tree_Node F r ello genermos funiones de onversin meE dinte los mros ofreidos por l lse Dlink @ PFRFU @gF UPAAX Mtodos privados de Tree_Node 265c (264a) 265d LINKNAME_TO_TYPE(Tree_Node, child); LINKNAME_TO_TYPE(Tree_Node, sibling); e su vezD este pr de mtodos nos permite de(nir el eso los nodos del entorno de un Tree_Node X Mtodos privados de Tree_Node 265c + (264a) 265c Tree_Node * upper_link() { return child_to_Tree_Node(child.get_prev()); } Tree_Node * lower_link() { return child_to_Tree_Node(child.get_next()); } Tree_Node * left_link() { return sibling_to_Tree_Node(sibling.get_prev()); } Tree_Node * right_link() { return sibling_to_Tree_Node(sibling.get_next()); } is deirD el pdre y el hijoD trvs de upper_link() y lower_link()D en so de que se trte de un nodo que se el ms l izquierdD y los hermnos izquierdo y derehoD left_link() y right_link()D si se trt de ulquier otro nodo diferente l primognitoF i ien ls lists son irulresD ells no tienen nodo eerF or est rzn deemos estr muy pendientes de ul es el extremo de d listF in este sentido mrremos d nodo on nders que nos indirn el tipo de nodo segn que ste se extremo de lgun listF r ello de(nimos los siguientes itsX Atributos de Tree_Node 264b + (264a) 265a struct Flags { unsigned int is_root : 1; unsigned int is_leaf : 1; unsigned int is_leftmost : 1;

265d

265e

266

4. rboles

};

unsigned int is_rightmost : 1; Flags() : is_root(1), is_leaf(1), is_leftmost(1), is_rightmost(1) {}

Flags flags;

266a

v oservin y modi(in de ests nders de(nen los siguientes mtodos sore un nodoX Mtodos pblicos de Tree_Node 264c + (264a) 265b 266b bool is_root() const { return flags.is_root; }
bool is_leaf() const { return flags.is_leaf; } bool is_leftmost() const { return flags.is_leftmost; } bool is_rightmost() const { return flags.is_rightmost; } void set_is_root(bool value) { flags.is_root = value; } void set_is_leaf(bool value) { flags.is_leaf = value; } void set_is_leftmost(bool value) { flags.is_leftmost = value; } void set_is_rightmost(bool value) { flags.is_rightmost = value; }
4.5.1 Observadores de

Tree_Node

266b

eprte de ls nders y el dto genrioD desde un Tree_Node pueden oservrse sus noE dos dyentesD es deirD su pdreD su hijo ms l izquierd y sus hermnosF gomenemos por los hermnosD los ules son los oservdores ms simplesX Mtodos pblicos de Tree_Node 264c + (264a) 266a 266c Tree_Node * get_left_sibling() { if (is_leftmost()) return NULL; return left_link(); }
Tree_Node * get_right_sibling()

266c

get_right_sibling() es simtrimente similr get_left_sibling()F hesde un nodo se puede eder sus hijos extremosX el ms l izquierd y el ms l derehX Mtodos pblicos de Tree_Node 264c + (264a) 266b 267a
Tree_Node * get_left_child() { if (is_leaf()) return NULL; return lower_link(); } Tree_Node * get_right_child()

4.5. Un TAD genrico para rboles

267

if (is_leaf()) return NULL; Tree_Node * left_child = lower_link(); return left_child->left_link();

267a

emos mtodos pueden referir l mismo nodo en so de que this teng un solo hijo o est voF in so de que el grdo del nodo se myor que dosD el resto de los nodos puede ederse medinte get_left_sibling() y get_right_sibling()F e efetos de l verstiliddD puede onvenirnos el eso segn el ordinlX Mtodos pblicos de Tree_Node 264c + (264a) 266c 267b Tree_Node * get_child(const int & i) { Tree_Node * c = get_left_child(); for (int j = 1; c != NULL and j < i; ++j) c = c->get_right_sibling(); return c; } il mtodo retorn NULL si index es myor o igul que el grdo del nodoF pinlmenteD el ltimo oservdor onierne l nodo pdreX Mtodos pblicos de Tree_Node 264c + (264a) 267a 267c Tree_Node * get_parent() { if (is_root()) return NULL; Tree_Node * p = this; while (not ISLEFTMOST(p)) // baje hasta el nodo ms a la izquierda p = p->left_link(); return p->upper_link(); } vos roles pueden soirse en un roreseni
4.5.2 Modicadores de

267b

Tree_Node

267c

gundo se re un nuevo nodo se sume rz de un rolF ry dos tipos de inserinX omo hermno y omo hijoF egn el tipo de inserinD el nodo puede dejr de ser rzF ry dos forms de insertr omo hermnoX l izquierd y l derehF i el nodo hermno es rzD entones el nodo insertdo sigue siendo rzF in este soD trtmos on un roreseni sequile medinte los hermnosF in so ontrrioD el nodo insertdo omprte el mismo pdreF v inserin omo hermno dereho se espei( de l siguiente formX Mtodos pblicos de Tree_Node 264c + (264a) 267b 268a void insert_right_sibling(Tree_Node * p) { if (p == NULL) return;
if (not is_root())

268

4. rboles

p->set_is_root(false); p->set_is_leftmost(false); Tree_Node * old_next_node = get_right_sibling(); if (old_next_node != NULL) p->set_is_rightmost(false); this->set_is_rightmost(false); this->sibling.insert(SIBLING_LIST(p));

268a

v inserin omo hermno izquierdo es un poo ms omplid porque p puede devenir el hijo ms l izquierdD en uyo soD el ntiguo ms izquierd dee srse de l list de hijos child y sustituirse por pF Mtodos pblicos de Tree_Node 264c + (264a) 267c 268b void insert_left_sibling(Tree_Node * p) { if (p == NULL) return;
if (not this->is_root()) p->set_is_root(false); p->set_is_rightmost(false); Tree_Node * old_next_node = this->get_left_sibling(); if (old_next_node != NULL) p->set_is_leftmost(false); else if (not this->child.is_empty()) // p ser ms a la izq { // this es ms a la izq ==> p debe a ser primognito Tree_Node * parent = this->get_parent(); Tree_Node * left_child = this->get_left_child(); CHILD_LIST(this)->del(); // sacar this de lista de hijos if (parent != NULL) // ahora meter a p en la lista de hijos parent->insert(p); else left_child->append(p); } this->set_is_leftmost(false); this->sibling.append(SIBLING_LIST(p));

268b

ems primitivsD insert_right_sibling() e insert_left_sibling()D insertn por l izquierd y dereh y requieren que el nodo insertr est voF il segundo tipo de inserinD es deirD omo hijoD puede efeturse omo el hijo ms l izquierd o el ms l derehF re qu l de l izquierdX Mtodos pblicos de Tree_Node 264c + (264a) 268a 269a void insert_leftmost_child(Tree_Node * p) { if (p == NULL) return;

4.5. Un TAD genrico para rboles

269

p->set_is_root(false); if (this->is_leaf()) { this->set_is_leaf(false); CHILD_LIST(this)->insert(CHILD_LIST(p)); } else { Tree_Node * old_left_child_node = this->lower_link(); old_left_child_node->set_is_leftmost(false); p->set_is_rightmost(false); CHILD_LIST(old_left_child_node)->del(); CHILD_LIST(this)->insert(CHILD_LIST(p)); SIBLING_LIST(old_left_child_node)->append(SIBLING_LIST(p)); }

269a

min existe su equivlente por l derehD llmdo insert_rightmost_child()F eunque eventulmente es posile onstruir un roreseni medinte lguns de ests lses de inserinD es preferile onstruir roles y luego endenrlos en un roreseni medinte el siguiente mtodoX Mtodos pblicos de Tree_Node 264c + (264a) 268b 269b void insert_tree_to_right(Tree_Node * tree) { tree->set_is_leftmost(false); Tree_Node * old_next_tree = this->get_right_tree(); if (old_next_tree != NULL) tree->set_is_rightmost(false);
this->set_is_rightmost(false); SIBLING_LIST(this)->insert(SIBLING_LIST(tree));

il prmetro tree dee impertivmente ser un rolD es deirD tree tiene que ser un rzY de lo ontrrio se onsider un errorF
4.5.3 Observadores de rboles

269b

eroresenis onstruids medinte insert_tree_to_right() pueden onsultrse trvs de los siguientes mtodosX Mtodos pblicos de Tree_Node 264c + (264a) 269a 269c Tree_Node * get_left_tree() Tree_Node * get_right_tree() istos mtodos retornn el rol situdo l izquierd o dereh de this respetivmenteF iventulmenteD slo desde el primer rol de l roreseniD o seD desde el ms l izquierd puede onsultrse el rol ms l dereh de l roreseni medinte l siguiente operinX Mtodos pblicos de Tree_Node 264c + (264a) 269b Tree_Node * get_last_tree()

269c

270

4. rboles

4.5.4

Recorridos sobre

Tree_Node

270a

il primer ejeriio del eh rein explido es el desrrollo de los reorridosF gonsidereE mos en primer lugr el reorrido pre(jo reursivo de un rolX Mtodos utilitarios de rboles 270a (264a) 270b template <class Node> static inline void __tree_preorder_traversal(Node * root, const int & level, const int & child_index, void (*visitFct)(Node *, int, int)) { (*visitFct)(root, level, child_index); Node * child = root->get_left_child(); for (int i = 0; child != NULL; ++i, child = child->get_right_sibling()) __tree_preorder_traversal(child, level + 1, i, visitFct); } v rutin reorre reursivmenteD en pre(joD el rol on rz rootF in d visit se invo l funin puntd por (*visitFct)D uyos prmetros son el nodo visitdoD su nivel dentro del rol y su ordinl omo hijo respeto su pdreF __tree_preorder_traversal() no est destind omo interfz pliF in su lugrD disemos dos primitivs plis de reorrido pre(jo que llmn l versin esttiD un pr un rol y otr pr un roreseniX Mtodos utilitarios de rboles 270a + (264a) 270a 270c template <class Node> inline void tree_preorder_traversal(Node * root, void (*visitFct)(Node *, int, int)) { __tree_preorder_traversal(root, 0, 0, visitFct); } template <class Node> inline void forest_preorder_traversal(Node * root, void (*visitFct)(Node *, int, int)) { for (/* nada */; root != NULL; root = root->get_right_tree()) __tree_preorder_traversal(root, 0, 0, visitFct); } il reorrido su(jo es muy similr y omprensile luego de estudido el reorrido pre(joF
4.5.5 Destruccin de

270b

Tree_Node

270c

r her l eh Tree_Node mnimmente opertivo nos es esenil l destruinD uy espei(in es omo sigueX Mtodos utilitarios de rboles 270a + (264a) 270b 271a template <class Node> inline void destroy_tree(Node * root) { if (not IS_UNIQUE_SIBLING(root)) SIBLING_LIST(root)->del(); // no ==> sacarlo de lista hermanos // recorrer los subrboles de derecha a izquierda for (Node * p = root->get_right_child(); p != NULL; /* nada */) { Node * to_delete = p; // respaldar subrbol a borrar p

4.5. Un TAD genrico para rboles

271

} template <class Node> inline void destroy_forest(Node * root) { while (root != NULL) // recorre los rboles de izquierda a derecha { Node * to_delete = root; // respalda raz root = root->get_right_sibling(); // avanza a siguiente rbol SIBLING_LIST(to_delete)->del(); // elimine de lista rboles destroy_tree(to_delete); // Borre el rbol } }
4.5.6 Bsqueda por nmero de Deway

} if (root->is_leftmost()) // sacar lista hijos? CHILD_LIST(root)->del(); delete root;

p = p->get_left_sibling(); // Avanzar p a hermano izquierdo destroy_tree(to_delete); // eliminar recursivamente rbol

271a

lntemosnos l squed de un nodo en un rol ddo su nmero de hewy @ RFPFR @gF PQIAAF in ese sentido de(nimos un mino de hewy omo un seueni de enteros gurdd en un rreglo de tipo int path[] y delimitd on un vlor negtivo que indi el (n de l seueniF v primitiv fundmentl de squed de hewy es l siguienteX Mtodos utilitarios de rboles 270a + (264a) 270c 271b template <class Node> static inline Node * __deway_search(Node * node, int path [], const int & idx, const size_t & size) { if (node == NULL) return NULL; if (path[idx] < 0) // verifique si se ha alcanzado el nodo return node; // avance hasta el prximo hijo path[0] Node * child = node->get_left_child(); for (int i = 0; i < path[idx] and child != NULL; ++i) child = child->get_right_sibling(); return __deway_search(child, path, idx + 1, size); // prximo nivel } v rutin retorn NULL si el nodo on el nmero de hewy espei(do en path[] no se enuentr en el rolY l direin de tl nodoD en so ontrrioF v primitiv nterior es privd porque un versin ms omplet que inluy squed en un roreseniD puede implntrse tl omo sigueX Mtodos utilitarios de rboles 270a + (264a) 271a 272a template <class Node> inline Node * deway_search(Node * root, int path [], const size_t & size) { for (int i = 0; root != NULL; i++, root = root->get_right_sibling()) if (path[0] == i) return __deway_search(root, path, 1, size);

271b

272

4. rboles

return NULL;

4.5.7

Clculo del nmero de Deway

272a

in muhos ontextos5 D un prolem importnte onsiste en usr un nodo en el rol y entones determinr su nmero de hewyF r ello plntemos un reorrido pre(jo del rol on un rreglo que onteng el nmero de hewy tul del nodo visitdo segn el siguiente prototipoX Mtodos utilitarios de rboles 270a + (264a) 271b 272b template <class Node, class Equal> inline static Node * __search_deway(Node * root, const typename Node::key_type & key, const size_t & current_level, int deway [], const size_t & size, size_t & n);

272b

__search_deway() us reursivmente en el rol uy rz es root l lve keyF e d llmd reursiv se inrement el nivel current_levelD el ul se us pr tulizr el nmero de dewy lmendo en el rreglo deway y uy pidd es sizeF il prmetro n tiene sentido si se enuentr l lve y lmen l longitud del nmero de hewyF v rutin nterior es iniid por l siguiente interfz pliX Mtodos utilitarios de rboles 270a + (264a) 272a 272c
template <class Node, class Equal = Aleph::equal_to<typename Node::key_type> > inline Node * search_deway(Node * root, const typename Node::key_type & key, int deway [], const size_t & size, size_t & n) { n = 1; // valor inicial de longitud de nmero de Deway for (int i = 0; root != NULL; i++, root = root->get_right_sibling()) { deway[0] = i; Node * result = __search_deway <Node, Equal> (root, key, 0, deway, size, n); if (result != NULL) return result; } return NULL; }

272c

xos flt por de(nir l rutin que reorrer en pre(jo el rol l squed de l lveX Mtodos utilitarios de rboles 270a + (264a) 272b 273 template <class Node, class Equal> inline static Node * __search_deway(Node * root, const typename Node::key_type & key, const size_t & current_level, int deway [], const size_t & size, size_t & n) { if (root == NULL) return NULL;
5
En particular para programas que requieran como entrada el nmero de Deway de un nodo.

4.5. Un TAD genrico para rboles

273

if (Equal () (KEY(root), key)) { n = current_level + 1; // longitud del arreglo deway return root; } Node * child = root->get_left_child(); for (int i = 0; child != NULL; i++, child = child->get_right_sibling()) { deway[current_level + 1] = i; Node * result = __search_deway <Node, Equal> (child, key, current_level + 1, deway, size, n); if (result!= NULL) return result; } return NULL;

4.5.8

Correspondencia entre

Tree_Node

y rboles binarios

273

in est susein implntremos l orrespondeni entre roles mErios y inrios exE plid medinte el lgoritmo RFR presentdo en RFRFIU @gF PTHA6 F il primer lgoritmo que desrrollremos ser el de l onversin de un rol mErioD implntdo medinte del eh Tree_Node hi un rol inrio implntdo trvs del eh BinNode<Key>F gundo deimos implntdo trvs del eh FFF nos referimos que el rol mErio y inrio se fundmentn en ls lses Tree_Node y BinNode<Key> respetivmenteD pero no por fuerza son con exactitud de estas dos clasesD sino que podrn serD por ejemploD lses derivdsF v onversin de un rol mErio hi uno inrio se expres diretmente segn ls puts del lgoritmo RFRD es deirD en el rol inrioD tod rm izquierd orresponde un hijo ms l izquierd del rol mErioD mientrs que tod rm dereh orresponde l siguiente hermnoF egn estos linemientosD l implntin resultnte es omo sigueX Mtodos utilitarios de rboles 270a + (264a) 272c 274a template <class TNode, class BNode> BNode * forest_to_bin(TNode * root) { if (root == NULL) return BNode::NullPtr; BNode * result = new BNode (root->get_key()); LLINK(result) = forest_to_bin<TNode,BNode>(root->get_left_child()); RLINK(result) = forest_to_bin<TNode,BNode>(root->get_right_sibling()); return result; } v rutin mnej dos tipos genriosF il primeroD TNodeD es un nodo mErio sdo en el eh Tree_Node F il segundo tipo es BNodeD el ul represent el nodo inrio y dee estr sdo en BinNode<Key>F v veri(in de estos tipos se llev o implitmente en
6
En el diseo e implantacin de las funciones explicadas en esta subseccin es menester sealar la participacin fundamental de Juan Fuentes.

274

4. rboles

tiempo de instniin de l plntill undo se ompiln ls tres penltims lnes y se veri( l existeni de los mtodos que se invonF v onversin de un rol inrio hi uno mErio es un poo ms loriosD rzn por l ul nos onviene desomponerl en rutins espe(s y seprds que efeten iones onrets y modulrizdsF in este sentido hy dos iones pr un Tree_Node X IF snserin de primognitoX omo y semosD en un rol inrio un rm izquierd represent un primognito en el rol mErio equivlenteF gundo en un nodo inrio mirmos su hijo izquierdo lo insertmos en el rol mErio omo priE mognitoF he este modoD plntemos l surutin siguienteX
274a

Mtodos utilitarios de rboles 270a +

(264a)

273 274b

template <class TNode, class BNode> inline static void insert_child(BNode * lnode, TNode * tree_node) { if (lnode == BNode::NullPtr) return; TNode * child = new TNode(KEY(lnode)); tree_node->insert_leftmost_child(child); }

il prmetro lnode es un nodo inrio que es hijo izquierdoF il prmetro tree_node es un nodo mErio equivlente l nodo inrio pdre de lnodeF PF snserin de hermnoX nlogmenteD undo en el nodo inrio mirmos su hijo dereho lo insertmos en el rol mErio omo su hermno derehoF isto ondue l siguiente surutinX
274b

Mtodos utilitarios de rboles 270a +

(264a)

274a 274c

template <class TNode, class BNode> inline static void insert_sibling(BNode * rnode, TNode * tree_node) { if (rnode == BNode::NullPtr) return; TNode * sibling = new TNode(KEY(rnode)); tree_node->insert_right_sibling(sibling); }

il prmetro rnode es un nodo inrio que es hijo derehoF il prmetro tree_node es un nodo mErio equivlente l nodo inrio pdre de rnodeF ehor estmos listos pr implntr el lgoritmo que lule el rol mErio equivlente uno inrioX Mtodos utilitarios de rboles 270a + (264a) 274b 275 template <class TNode, class BNode> inline static void bin_to_tree(BNode * broot, TNode * troot) { if (broot == BNode::NullPtr) return;

274c

4.6. Algunos conceptos matemticos de los rboles

275

insert_child(LLINK(broot), troot); TNode * left_child = troot->get_left_child(); bin_to_tree(LLINK(broot), left_child); insert_sibling(RLINK(broot), troot); TNode * right_sibling = troot->get_right_sibling(); } bin_to_tree(RLINK(broot), right_sibling);

275

il prmetro broot es l rz de un rol inrio fundmentdo en el eh BinNode<Key>F il prmetro troot es l rz de un rol mErioD fundmentdo en el eh Tree_Node D equivlente brootF pinlmenteD l interfz pli y de(nitiv que re l rz iniil y dispr l onsE truin reursivD se de(ne de l siguiente formX Mtodos utilitarios de rboles 270a + (264a) 274c template <class TNode, class BNode> inline TNode * bin_to_forest(BNode * broot) { if (broot == BNode::NullPtr) return NULL; TNode * troot = new TNode (KEY(broot)); bin_to_tree(broot, troot); return troot; }

4.6 Algunos conceptos matemticos de los rboles


vos roles se enuentrn entre ls estruturs ms interesntes y omplejs de l mtemti omintoriF in est sein presentremos un orpus mtemtio mnimo que nos permit ordr el nlisis de ls diferentes estruturs rol que luego estudiE remosF xos onierne onoer qu tnto un rol se pree un rolD pues pr lguns situiones omputionlesD unto ms un rol se un rolD entonesD ms e(iente es su utilizinF xotemos que un list de elementos enj en el onepto de rolD emperoD ovimenteD si los roles tuviesen topologs similres ls listsD entones ser preferile utilizr listsF
4.6.1 Altura de un rbol

n primer indidor er de qu tn ueno puede ser un rol es onoer ls lturs posiles en funin del nmero de nodosD pr ello es til estudir l siguiente proposiinF
Proposicin 4.1

e T un rol mErio on n nodosF intonesX logm (n(m 1) + 1)

h(T ) n

@RFISA

276

4. rboles

Demostracin

 h(T ) logm (n(m 1) + 1)

v ltur de un rol es mnim undo el nmero de nodos ompletos es mximoF r omprender esto onsideremos onstruir progresivmente un rol mErio evitndo en lo posile umentr su lturF e prtir del rol vo slo podemos insertr el nodo rzF vuegoD tenemos m espios disponiles en el nivel 1F osteriormenteD d uno de los m nodos del nivel 1 tmin tiene m elds disponiles que estrn en el nivel 2Y es deir m m elds que pueden olorse en el nivel 2F gontinundo est lne de rzonmiento es fil oservr que d nivel i puede ontener lo sumo mi nodosF or tntoD el nmero de nodos de un rol onstruido de est form puede expresrse omoX
h(T )1

i=0

mi = m0 + m1 + m2 + + mh(T )1

@RFITA

wultiplindo @RFITA por m tenemosX


h(T )1

mn

i =0

= m1 + m2 + + mh(T )1 + mh(T )

@RFIUA

estndo @RFIUA menos @RFITAD tenemosX

logm (n(m 1) + 1)  h(T ) n

n(m 1) + 1 mh(T ) = h(T )

m n n mh(T ) 1 =

r este so seguimos l lne de rzonmiento invers l punto nteriorD es deirD onstruimos progresivmente un rol mErio trtndo siempre de umentr su lturF l rol es qul que tiene extmente n niveles y un nodo por nivelF ues este rol tiene ltur n

ist proposiin revel ots pr el ms orto y lrgo mino desde l rz hst un hoj en funin de l rdinlidd del rolF uponiendo n nodosD el rol ms orto posile tiene ltur h(T ) = logm (n(m 1) + 1) D mientrs que el ms lto h(T ) = nF vos roles on ltur mnim son de grn importni omputionlD pues grntiE zn l myor e(ieni de muhos de los lgoritmos sore rolesF e l feh tul hy poos esquems en los ules se pued restringir l ltur dinmi y e(zmente pr que st se mnimF es puesD muhs vees es neesrio mntener roles uy ltur no se mnimF v lidd de est ltim lse de roles se mide en qu tnto estos roles se ern los de ltur mnim y no relmente por el vlor de su lturF equerimos entones un medid diionl que nos indique qu tn ueno es el rolF il mro onE eptul de est medid se denomin longitud del mino internoGexternoD y se enunir en l susein siguienteF

4.6. Algunos conceptos matemticos de los rboles

277

4.6.2

Longitud del camino interno/externo

Denicin 4.3 (Nodo externo)

e T un rol mErio on n nodos y se ni lgn nodo inompleto de T tl que grado(ni ) = m < mF intonesD los nodos externos de ni se de(nen omo los grado(ni ) m suroles fltntesF in otrs plrsD un nodo externo es todo puntero nuloF gonseuentementeD un nodo interno es todo nodo perteneiente l rolF e menudo es onveniente y ms fil nlizr un rol on un versin espeil en que se muestren todos sus nodos externosF rdiionlmenteD los nodos internos se represenE tn on rulos y los externos on lnes horizontlesF v (gur RFPR ilustr l versin extendid de un rol inrioF

pigur RFPRX rol inrio extendido or trdiinD en expresiones lgerisD un nodo interno se denot omo ni y uno externo omo nx F
Proposicin 4.2

e T un rol mErio on n nodos internosF intonesD el nmero de

nodos externos esX

(m 1) n + 1
Demostracin

@RFIVA

is lro que existen m n puntdoresF he los n nodosD n 1 tienen pdre @l rz noAF ixisten entones n 1 rms o puntdores diferentes de nuloD por lo que el nmero de nodos externos estr ddo por el totl de puntdores menos l ntidd de puntdores no nulosF isto esX

mn (n 1) = (m 1)n + 1
or l proposiin RFPD pr un rol inrio de n nodos existen 2n puntdoresD n 1 puntdores nodos internos y n + 1 nodos externosF e T un rol mErioD entonesD l rdinE lidd del nivel iD denotd |nivel(i)|D se de(ne omo el nmero de nodos internos en el nivel iF
Denicin 4.4 (Cardinalidad del nivel) Denicin 4.5 (Longitud del camino interno/externo) e T un rol mErio on n nodosF v longitud del mino interno del rol T D denotd omo IPL(T )D se de(ne omoX

IPL(T ) =
ni T

nivel(ni ) =
ni nodo interno i

i | nivel(i)|

@RFIWA

enlogmenteD l longitud del mino externoD denotd omo EPL(T )D se de(ne omoX EPL(T ) =
nx T

nivel(nx )
nx nodo externo

@RFPHA

278

4. rboles

r el rol de l (gur RFPRD l longitud del mino interno es IPL(T ) = 0 + 1 + 1 + 2 + 2 + 2 + 2 + 3 + 3 + 3 = 19 y l longitud del mino externo es EPL(T ) = 3 + 3 + 3 + 3 + 3 + 4 + 4 + 4 + 4 + 4 + 4 = 39 il lulo de l longitud del mino es fundmentl pr el nlisis emprio de desemE peo de lgoritmos sdos en roles inrios de squedY un lse de rol inrio espeil que estudiremos ms delnteF isto justi( diser un primitiv que lule el IPLX Funciones de BinNode_Utils 243a + 259a 278b template <class Node> inline static size_t __internal_path_length(Node * p, const size_t & level) { if (p == Node::NullPtr) return 0; return level + __internal_path_length(LLINK(p), level + 1) + __internal_path_length(RLINK(p), level + 1); } il prmetro level indi el nivel tul del nodo visitdo y tmin dee iniilizrse en eroF v interfz pli internal_path_length_rec() funge pues de wrpper que ejeute l llmd iniilX Funciones de BinNode_Utils 243a + 278a 311 template <class Node> inline size_t internal_path_length(Node * p) { return __internal_path_length(p, 0); }
Proposicin 4.3

278a

278b

e T un rol mErioD entonesX


m

|T | =
i=1 m

|T i | + 1
IPL(T i ) + |T | 1
i=1 m

@RFPIA @RFPPA @RFPQA

IPL(T ) = EPL(T ) =
i=1

EPL(T i )

(m 1)|T | + 1

Demostracin

r @RFPIA es evidente que |T | es l sum de ls rdinliddes de sus suroles ms su rzF in unto @RFPPAD notemos que el nodo rz de T no tiene inideni en l longitud del minoD pues su nivel es 0F gundo lulmos ls longitudes de los minos de los suroles de T D sumimos que los nodos estn un nivel inferiorD es deirD d nodo es sumdo en un nivel menosF or ejemploD l rz de T i D que en T est en el nivel 1 se ponder on 0 en lugr de 1Y lo mismo suede on el resto de los nodosF es puesD pr otener el vlor de IPL(T ) deemos sumr 1 d nodo onsiderdoD es deirD l ntidd de nodos |T | 1D pues l rz no uentF pinlmenteD pr @RFPQAD el rzonmiento es extmente el mismo que pr @RFPPAD slo que el nmero de nodos externos esD segn @RFIVA @proposiin RFPAD (m 1)|T | + 1

4.6. Algunos conceptos matemticos de los rboles

279

ists identiddes son fundmentos de muhs de ls demostriones involurds en los rolesF


Proposicin 4.4

e T un rol mErioF intonesX EPL(T ) = (m 1) IPL(T ) + m |T | @RFPRA

Demostracin (por induccin sobre la cardinalidad de

T)

esumiremos que k

represent l rdinlidd de un rol Tk F  |Tk | = 0 in este so EPL(T0 ) = (m 1) IPL(T0 ) + m |T0 | = 0F v proposiin es iert pr el so seF  |Tk+1 | = k + 1 in este so sumimos que l proposiin es iert pr todo k y proeE demos veri(r si es iert pr k + 1F gomenzmos por plnter l rest de l euin @RFPQA menos @RFPPA en funin de los resultdos de l proposiin RFQ @euiones @RFPQA y @RFPPAAX

EPL(Tk+1 ) IPL(Tk+1 )

i EPL(Tk +1 ) + (m 1)|Tk+1 | + 1 i IPL(Tk +1 ) + |Tk+1 | 1

i=1 m

i=1 m

=
i=1 m

i EPL(Tk +1 ) + mk + m 2k

i IPL(Tk +1 )

i=1

ehor plimos l hiptesis indutiv sore el trmino

m i i=1 EPL(Tk+1 )X

EPL(Tk+1 ) IPL(Tk+1 )

=
i=1

i i (m 1) IPL(Tk +1 ) + m|Tk+1 | + m i IPL(Tk +1 )

mk + m 2k
i=1 m

( m 2)
i=1

i IPL(Tk +1 ) + 2mk + m 2k

m i i xotemos queD por @RFPIAD m i=1 |Tk+1 | = (k + 1) 1 = kF v sumtori i=1 IPL(Tk+1 ) puede reemplzrse por IPL(Tk+1 ) kD que es el resultdo de despejr l sumtori de @RFPPA evlud en Tk+1 X

EPL(Tk+1 ) IPL(Tk+1 ) EPL(Tk+1 )

= = =

(m 2) IPL(Tk+1 )

(m 2)(IPL(Tk+1 ) k) + 2mk + m 2k mk + 2k + 2mk + m 2k =

(m 1) IPL(Tk+1 ) + m(k + 1)

@RFPSA

que es l mism expresin de l proposiin evlud pr k + 1 nodos ist proposiin nos yudr estudir los lmites reliondos on l longitud del minoD los ules se estleen en l siguiente proposiinF

280

4. rboles

Proposicin 4.5

e T un rol mErio de n nodosF intonesX @RFPTA

logm (n(m 1)) m logm (n(m1)+1) + mn n(n 1) IPL(T ) m1 2


Demostracin

+1 ) r demostrr IPL(T ) n(n plntemos l longitud del mino del 2 rol de myor ltur posileF l rol es qul uyos nodosD on exepin de l rz y l hojD slo tienen un rmF v longitud del mino de este rol est dd porX n

IPL(T ) =
i=0

i=

n(n 1) 2

r demostrr l ot inferior plntemos l longitud del mino externo del rol de ltur mnim h en funin de l proposiin RFR @pgF PUWAX EPL(T ) hmh = (m 1) IPL(T ) + mn = hmh + mn IPL(T ) m1

@RFPUA

or l proposiin RFI @pgF PUSAD onoemos el vlor mnimo de hF ustituimosD puesD l prte izquierd de @RFISA en @RFPUAX IPL(T ) logm (n(m 1)) m logm (n(m1)+1) + mn m1

ris lses de roles no otn l lturD pero sonD en formD uenosF il sv es un mtri que permite omprr roles entre s y determinr qu tn ueno es uno respeto l otroF heimos que un nodo est lleno undo ste ontiene todos sus hijosF or el ontrrioD deimos que un nodo est inompleto undo le flt l menos un hijoF
4.6.3 rboles completos

gonsideremos l mner de onstruir un rol mErio de n nodos uy longitud del mino se mnimF r onstruir tl rolD deemos poner l myor ntidd de nodos en los niveles inferioresY no deemos ponerlos en un nivel superior hst que no se hyn ompletdo todos los niveles predeesoresF iguiendo est lne de rzonmiento podemos ver que slo un nodoD l rzD puede estr distni 0 de l rzF e lo sumoD m nodos pueden estr distni 1 de l rzF e lo sumo m m = m2 nodos pueden estr distni 2F in generlD lo sumoD m m m . . . m = mi nodos pueden estr en el iEsimo nivelF es puesD l longitud del mino interno de este rol ser l sum de los primeros n trminos de ls seriesX

0, 1, 1, . . . 1, 2, 2, . . . 2, 3, 3, . . . , 3, 4, 4, . . . , 4, . . . ,
m m2 veces m3 veces m4 veces

cantidad de nodos en el ltimo nivel

mh1 , mh1 , , mh1

e T un rol de n nodosD de ltur hD uyos nodos estn ls mnims distnis de l rzF odemos entones denotr un expresin de se pr l longitud del minoX
h2

IPL(T ) =
i =0

i mi + (h 1)n

@n es l ntidd de nodos en el ltimo nivelA

@RFPVA

4.6. Algunos conceptos matemticos de los rboles

281

h1 i r ontr el nmero de nodos en el ltimo nivel rzonmos omo sigueF i=0 m ser el totl de nodos si el ltimo nivel estuviese ompletmente llenoF ehor ienD si el 1 i ltimo nivel no estuviese ompletoD entones fltrn h i=0 m n nodos pr ompletr el nivelF edemsD si el ltimo nivel estuviese ompletoD entones hr mh1 nodos en el ltimo nivelF e n el nmero de nodos en el ltimo nivelD entonesX h1 h1

n =m

h 1

i=0

=m

h 1

i=0

mi + n

@RFPWA

es deirD el mximo nmero de nodos en el ltimo nivel menos los nodos que fltn pr ompletr el nivelF el resolver ls sumtoris involurdsD tenemosX IPL(T ) =

(h 1)mh1 (h 2)mh m mh 1 h 1 + ( h 1 ) m +n (m 1)2 m1

@RFQHA

v soluin (nl de @RFQHA se deleg omo ejeriioF ytr form de resolver @RFPVA y @RFQHA es plntendo un sumtori distint que inE volure logritmosX
n

IPL(T ) =
i =1

logm i

@RFQIA

uy soluin tmin se deleg en ejeriio y que puede resolverse por desomposiin de l sumtori en dos prtesF vos roles ompletosD que son de longitud de mino mnimD son muy importntesD pues representn l myor e(ieni posile sore muhos lgoritmosF n propiedd muy interesnte de los roles ompletos est dd por el heho de que ellos pueden representrse seuenilmente en memori medinte un rregloF v (gur RFPS ilustr un rol trinrio ompleto donde d nodo est etiquetdo on su respetivo ndie dentro de un rreglo seuenilF v disposiin de los ndies orresponde un reorrido por nivelesF
1

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

pigur RFPSX rol trinrio ompletoY nodos enumerdos segn posiin en rreglo seuenE il r distinguir est representin de l explid en RFQFP @gF PQPA l denotremos omo representin medinte rreglo seuenilF e i el ndie de un nodo ni dentro de un rol de n nodos representdo on un rregloF e T (i, j) el jEsimo surol de l rz de un surol on ndie i @los ndies

282

4. rboles

omienzn en 1AF intonesX padre(ni ) =

m+i2 i1 = m m

@RFQPA @RFQQA

T (i, j) = m(i 1) + 1 + j

ists frmuls funionn pr ulquier orden de rolF or sus ventjsD l inmens myor de utores y odi(dores pre(ere est representin pr lgoritmos que mneE jen roles ompletosD notlemente los heps inriosD un estrutur muy verstil que permiteD entre otrs ossD ordenr e(ientemente e implntr ols de prioriddF

4.7 Heaps
gomenemos est sein desde lo strto introduiendo l de(niin de l estruE tur de dtos de est seinX
Denicin 4.6 (Heap)

n hep 7 T es un rol on ls dos siguientes propieddesX

IF FormaX el rol es ompletoD lo ul impli queD pitrimenteD exhie l siguiente formX

PF OrdenX ni T = KEY(hijo1 (ni )) < KEY(ni ) KEY(hijo2 (ni )) < KEY(ni ) KEY(hijom (ni )) < KEY(ni ) egn el grdo del rolD un hep puede ser inrioD trinrio o de ulquier otro ordenF rid uent de l equivleni entre los roles inrios y ls roresenis @ver RFRFIU @gF PTHAAD en este texto slo onsiderremos los heps inriosF or tntoD si se trt de un rol inrioD entones l propiedd de orden puede expresrse omoX ni T = KEY(L(n1 )) < KEY(ni ) KEY(R(n1 )) < KEY(ni )F v ondd de un hep se resume en dos rterstisX IF il menor elemento de un onjunto de lves se enuentr diretmenteD por onseuenE i de l propiedd de formD en l rz del rolY diho de otro modoD l onsult del menor elemento es O(1)F PF gulquier modi(in del hepD entendmos un inserin o elimininD uest O(lg(n))F sntuitivmenteD esto es un onseueni de l propiedd de formD l ul grntiz que l ltur est otd O(lg(n))F
7
En pro de la compresin, preservaremos el trmino en su voz anglosajona, sin traduccin. Cabe mencionar adems que el trmino heap plantea algunas ambigedades. Al respecto, es menester hacer dos aclaratorias: 1. En ingls, el trmino heap tiene varias acepciones, pero en nuestro caso connota un montn, bulto o pila de cosas. Por ejemplo,

 hep of dirty lothes

reere a una pila de ropa sucia.

2. En las ciencias computacionales, heap se ha utilizado para connotar dos cosas. La primera concierne a una especie de rbol binario, la cual es el sujeto de estudio de la presente seccin. La segunda reere a la administracin de memoria en un proceso.

4.7. Heaps

283

2 14 68 104 134 149 99 98 188 243 56 166 112 31 48 185 217 87 200 207 69 80 228 38 145 156

pigur RFPTX n hep inrio v estrutur de dtos preferid pr implntr un hep es un rreglo que lmene el reorrido por niveles del rol ompletoF or ejemploD el hep de l (gur RFPT puede representrse on l siguiente seueniX P IR QV TV QI TW IRS IHR WV ST RV VU VH PPV IST IQR IRW WW IVV PRQ ITT IIP IVS PIU PHH PHU l ul se lmen en un rreglo array[] espei(do del siguiente modoX miembros privados de ArrayHeap<Key> 283a (284b) 283c T * array; v rzD o seD el menor elemento del onjuntoD se enuentr enX Raz del heap 283b array[1]; xotemos que es array[1] y no array[0]D por eso el rreglo se prt pr dim + 1F r mnejr est estrutur de dtosD deemos espei(r l dimensin del rreglo y ontr l ntidd de elementos del hep medinteX miembros privados de ArrayHeap<Key> 283a + (284b) 283a 284a const size_t dim; size_t num_items; hdo un ndie iD los esos l pdre y los hijos se espei(n de ls siguientes formsX IF PadreX en este so nos smos en @RFQPAX
283d

283a

283b

283c

Rutinas heap 283d

283e

static size_t u_index(const size_t & i) { return i  1; // divide i entre 2 }

PF Hijo izquierdo: segn @RFQQAX


283e

Rutinas heap 283d +

283d 284c

static size_t l_index(const size_t & i) { return i  1; // multiplica i por 2 }

284

4. rboles

QF Hijo derecho: tmin segn @RFQQAX


284a

miembros privados de ArrayHeap<Key> 283a +

(284b)

283c 288a

static size_t r_index(const size_t & i) { return (i  1) + 1; // multiplica i por 2 y suma 1 }

284b

istos lulos reveln un ventj del hep inrio respeto ulquier de otro ordenX los produtos y divisiones pueden herse rpidmente medinte desplzmientos de itsD los ules son sustnilmente ms rpidos que los produtos y divisiones que ofree el proesdor o un ilioteF vos heps inrios implntdos medinte rreglos se espei(n en el rhivo tplrryrepFr 284b D uy espei(in generl es omo sigueX tpl_arrayHeap.H 284b template <typename T, class Compare = Aleph::less<T> > class ArrayHeap { miembros privados de ArrayHeap<Key> 283a miembros pblicos de ArrayHeap<Key> 288b }; ist lse prmetrizd implnt un hep inrio de elementos de tipo genrio TD medinte un rreglo esttio y on riterio de omprin estleido en l lse CompareF
4.7.1 Insercin en un heap

gonsideremos un hep inrio de tmo n y l inserin de un nuevo elemento xF ry un solo lugrD dentro del rolD en el ul puede dirse un nuevo elemento sin lterr l propiedd de formY tl lugr se pitoriz en l (gur RFPUF qrntizd l propiedd de

pigur RFPUX vugr de inserin en un hep formD flt por veri(r on(rmr yD eventulmenteD resturrD l de ordenF r eso nos vldremos de l rutinX Rutinas heap 283d + 283e 286 template <typename T, class Compare> inline void sift_up(T * ptr, const size_t & l, const size_t & r) { for (size_t p, i = r; i > l; i = p) { p = u_index(i); // ndice del padre (c = i/2) if (Compare () (ptr[p], ptr[i])) // cumple propiedad orden? return; // si, todo el arreglo es un heap
} std::swap(ptr[p], ptr[i]); // intercambie y restaure nivel p

284c

4.7. Heaps

285

v entrd de sift_up() es un rreglo ontentivo de un hep inrio entre l y r 1D on un eventul violin de l propiedd de orden en array[n]Y l slid es un hep inrioD en form y ordenD entre l y rD on l eventul violin orregidF il proeso se ejempli( en l (gur RFPVF fsimenteD sift_up() se veri( si existe un violin de orden entre ptr[i] y ptr[p]F i tl es el soD entones intermi sus elementos y siende proesr el nivel inferiorY si noD entonesD todo el rol es un hepF il proeso ontinu hst que el pdre se menor o se lne l rzF
33 33 59 39 59 39

118

108

61

79

118

108

61

79

143

135

123

169

66

81

100

113

143

135

123

169

66

38

100

113

256

198

145

138

170

152

182

227

190

144

120

38

256

198

145

138

170

152

182

227

190

144

120

81

(a)
33

(b)
33

59

39

59

38

118

108

38

79

118

108

39

79

143

135

123

169

66

61

100

113

143

135

123

169

66

61

100

113

256

198

145

138

170

152

182

227

190

144

120

81

256

198

145

138

170

152

182

227

190

144

120

81

(c)

(d)

pigur RFPVX yperin sift_up() sore el vlor de lve 38 heemos prestr espeil uiddo l heho de que intervlo del hep es [1 . . . n] y no [0 . . . n 1]D omo trdiionlmente se mnejn los rreglos en lenguje C y C++ F gonseE uentementeD l direin ptr dee estr desplzd en un uniddF il oste de sift_up() se expres por el siguiente lemX
Lema 4.1 e T un hep inrio de n elementos on un violin eventul de orden en array[n]F intonesD l durin de sift_up(array, 1, n) es O(lg(n))F Demostracin

il tiempo de ejeuin de sift_up() estr domindo por l ntidd de intermios que osione el elemento violtorioF in este sentidoD lo peor que puede ourrir es que el elemento violtorio deveng l rz de T F or tntoD l ntidd mxim de intermios es proporionl l ltur del rolF uesto que T es ompletoD y segn se desprende de l proposiin RFID su ltur est otd por O(lg(n))
285

wedinte sift_up() es simple dir un nuevo elemento key l hepX Aadir elemento al heap 285 (288d) array[++num_items] = key; // colocar nuevo elemento sift_up<T,Compare>(array, 1, num_items); // restaurar propiedad orden lo ulD por el lem RFID es O(lg(n))F
4.7.2 Eliminacin en un heap

v eliminin puede plnterse de dos mnersX @IA eliminin de l rz y @PA eliminE in de ulquier elementoF in reliddD el so @PA es generl y omprende l @IAD peroD en fvor de l simpliiddD trtremos el primero por seprdoF

286

4. rboles

gonsideremos pues l eliminin del menor elemento de un hepD es deirD su rzF hesde l perspetiv de formD eliminr l rz equivle pitrimente l (gur RFPWED lo ul morfolgimente no es un hepF ryD de nuevoD un mner de resturr l formD l ul equivle pitrimente l (gur RFPWEF is deirD el ltimo elemento soreesrie
min x
(a) Heap sin raz

timo elemento

x
(b) Reemplazo por l-

pigur RFPWX isquem pitrio de l eliminin l rzF elegrimenteD el hep se ort por el ltimo nivel del rol yD on ese pedzoD se rellen el hueo dejdo por l rzF il nuevo elemento rzD muy prolemente violr l propiedd de ordenD l ul puede resturrse medinte el proedimiento sift_down()D enrgdo de intermir elementos del hep hst que l propiedd de orden se resturdF sift_down() es ligermente ms omplejo que sift_up()D pues hy que mirr los dos hijos del eventul elemento violdor y esoger pr intermir el menor de ellosF he este modo se grntiz l propiedd de ordenF il proeso ontin en el siguiente nivel hst que los dos hijos sen myores o se lne el ltimo nivelF
81 38

59

38

59

81

118

108

39

79

118

108

39

79

143

135

123

169

66

61

100

113

143

135

123

169

66

61

100

113

256

198

145

138

170

152

182

227

190

144

120

33

256

198

145

138

170

152

182

227

190

144

120

(a)
38

(b)
38

59

39

59

39

118

108

81

79

118

108

61

79

143

135

123

169

66

61

100

113

143

135

123

169

66

81

100

113

256

198

145

138

170

152

182

227

190

144

120

256

198

145

138

170

152

182

227

190

144

120

(c)

(d)

pigur RFQHX yperin sift_down() sore l rz 33 en el hep de l (gur RFPV


286

Rutinas heap 283d +

284c 287b

template <typename T, class Compare> inline void sift_down(T * ptr, const size_t & l, const size_t & r) { size_t i = l, c; while (true) { c = l_index(i); // ndice del hijo izquierdo (c = i/2) if (c > r) // hay hijo izquierdo? return; // no ==> termine if (c + 1 <= r) // hay hijo derecho?

4.7. Heaps

287

if (Compare () (ptr[c + 1], ptr[c])) // s ==> escoja menor c++; if (Compare () (ptr[i], ptr[c])) // cumple propiedad orden? return; // s ==> termine std::swap(ptr[c], ptr[i]); i = c;

v rutin tom un hep entre [l + 1 . . . r] y restur l propiedd de ordenF hespus de efetud l llmdD l seueni deviene un hep ompleto entre [l . . . r]F v durin de sift_down() se revel en el siguiente lemX e T un hep inrio de n elementos on un violin eventul de orden en array[1]F intonesD l durin de sift_down(array, 1, n) es O(lg(n))F
Lema 4.2

il tiempo de ejeuin de sift_down() est domindo por l ntidd de intermios que osione el elemento violtorioF in este sentidoD lo peor que puede ourrir es que el elemento violtorio lne el mximo nivel de T D o seD su lturF or tntoD l ntidd mxim de intermios es proporionl l ltur del rolF gomo T es ompleto yD segn l proposiin RFID su ltur est otd por O(lg(n))
Demostracin
287a

gon lo nterior en mente podemos plnter l eliminin del siguiente modoX Eliminar raz en heap 287a (288d) array[1] = array[num_items]; sift_down<T,Compare>(array, 1, num_items); // propiedad orden l ulD segn el lem RFPD es O(lg(n))F v segund mner de eliminrD ms generlD es plntendonos l supresin de un elemento ulquierF r elloD simplemente plimos el mismo prinipio del primer tipo de elimininX soreesriir el elemento que desemos eliminr on el ltimo de l seueniF v difereni on el primer mtodo es que qu pueden presentrse violiones del orden por el pdre o por los hijosF vlmremos l rutin generl de supresin sift_down_up()D pues se remite slo ess ionesX Rutinas heap 283d + 286 290c template <typename T, class Compare> inline void sift_down_up(T * ptr, const size_t & l, const size_t & i, const size_t & r) { sift_down <T, Compare> (ptr, i, r); sift_up <T, Compare> (ptr, 1, i); } gon l rutin nterior podemos plnter l eliminin del iEsimo elemento del hepX Eliminar elemento i 287c array[i] = array[num_items]; sift_down_up <T, Compare> (array, 1, i, n);

287b

287c

288

4. rboles

4.7.3

Colas de prioridad

ixiste un mplsim gm de situiones en ls ules dinmimente se requiere mnejr un onjunto de lves y onoer el menor elemento en ulquier momentoF r tl tipo de irunstni se emple un eh onoido omo ol de prioriddD uys operiones y desempeo se resumen en l tl RFIF
xomre de operin i(ieni peor so
O(lg(n)) O (1) O(lg(n))

insert(item) top() remove(n)

le RFIX hesempeo de ls operiones de un ol de prioridd vs ols de prioridd se modelizn diretmente medinte el eh ArrayHeap<Key>D y introduidoD y el eh BinHeap<Key>D que ser trtdo en RFUFT @gF PWQAF v nder array_allocated indi si se prt o no el rreglo y se de(ne sX miembros privados de ArrayHeap<Key> 283a + (284b) 284a mutable bool array_allocated; on est nder el destrutor se si se dee o no lierr l memoriX miembros pblicos de ArrayHeap<Key> 288b (284b) 288c virtual ~ArrayHeap() { if (array_allocated and array != NULL) delete [] array; } v onsult del menor es l operin ms simple y rpid de un hepX miembros pblicos de ArrayHeap<Key> 288b + (284b) 288b 288d T & top() { return array[1]; } v inserin y eliminin tmin son muy senillsD ddo que todo el trjo y h sido efetudoX miembros pblicos de ArrayHeap<Key> 288b + (284b) 288c 289a T & insert(const T & key) {
} T getMin() { T ret_val = array[1]; } return ret_val; return array[num_items];

288a

288b

288c

288d

Aadir elemento al heap 285

Eliminar raz en heap 287a

eordemos queD segn se desprende de los lems RFI y RFPD los loques edir elemento l hep 285 y iliminr rz en hep 287a son O(lg(n))F uesto que el resto del entorno de insert() y getMin() es O(1)D entones ests operiones son O(lg(n))F

4.7. Heaps

289

4.7.3.1

Modicacin de prioridad

289a

is plusile modi(r el vlor de prioridd de un elemento prtiulrF gomo est operE in no lter topolgimente l rolD l propiedd de form est grntizdF vo nio que deemos eriorr es que el orden se preserveD lo ul se he medinte l siguiente operinX miembros pblicos de ArrayHeap<Key> 288b + (284b) 288d void update(T & data) { const size_t i = &data - array; sift_down_up <T, Compare> (array, 1, i, num_items); } v rutin sume que el vlor de prioridd de l iEsim entrd del rreglo h sido modiE (d y restur l propiedd de ordenF
4.7.4 Heapsort

n mtodo de ordenmientoD estleD on rendimiento O(n lg(n)) pr el peor soD puede explirse en dos fsesX IF qurde en un ol de prioridd todos los elementos del rregloF PF ixtrig itertivmente de l ol y gurde el elemento extrdo en l posiin de iterin iF uesto que l ol siempre retorn el menor elementoD l (nl de est iterinD el rreglo estr ordendoF iste prinipio puede llevrse o del siguiente modoX Heapsort con cola de prioridad 289b ArrayHeap<T, n> heap; for (int i = 0; i < n; ++i) // inserta elementos en heap heap.insert(array[i]);
for (int i = 0; i < n; ++i) // saca en orden de heap y pone en array array[i] = heap.getMin();

289b

289c

gd psd demor O(n) O(lg(n)) = O(n lg(n))F or tntoD el proedimiento es O(n lg(n)) + O(n lg(n)) = O(n lg(n))D independientemente de l permutin del rregloF in emrgoD el uso del hep requiere lmenr todos los elementos del rregloD por lo que el onsumo de espio es O(n)D rtersti indesele en muhs irunstnisF xo es difil prehender que podemos utilizr el propio rreglo que pretendemos orE denr pr gurdr el hepF r eso es neesrio invertir l ondiin de orden de modo tl que l rz lmene el myor entre todos los elementosF isto se instrument filmente medinte un lse envoltori que hg l inversinX Comparacin invertida 289c template <class T, class Compare> struct Inversed_Compare { bool operator () (const T & op1, const T & op2) const { return Compare () (op2, op1); } };

290

4. rboles

he este modoD l primer fse puede plnterse pitrimente sX


Heap entre 1 e i 1 i Desorden

290a

l ul reorre el rreglo desde 2 hst nD ejeutndoD d iterin iD sift_up <T, __Inversed_Compare<T, Compare> >(arreglo, i)D es deirD orrigiendo l eventul vioE lin que rrer insertr un nuevo elemento en l posiin iF v primer fse puede odi(rseD entonesD omo sigueX Convertir arreglo en un heap con sift_up() 290a (290c) for (int i = 2; i <= n; ++i) sift_up <T, Aleph::Inversed_Compare<T, Compare> > (array, 1, i); v ide es omenzr desde el hep omprendido entre [1 . . . 1] y luegoD d iterin iD se sume un inserin en l posiin iF el rreglo entre [1 . . . i]] se le restur l propiedd de hep medinte sift_up(array, 1, i)F el (nl de l primer fseD todo el rreglo es un hep uyo mximo elemento se enuentr en l rzF e prtir del heho de que l posiin de(nitiv del myor elemento es nD plntemos l segund fse del siguiente modoX
swap(ptr[1], ptr[i])

Heap entre 1 e i i

Orden denitivo

l ul se implnt sX
290b

Ordenar a partir del heap 290b

(290c 291c)

for (int i = n; i > 1; i) { std::swap(array[1], array[i]); // poner en raz i-simo item sift_down<T,Aleph::Inversed_Compare<T,Compare> >(array, 1, i - 1); }

290c

qrosso modoD se intermi array[1] on array[i]D lo ul (j el orden de(nitivo en el intervlo [i . . . n]F iste intermio es equivlente que se huiese elimindo del hep el menor elementoD es deirD el de l rzF es puesD sift_down(array, 1, i - 1) restur el hep entre [1 . . . i 1]F gon lo nteriorD podemos (niquitr el mtodo de ordenmientoX Rutinas heap 283d + 287b 291c template <typename T, class Compare = Aleph::less<T> > void heapsort(T * array, const size_t & n) { array; //desplazar posicin hacia atrs ==> array[1] == primero
}

Convertir arreglo en un heap con sift_up() 290a Ordenar a partir del heap 290b

ixiste un mner ltern l loque gonvertir rreglo en un hep on siftup@A 290a D que logrD ms e(ientementeD en O(n)D hepi(zr el rregloF r proximrnosD onsideremos l primer psd del hepsort de l siguiente formX
Desorden i Heap entre i + 1 y n

4.7. Heaps

291

291a

o seD un rrido desde l ltim posiin array[n] hst l primer array[1]F odemos her esto medinte sift_down()X Convertir arreglo en un heap con sift_down() 291a for (int i = n - 1; i > 1; i) sift_down <T, Aleph::Inversed_Compare<T, Compare> > (array, i, n); il nlisis de este loque es un poo ms sutilF gd llmd sift_down() uest O(lg(r) lg(l))D lo que nos dX
n1 i=1 n1

O(lg(r) lg(l)) =

i=1

O lg

r l

= O(n) ;

@RFQRA

291b

oste mejor que el de O(n lg(n)) soido l loque gonvertir rreglo en un hep on siftup@A 290a F ry n un mejor dems si prehendemos el heho de que pr l > n 2 D array[l..n] n esD on ertitudD un hep en propiedd de ordenD pues pr l > 2 = 2l > nD es deirD no hy desendientesF or tntoD l veloidd de gonvertir rreglo en un hep on siftdown@A 291a puede duplirse de l siguiente mnerX Convertir arreglo en un heap con sift_down() mejorado 291b (291c) for (int i = n/2; i >= 1; i) sift_down <T, Aleph::Inversed_Compare<T, Compare> > (array, i, n); lo que nos rroj l siguiente nuev versin mejord del hepsortX Rutinas heap 283d + 290c template <typename T, class Compare = Aleph::less<T> > void faster_heapsort(T * array, const size_t & n) { array; // desplazar posicin hacia atrs ==> array[1] == primero
}

291c

Convertir arreglo en un heap con sift_down() mejorado 291b Ordenar a partir del heap 290b

4.7.5

Aplicaciones de los heaps

vos heps son muy importntes en situiones en ls ules se requier mntener y onoer rpidmente los vlores lmites de un onjunto segn lgn riterio de ordenD es deirD su@sA menor@esA elemento@sA o su@sA myor@esAF ry undntes osiones en que esto es neesrioF re qu un list inomplet de ls que reemos son ls ms populresX IF Aritmtica otanteX pr l preisin de punto )otnte es rtio el orden en que se hgn ls operionesD el ulD si nun neesrimenteD orresponde on el exE presdo por el progrmdorF or ejemploD l sum pierde preisin si un nmero muy pequeo es sumdo @o multiplindoA uno grndeF n esquem de lt preE isin mntiene en un hep los operndosD de mner tl que l sum privilegi los operndos pequeosF PF Simulacin a eventos discretosX muhs situiones de l vid rel se modelizn y estudin medinte eventosF qrosso modoD un evento es un representin oE jetiv de lgn sueso de inters dentro de l situin que se dese estudirF gomo ojetoD un evento tiene dos triutos fundmentlesX

292

4. rboles

@A iempo de ourreni te F @A ein modi(nte sore el estdo del sistemD l ul se divide en l modiE (in de ls vriles del modelo yD sore todoD en l generin de nuevos eventos en el futuroF vos sistems de simulin mntienen un tiempo simuldo orrespondiente l tiempo en que se ejeut l simulin del evento tulF sniilmente se progrmn lgunos eventos iniiles ejeutrse en lgunos tiempos (josF or ejemploD onsideremos tres eventos iniiles ejeutrse en tres tiemposX
e1 e2 e3 t

il tiempo de simulin omienz en el tiempo te1 D que es undo ourrir e1 F vos eventos se ponen en un list ordend por tiempoF il simuldorD sistemtimenteD extre de l list el prximo evento en el tiempoF isto es lo mrvilloso de un simuldor eventos disretosD pues el tiempo se simul medinte desplzmientos disretos entre los eventos y no ontinumente omo ee en l vid relF gd evento gener nuevos eventosD uyos tiempos de ourreni se onoen durnte l generinF upongmos que e1 gener los eventos e11 , e12 , e13 D uyos tiempos de ourreni se pitorizn sX
e1 e13 e12 e2 e11 e3 t

yservemos que los nuevos eventos e13 , e12 ourrirn ntes que e2 Y esto quiere deir que el prximo evento simulr es e13 y no e2 D ul er el que est progrmdo ntes de simulr e1 F il simuldor se pert de esto porque l list est strtE mente ordend por tiempoF wntener un seueni ordend por tiempoD no slo es ostoso en durinD sino intilD pues lo que en relidd se requiere es onoer el prximo evento ms inmedito en tiempoD es deirD el menorF v list de eventos de un simuldor se implement medinte un hepF il simuE ldor extre del hep el menor evento en el tiempoF il hep permite tmin simulr e(ientemente l nelin de un eventoF r ello se us l operE in sift_down_up()F QF Cdigos de HumanX sern estudidos en RFIQ @gF QRSAF RF BsquedaX inontrr los m menores elementos de un onjunto de rdinliE dd n mD por ejemploD onoer los 1000 menores elementos entre un onjunto de 109 lvesF in este so se dee usr un hep (nitoD es deirD uno uy pidd est limitd mF e medid que el hep se v tulizndo se dee onoer el myor elemento entre los m lmendosD de mner tl que ste se sustituido por el nuevo menor enontrdoF SF Procesamiento ordenado: en generlD tod situin en l ul se requier proeE sr de primero el menor elementoD es muy suseptile de onsiderr un hepF

4.7. Heaps

293

4.7.6

El TAD

BinHeap<Key>

293

ry situiones lgortmisD sore todo quells que spirn l generliddD en ls ules no se tiene ide ext de l ntidd de elementos que se proesrnF iste desonoiE mientoD undo l eslD puede omplir y omprometer onsiderlemente el uso de un rregloD puesD l menosD nuestr implntin ArrayHeap<Key> requiere que onozmos su dimensinF i l dimensin es muy grnde y se usn vrios heps @lo ul puede ser el so en lgoritmos sore grfosAD entones se puede inurrir en un desperdiio de memori importnteF i l dimensin es pequeD entones se puede sri(r proesmiento de lt eslF in estos tipos de situiones se dee onsiderr un hep ltmente dinmio que onsum memori extmente proporionl l ntidd de elementos que mnejF n lterntivD delegd en ejeriioD tnto en estudio omo en diseo e implntinD es utilizr rreglos dinmios del tipo DynArray<T> desrrolldo en PFIFR @gF QRAF ist vrinteD unque ms )exile que el mero rreglo esttioD tmin puede inurrir en los mismos prolemsD pues se tiene un desperdiio deido ls entrds no usds del diretorioD segmento y loqueF n desventj de implementr un hep medinte un rreglo es queD puesto que los elementos se muevenD no se pueden mntener puntdores sore ellosF iste inonveniente puede plirse si en el ArrayHeap<Key> gurdmos punteros tipedos los dtos y progrE mmos l lse de omprin pr que opere sore punteros tipedosF ero eso onsume espio y durin diionles deido l puntdor extr y su derefereniF in es sein desrrollremos un soluin sd en nodos inrios del tipo BinNode<Key> y de(nid en el rhivoX tpl_binHeap.H 293 Denicin de nodo de BinHeap<Key> 295c template <template <class> class NodeType, typename Key, class Compare = Aleph::less<Key> > class GenBinHeap { typedef NodeType<Key> Node; Atributos de BinHeap<Key> 295a Miembros privados de BinHeap<Key> 296a Miembros pblicos de BinHeap<Key> 295b }; template <class Key, typename Compare = Aleph::less<Key> > class BinHeap : public GenBinHeap<BinHeapNode, Key, Compare> { typedef BinHeapNode<Key> Node; };

GenBinHeap<NodeType, Key, Compare implnt un hep inrio medinte nodos iE nrios de tipo NodeTypeF uesto que un hep inrio es un rol inrioD podr pensrse que el tipo BinNode<Key> st pr implementr un hep ltmente dinmioD pero hy dos di(ultdesX
IF il eh BinNode<Key> no tiene medio direto de onoer el pdreD el ul se requiere en l operiones sift_up() y sift_down()F ry dos mners de sorter este ostuloF v primer es medinte un pil que gurde

294

4. rboles

el mino de eso desde l rz hst el nodo sore el ul se ejeut sift_up() o sift_down()F v segund onsiste en mntenerD por d nodoD un puntero diionl l pdreF il primer enfoque tiene l ventj de que onsume menos espio que el segundoD pero el mnejo de l pil desde l rz hst el nodo de operin onsume un tiempo O(lg(n))F PF gundo ourre un inserin o elimininD es neesrio eder l pdre del nodo ms l dereh del ltimo nivelD pues puede requerirse tulizr sus enlesF e last el nodo ms l dereh del ltimo nivelF gmo onoer este nodo y su pdrec ertE mosnos de que last y su pdre pueden mir d vez que ourre un modi(in sore hepF n enfoque pr determinr last onsiste en dividir suesivmente el vlor de rdiE nlidd del hepF i l rdinlidd es nD entones n mod 2 nos indi si last es hijo izquierdo o derehoF uesivmenteD n mod 4 nos die si el pdre de last es desenE diente izquierdo o derehoF il proedimiento se repite hst lnzr l rzD es deirD hst que n/i = 1F in este momento tenemos el nmero de hewyD invertidoD de last yD prtir de lD tod su sendeniF il lulo nterior es O(lg(n))D tnto en espio omo en durinF odr pensrse que el mntener permnentemente l seueni de hewy hi last horr tiempoD pero en el peor so puede ser neesrio tulizrl hst l rz y esto uest O(lg(n))F in nuestro diseo trnsremos por l rpidezF r sorter el primer ostulo usremos un puntero l pdreD el ul posiilit todo el ontexto pr ls operiones de intermio entre niveles requerids por sift_up() y sift_down()F r evitr el segundo ostulo provehremos los n + 1 punteros nulos del hep pr mntener un listD dolemente enlzdD irulrD de los nodos orde de los ltimos nivelesD es deirD un list onformd por los nodos hojs yD eventulmenteD el nodo de pdre de lastD el ul es inompleto undo last es hijo izquierdoF n instni de est estrutur de dtos puede pitorizrse omo en l (gur RFQIF last siempre punt l
head
1

root

10

11

12

last

pigur RFQIX epresentin del eh BinHeap<Key> nodo ms l dereh del ltimo nivelF head es un nodo eerD entinelD que permite trtr de mner generl el intermio entre l rz y lguno de sus dos hijosF root es un puntero refereniD permnenteD l rzD que es hij dereh de headF equerimos entones los siguientes triutos pr el eh BinHeap<Key>X

4.7. Heaps

295

295a

Atributos de BinHeap<Key> 295a


Node Node * Node *& Node * size_t head_node; head; root; last; num_nodes;

(293)

295b

il ltimo triutoD num_nodesD ontiliz l rdinlidd del hepF n BinHeap<Key> se iniiliz sX Miembros pblicos de BinHeap<Key> 295b (293) 297 GenBinHeap() : head(&head_node), root(RLINK(head)), last(&head_node), num_nodes(0) {} vs onsideriones de diseo nteriores nos llevn inluir l siguiente informin diionl por nodo Denicin de nodo de BinHeap<Key> 295c (293) class BinHeapNode_Data { struct Control_Fields // Definicin de banderas de control { int is_leaf : 4; // true si el nodo es hoja int is_left : 4; // true si el nodo es hijo izquierdo }; BinHeapNode_Data * pLink; // puntero al padre Control_Fields control_fields;
BinHeapNode_Data() : pLink(NULL) { control_fields.is_leaf = true; control_fields.is_left = true; } BinHeapNode_Data *& getU() { return pLink; } Control_Fields & get_control_fields() { return control_fields; } }; DECLARE_BINNODE(BinHeapNode, 64, BinHeapNode_Data);
Uses

295c

DECLARE_BINNODE.

295d

ist lse nodo justi( de(nir los mros siguientes fvor de l legiilidd de digoX Denicin de macros de BinHeap<Key> 295d # define PREV(p) (p->getL()) # define NEXT(p) (p->getR()) # define ULINK(p) reinterpret_cast<Node*&>((p)->getU()) # define IS_LEAF(p) ((p)->get_control_fields().is_leaf) # define IS_LEFT(p) ((p)->get_control_fields().is_left) # define CTRL_BITS(p) ((p)->get_control_fields()) i IS_LEAF(p) == trueD entones NEXT(p) y PREV(p) ontienen el suesor y predeesor de l list de hojsF iD por el ontrrioD IS_LEAF(p) == falseD entones los mismos mpos se usn omo LLINK(p) y RLINK(p)F wedinte el mpo IS_LEAF(p) podemos determinr si p pertenee o no l list enlzdX

296

4. rboles

296a

Miembros privados de BinHeap<Key> 296a

(293) 296b

static bool is_in_list(Node * p) { if (IS_LEAF(p)) return true; return ULINK(LLINK(p)) == RLINK(LLINK(p)); }

296b

il segundo return veri( si p es el pdre de last y ste es su hijo izquierdo 8 F ytro predido que requeriremos es onoer si un nodo tiene o no un hermnoX Miembros privados de BinHeap<Key> 296a + (293) 296a 296c static bool has_sibling(Node * p) { return ULINK(p) != RLINK(p); } smos este mtodo porque oper n si p es prte de l list enlzdF
4.7.6.1 Intercambio entre nodos

296c

uiz l rutin esenil de nuestr implntin es l que intermi dos nodos de nivelF vlmremos est rutin swap_with_parent(p)D uy misin es intermir el nodo p on su pdreF ist es l rutin ms omplid de l implntin porque el intermio dee distinguir los sos prtiulres en los ules p no tiene uelo @undo slo hy dos o tres nodosA y el so en que p est en ltimo nivelD situin en l ul p es prte de l listF v rutin swap_with_parent() es stnte omplid y no se muestr en este texto @ell puede exminrse en l ilioteAF swap_with_parent() oper independientemente de l situin de p dentro del hepF odemosD puesD emplerl pr efetur los interE mios requeridos por sift_up() y sift_down()D l ulesD un vez efetud l operE in swap_with_parent()D son muho ms simples que su ontrprte on rreglosX Miembros privados de BinHeap<Key> 296a + (293) 296b 298a virtual void sift_up(Node * p) { while (p != root and Compare() (KEY(p), KEY(ULINK(p)))) swap_with_parent(p); } virtual void sift_down(Node * p) { while (not IS_LEAF(p)) { Node * cp = LLINK(p); // guarda el menor hijo de p if (has_sibling(cp)) if (Compare() (KEY(RLINK(p)), KEY(LLINK(p)))) cp = RLINK(p);
if (Compare() (KEY(p), KEY(cp))) return;
8
Para aprehender este caso, ejectese la rutina con

p=6

en la gura 4.31.

4.7. Heaps

297

swap_with_parent(cp);

4.7.6.2

Insercin en

BinHeap<Key>

v rutin sift_up() nos permite espei(r l primer rutin pli de BinHeap<Key>X l inserinD l ul se de(ne del siguiente modoX
297

Miembros pblicos de BinHeap<Key> 295b +

(293)

295b 298b

Node * insert(Node * p) { if (root == NULL) // heap est vaco? { // S, inicialice root = p; LLINK(p) = RLINK(p) = p; ULINK(p) = head; IS_LEAF(p) = true; IS_LEFT(p) = false; /* root is right child of header node */ last = root; num_nodes = 1; return p; } // insercin general Node * pp = RLINK(last); // padre de actual last LLINK(p) = last; ULINK(p) = pp; if (IS_LEFT(last)) { // p ser hijo derecho IS_LEFT(p) = false; RLINK(p) = RLINK(pp); LLINK(RLINK(pp)) = p; RLINK(pp) = p; } else { // p ser hijo izquierdo IS_LEFT(p) = true; RLINK(p) = pp; IS_LEAF(pp) = false; // si p es izquierdo ==> pp era hoja LLINK(pp) = p; } RLINK(last) = p; last = p; num_nodes++; sift_up(last); return p;

298

4. rboles

4.7.6.3

Eliminacin del elemento mnimo

r l eliminin por l rz plimos l mism estrtegi explid en RFUFP @gF PVSAX intermir l rz por last y luego ortr por lastF r ello nos vlemos en primer lugr de un rutin swap_root_with_last()D uy misin es intermir l rz on last y que no se muestr en este texto @ell tmin puede ser exmind en l ilioteAF itrimenteD swap_root_with_last()D nivel de los nodosD no de sus ontenidosD efet l siguiente operinX
root

last

298a

plt ortr el nodo ms l dereh del ltimo nivelD lo ul se he sX Miembros privados de BinHeap<Key> 296a + (293) 296c 301a Node * remove_last() { Node * ret_val = last; Node * pp = ULINK(last); Node * new_last = LLINK(last);
if (IS_LEFT(last)) { IS_LEAF(pp) = true; LLINK(pp) = new_last; } else { RLINK(pp) = RLINK(last); LLINK(RLINK(last)) = pp; } RLINK(LLINK(last)) = pp; last = new_last; num_nodes; ret_val->reset(); } return ret_val;

298b

ist mquinri nos permite de(nir getMin() extmente omo explido en RFUFP @gF PVSAD es deirD intermir root on lastD luego ortr por lastX Miembros pblicos de BinHeap<Key> 295b + (293) 297 299a Node * getMin() { Node *ret_val = root;
if (num_nodes == 1) { root = NULL; ret_val->reset(); num_nodes = 0;

4.7. Heaps

299

return ret_val; } swap_root_with_last(); remove_last(); sift_down(root); ret_val->reset(); } return ret_val;

4.7.6.4

Actualizacin en un heap

299a

el igul que on ArrayHeap<Key>D es plusile modi(r el vlor de prioridd de un nodo prtiulrF in este so efetumos l mism orreinX Miembros pblicos de BinHeap<Key> 295b + (293) 298b 299b void update(Node * p) { sift_down(p); sift_up(p); }
4.7.6.5 Eliminacin de cualquier elemento

299b

uiz un de ls operiones que ms ore sentido on este tipo de implntin de hep es l de eliminrD ritrrimenteD ulquier elementoD dd l direin del nodoF n ejemplo de est situin es l nelin de un eventoD tnto en un sistem de simulin eventos disretos omo en un mnejdor de eventos en tiempo rel 9 F in este soD teE niendo un puntdor l eventoD ul puedeD por ejemploD derivr de BinHeap<Time>::NodeD puede eliminrse del hep ulquier elementosF is onveniente pertrse de que en l implntin del hep on rreglosD est opeE rin requiere un ierre de reh que es O(n)F r eliminr node se oper preido su ontrprte ArrayHeap<Key>X @IA se deE senlz last del rol y se respld en un vrile pY esto se reliz on l operinD y de(nidD remove_last()F vuegoD @PA se sustituye el nodo eliminr node por p yD (nlmenteD se ejeut sift_down() y sift_up() pr justr l propiedd de ordenF il pso @PA de l operin nterior se vle l operin replace_node(Node * node, Node * new_node)D uyo rol es reemplzr dentro del rol inrio el nodo node por new_nodeF odo el ontexto neesrio est ddoD pues d nodo ontiene un puntero su pdreF ist operin puede onsultrse en l ilioteF ehorD slo nos flt remitirnos l tni explid pr implntr l eliminin de un nodo nodeX Miembros pblicos de BinHeap<Key> 295b + (293) 299a 301b Node * remove(Node * node) { if (node == root)
9
En programados por el reloj del sistema. La implantacin de

ALEPH,

existe un TAD, llamado

TimeoutQueue,

cuyo n es modelizar un manejador de eventos

TimeoutQueue hace uso del TAD BinHeap<Key>

y ofrece, entre sus funciones, la cancelacin de un evento previamente programado.

300

4. rboles

return getMin(); if (node == last) return remove_last(); Node * p = remove_last(); if (node == last) { remove_last(); insert(p); return node; } replace_node(node, p); update(p); node->reset(); } return node;

4.7.6.6

Destruccin de

BinHeap<Key>

300

el igul que on otros enfoques de soluin del prolem fundmentl que hemos estuE dido hst el presenteD en lugr de mnejr diretmente ls lves del onjuntoD el eh BinHeap<Key> mnej los nodos que ls ontienenF hel mismo modoD en funin del prinE ipio (nEE(nD otro ehD en nuestro soD DynBinHeap<Key> se enrg de mnejr ls lves sin que el usurio teng por qu pensr en los nodos omo ojetos de mnipulin del hepF gundo implntmos un versin del prolem fundmentl sd en lves y no en los nodos que l ontengnD un operin fundmentl del eh de se es l posiilidd de lierr todos los elementos Ey tod l memori oupdE en un sol operinF iste es el soD por ejemploD de ls operiones remove_all_and_delete() @ PFRFU @gF UPAA y destroyRec() @ RFRFIH @gF PSHAAD diseds pr ls lists enlzds y los roles inrios respetivmenteF in el so de un hep dinmio omo BinHeap<Key>D o del destrutor del eh DynBinHeap<Key>D no es posile invor l operin destroyRec()D pues us de l omplejidd del nodo de un BinHeap<Key> no se dispone del vlor NullPtrD del ul se sirve destroyRec() pr reonoer ls hojsF n tentin pr trtr on este prolemD es deirD pr eliminr todos los elementos de BinHeap<Key>D es un ilo del siguiente estiloX Eliminar todos los elementos del BinHeap<Key> 300 while (not this->is_empty()) delete getMin(); iste loque umple l funinD pero expenss de un oste en tiempo que puede devenir importnteD pues es O(n lg(n))D que es myor que O(n)D el tiempo que nos llev el E rrido de los elementos y su orrespondiente elimininF hesde est perspetiv se nos revel neesrio proveer desde el eh BinHeap<Key> un primitiv que elimine todos los elementos en O(n)F in tl sentidoD hremos un reorrido su(joD reursivoD que liere los

4.7. Heaps

301

nodos del hepX


301a

Miembros privados de BinHeap<Key> 296a +

(293)

298a

static void __postorder_delete(Node * p, Node * incomplete_node) { if (IS_LEAF(p)) { delete p; return; } __postorder_delete(LLINK(p), incomplete_node); if (p != incomplete_node) __postorder_delete(RLINK(p), incomplete_node); } delete p;

301b

uesto que en l estrutur de dtos se omin l estrutur rol inrio on list dolemente enlzdD se dee tener espeil uiddo undo el ltimo nodo @lastA se izquierdoY slo en este soD p ser un nodo de un solo hijoD por lo que l llmd hi l dereh ser inorret y usnte de un dole elimininF ist rutin se invo por l siguiente interfz pliX Miembros pblicos de BinHeap<Key> 295b + (293) 299b void remove_all_and_delete() { if (root == NULL) return;
if (num_nodes <= 3) { while (not this->is_empty()) delete getMin(); return; } if (IS_LEFT(last)) __postorder_delete(root, ULINK(last)); else __postorder_delete(root, NULL); root = NULL; // reiniciar como si fuese constructor last = &head_node; num_nodes = 0;

hdo que el hep es un rol ompletoD el riesgo de desorde de pil deido l reursin es mnimoF v rutin remove_all_and_delete() es invod por el destrutor del eh DynBinHeap<Key>D el ulD omo es de suponerD es un extensin de BinHeap<Key> orienE td mnejr lvesF he este modoD l destruin es O(n)F

302

4. rboles

4.8 Enumeracin y cdigos de rboles


eordemos un prolem omintorio queD si ien te los rolesD relion muE hos otros prolems omintoriosX untos roles diferentes pueden onstruirse on n nodosc or ejemploD estos son todos los posiles roles de 4 nodosX

eordemos que existe un orrespondeni unvo entre los roles y los roles iE nrios @ RFRFIU @gF PTHAAF hdo un rol ulquier de n nodosD entonesD segn RFRFIU @gF PTHAD l rz de su equivlente inrio no tiene rm derehF pltnD entonesD n 1 nodos pr ominr en l rm izquierdF or lo tntoD el nmero de posiles roles que se pueden onstruir on n nodos es equivlente l nmero de roles inrios que se pueden onstruir on n 1 nodosF odemos resolver este prolem de onteo en el ontexto ms fmilir yD quiz ms simpleD de los roles inriosF
4.8.0.7 Cdigos de un rbol binario

gomenemos por enunir el onepto de digo de un rol inrioFr ello diujemos un rol extendido Eon sus nodos externosE tl omo el de l (gur RFQPF
a a a a a a b b b b b b b b b a b a a

pigur RFQPX n rol inrio extendidoX nodos internos etiquetdos on aY nodos externos on b

e un rol inrio T de n nodosF e de(ne codigo(T ) : B {a, b} omo el reorrido pre(jo del rol extendido donde sus n nodos internos estn etiquetdos on a y sus externos on bF
Denicin 4.7

or ejemploD pr el rol de l (gur RFQPD codigo(T ) = aaaabbabbaabbbababbF istudiemos mo se rteriz un plr codigo(T ) {a, b} F he entrdD summos que L {a, b} es el lenguje que rteriz un digo de un rolF L es llmdo lenguje de vuksiewizD en honor l mtemtio polo tn vuksiewizF
Proposicin 4.6

il lenguje de vuksiewizD de todos los digos posiles est de(nido

porX in otrs plrsD L = codigo(B )F v expresin @RFQSA es un de(niin reursiv del onjunto L y signi( que un plr L es el resultdo de ontenr a on dos plrs seguids que pertenezn l onjunto L o on l letr bF vo ms interesnte de este tipo de de(niin es que hemos de(nido un onjunto in(nito de plrs en un sol expresin reursivF

L = aLL b

@RFQSA

4.8. Enumeracin y cdigos de rboles

303

Demostracin

L codigo(B )

r demostrr L = codigo(B ) deemos demostrr L codigo(B ) y

 aLL b codigo(B )X i T = D tenemos que codigo() = b aLL bF i T = D entones T puede expresrse omo T =< L(T ), raiz(T ), R(T ) >F or l de(niE in de digoD codigo(< L(T ), raiz(T ), R(T ) >) = a codigo(L(T )) codigo(R(T )) codigo(B )  codigo(B ) aLL bX e w LF i |w| = 1 = w = codigo() = bF he lo ontrrioD |w| > 1 = w = auv, u, v LY donde a orresponde l rz de un rol T mientrs que u = codigo(L(T )) y v = codigo(R(T ))

gundo tenemos un plr w = uvD es deirD que puede omponerse de l onteE nin de otrs dos plrs u y vD entones u se le die que es pre(jo de wF or ejemploD si w = abbbaD entones , a, ab, abb, abbb, abbba son pre(jos de w10 F in lo que respet los pre(josD denotremosX

uv u<v

si si

u u

es prejo de es prejo de

v v
y

u = v.

(En este caso decimos que

es prejo propio de

v)

r el ejemplo nteriorD a < abbbaD pero abbba abbbaF n onjunto de plrs es pre(jo si ningun de sus plrs es pre(jo de lgun de ls otrsF isto esD ddo un lenguje XD se die que X es un lenguje pre(jo u, v XD u y v no son pre(jos entre siF is deirD u v = u = vF or ejemploD X = {ab, baa, bab}F
Denicin 4.8 (Conjunto prejo) Lema 4.3

e X un lenguje pre(jo y u, v, u , v XF intonesD uv = u v = u = u y v = v F in otros trminosD si u, v, u , v X | u = u , v = v = uv = u v F


Demostracin (por contradiccin)

upongmos que X es un lenguje pre(joDes deirD uv = u v = u = u o v = v F r filitr l omprensinD superpongmos ls plrs uv y u v omo sigueX
u u v v

in el digrm se prei que u uF odemos imginr otrs superposiiones y suponer otros pre(josF in todo soD es lro que o u u o v v F in emrgoD puesto que hemos diho que X es un onjunto pre(joD es imposile que u se pre(jo de uF uesto que l negin del lem es flsD el lem es ierto iste lem nos proporion el rgumento prinipl pr demostrr l proposiin siE guienteF
Proposicin 4.7 (Human 1952 [81])
10
El smbolo denota la palabra vaca.

il lenguje de vuksiewiz es pre(joF

304

4. rboles

Demostracin (por contradiccin inductiva sobre la longitud de una palabra)

upongmos que el lenguje de vuksiewiz no es pre(joD entones u, v, x L | ux = vF  |u| = 1: in este soD u = b = x = = v = bD pero L no ontiene que L es pre(jo pr tods l plrs de longitud 1F lo que impli

 ehor sumimos que L es pre(jo pr tods ls plrs u, v L de longitud nominl y exminremos si u, x L | ux = vF is deirD si existe un plr de myor longitud que pued ser ompuest on un plr perteneiente LF en u1 , u2 , v1 , vx , x L | |u1 | < |u| , |u2 | < |u| , |u2 | < |u| , |v1 | < |v| , |v2 | < |v|F rgmos ls siguientes desomposiionesX

u = au1 u2 v = av1 v2
pltemosX

au1 u2 x = av1 v2 = u1 u2 x = v1 v2
isto nos rroj dos sos exminrX IF |u1 | |v1 |X in este soD u y v se superponen de l form siguienteX
u1 v1 u2 v2 x

v ni posiilidd es que u1 = v1 D pues de lo ontrrio u1 ser pre(jo de v1 D pero ello no es s por l hiptesis indutivF or lo tntoD x = / LF il plntemiento esD entonesD ontrditorioF PF |v1 | < |u1 | < |u|X in este soD u y v se superponen de l form siguienteX
u1 v1 u2 v2 x

he nuevoD v1 no puede ser pre(jo de u1 D pues si no se ontrdie l hiptesis indutivF or lo tntoD v1 = u1 y x = / LF emos sosD on |u1 | = |v1 | | |u1 | < |u|, |v1 | < |v|D ontrdien l hiptesis indutivF or lo tntoD l hiptesis es iert
Proposicin 4.8 Demostracin

T1 , T2 B , T1 = T2 codigo(T1 ) = codigo(T2 )F
v prue se estrutur en dos prtesX

 Inyectividad (=): eplimos induin sore ls rdinliddes de T1 y T2 X T1 , T2 B , T1 = T2 = codigo(T1 ) = codigo(T2 )F


 Caso baseX

i T1 = , T2 = = codigo(T1 ) = b, codigo(T2 ) = auv, u, v L = codigo(T1 ) = codigo(T2 )F i T1 = , T2 = y |T1 | = |T2 | = | codigo(T1 )| = | codigo(T2 )| = codigo(T1 ) = codigo(T2 )F

 Hiptesis inductivaX

4.8. Enumeracin y cdigos de rboles

305

i |T1 | = |T2 | entonesX

w1 = codigo(T1 ) = au1 v1 w2 = codigo(T2 ) = au2 v2

u1 = codigo(L(T1 )) v1 = codigo(R(T1 )) u2 = codigo(L(T2 )) v2 = codigo(R(T2 ))

ehor que l proposiin es iert pr dos roles de un mism rdinlidd nominl y promos si l proposiin es iert pr roles de rdinlidd myorD por l hiptesis indutiv tenemos que o u1 = u2 o v1 = v2 F heemos responder siX au1 v1 = au2 v2 @RFQTA r elloD plnteemos el siguiente lemX
Lema 4.4

v demostrin se deriv del lem RFQF i negmos el lem RFQ tenemos que u1 = u2 o v1 = v2 = u1 v1 = u2 v2 on u1 , u2 , v1 , v2 {venguje pre(jo}F impero por l proposiin RFU semos que L es un lenguje pre(joF es puesD el lem es iertoF
Demostracin

en u1 , u2 , v1 , v2 LF i u1 = u2 o v1 = v2 D entonesD u1 v1 = u2 v2 F

il lem RFR nos grntiz que @RFQTA es ierto pr roles inrios de rdinlidd myorD lo ul impli que codigo(T ) : B L es inyetivF v inyetividd prue T1 , T2 B , T1 = T2 = codigo(T1 ) = codigo(T2 )  Suprayectividad: in este so deemos demostrr queX

w L T B | codigo(T ) = w

@RFQUA

v demostrin es por induin sore l longitud de wF v hiptesis indutiv es @RFQUAF


 

|w| = 1 = codigo() = b = @RFQUA es ierto pr |w| = 1F

ehor sumimos que @RFQUA es ierto pr todo |w| = n y veri(mos si l hiptesis es stisfeh pr |w| = n + 1F i |w| = n + 1D l plr w = auv stisfe |auv| = 1 + |u| + |v|F or l hiptesis indutivD Tu B | codigo(Tu ) = u y Tv B | codigo(Tv ) = v tl que | codigo(Tu )| + | codigo(Tv )| = n = |w| = 1 + |u| + |v| = n + 1

uesto que codigo(T ) : B L es inyetiv y supryetivD codigo(T ) : B L es iyetivF no de los teorems fundmentles de l teor de onjuntos estlee que si un funin f : A B es iyetivD entonesD |A| = |B|F or este teorem podemos onluir que |B | = |L|F vo que demuestr que codigo(T1 ) = codigo(T2 ) = T1 , T2 B , T1 = T2 ehor vemos mo se rteriz un plr en LF r elloD de(nmosX

|w|a = el nmero de ourrenis de a en w |w|b = el nmero de ourrenis de b en w

306

4. rboles

Proposicin 4.9

w L
Demostracin

@A |w|b = 1 + |w|a

@A u, v, |u| < |w| | w = uv = |u|a |u|b

@RFQVA

@A e T un rol inrio ulquier on w = codigo(T )F or l de(niin de digo semos que |w|a = |T |Y es deirD el nmero de nodos internosF or l proposiin RFP semos que T extendido tiene 2|T | + 1 nodosD es deirD n nodos internos y n + 1 nodos externosF es puesD |w| = 2|T | + 1 = 2|w|a + 1 = |w|a + |w|b = |w|b = |w|a + 1 @A @induin sore |w|A  |w| = 1 = w = b = u =

 e |w| = n + 1 y summos @A ierto pr todo |w| < n + 1F or de(niinD w tiene que estr ompuesto omo w = auvF il smolo a por l hipotti rz de un rol inrio y u y v los digos de ls rm izquierd y derehF gonsideremos un pre(jo w ulquier de wD el ul puede tener lgun de ls siE guientes on(gurionesX
w a Caso 1: w a Caso 2: w a u u u v v

= |u|a = 0 |u|b = 0F @A es ierto pr el so seF

in el so PD |v | < |v|D por lo que l hiptesis indutiv es iert entre v y vD lo ul permite determinr que |uv |a |uv |b yD en onseueniD |auv |a |auv |b ist proposiin nos d un mner e(ientsim de veri(r si un seueni de its es un plr vuksiewizD o seD si un plr se orresponde on el digo de un rol inrioF
4.8.0.8 Cdigos de Dick

in el so ID |u | < |u|D por lo que l hiptesis indutiv es iert entre u y uF or lo tntoD |u |a |u |b yD ovimenteD |au | |u |F

n lterntiv pr odi(r rolesD ompletmente equivlente los digos de l sein nteriorD es etiquetr el rol extendido de mner diferenteX ls rms izquierds on a y ls derehs on b tl omo el rol de l (gur RFQQF
a a a b b a b b a b a b

a ba b a b

pigur RFQQX rol inrio extendidoX rms izquierds etiquetds on aY rms derehs on b

4.8. Enumeracin y cdigos de rboles

307

n plr de hikD denotd omo dick(T ) : B {a, b} es el reorrido pre(jo de un rol etiquetdo on sus rms izquierds en a y sus rms derehs en bF or ejemploD pr el rol de l (gur RFQQX dick(T ) = aaaabbabbaabbbabab is fil otener un de(niin reursiv de un plr de hikF in primer luE gr de(nimos dick() = F r un rol no voD en su versin extendidD T =< L(T ), raiz(T ), R(T ) >, dick(< L(T ), raiz(T ), R(T ) >= a dick(L(T ))b dick(R(T ))F es puesD si D es el onjunto de tods ls plrs de hikD entones

D = aDbD
Proposicin 4.10

e D el lenguje de tods ls plrs de hikD entones

Db = L
in otrs plrsD codigo(T ) = dick(T )bF
Demostracin

Db
L

Db = (aDbD )b = = a Db Db b
L L

D = aDbD

ontenmos l euin on b = segn @RFQSA

istmos en pidd de formulr un nuevo prolem omintorioX unts expreE siones que utilien n prntesis izquierdos y n prntesis derehos estn lnedsc or ejemploD ((()())())D es un expresin lnedD mientrs que ()(((()()))())) no lo es @flt un prntesis izquierdoAF v respuest est dd por l ntidd de plrs de hik de longitud 2nF in efetoD si onsidermos el rter a omo el prntesis izquierdo y el b omo el derehoD un plr de hik represent un expresin on prntesis ien formdF
4.8.1 Nmeros de Catalan

ehor retomemos el prolem de ontr l ntidd de roles inrios que ontienen n 1 nodosF xotemos que por l proposiin RFVD ontr el nmero de roles es equivlente ontr el nmero de plrs de vuksiewiz de longitud 2n + 1 o el nmero de plrs de hik de longitud 2nF
Proposicin 4.11

il nmero totl de roles inrios diferentes on n nodos esX

Cn =

2n 1 n+1 n

@RFQWA

honde Cn es onoido omo el nEsimo nmero de gtln en honor l mtemtio elg iugene gtlnF

308

4. rboles

b b a

b b a

b b b

b a

b b

pigur RFQRX gmino de gtln del rol de l (gur RFQQ

Demostracin

ixiste un demostrin lsi sd en plnter l siguiente euin

reurrenteX

Cn =

1
n1 i=0 Ci Cni1

n=0 n>0 .

@RFRHA

is deirD ponemos el nodo rz y ontmos el nmero de suroles izquierdos y el nmero de suroles derehosF il rol izquierdo puede omenzr desde el vo hst el que tiene n1 nodosF i un surol izquierdo tiene i nodosD entones el dereho tiene ni1 nodosF or l regl del produtoD tenemos Ci Cni1 roles posiles uyo surol izquierdo tiene i nodosF in lugr de resolver est euin reurrenteD nuestr demostrin estr sd en un interpretin geomtri plnted por ureher y tinson IHPF uesto que l orrespondeni entre roles mErios y inrios es inyetiv @ver RFRFIU @gF PTHAAD ontr el nmero de roles de n nodos es equivlente ontr el nmero de roles inrios de n nodosF isto equivle ontr el nmero de plrs de vuksiewiz de longitud 2n + 1D ulD por l proposiin RFIHD es equivlente ontr el nmero de plrs de hik de longitud 2nF ixiste un interpretin gr( de un plr de hik @o de vuksiewizA denomiE nd mino de gtlnF hd un plr w = w1 w2 . . . w2n+1 L n mino de gtln es formdo por un seueni de puntos en el plnoX
P ( w) = p = (x, y) | wi w1 w2 . . . w2n+1 L, y = i y x = xi1 + 1 x = xi1 1

si wi = a si wi = b

@RFRIA

il mino de gtln orrespondiente l digo del rol de l (gur RFQQ se muestr en l (gur RFQRF egn l proposiin RFWD |u|a |u|b pr todo u pre(jo propio de w L y esto impli que todo mino de gtln jms trspsr el eje x ntes del (nl de l plrF gontr el nmero de plrs de hik de longitud 2n es equivlente ontr el nmero de minos de gtln generles que pueden formrse on n aes y n bes tl que nun ruen el nivel xF il nmero totl de minos posiles de gtlnD que ruen o no el eje xD est ddo por el nmero de plrs que se pueden formr on n aes y n besF iste onteo puede visulizrse medinte l siguiente (gurX
1 2 3 4 . . . 2n

a1 a2 . . . an

4.8. Enumeracin y cdigos de rboles

309

es deirD el nmero de ominiones de 2n elds enumerds en n aesY l ntidd de bes son ls elds restntesF he este modo onluimos que 2n n es el totl de minos de gtln posiles que puede onform un plr ompuest por el lfeto {a, b} F he este modoD podemos plnterX

Cn =

2n ntidd de minos que ruzn el eje x n

@RFRPA

equerimosD puesD ontr l ntidd de minos que ruzn el eje x y que terminn en el eje xD orrespondiente un plr w / D | |w|a = |w|b F e

P = {(0, 0), (1, y1 ), . . . , (2n 1, y2n1 ), (2n, 0)} ,


un onjunto de puntos que represent un mino de gtln que ruz el eje x orresponE diente un plr w / DF gomo ejemploD vemos el mino de gtln de l (gur RFQSF

b b b a

b b a

pigur RFQSX gmino de gtln de l plr aabbbaabbaab / DD e p = (x , 1) P el primer punto de P por dejo del eje xD entones podemos desomponerX

P(w) = P(uv) = P(u) P(v) = {(0, 0), (1, y1 ), . . . , (x , 1)} (P(w) P(u))
r todo P(w) = uv, w / D, u orresponde l pre(jo de w entre {(0, 0), . . . , (x , 1)}D es deirD el pre(jo hst el primer punto que est por dejo del eje xF he(nmos el mino siguienteX P (w) = P (u) (P(w) P (u)) ;

u es el omplemento de uD es deirD l plr orrespondiente mir tods ls letrs a por b y tods ls letrs b por aF P (u) se de(ne omoX P (w) = {(2 x, y) P(u) | 1 x x 1, (x, y) P(u)
r el ejemplo nteriorD aabbbaabbaab / D se prtiion entones omo bbaaa.aabbaab y tiene el mino de gtln mostrdo en l (gur RFQTF qeomtrimenteD P (w) = P (uv) | uD que es el pre(jo orrespondiente l mino de gtln P(uv) hst el primer punto dejo del eje xD puede ser interpretdo omo u desplzdo 2 uniddes por dejo del eje xF

310

4. rboles

b b a

b b a

pigur RFQTX gmino de gtln de bbaaa.aabbaab /D v relin P(w) P (w) | w / D es un funin iyetivF qeomtrimenteD P(w1 ), P(w2 ), P(w1 ) = P(w2 ) = P (w1 ) = P (w2 ) tendr un imgen niF vo mismo suede P (w1 ), P (w2 ), P (w1 ) = P (w2 ) = P(w1 ) = P(w2 )F etomndo @RFRPAD ontr el nmero de minos que ruzn el eje x es equivlente ontr el nmero de minos que prten desde (0, 2) y rrin (0, 2n)F gulquier mino de est form dee orresponder n + 1 letrs a y n 1 letrs bF rtiendo desde 2n 2 se requieren 2 letrs a ms que l letr bF es puesD existen n +1 minos que ruzn el eje xF ustituimos en @RFRPAX

Cn =

2n 2n n n+1

2n 1 n+1 n

vos nmeros de gtln tienen un importni trsendentl en l omintoriD pues hy muhs situiones de onteo identi(ds medinte est lse de nmeroF intre lguns de ls pliiones tenemosX  v ntidd de mners en que un polgono regulr onvexo de n + 2 ldos puede ser 1 6 ortdo en n tringulosF or ejemploD hy 4 3 = 5 diferentes mners de ortr un pentgono en tringulosF  il nmero de mners en que n nmeros pueden ser multiplidos soitivmente on 1 6 2n prntesisF or ejemploD hy 4 3 = 5F
(n1 (n2 (n3 n4 ))) (n1 ((n2 n3 )n4 )) ((n1 n2 )(n3 n4 )) ((n1 (n2 n3 ))n4 ) (((n1 n2 )n3 )n4 )

pigur RFQUX hiferentes mners de ortr un pentgono en 3 tringulos

4.8. Enumeracin y cdigos de rboles

311

 il nmero de expresiones prentizds on n prntesis izquierdos y n prntesis dereE hos que estn lnedsF  il nmero de roles inrios de n nodosF  il nmero de roles de n + 1 nodosF  il nmero de minos de longitud 2n en un mll n n que estn por dejo de l 1 8 digonlF or ejemploD pr un mll 4 4D hy 5 4 = 14 minos diferentes que psn dejo de l digonlF

pigur RFQVX hiferentes minos dejo de l digonl en un mll 4 4  il nmero de plrs de hik de longitud 2n o el nmero de plrs vuksiewiz de longitud 2n + 1F  il nmero de minos en el plnoD onformdos por 2n puntosD que prten desde (0, 0) y terminn en (2n, 0) que no ruzn el eje xF

4.8.2

Almacenamiento de rboles binarios

311

uiz un de ls funionliddes ms preid de un den de vuksiewiz es que nos ofree un mner ms ompt de seuenilizr l topolog de un rol inrio que ls estudids en RFRFIQ @gF PSQAF esD podemos usr l seueni pr gurdr el rol en un medio de lmenmiento seundrio o pr trnsmitirlo por un redF hdo un rol rdorD sistidos del tipo BitArray PFIFS @gF SQAD podemos otener su plr de vuksiewiz de l siguiente mnerX Funciones de BinNode_Utils 243a + 278b 312a template <class Node> inline void tree_to_bits(Node * root, BitArray & array) { if (root == Node::NullPtr) { array.push(1); return; } array.push(0); tree_to_bits((Node*) LLINK(root), array); tree_to_bits((Node*) RLINK(root), array); }
Uses

BitArray

54a.

312

4. rboles

312a

v plr de vuksiewiz resultnte es gurdd en arrayF xo requerimos retornr su longitud porque es derivle de l rdinlidd del rol @2n + 1AF il rreglo de its resultnte y est listo pr los usos meniondos y otros diionlesY entre ellosD prtir de l orrespondeni entre roles y roles inrios @ RFRFIU @gF PTHAAD el gurdr roles en generlF r otener el rol prtir de l seueni progrmmos l siguiente rutin inversX Funciones de BinNode_Utils 243a + 311 312b template <class Node> static inline Node * __bits_to_tree(BitArray & array, int & i) { int bit = array.read_bit(i++); if (bit == 1) // Es un nodo externo? return Node::NullPtr; // s
Node * p = new Node; // crear nodo interno actual LLINK(p) = (Node*) __bits_to_tree<Node>(array, i); // subrbol izq. RLINK(p) = (Node*) __bits_to_tree<Node>(array, i); // subrbol der. }
Uses

return p;
BitArray
54a.

312b

il prmetro array ontiene l plr de vuksiewiz de un rol rdorF il pE rmetro i es el it tul de proesmientoF il pse se he por refereni pr poder tulizrlo onforme se v leyendo l seueni y dee iniilizrse en el ndie dentro de array en donde omienz l seueniY esto permite gurdr vrios roles en un BitArrayD s omo reuperrlosF gomo se veD l rutin nterior es esttiD pues mnej el prmetro iD por refereniD de ndie tul de l den de itsF v rutin de interfz se de(ne de l siguiente mnerX Funciones de BinNode_Utils 243a + 312a 312c template <class Node> inline Node * bits_to_tree(BitArray & array, int idx = 0) { return __bits_to_tree <Node> (array, idx); }
Uses

BitArray

54a.

312c

il rreglo slo lmen l formD ms no el ontenido de los nodosF r lmenr el ontenido ontenmos l plr de vuksiewiz ulquier de los reorridosD en nuestro soD el reorrido pre(joF isto nos ondue l siguiente rutin uxilirD uy funin es gurdr ls lves en pre(joX Funciones de BinNode_Utils 243a + 312b 313a template <class Node, class Get_Key> inline void save_tree_keys_in_prefix(Node * root, ofstream & output) { if (root == Node::NullPtr) return;
output  Get_Key () (root)  " "; save_tree_keys_in_prefix<Node,Get_Key>((Node*)LLINK(root), output);

4.9. rboles binarios de bsqueda

313

save_tree_keys_in_prefix<Node,Get_Key>((Node*)RLINK(root), output);

313a

il rol de l lse Get_Key es otener el ontenido del nodo que se dese lmenrF v operin nlogD es deirD otener ls lves del rhivo y olorls en los nodos se he por medio de l siguiente rutinX Funciones de BinNode_Utils 243a + 312c 313b template <class Node, class Load_Key> inline void load_tree_keys_in_prefix(Node * root, ifstream & input) { if (root == Node::NullPtr) return;
Load_Key () (root, input); load_tree_keys_in_prefix<Node,Load_Key>((Node*)LLINK(root), input); load_tree_keys_in_prefix<Node,Load_Key>((Node*)RLINK(root), input);

313b

in este soD l lse Load_Key tiene omo misin leer de input l lve y ponerl en el nodoF uesto que existen diverss mners de lmenr el ontenido del nodoD l rutin no dee pretender un formto preestleidoF ehor tenemos tods ls herrmients lists pr instrumentr el lmenmiento de roles inrios en memori seundri11 X Funciones de BinNode_Utils 243a + 313a 315a template <class Node, class Get_Key> inline void save_tree(Node * root, ofstream & output) { BitArray prefix; tree_to_bits(root, prefix); prefix.save(output); save_tree_keys_in_prefix <Node, Get_Key> (root, output); } template <class Node, class Load_Key> inline Node * load_tree(ifstream & input) { BitArray prefix; prefix.load(input); Node * root = bits_to_tree <Node> (prefix); load_tree_keys_in_prefix <Node, Load_Key> (root, input); return root; }
Uses

BitArray

54a.

4.9 rboles binarios de bsqueda


upongmos que 1300 millones de persons estn susrits l serviio telefnioF hdo el nomre de un susriptorD mo verigur su nmero telefnioc i los regisE tros de quells 1300 millones de persons estn ordendos lftimente en un
11
As como tambin segn sea el

stream,

su transmisin por red.

314

4. rboles

rhivoD entones l squed inri nos permitir enontrr el nmero de elulr de hng hunnien gheung u en lo sumo lg 1300000000 = 31 intentosF v squed inri exige que l seueni de dtos est ordend y esto es difil de grntizrD pues es de esperr que menudo prezn nuevos susriptores y desprezE n otrosF etulizr en lne un seueni ordend de nmeros telefnios ser muy ine(ienteD pues l inserin y supresin en un seueni ordend es O(n)F efortundmenteD si ien no podemos mntener sin ostes importntes un seueni ordendD s podemos simulrl medinte un rol inrio que emule l squed inri y que nos ofrez ordenmiento y rpidez pr ls operiones de inserinD squed y supresinF e un rol inrio T =< L(T ), raiz(T ), R(T ) >D entonesD T es un rol inrio de squed @effA si y slo siX
Denicin 4.9 (rbol binario de bsqueda)

T ABB

ni L(T ) = KEY(ni ) < KEY(raiz(T ))

ist regl se onoe omo l propiedd o ondiin de orden de un rol inrio de squedF r disminuir l longitud del disursoD en muhos ontextos utilizremos  ABB pr denotr un rol inrio de squedF
340 151 79 17 4 34 77 273 104 137 153 180 188 278 292 308 322 268 306 331 345 354 356 416 457 467 346 384 474 497

ni R(T ) = KEY(ni ) > KEY(raiz(T ))

pigur RFQWX n rol inrio de squed hdo un nodo ulquierD todos los nodos en el surol izquierdo deen tener lves menoresD mientrs que todos los nodos en el surol dereho deen tener lves myoresF il rol de l (gur RFQW stisfe l de(niinF il orden se dest undo se oserv el reorrido in(joF r el rol de l (gur RFQWD el reorrido in(jo esX 4 17 34 77 79 104 137 151 153 180 188 268 273 278 292 306 308 322 331 340 345 346 354 356 384 416 457 467 474 497 F iste orden es deduile de l de(niinX visite los nodos l izquierdD los ules son menores l rzD luego visite l rz yD (nlmenteD visite los nodos l derehD que son myores que l rzF

4.9. rboles binarios de bsqueda

315

v propiedd de orden de un rol inrio de squed permite odi(rlo on el reorrido pre(jo o su(joF is deirD podemos reonstruir ompletmente un eff prtir de su reorrido pre(joF e n0 , n1 , . . . , n|T |1 el reorrido pre(jo de un eff T =< L(T ), raiz(T ), R(T ) >F il reE orrido pre(jo nos proporion diretmente raiz(T ) = n0 y raiz(L(T )) = n1 F v propiedd de orden nos grntiz que raiz(R(T )) ser el primer nodo en el reorrido pre(jo que se myor o igul que raiz(T )F es puesD plimos este rzonmiento reursivo y otenemos el lgoritmo siguienteX
315a

Funciones de BinNode_Utils 243a +

313b 316a

template <class Node> inline Node * preorder_to_binary_search_tree (DynArray<typename Node::key_type> & preorder, const int & l, const int & r) { if (l > r) return Node::NullPtr; Node * root = new Node(preorder[l]); if (l == r) return root;

Sea first_greater el primer nodo mayor que la raz 315b


LLINK(root) = preorder_to_binary_search_tree<Node>(preorder, l + 1, first_greater - 1); RLINK(root) = preorder_to_binary_search_tree<Node>(preorder, first_greater, r); return root;
DynArray
34.

}
Uses

315b

right_root es el primer nodoD de izquierd derehD que se myor que l rz @preorder[inf]AY este nodo es l rz del surol derehoF r lolizrloD reorremos linelmente el rregloX Sea first_greater el primer nodo mayor que la raz 315b (315a) int first_greater = l + 1; while ((first_greater <= r) and (preorder[first_greater] < preorder[l])) ++first_greater;
iste nodo prtiion el rreglo en dos prtesF v primer omprendid entre l + 1 y right_root - 1D orresponde l reorrido pre(jo del surol izquierdoF v segund prteD omprendid entre right_root y rD orresponde l reorrido pre(jo del surol derehoF
4.9.1 Bsqueda en un ABB

gonsideremos T ABB y un lve k usrse en el rolF r herlo inspeionE mos KEY(T )D si k = KEY(T )D entones k h sido enontrdoF he lo ontrrio omprE

316

4. rboles

316a

mos k < KEY(T )Y si el predido es iertoD entones usmos en el surol izquierdoY de lo ontrrioD usmos en el surol derehoF i durnte este proeso nos enontrmos on un surol voD entones onluimos que k no se enuentr dentro del rolF il siguiente lgoritmo re)ej este proesoX Funciones de BinNode_Utils 243a + 315a 316b template <class Node, class Compare = Aleph::less<typename Node::key_type> > inline Node * searchInBinTree(Node * root, const typename Node::key_type & key) { while (root != Node::NullPtr) if (Compare () (key, KEY(root))) // en rama izquierda? root = static_cast<Node*>(LLINK(root)); // baje a la izquierda else if (Compare() (KEY(root), key)) // en rama derecha? root = static_cast<Node*>(RLINK(root)); // baje a la derecha else break; // se encontr!
} return root;

Denes:

searchInBinTree,

used in chunk 320b.

ist primitiv us en el rol un nodo on vlor de lve key y retorn su direin si l lve se enontr o Node::NullPtr de lo ontrrioF searchInBinTree() se utiliz en l myor de eh fundmentdos en effF il desempeo de este lgoritmo depende de un equilirdo est el rolF i ste tiende estr ompletoD entones su ltur tiende lg |T | F he este modoD si grntizmos que el rol se equilirdoD entones l squed en un rol inrio no requerir ms de lg |T | omprionesY extmente l mism lidd de serviio de l squed inriF il truo esD puesD logrr que ls inseriones y supresiones del rol lo mntengn en equilirioF
4.9.1.1 Bsqueda del menor y del mayor elemento en un ABB

emos que el reorrido in(jo de un eff muestr l seueni ordendF or tntoD el menor y el myor de todos los elementos del onjunto estrn ddos por el primer y ltimo elementos del reorrido in(joD los ules se identi(n pitrimenteD de mner generlD en l siguiente (gurX
T

Mnimo

L(T )

R(T )

Mximo

316b

r T ABBD el mnimo se enuentr en el nodo ms l izquierdD mientrs que el mximo en el ms l derehF he este onoimiento se deduen los siguientes lgoritmosX Funciones de BinNode_Utils 243a + 316a 317 template <class Node> inline Node * find_min(Node * root) { while (LLINK(root) != Node::NullPtr)

4.9. rboles binarios de bsqueda

317

} template <class Node> inline Node * find_max(Node * root) { while (RLINK(root) != Node::NullPtr) root = static_cast<Node*>(RLINK(root)); return root; }

root = static_cast<Node*>(LLINK(root)); return root;

ems primitivs reien un nodo rz de un eff y retornn el mnimo y mximo respetivmenteF i el eff est equilirdoD entones find_min() y find_max() tienen omplejidd O(lg n)F
4.9.1.2 Bsqueda del predecesor y sucesor

317

hdo T ABBD ul es el suesor de KEY(T )? or l propiedd de orden de un eff semos que este suesorD si existeD se enuentr en el nodo ms l izquierd de l rm dereh y l ondiin de existeni es justmente que exist un rm derehF he lo nterior se dedue el lgoritmo siguienteX Funciones de BinNode_Utils 243a + 316b 318 template <class Node> inline Node * find_successor(Node * p, Node *& pp) { pp = p; p = (Node*) RLINK(p); while (LLINK(p) != Node::NullPtr) { pp = p; p = (Node*) LLINK(p); } return p; }

find_successor() retorn el nodo suesor de p y su pdre en el prmetro ppF v llmd dee herse sore p y su pdreF find_successor() no requiere un operdor de omprinD pues l topolog del rol proporion el resultdoF
T

L(T )

Predecesor

Sucesor

R(T )

pigur RFRHX iiones generles del nodo predeesor y suesor de l rz de un rol v squed del predeesor es nlogF
4.9.1.3 Bsquedas especiales sobre un ABB

in lguns no tn exepionles osiones se requiere enontrr un nodo queD en lugr de orresponderse on l lveD de lgun form gurde otr relin on ellF in est

318

4. rboles

318

situin enjn dos tipos de squedX l del pdre de un lve perteneiente l rol y l del que ser el pdre de un lve no perteneienteF v primer squed se expres del siguiente modoX Funciones de BinNode_Utils 243a + 317 319a template <class Node, class Compare = Aleph::less<typename Node::key_type> > inline Node * search_parent(Node * root, const typename Node::key_type & key, Node *& parent) { while (true) if (Compare () (key, KEY(root))) { if (LLINK(root) == Node::NullPtr) return root; parent = root; root = static_cast<Node*>(LLINK(root)); } else if (Compare () (KEY(root), key)) { if (RLINK(root) == Node::NullPtr) return root; parent = root; root = static_cast<Node*>(RLINK(root)); } else return root; }

search_parent() us l lve key en el eff uy rz es rootF v rutin retorn el nodo que ontiene key y su nodo pdre se gurd en el prmetro por refereni parentD el ul dee iniilizrse en el pdre de l rzF gonsideremos el siguiente eff de ejemploX
50 25 10 30 80 90

il rol ontiene ls lves 10, 25, 30, 50, 80, 90 entre un onjunto in(nito de posiles vE loresF i el rol reiese nturlmenteD es deirD slo por sus puntsD en dnde olor nuevs lvesc v respuest se evideni en el rol siguienteX
50 25 10 30 80

[51..79] [81..89]

90

[..9] [11..24]

[26..29]

[31..49]

[91..]

il nio espio 12 por donde puede reer nturlmente un eff es trvs de sus
12
En este prrafo las nociones de

espio , nturl

fsio

se enuncian en el sentido de la ciencia

fsica moderna. Se usan comillas y nfasis itlico porque tales ideas que si bien tambin son abstractas en nuestro mundo cotidiano, son an ms abstractas en el discurso de la programacin de computadores, mxime cuando el concepto de rbol binario es, como tal, pura abstraccin.

4.9. rboles binarios de bsqueda

319

319a

nodos externosF hiho de otro modoD que el vo que represent un nodo externo se oupdo fsimente por un nuevo nodo internoF vuego de expresdo lo nteriorD dquiere sentido pensr un squed de un rngo que no est en el rolF y seD usr los puntos por donde puede reer un effF l squed l instrument l funinX Funciones de BinNode_Utils 243a + 318 321a template <class Node, class Compare = Aleph::less<typename Node::key_type> > inline Node * search_rank_parent(Node * root, const typename Node::key_type & key) guy implementin puede oservrse en l ilioteF v rutin us l lve key en un rol on rz root y retorn el nodo que ser pdre de un lve keyF
4.9.2 El TAD

BinTree<Key>

319b

entes de introduir los lgoritmos de inserin y supresinD es onveniente introduir nuestro eh de se que modeliz un rol inrio de squedF l eh se espei( en el rhivo tplinreeFr 319b uy estrutur es l siguienteX tpl_binTree.H 319b template <template <typename> class NodeType, typename Key, class Compare> class GenBinTree { Deniciones pblicas BinTree<Key> 320a miembros dato de BinTree<Key> 319c Mtodos de BinTree<Key> 320b }; template <typename Key, class Compare = Aleph::less<Key> > class BinTree : public GenBinTree<BinNode, Key, Compare> {};
Uses

BinNode

240. 319b

tplinreeFr

de(ne tres lsesX

 GenBinTree<NodeType, Key, Compare>X lse genri que implnt el proE lem fundmentl de estruturs de dtos13 medinte un effF ist lse slo est destind implntr y no es de uso del lienteF  BinTree<Key>X lse prmetrizd que implnt el prolem fundmentl trvs de un rol inrio de squed de nodos inrios on lves de tipo KeyF ist lse es implntd diretmente por derivin pli de GenBinTreeF es puesD su interfz es extmente l mism que GenBinTreeF  BinTreeVtl<Key>X equivlente l BinTree<Key>D slvo que los nodos poseen desE trutores virtulesF r filitr los lgoritmosD todos los tipos strtos sdos en roles inrios de squed utilizrn un nodo eerX miembros dato de BinTree<Key> 319c (319b) Node headNode; Node * head; Node *& root;
13
Recordar 1.3 (Pg. 17).

319c

320

4. rboles

320a

headNode represent el nodo eerD head es l direin de l eer y root es un refereni l lzo dereho de headF in otros trminosD RLINK(head) == rootF vs primitivs de GenBinTree mnipuln nodos inrios uy espei(in se export l usurio del siguiente modoX Deniciones pblicas BinTree<Key> 320a (319b) typedef NodeType<Key> Node;
il tipo ser BinTree<Key>::Node pr nodos omunes o BinTreeVtl<Key>::Node pr nodos on destrutores virtulesF v squed se remite invor searchInBinTree()X Mtodos de BinTree<Key> 320b (319b) 320c Node * search(const Key & key) { return searchInBinTree <Node, Compare>(root, key); }
Uses

320b

searchInBinTree

316a.

320c

n oservdor esenilD sore todo pr poder lierr l memori oupd por el rol inrioD es l onsult de l rzX Mtodos de BinTree<Key> 320b + (319b) 320b 321b Node*& getRoot() { return root; }
4.9.3 Insercin en un ABB

v inserin oedee l reimiento nturl de un rol D es deirD por ls punts u hojsF hdo un nodo insertr pD deemos enontrr un nodo externo pr sustituirlo por p de mner tl que no se viole l propiedd de orden de un effF esumiendo que ls lves no se repitenD ondiin que desde hor imponemos l eh BinTree<Key>D existe un slo nodo externo pr sustituir por pF or ejemploD onsideremos insertr un nodo que onteng vlor de lve 27 tl omo se muestr en l (gur RFRIF il exEnodoEexternoD hijo
23 23 15 10 31 47 59 10 27 15 31 47 59

(a) Antes de

27

(b) Luego de

27

pigur RFRIX n ejemplo de inserin en rol inrio izquierdo del 31D fue sustituido por uno interno on vlor 27D el ulD trvs de sus dos nodos externosD re dos rehs en el rolF v primer est dd por el lzo izquierdo del 27 y puede lergr lves entre [24..26]D mientrs que l segund reh l represent el lzo dereho y podr lergr lves entre [28..30]F il ejeriio nterior nos indii que pr efetur un inserin es menester usr el nodo externo sustituirF ehor ienD efetos de enlzr el nuevo nodo se reE quiere otener un puntero l que ser el pdre del nodo insertr Een el ejemploD un

4.9. rboles binarios de bsqueda

321

321a

puntero l nodo on lve 31EF i ien est in puede instrumentrse medinte l rutin search_rank_parent() meniond en RFWFIFQ @gF QIUAD es preferileD efetos de l simpliiddD memorizr este puntero relizndo un squed reursiv y luego insertndo el nuevo nodoF iste es el enfoque del siguiente lgoritmoX Funciones de BinNode_Utils 243a + 319a 322 template <class Node, class Compare = Aleph::less<typename Node::key_type> > inline Node * insert_in_binary_search_tree(Node *& root, Node * p) { if (root == Node::NullPtr) return root = p;
if (Compare () (KEY(p), KEY(root))) // p < root? return insert_in_binary_search_tree<Node,Compare>((Node*&) LLINK(root), p); else if (Compare () (KEY(root), KEY(p))) // p > root? return insert_in_binary_search_tree<Node,Compare>((Node*&) RLINK(root), p); } return Node::NullPtr; // clave repetida ==> no hay insercin

Denes:

insert_in_binary_search_tree,

used in chunks 321b and 327.

321b

v rutin insert el nodo p en el eff on rz root y retorn l rz del rol inrio resultnte en so de que l inserin teng xitoD es deirD si l lve ontenid en p no se enuentr en el rolF he lo ontrrioD puesto que no se permiten lves duplidsD se retorn Node::NullPtrF xotemos que el prmetro root se ps por refereniD pues en el so se de l reursin se modi( l rzF wedinte l nterior rutin genriD l implntin del mtodo insert() es mer uestin de formX Mtodos de BinTree<Key> 320b + (319b) 320c 323 Node * insert(Node *p) { return insert_in_binary_search_tree<Node, Compare>(root, p); }
Uses

insert_in_binary_search_tree

321a.

4.9.4

Particin de un ABB por clave (split)

in est operinD un rol T on seueni in(j genri Si =< k1 , k2 , k3 , . . . , kn > se prtiion segn un lve kx en dos roles T< y T> tl que Si< =< k1 , k2 , k3 , . . . , > | ki T< , ki < kx y Si> =< . . . , kn > | ki T> , ki > kx F v primitiv que nos efet l prtiin se denomin split_key_rec(T, kx , T< , T> )Y donde T es el rol prtiionrD kx es l lve de prtiin y T< y T> son los roles resultntes de l prtiinF il prinipio reursivo de l prtiin es simple y se pitoriz en el digrm de l (gur RFRPF vlmemos kx l lve de prtiin y supongmos kx > KEY(T )F in este so se efet un llmd reursiv split_key_rec(R(T ), kx , T< , T> ) sore R(T )D l ul

322

4. rboles

split_key_rec(T,

kx , T < , T > )

K (T )

if

kx > KEY(T )
split_key_rec(R(T),

kx ,

R(T),

T> )

split_key_rec(T,

kx , T < , T > )

K (T )

L(T )
T< T>

L(T )

R(T )

T<

T>

(a) Situacin inicial

(b) Luego de

split()

en raz

pigur RFRPX isquem generl de l prtiin por lve rroj dos roles T< y T> produto de prtiionr R(T ) on kx F il resultdo de(nitivo es T< =< L(T ), T, L(T ) >D donde L(T ) = T< F v otr prtiinD T> D es diretmente el rol T> = T> F i kx < KEY(T )D entones el lgoritmo es simtrimente idntioF il so se de l reursin es l prtiin sore el rol voD l ul rroj dos roles vosF gon lo nteriorD el lgoritmo resultnte deer ser omprensile sin di(ultdesX Funciones de BinNode_Utils 243a + 321a 324 # define SPLIT split_key_rec<Node, Compare> template <class Node, class Compare = Aleph::less<typename Node::key_type> > inline bool split_key_rec(Node * root, const typename Node::key_type & key, Node *& ts, Node *& tg) { if (root == Node::NullPtr) { // key no se encuentra en rbol ==> split tendr xito ts = tg = Node::NullPtr; return true; } if ( Compare() (key, KEY(root)) ) // key < KEY(root)? if (SPLIT((Node*&) LLINK(root), key, ts, (Node*&) LLINK(root))) { tg = root; return true; } else return false;
if ( Compare() (KEY(root), key) ) // key > KEY(root)? if (SPLIT((Node*&) RLINK(root), key, (Node*&) RLINK(root), tg)) { ts = root; return true; } else return false; return false; // clave existe en rbol ==> se deja intacto

322

4.9. rboles binarios de bsqueda

323

}
Denes:

split_key_rec,

used in chunks 323 and 326b.


19
split_key_rec(13, 19, ...)

29

split_key_rec(29, 19, ...)

13
split_key_rec(25, 19, ...)

45 25 30 27 22 18 53 77 91

8
split_key_rec(20, 19, ...)

12 15

20

split_key_rec(15, 19, ...)

split_key_rec(18, 19, ...)

pigur RFRQX rzdo de un lne de divisin

323

split_key_rec() tiene utro prmetrosD dos de entrd y dos de slidF vos de entrd son l rz del rol prtiionr root y l lve de prtiin keyF vos prmetros de slid son dos roles ts y tgF hespus de l llmdD ts ontiene l lves menores que key y tg ontiene ls myores o igulesF i l lve no se enuentr en el rolD entones split_key_rec() retorn true pr indir que el rol fue prtiiondoF he lo ontrrio se dej el rol intto y se retorn falseF itrimenteD l prtiin puede interpretrse omo el trzdo de un lne divisori segn l lve de prtiinF v (gur RFRQ ilustr tl lne on lve 19 y se indin ls llmds reursivs de l prtiinF hesde el nodo rz 29 se determin que deemos prtiE ionr l rm izquierd de rz 13D pues 19 es menor que 29F split_key_rec(13, 19, ts, tg) retorn l prtiin del surol on rz 13F il prmetro ts es el rol T< resultdo de split_key_rec (29, 19, ts, tg)D mientrs que el rol T> ser < tg, 29, R(29) >F gon l rutin nteriorD y estmos listos pr esriir l versin de l prtiin del eh BinTree<Key>X Mtodos de BinTree<Key> 320b + (319b) 321b 326a
bool split(const Key & key, GenBinTree & l, GenBinTree & r) { return split_key_rec<Node, Compare>(root, key, l.root, r.root); }
split_key_rec
322.

Uses

4.9.5

Unin exclusiva de ABB (join exclusivo)

gonsideremos dos roles T< y T> resultntes de split_key_rec() y l operin inversX pegr T< y T> en un rol T F eordemos que en este soD T< y T> son exluyentesF vlmemos est operin join_exclusive(T< , T> )D l ul retorn el rol orresponE diente de unir T< on T> F gli(mos l operin de exlusiv porque semos que los rngos de lves no se solpn y que T< T> = D lo ul es un onoimiento muy vliosoD pues nos permite her un lgoritmo prtiulr pr este so on mejor desempeo que el de l unin generl si los intervlos se solpn o los elementos se omprtenF v siguiente (gur ilustr los omponentes generles de T< y T> que requerimos idenE ti(r pr diser join_exclusive(T< , T> )X

324

4. rboles

join_exclusive(T< ,T> )

T<

T>

L(T< )

R(T< )

L(T> )

R(T> )

l soluin se pitoriz del siguiente modoX


T< T>
L(T< )

join_exclusive(R(T< ),L(T> ))
R(T> )

324

il so se del lgoritmo es que lguno de los dos roles se voF vo nterior nos llev l siguiente lgoritmoX Funciones de BinNode_Utils 243a + 322 325 template <class Node> inline Node * join_exclusive(Node *& ts, Node *& tg) { if (ts == Node::NullPtr) return tg;
if (tg == Node::NullPtr) return ts; LLINK(tg) = join_exclusive(RLINK(ts), LLINK(tg)); RLINK(ts) = tg; Node * ret_val = ts; ts = tg = Node::NullPtr; // deben quedar vacos despus del join } return ret_val;

Denes:

join_exclusive,

used in chunks 325 and 513.

ist rutin nos ser de sum utilidd pr simpli(r onsiderlemente el lgoritmo de eliminin de un effF
4.9.6 Eliminacin en un ABB

v eliminin por lve exhie dos fsesX usr el nodo que onteng l lve yD luegoD quitrlo del rolF ero hy un di(ultd topolgi pr quitr el nodoF gonsidereE mos un nodo p quitrse de un eff y el digrm de l (gur RFRRF i literlmente quitmos pD entones deemos her lgo on los tres ros que quedn sueltos si despree pX q pD p L(p) y p R(p)F ediionlmenteD pr poder modi(r orretmente q deemos distinguir extmente si p es hijo izquierdo o derehoF e onoen dos mners de trtr on l di(ultd nteriorX IF ustituimos p por su nodo predeesor en L(p)D o por su suesor en R(p)F ry dos puntos fundmentles que deemos notrF rimeroD tnto el predeesor omo el suesor de p siempre son inompletosF in el so del predeesorD ste est

4.9. rboles binarios de bsqueda

325

q p

L(p)

R (p )

pigur RFRRX ituin generl de eliminin del nodo p ddo por el nodo ms l izquierd de L(p)D el ul tiene que ser inompletoD pues si no ontrdir el heho de que el predeesor se el ms l izquierdF il rzonmiento simtrio ourre on el suesorF uesto que el nodo sustituir est inompletoD tenemos su(iente espio pr enlzr ls tres rms si intermimos el nodo sustituto por pD puesD por ejemplo en el predeesorD su rm izquierd fltnte se sustituye por L(p)F v segund uestin notr es que el predeesor y el suesor son los dos nios posiE les nodos inompletos intermirD pues de lo ontrrio se violr l propiedd de orden de un effF n lgoritmo elegnte sdo en este prinipio es stnte loriosoD pues pr efetur orretmente los intermios se requieren mntener punteros pD su pdreD l predeesor y l pdre del predeesorF or didurD si el predeesor no es hojD hy que efetur un pso diionl onsistente en ortoEiruitr p en su nuev posiin on el rol que ste ontengF v elegni de l que hlmos en el prrfo nterior onsiste en no intermir los ontenidos de los nodosD pues se fetr l ohereni de eventules estruturs de dtos que punten ellosF ist form est en desusoD pues l otr mnerD que expliremos inmeditmenteD no slo es muho ms simpleD sino ms e(ienteF he todos modosD en TFRFIFP @gF RUWA se muestr est tniF PF il rol uy rz es p se sustituye por el rol resultnte de l unin exlusiv de sus rmsF in funin de esto se desprende el siguiente lgoritmoX
325

Funciones de BinNode_Utils 243a +

324 326b

# define REMOVE remove_from_search_binary_tree<Node, Compare> template <class Node, class Compare = Aleph::less<typename Node::key_type> > inline Node * remove_from_search_binary_tree(Node *& root, const typename Node::key_type & key) { if (root == Node::NullPtr) return Node::NullPtr; if (Compare () (key, KEY(root))) // key < KEY(root)? return REMOVE((Node*&) LLINK(root), key); else if (Compare () (KEY(root), key)) // key > KEY(root)?

326

4. rboles

return REMOVE((Node*&) RLINK(root), key); Node * ret_val = root; // respaldar root que se va a borrar root = join_exclusive((Node*&) LLINK(root), (Node*&) RLINK(root)); return ret_val;

Denes: Uses

remove_from_search_binary_tree, join_exclusive 324.

used in chunks 326a and 327.

il prmetro root es l rz del effD el ul es por refereniD de form tl que se modi(que l rz undo se enuentre l lveF il segundo prmetro es l lve mism eliminrF el igul que on l inserinD el mtodo de eliminin de BinTree<Key> deviene muy simpleX Mtodos de BinTree<Key> 320b + (319b) 323 328 Node * remove(const Key & key) { return remove_from_search_binary_tree<Node, Compare>(root, key); }
Uses

326a

remove_from_search_binary_tree

325.

4.9.7

Insercin en raz de un ABB

326b

in el lgoritmo de inserin desrrolldo en RFWFQ @gF QPHAD el rol ree por los nodos externosF elguns vees es preferile que el nuevo nodo deveng rz del rolF v tni nterior fvoree l lolidd de refereni en el sentido de que los nodos ernos l rz son los reientemente insertdosF snsertr un nuevo nodo omo rz es muy fil luego de que se dispone de l prtiE in split_key_rec() desrrolld en RFWFR @gF QPIAF odo lo que hy que her es prtiionr segn l lve de inserin y luego tr est lve los roles resultntes de l prtiinX Funciones de BinNode_Utils 243a + 325 327 template <class Node, class Compare = Aleph::less<typename Node::key_type> > inline Node * insert_root(Node *& root, Node * p) { Node * l = Node::NullPtr, * r = Node::NullPtr;
if (not split_key_rec<Node, Compare>(root, KEY(p), l, r)) return Node::NullPtr; LLINK(p) = l; RLINK(p) = r; root = p; } return root;

4.9. rboles binarios de bsqueda

327

Denes: Uses

insert_root, used in chunk split_key_rec 322.

327.

v rutin retorn Node::NullPtr si el rol ontiene un nodo on lve igul l nodo de inserin pF

pigur RFRSX rol resultnte de 512 inseriones letoris en l rz

4.9.8

Unin de ABB (join)

gonsideremos T1 , T2 ABB y l operin de unin T1 T2 F in nuestr interfzD l unin se denominr join(T1 , T2 , d)D l ul retorn un eff omo produto de unir ls lves de T1 on ls de T2 F uesto que hemos orddo no tener lves repetidsD ls eventules repitenis entre T1 y T2 se gurdrn en un eff uxilir llmdo dD el ul es un prmetro por refereni join()F heemos prever esto porque los roles unir pueden herse onstruido independientementeF n primer form de implntr el join() es reorrer en pre(jo un rolD por ejemploD T2 D e ir insertndo sus lves en el otro rol T1 F ytr mnerD quiz ms onson on l reursin inherente un rol inrioD se ilustr en l (gur RFRTF
insert_root(K (T1 ),

T2 )

T1

T1

T2

T2
L(T1 ) R(T1 ) L(T1 ) R(T1 )

L(T2 ) R(T2 )

join(L(T1 ),L(T2 ))

join(R(T1 ),R(T2 ))

pigur RFRTX isquem generl de unin reursiv de dos roles inrios ommos l rz de uno de los roles y l insertmos omo rz del otroF in el so de l (gur tommos l rz del rol T1 y l insertmos en T2 pr otener T2 F vuego de insertr raiz(T1 )D ls rms suelts L(T1 ) y R(T1 ) se unen reursivmente on ls rms izquierd y dereh de T2 D o seD L(T2 ) = join(L(T1 ), L(T2 )) y R(T2 ) = join(R(T1 ), R(T2 ))F gon el prinipio nterior lroD podemos diser un lgoritmoX Funciones de BinNode_Utils 243a + 326b 344 template <class Node, class Compare = Aleph::less<typename Node::key_type> > inline Node * join(Node * t1, Node * t2, Node *& dup)

327

328

4. rboles

if (t1 == Node::NullPtr) return t2; if (t2 == Node::NullPtr) return t1; Node * l = (Node*) LLINK(t1); // respaldos ramas de t1 Node * r = (Node*) RLINK(t1); t1->reset(); // mientras la clave raz de t1 est contenida en t2 while (insert_root<Node, Compare>(t2, t1) == Node::NullPtr) { // s ==> squelo de t1 e insrtelo en dup Node * p = remove_from_search_binary_tree(t1, KEY(t1)); insert_in_binary_search_tree<Node, Compare>(dup, t1); } LLINK(t2) = join<Node, Compare>(l, (Node*) LLINK(t2), dup); RLINK(t2) = join<Node, Compare>(r, (Node*) RLINK(t2), dup);

}
Uses

return t2;
insert_in_binary_search_tree
321a,

insert_root

326b, and

remove_from_search_binary_tree

325.

(a)

insert_root()

(b)

insert_in_search_binary_tree()

(c)

join()

de rboles (a) y (b)

pigur RFRUX ijemplo de join() de roles inrios ehor inorpormos est versin l mtodo orrespondiente en BinTree<Key>X
328

Mtodos de BinTree<Key> 320b +

(319b)

326a

void join(GenBinTree & tree, GenBinTree & dup) {

4.9. rboles binarios de bsqueda

329

root = Aleph::join<Node, Compare> (root, tree.root, dup); tree.root = Node::NullPtr;

4.9.9

Anlisis de los rboles binarios de bsqueda

ods ls operiones estudids sore un eff deen llevr o squedsY su tiempo de ejeuin depende por tnto del tiempo de squedD el ul est otdo por l ltur del rolF gonseuentementeD lo trsendentl en el nlisis es onoer ul ser el nivel promedio de un nodoF in lo que sigue de nuestro nlisis supondremos que el orden de inserin de ls lves es letorioD es deirD uniformemente distriuidoF esD ddo un rol T D hy |T |! rdenes 2| T | diferentes de inserin que pueden produir C|T | = |T |1 +1 |T | roles inrios diferentesF ehor ienD es posile demostrrD preferilemente por induinD que |T |, C|T | < |T |!F vo ul impli que lgunos roles se repetirn pr permutiones de inserin diferentesF
Proposicin 4.12 e T un rol inrio de squed de n nodos onstruido letoriE mente segn un seueni de inserin letoriF xo hy supresionesF enX

 Sn el nmero de nodos visitdos durnte un squed exitosD y  Un el nmero de nodos visitdos durnte un squed fllidF intonesX Sn = 2 1 + Un = 2Hn+1

1 Hn n 2

1.386 lg n

= O(lg n) y = O(lg n)

1.386 lg (n + 1)

honde Sn y Un denotn los promedios de Sn y Un respetivmenteD mientrs que Hn es el nEsimo nmero rmnio14 F il nmero de nodos visitdos en un squed exitos es l longitud del mino desde raiz(T ) hst el nodo enontrdoF i ni es el nodo enontrdoD entones |Craiz(T ),ni | = nivel(ni ) + 1D pues el nivel omienz desde eroF or de(niin de promedioD tenemosX
Demostracin

Sn =

1 n 1 n

(nivel(ni ) + 1)
ni T

= =

nivel(ni )
ni T

+ 1

1
@RFRQA

1 IPL(T ) n

ustituimos @RFPRA en @RFRQA @por l proposiin RFRAX Sn =


14

EPL(T ) 2n n

@RFRRA

Hn =

n 1 i=1 i .

330

4. rboles

ehor plntemos un euin similr pr un squed infrutuosF uesto que el nodo no se enuentr en el rolD l squed desender hst un nodo externoF il nmero de nodos visitdos en un squed infrutuos esD puesD equivlente l longitud del mino desde l rz hst el nodo externoF odemos entones plnter el promedio de longitudes entre todos los minos desde l rz hst un nodo externoF isto esX Un =

1 n+1

nivel(nx )
nx nodo externo nx

EPL(T ) = = n+1 EPL(T ) = (n + 1) Un ustituimos @RFRSA en @RFRRAX Sn =

@RFRSA

(n + 1) Un 2n n

@RFRTA

v euin @RFRTA nos plnte ls dos ingnits que intentmos enontrrF r poder resolverl requerimos un segund euinD independiente de @RFRTAD que tmin nos relione Sn y Un D upongmos que l permutin de inserin es n0 n1 n2 . . . nn2 nn1 F xotemos que l ntidd de nodos que se visitn undo se us exitosmente el nodo ni es equivlente uno ms el nmero de nodos que se visitron durnte l squed infrutuos que se reliz durnte l inserin de ni F isto slo es orreto si se sume que no hy supresionesF v useni de supresiones grntiz que los nodos nun min de lugr en el rolF odemos entones deir queX Si = Ui-1 +1 @RFRUA ehorD por l mism de(niin de promedioD podemos plnter un nuev euinX Sn =

(U0 +1) + (U1 +1) + (U2 +1) + + (Un-1 +1) n + 1 n


n1

= 1

Ui
i =0

@RFRVA

sgulmos @RFRVA on @RFRTAX

(n + 1) Un 2n n

1 = 1
n 1

+
Ui

1 n +

n1

Ui
i=0

=
@RFRWA

(n + 1) Un =
i =0

2n

ivlumos @RFRWA pr n 1 y otenemosX


n2

n Un-1 =
i =0

Ui

2(n 1)

@RFSHA

4.9. rboles binarios de bsqueda

331

estmos @RFRWA menos @RFSHAX

(n + 1 ) Un

n Un-1 = Un-1
Un

+ 2 2 = Un-1 + n+1

=
@RFSIA

vo que d un euin reurrente de Un que podemos resolver por expnsin suesiv hst el ltimo trmino U0 = 0X Un = Un-1 +

2 n+1 2 2 = Un-2 + + n n+1 ... 2 2 2 2 2 = U0 + + + + + + 2 3 n1 n n+1 1 1 1 1 1 + + + + + 2 3 n1 n n+1

= 2
v serie
n 1 i=1 i

es el nEsimo nmero rmnioF es puesX @RFSPA

Un = 2(Hn+1 1) = 2Hn+1 2 2(ln (n + 1) ) 2 1, 386 lg (n + 1)


15

ehor sustituimos @RFSPA en @RFRTAX Sn =

(n + 1)2(Hn+1 1) 2n + 1 n n+1 (2(Hn+1 1)) 1 = n n+1 1 = 2 1 1 Hn + n n+1 n+1 Hn 3 2 ln n 1, 386 lg n n

= 2

pigur RFRVX n rol inrio de squed de 512 lves letoris


15
El smbolo

denota la constante de Euler caracterizada por:

=
.

lim

(Hn ln n) 0, 5772156649 . . .

332

4. rboles

xuestro nlisis supone que no hy supresiones interlds entre ls inserionesF i ls supresiones son ejeutds despus de ls inseriones hst vir el rolD el desempeo n es O(lg n)D pues ls premiss de l proposiin RFIP n son iertsF il nlisis on supresiones interlds entre l inseriones es un prolem extremdE mente di(ultoso que l feh tul no h sido resuelto stisftorimenteF v di(E ultd estri en que l eliminin efet un deisin que no es letori undo en l unin exlusiv esoge ul ser l rz del surol resultnteF xo se se extE mente mo mnejr ls proiliddes de ls permutiones nte estos desplzmientosF edemsD es importnte notr que el lgoritmo de supresin desrrolldo en RFWFT @gF QPRA plnte un simetr importnteF gundo se suprime un nodo ompleto y se efeE t el join_exclusive()D el nodo rz del rol resultnte es el surol izquierdoF ist deisin us que el nmero de nodos por el ldo izquierdo del punto de eliminin disminuyF gonseuentementeD l rz del rol tiende desplzrse hi l izquierdD lo ul re un desequilirioF istudios emprios rrojn un longitud promedio del mino tendiente O( n)F v proposiin RFIP nos demuestr que si no se interln supresiones on inserionesD el desempeo esperdo de l squed y l inserin es O(lg n)D lo ul he un rol inrio un lterntiv stnte eptle pr implntr tls de smolos en situiones en que el orden de inserin se letorio y el nmero de supresiones interlds se reltivmente pequeoY por ejemploD l tl de smolos de un ompildorF vmentlementeD existen situiones donde el orden de inserin podr ser sesgdoF or ejemploD los pellidos en stellno estn sesgdosY prolementeD un pellido omo ven ser ms freuente que unuthF

4.10 El TAD DynMapTree


iv eh BinTree<Key>D s omo otros eh pr eff que estudiremos en el ptulo TD efetn tods sus operiones en funin de nodos y no en funin del tipo de lveF vs rzones pr esto se fundmentn en el prinipio (n (n y y hn sido duids nteriormenteF gmo se implnt un onjunto de lves mntenido por lgun lse de effc hiho de otr mnerD mo se resuelve el prolem fundmentl medinte un effc ALEPH implnt el onjunto fundmentl on roles inrios de squed de dos mnersF v primer es medinte el tipo DynSetTree<Tree,Key,Compare>D el ul insE trument un onjunto de lves de tipo Key implntdo medinte lgun lse de rol inrio de squed Tree<Key> y riterio de omprin CompareF v segund mner es medinte un lse de mpeo llmd DynMapTreeD uy difereni on DynSetTree es que l ltim gurd presY o seD mnej un onjunto rngo del mpeo o funinF odos los eh fundmentdos en eff de este texto exhien l mism interfz que el eh BinTree<Key>F or es rznD DynSetTree<Tree,Key,Compare> y DynMapTree pueden instrumentr ulquier lse de onjunto implementdo medinte roles inrios de squedF in est sein desrrollremos el ms omplejo de los eh meniondosD l lse DynMapTreeF u funin es implntr un onjunto de lves o un mpeo de lves en un dominio hi elementos en un onjunto rngo medinte un lse de effF il eh en uestin se de(ne en el rhivo tpldynwpreeFr 332 X tpl_dynMapTree.H 332

332

4.10. El TAD

DynMapTree

333

template < template <typename /* Key */, class /* Compare */> class Tree, typename Key, typename Range, class Compare = Aleph::less<Key> > class DynMapTree { Miembros privados de DynMapTree 333a Miembros pblicos de DynMapTree 334a }; Clases dinmicas derivadas de DynMapTree 335c

DynMapTree tiene utro prmetros lseF v lse Tree represent el tipo de eff on el ul se dese implntr el mpeoF intre los tipos posiles de los desrrolldos en este texto tenemos BinTree<Key>D Rand_Tree<Key>D Treap<Key>D Avl_Tree<Key>D Rb_Tree<Key> y Splay_Tree<Key>F gon exepin de BinTree<Key>D el resto de ls lses orresponde eff espeilesD on prestiones propis segn el tipo de rolD que implntn ls misms operiones que BinTree<Key>F he este modoD el usurio de DynMapTree seleionD segn sus riterios de ulidd y requerimientoD l lse de eff que dese usrF il prmetro lse Key represent el tipo de dto orrespondiente l dominio del mpeoF il prmetro Range represent el tipo de dto del rngo del mpeoF i lo que se dese es mermente mntener un onjunto de lvesD entones este prmetro se dee orresponder on un lse vY por ejemploD Empty_NodeD el ul fue de(nido y usdo pr el eh BinNode<Key>F pinlmenteD el ltimo prmetroD onstituye l lse de omprin entre lves de tipo KeyF gon lo nterior en mente podemos plnter los triutos de DynMapTreeX
333a

Miembros privados de DynMapTree 333a


Tree<Key, Compare> tree; size_t num_nodes;

(332) 333b

333b

tree es un instni de eff on lve Key y num_nodes es l ntidd de nodos que ontiene el rol treeF ist ntidd se ontiliz en ls primitivs de DynMapTree que inserten o eliminen nodos y es oservleF il eh BinTree<Key> y dems eh reliondos opern sore nodos que lmeE nn un lve genri de tipo KeyF ehor ienD pr el mpeo requerimos de un dto de ms de tipo RangeD el ul se espei( por derivin del tipo genrio Tree<Key, Compare>::NodeX Miembros privados de DynMapTree 333a + (332) 333a typedef typename Tree<Key, Compare>::Node Base_Node;
struct Node : public Base_Node { Range data; Node() {} Node(const Key & _key) : Tree<Key, Compare>::Node(_key) {} }; Range & get_data() { return data; }

334

4. rboles

334a

DynMapTree oper internmente on nodos del tipo NodeD los ules se ordenn por lve de tipo KeyD nivel del rol inrio que se utilieD pero d nodo ontiene un pr de tipo (Key, Range)F vos onstrutores por omisin y de opi pueden entones de(nirse junto on el desE trutorX Miembros pblicos de DynMapTree 334a (332) 334b DynMapTree() : num_nodes(0) {}
DynMapTree(DynMapTree & src_tree) : num_nodes(src_tree.num_nodes) { Node * src_root = (Node*) src_tree.tree.getRoot(); tree.getRoot() = copyRec(src_root); } virtual ~DynMapTree() { if (num_nodes > 0) destroyRec(tree.getRoot()); }

334b

Miembros pblicos de DynMapTree 334a +

r insertrX

(332)

334a 334c

Range * insert(const Key & key, const Range & data) { Node * node = new Node (key); node->data = data; if (tree.insert(node) == NULL) { delete node; return NULL; } ++num_nodes; } return &node->data;

334c

v rutin retorn l ntidd de nodos que tiene el rolF uesto que no se permiten elementos repetidosD est ntidd puede otejrse pr ser si ourri o no l inserinF r l elimininD slo st l lveD y st se he medinte el siguiente mtodoX Miembros pblicos de DynMapTree 334a + (332) 334b 335a size_t remove(const Key & key) { Node * node = (Node*) tree.remove(key); if (node == NULL) return num_nodes;
delete node; } return num_nodes;

remove() retorn l ntidd de elementosD lo que permiteD l igul que insert()D deterE minr si huo o no elimininF

4.11. Extensiones a los rboles binarios

335

335a

ry osiones en ls ules es desele eliminr todos los elementosF r ello usmos el mtodo empty()X Miembros pblicos de DynMapTree 334a + (332) 334c 335b void empty() { num_nodes = 0; destroyRec(tree.getRoot()); } ry dos mners de onsultrX Miembros pblicos de DynMapTree 334a + bool test_key(const Key & key) { return (Node*) tree.search(key) != NULL; } Range * test(const Key & key) { Node * p = (Node*) tree.search(key); return p != NULL ? &(p->get_data()) : NULL; }
(332) 335a

335b

335c

v primerD test_key()D se destin pr onjuntos que slo ontengn lvesD mientrs que l segundD test()D es pr mpeosF ytr mner de insertr y usr elementos es medinte el operdor []D el ul indiz lves y retorn imgenes dentro del rngoF or supuestoD este esquem slo tiene sentido si se trt de un mpeo y no de un onjunto de lvesF hel eh DynMapTree podemos espeilizr diverss lses segn el tipo de rol iE nrio de squedY por ejemploX Clases dinmicas derivadas de DynMapTree 335c (332) template <typename Key, typename Type, class Compare = Aleph::less<Key> > class DynMapBinTree : public DynMapTree<BinTree, Key, Type, Compare> {};
template <typename Key, typename Type, class Compare = Aleph::less<Key> > class DynMapAvlTree : public DynMapTree<Avl_Tree, Key, Type, Compare> {};

il segundo tipoD DynMapAvlTreeD es un mpeo sdo en roles evD un lse espeE il de rol inrio de squedD uy ltur est determinstimente otdD y que estudiremos en TFR @gF RUIAF ry ms lses segn los tipos de roles inriosF

4.11 Extensiones a los rboles binarios


iv eh BinTree<Key> y sus derivdos @ver T @gF RSIAA son idneos pr l soluE in l prolem fundmentl on ls operiones de inserinD squed y eliminin en O(lg(n))F isto es un grn pso respeto un rreglo donde l inserin y l eliminin son O(n)F in emrgoD un rreglo ordendo nos ofree l lterntiv de usr el iEsimo menor elemento en O(1)D mientrs que en un effD est operin requiere un reorrido in(jo que es O(n)F ixiste un estrutur de dtoD sd en un effD que nos permite mntener un onjunto de lves on ls siguientes operiones y sus tiemposX  snserinD squed y eliminin de un lve en O(lg(n))F

336

4. rboles

 eeso l iEsimo elemento del reorrido in(jo en O(lg(n))F il prinipio fundmentl de l estrutur de dtos suye en lmenr l rdinliE dd del rol en d nodoF r ello nos vldremos de l siguiente de(niinX n rol inrio on rngos es un rol inrio on un mpo diionl en d nodoD denotdo C(n)D que lmen l rdinlidd y el ul stisfeX
Denicin 4.10 (rbol con rangos)

 gonoimiento de l posiin in(j dd un lve en O(lg(n))F

n T,

C(n) = C(L(n)) + 1 + C(R(n)), C() = 0

n eff puede ser extendido y lo de(nimos omo sigueF


Denicin 4.11 (rbol binario de bsqueda extendido) n rol inrio de squed extendido T es un rol inrio de squed on rngosF il rnimo effi re(ere un rol inrio de squed extendidoF

336

v (gur RFRW ilustr un effiF il mpo superior es l lve y el inferior es l rdinlidd del surolF in l (gurD d nodo tiene un etiquetD que no form prte de l estrutur de dtosD orrespondiente su posiin in(jF hdo ni T | in ABBED entonesD C(L(n)) nos d l posiin in(j de ni respeto l surol on rz ni F iste es el onoimiento que nos permitir eder l rol por su posiin in(jF istmos listos pr diser un infrestrutur de striones y digo que nos mneje roles extendidosF v primer fse onsiste en de(nir l estrutur de un nodo inrio omponente de un effiD l ul se de(ne en el rhivo tplinxodetFr 336 X tpl_binNodeXt.H 336 class BinNodeXt_Data { size_t count; // cardinalidad del rbol
BinNodeXt_Data() : count(1) {} BinNodeXt_Data(SentinelCtor) : count(0) {} size_t & getCount() { return count; } const size_t & size() const { return count; }

}; DECLARE_BINNODE_SENTINEL(BinNodeXt, 255, BinNodeXt_Data); # define COUNT(p) ((p)->getCount()) Primitivas bsicas sobre BinNodeXt<Key> 337
Uses

DECLARE_BINNODE_SENTINEL.

v rdinlidd se gurd en el triuto countD el ul tiene su oservdor y modi(E dor de(nidos en l prte pli de l lse BinNodeXt<Key>F in un effi es desele utilizr un nodo entinel espeil que represente el rol voF v ventj del entinel es que su mpo count siempre es eroD lo que evit l neesidd de veri(r si el nodo edido es el nulo o no en quellos lgoritmos que pregunten l rdinliddF v rdinlidd de es 0D que es el mismo vlor de l posiin in(j de un nodo inompleto por l izquierdF il nodo entinel es un instni estti de BinNodeXt<Key>D uyo espio es reserE vdo en el mro DECLARE_BINNODE_SENTINELF

4.11. Extensiones a los rboles binarios

337

20 186 30 16 165 20 7 67 16 3 24 7 1 8 3 0 0 1 2 11 1 4 33 1 5 46 3 6 58 1 8 75 3 9 84 2 10 87 1 13 133 1 12 129 3 14 158 2 11 98 8 15 164 4 17 166 3 18 168 2 19 173 1 22 219 2 23 220 1 24 229 4 25 234 1 21 197 6 26 239 5 28 270 1 27 253 9 29 284 2

pigur RFRWX n rol inrio extendido

4.11.1

Seleccin por posicin

hdo T ABBE on rz r se dese enontrr el iEsimo elemento en l posiin in(jF v estrutur de dtosD und l uso del nodo entinelD ofree un soluin ompletmente generlD es deirD sin ningn so prtiulrD l ul se pitoriz del siguiente modoX
T C(r)
select_rec(r, i) if

if

i < C(L(r))

i > C(L(r)) + 1
select_rec(R(r), i-COUNT(LLINK(r))-1)

select_rec(L(r),i)

L(T ) C(L(r))

R(T ) C(R(r))

337

wenin prtiulr meree l llmd reursiv por l derehF qenerlmente hlndoD undo usmos por l dereh lo hemos reltivmente sore un rol que onE tiene C(R(r)) nodosD pero l posiin i de l llmd originl te un rol on C(r) nodosF heemosD puesD ompensr l llmd on l ntidd de nodos que el reorrido in(jo dej undo se v por l derehF isto esX C(L(r)) del surol izquierdo ms l rzF gon lo nteriormente expuesto omprendidoD el lgoritmo resultnte dee ser senilloX Primitivas bsicas sobre BinNodeXt<Key> 337 (336) 338a template <class Node> inline Node * select_rec(Node * r, const size_t & i) { if (i == COUNT(LLINK(r))) return r;
if (i < COUNT(LLINK(r))) return select_rec((Node*) LLINK(r), i); return select_rec((Node*) RLINK(r), i - COUNT(LLINK(r)) - 1);

338

4. rboles

338a

v versin itertiv tmin es muy senillD ms segur y muho ms e(ienteX Primitivas bsicas sobre BinNodeXt<Key> 337 + (336) 337 338b template <class Node> inline Node * select(Node * r, const size_t & pos) { for (size_t i = pos; i != COUNT(LLINK(r)); /* nada */) if (i < COUNT(LLINK(r))) r = static_cast<Node*>(LLINK(r)); else { i -= COUNT(LLINK(r)) + 1; r = static_cast<Node*>(RLINK(r)); } return r; }
4.11.2 Clculo de la posicin inja

338b

hd un lve existente en el effiD desemos lulr su posiin in(jY es deirD su orden dentro del onjunto de lvesF iste prolem se resuelve reursivmente del siguiente modoX Primitivas bsicas sobre BinNodeXt<Key> 337 + (336) 338a 338c template <class Node, class Compare = Aleph::less<typename Node::key_type> > inline int inorder_position(Node * r, const typename Node::key_type & key, Node *& p) { if (Compare () (key, KEY(r))) return inorder_position<Node,Compare>((Node*) LLINK(r), key, p); else if (Compare () (KEY(r), key)) return inorder_position<Node,Compare>((Node*) RLINK(r), key, p) + COUNT(LLINK(r)) + 1; else { p = r; return COUNT(LLINK(r)); } } v rutin reie omo entrd l rz del rol r y l lve keyF il terer prmetroD nodeD es de slid y es un nodo que ontiene l lve keyY este resultdo tiene sentido slo si l lve fue enontrdF il vlor de retorno es l posiin de key dentro del reorrido in(joF in so de que key no se enuentre en el rolD entones se retorn un vlor negtivoF
4.11.3 Insercin por clave en rbol binario extendido

338c

v inserin por lve es idnti l de un eff presentd en RFWFQ @gF QPHAD slvo que neesitmos tulizr los ontdoresX Primitivas bsicas sobre BinNodeXt<Key> 337 + (336) 338b 339 template <class Node,

4.11. Extensiones a los rboles binarios

339

class Compare = Aleph::less<typename Node::key_type> > inline Node * insert_by_key_xt(Node *& r, Node * p) { if (r == Node::NullPtr) return r = p; Node * q; if (Compare () (KEY(p), KEY(r))) { q = insert_by_key_xt<Node, Compare>((Node*&) LLINK(r), p); if (q != Node::NullPtr) ++COUNT(r); } else if (Compare ()(KEY(r), KEY(p))) { q = insert_by_key_xt<Node, Compare>((Node*&) RLINK(r), p); if (q != Node::NullPtr) ++COUNT(r); } else return (Node*) Node::NullPtr; // clave duplicada } return q;

v sintxis y semnti son ls misms que pr los effF


4.11.4 Particin por clave

339

v prtiin por lve explid en RFWFR @gF QPIA puede implntrse on l mism estrutur pr un effiX Primitivas bsicas sobre BinNodeXt<Key> 337 + (336) 338c 340a # define SPLIT split_key_rec_xt<Node, Compare> template <class Node, class Compare = Aleph::less<typename Node::key_type> > inline bool split_key_rec_xt(Node * root, const typename Node::key_type & key, Node *& l, Node *& r) { if (root == Node::NullPtr) { l = r = Node::NullPtr; return true; } if (Compare() (key, KEY(root))) { if (not SPLIT(LLINK(root), key, l, LLINK(root))) return false; r = root; COUNT(r) -= COUNT(l); } else if (Compare() (KEY(root), key)) {

340

4. rboles

} else return false; // clave duplicada } return true;

if (not SPLIT(RLINK(root), key, RLINK(root), r)) return false; l = root; COUNT(l) -= COUNT(r);

Denes:

split_key_rec_xt,
4.11.5

used in chunk 340a.

Insercin en raz

340a

gon l funin nterior podemos implntr l inserin en l rz jo el mismo esquem que l desrrolld en RFWFU @gF QPTAX Primitivas bsicas sobre BinNodeXt<Key> 337 + (336) 339 340b template <class Node, class Compare = Aleph::less<typename Node::key_type> > inline Node * insert_root_xt(Node *& root, Node * p) { if (root == Node::NullPtr) return p;
if (not split_key_rec_xt<Node, Compare>(root, KEY(p), LLINK(p), RLINK(p))) return Node::NullPtr; COUNT(p) = COUNT(LLINK(p)) + COUNT(RLINK(p)) + 1; root = p; }
Uses

return p;
split_key_rec_xt
339.

4.11.6

Particin por posicin

340b

ist operin se pree l prtiin por lveD on l exepin de que el punto de prtiin es respeto un posiin i del reorrido in(joF v prtiin result en dos roles Tl =< k1 k2 . . . kl > y Tr =< ki . . . kn >F lvo que i est fuer de rngoD es deirD i C(T )D el lgoritmo siempre tiene xitoF r est situin disemos el siguiente lgoritmo reminisente l prtiin reurE siv por lveX Primitivas bsicas sobre BinNodeXt<Key> 337 + (336) 340a 341 template <class Node> inline void split_pos_rec(Node * r, const size_t & i, Node *& ts, Node *& tg) { if (i == COUNT(r)) // Es la ltima posicin (que est vaca)? {

4.11. Extensiones a los rboles binarios

341

} if (i == COUNT(LLINK(r))) // se alcanz posicin de particin? { ts = LLINK(r); tg = r; LLINK(tg) = Node::NullPtr; COUNT(tg) -= COUNT(ts); return; } if (i < COUNT(LLINK(r))) { split_pos_rec((Node*) LLINK(r), i, ts, (Node*&) LLINK(r)); tg = r; COUNT(r) -= COUNT(ts); } else { split_pos_rec((Node*) RLINK(r), i - (COUNT(LLINK(r)) + 1), (Node*&) RLINK(r), tg); ts = r; COUNT(r) -= COUNT(tg); }

ts = r; tg = Node::NullPtr; return;

Denes:

split_pos_rec,
4.11.7

used in chunk 341.

Insercin por posicin

gonsideremos el reorrido in(jo k0 , k1 , k2 , . . . , ki1 , ki , ki+1 , . . . , kn1 F gundo insertmos kp en l iEsim posiinD el reorrido resultnte es k0 , k1 , k2 , . . . , ki1 , kp , ki , ki+1 , . . . , kn1 D es deirD prtir de l posiin iD los elementos se desplzn hi l derehY l posiin in(j kp es iD su predeesor es ki1 y su suesor es ki F il lgoritmo que proponemos es muy senillo si nos inspirmos del de inserin en l rz presentdo en RFWFU @gF QPTAX
341

Primitivas bsicas sobre BinNodeXt<Key> 337 +

(336)

340b 342a

template <class Node> inline void insert_by_pos_xt(Node *& r, Node * p, const size_t & pos) { split_pos_rec(r, pos, (Node*&) LLINK(p), (Node*&) RLINK(p)); COUNT(p) = COUNT(LLINK(p)) + 1 + COUNT(RLINK(p)); r = p; }
split_pos_rec
340b.

Uses

lvo que pos est fuer de rngoD o seD que se igul o sorepse l ntidd de elementosD l inserin siempre tendr xitoF v inserin por posiin puede violr l ondiin de orden de un effF

342

4. rboles

4.11.8

Unin exclusiva de rboles extendidos

342a

v unin exlusiv presentd en RFWFS @gF QPQA es estruturlmente idnti en su versin pr roles extendidosF vo nio que deemos modi(r es l tulizin de los ontdoresX Primitivas bsicas sobre BinNodeXt<Key> 337 + (336) 341 342b template <class Node> inline Node * join_exclusive_xt(Node *& ts, Node *& tg) { if (ts == Node::NullPtr) return tg;
if (tg == Node::NullPtr) return ts; LLINK(tg) = join_exclusive_xt(RLINK(ts), LLINK(tg)); RLINK(ts) = tg; // actualizar contadores COUNT(tg) = COUNT(LLINK(tg)) + 1 + COUNT(RLINK(tg)); COUNT(ts) = COUNT(LLINK(ts)) + 1 + COUNT(RLINK(ts)); Node * ret_val = ts; ts = tg = Node::NullPtr; // deben quedar vacos despus del join } return ret_val;

Denes:

join_exclusive_xt,
4.11.9

used in chunks 342b and 343.

Eliminacin por clave en rboles extendidos

342b

iliminr por lve en un rol extendido tmin es muy similr l estudid en RFWFT @gF QPRAD on l diin de que hy que tulizr los ontdores en el mino de squedX Primitivas bsicas sobre BinNodeXt<Key> 337 + (336) 342a 343 # define REMOVE remove_by_key_xt<Node, Compare> template <class Node, class Compare = Aleph::less<typename Node::key_type> > inline Node * remove_by_key_xt(Node *& root, const typename Node::key_type & key) { if (root == Node::NullPtr) return (Node*) Node::NullPtr; // clave no encontrada
Node * ret_val = Node::NullPtr; if (Compare () (key, KEY(root))) { ret_val = REMOVE((Node*&) LLINK(root), key); if (ret_val != Node::NullPtr) // hubo eliminacin? COUNT(root); // S ==> actualizar contador return ret_val; }

4.11. Extensiones a los rboles binarios

343

}
Uses

else if (Compare () (KEY(root), key)) { ret_val = REMOVE((Node*&) RLINK(root), key); if (ret_val != Node::NullPtr) // hubo eliminacin? COUNT(root); // S ==> actualizar contador return ret_val; } ret_val = root; // clave encontrada ==> eliminar root = join_exclusive_xt((Node*&)LLINK(root), (Node*&)RLINK(root)); return ret_val;
join_exclusive_xt
342a.

4.11.10

Eliminacin por posicin en rboles extendidos

343

i l posiin in(j es vlidD entonesD l igul que on l inserin y l prtiinD l eliminin siempre tiene xito y se de(ne omo sigueX Primitivas bsicas sobre BinNodeXt<Key> 337 + (336) 342b 345b template <class Node> inline Node * remove_by_pos_xt(Node *& root, const size_t & pos) { if (COUNT(LLINK(root)) == pos) // posicin encontrada? { // Si ==> guarde nodo y realice join exclusivo Node * ret_val = root; root = join_exclusive_xt((Node*&) LLINK(root), (Node*&) RLINK(root)); return ret_val; } Node * ret_val; // guarda valor de retorno de llamada recursiva if (pos < COUNT(LLINK(root))) ret_val = remove_by_pos_xt((Node*&) LLINK(root), pos); else ret_val = remove_by_pos_xt((Node*&) RLINK(root), pos - (COUNT(LLINK(root)) + 1)); if (ret_val != Node::NullPtr) // hubo eliminacin? COUNT(root); // Si ==> el rbol con raz root perdi un nodo
}
Uses

return ret_val;
join_exclusive_xt
342a.

4.11.11

Desempeo de las extensiones

egn l proposiin RFIP @gF QPWAD un seueni de inserin letori produe un rol que en promedio est equilirdoF gonseuentementeD si onstruimos un effi por inserin de lves letorisD entones los desempeos de funiones que no modi(quen el rol sern O(lg(n))Y este es el so de l seleinD determinin del orden in(jo y de l inserin por lveF

344

4. rboles

in el ptulo T estudiremos diverss tnis pr mntener equilirdos roles inrios de squed que mnejn O(lg(n)) en tods ls operionesF gon ulquier de ests tnisD siempre es posile mntener los rngosF

4.12 Rotacin de rboles binarios


v (gur RFSH muestr dos eff equivlentes segn l propiedd de ordenF gd uno de ellos puede otenerse prtir del otro trvs de un trnsformin llmd rotinF
p q B q A B p


(a)

(b)

pigur RFSHX otin de un rol inrio il reorrido in(jo del rol RFSH@A es (A)BD mientrs que el del RFSH@A es A(B)F v operin de rotin no fet l propiedd de orden de un effF il rol RFSH@A se otiene prtir del rol RFSH@A medinte un rotin hi l dereh u horri del nodo BF enlogmenteD el rol RFSH@A se otiene prtir del rol RFSH@A medinte un rotin hi l izquierd o ntihorri del nodo AF ry dos rterstis importntes de un rotin que ejempli(remos on l rotin hi l derehX IF il nodo A disminuye en un nivelD mientrs que el nivel del nodo B del rol originl ument en unoF PF v rm disminuye entermente en un nivelD mientrs que l rm ument entermente en un nivelF ehor vemos mo implntr l rotin hi l derehF e p l rz del rol rotrD entonesX Funciones de BinNode_Utils 243a + 327 345a template <class Node> inline Node * rotate_to_right(Node * p) { Node * q = static_cast<Node*>(LLINK(p)); LLINK(p) = RLINK(q); RLINK(q) = p; return q; }

344

rotate_to_right() retorn l nuev rz del rol luego de l rotinF gon este vlor de retorno puede tulizrse el pdre del rol resultnteF or lo generlD est primitiv se utiliz en lgoritmos reursivos que invon rotiones de surolesF r lgoritmos itertivos es ms onveniente utilizr un versin de l rotin que efete l tulizin del pdreF r ello deemos psr el pdre del surol que ser

4.13. Cdigos de Human

345

rotdoX
345a

Funciones de BinNode_Utils 243a +


{

344

template <class Node> inline Node * rotate_to_right(Node * p, Node * pp) Node *q = static_cast<Node*>(LLINK(p)); LLINK(p) = RLINK(q); RLINK(q) = p; if (static_cast<Node*>(LLINK(pp)) == p) // actualizacin del padre LLINK(pp) = q; else RLINK(pp) = q; return q;

pp es el pdre del nodo pF vs versiones por l izquierd son simtrisF


4.12.1 Rotaciones en rboles binarios extendidos

gon roles extendidos hy que tener uiddo de justr los ontdoresF etomndo el so generl de rotin ilustrdo en l (gur RFSHD tenemos un rol inrio (A)B que desemos rotrF or l de(niin de rol extendidoD tenemos queX C(B) = C() + 1 + C() + 1 + C()
|B| || |{A}| || |{B}| | |

hespus de rotr se dee umplirX C(A) = C() + 1 + C() + 1 + C()


| A| || |{B}| || |{B}| ||

345b

es puesD l primitiv de rotin hi l dereh serX Primitivas bsicas sobre BinNodeXt<Key> 337 + (336) template <class Node> inline Node * rotate_to_right_xt(Node* p) { Node * q = static_cast<Node*>(LLINK(p)); LLINK(p) = RLINK(q); RLINK(q) = p; COUNT(p) -= 1 + COUNT(LLINK(q)); COUNT(q) += 1 + COUNT(RLINK(p)); return q; }

343

4.13 Cdigos de Human


v representin de este texto onsiste en un serie de smolos ltinosD resosD grieE gos y otros ms onvenidos desde mundos de los fsios y mtemtiosF in ppelD on el deudo formtoD los smolos onformn un seueni visulmente legile por un hispno hlnteF

346

4. rboles

e l in de reduir el espio oupdo por un texto @o seueniA se le denomin omprimirF in l elorin de un texto hy un ompromiso entre l ompresin y l legiiliddF in rs de l legiilidd se sri( l ompresinD y s es omo dee serF iD por ejemploD l letr es muy pequeD usmos menos espioD ppelD pero el texto se he menos legileF or el ontrrioD si l letr es muy grndeD entones requerimos ms espioD ergoD ms ppel o pntllF in l representin iernti de los smolos de un texto se us un digo de itsF in nuestrs irunstnisD un digo es un uerdo de representin de smolos medinte ominiones de itsF n ejemplo notle lo onstituye el digo egssD el ul mpe seuenis de siete its un smoloF re en l siguiente tl lguns de sus ourrenisX
molo e {
unicodeD

lor finrio
1000001 1100010 1111011

lor deiml
65 98 123

ry otros sistems de odi(in de rteresD de los ules uno muy notle es el extensileD de seuenis de longitud vrile y on l pretensin de servir todos los smolos de tods ls lengusF hesignemos omo el onjunto de todos los posiles smolos que puede ontener un textoF in este so podemos odi(r los || smolos on lg || itsF eorddo el digoD ulquier gente @o progrmA puede interpretr un textoF i onsidermos un texto prtiulr Tx uyos smolos se remiten un onjunto S D entones podrmos odi(rlo on lg |S| lg || itsF r ello onstruimos un tl mpeo de smolos seuenis de its y nos servimos de ell pr interpretr el textoF enemos qu un primer form de ompresinF in emrgoD este mtodo tiene l eventul desventj de que el texto dee leerse por ntiipdo efetos de onstruir l tlF isto puede ser prolemtio en lguns irunstnisD l letur de un rhivoD por ejemploY y prohiitivo en otrsD l trnsmisin de un textoF ytro inonveniente del enfoque nterior es que d smolo oup l mism ntiE dd de itsD independientemente de su freueni de priin en el textoF i ussemos seuenis de longitud vrileD entones podrmos esoger seuenis muy orts pr smolos muy freuentes y dejr ls ms lrgs pr smolos de rr priinF v ide es seleionr los smolos de un itD luegoD los de dosD y s suesivmente segn un freuente se l priin del smolo en el textoF or ejemploD el lnoD denotdoD pr distinguirloD omo  D y l D que son muy freuentesD podrn ser l seuenis 0 y 1 respetivmenteY mientrs que l eD iD  y  podrn denotrse omo 00D 01D 10 y 11F odrmos ontinur on seuenis ms lrgs hst rr ompletmente el onjunto SF ero sD en rutoD este enfoque plnte un migedd inslvle expresd por insE tni prtiulr en l seueni 001D pues no se puede distinguir si se trt de   o e o  iF v migedd nterior se solvent siD en detrimento de l ntidd de ominiones posiles de itsD usmos un digo pre(joD en el sentido de l de(niin RFV 16 D es deirD que ningun seueni si de longitud i se pre(j de lgun otr de rdinlidd superiorF i esogemos permutiones de seuenis pre(jsD entones podemosD sin prolem lgunoD
16
En la seccin 4.8.0.7 (Pg. 302) se usaron los smbolos  a por  0 y  b por  1.

4.13. Cdigos de Human

347

distinguirls e interpretrls en un textoF ws nD podemos utilizr seuenis de hikD ls ulesD omo orolrio de ls proposiiones RFU y RFIHD son pre(jsF ry un mejor n ms sustnil en usr un odi(in pre(jX podemos mper en O(1)D en lne on l letur del textoD su deodi(inF r elloD usmos un rol inrio uys hojs odi(n los smolos de SF or ejemploD pr S = { , a, e, i, b, c}D ulquier rol inrio de 6 hojs odi( SY un ourreni se muestr en l (gur RFSIF

molo
b c

gdigo
000 001 010 011 10 11

e i

pigur RFSIX rol odi(dor de S = { , a, e, i, b, c} y su mpeo

4.13.1

Un TAD para rboles de cdigo

347a

in el ontexto de l odi(inD siempre podemos distinguir dos gentesX uno odi(dorD que tom un texto y lo omprimeD y otro deodi(dorD que tom el texto omprimido y lo deodi( l seueni originlF r odi(r usremos l siguiente lseX Clase codicadora 347a class Huffman_Encoder_Engine {
};

miembros privados de codicador 347c miembros pblicos de codicador 351a

347b

ist lse se enrg de onstruir un rol de pre(jos ptimo y de odi(r textos en funin del rol nteriorF or ptimo pretendemos deir que un texto odi(do on los pre(jos del rol ptimo oup el menos espio posileF r deodi(r usremos l siguiente lseX Clase decodicadora 347b class Huffman_Decoder_Engine {
};

miembros privados de decodicador 348a miembros pblicos de decodicador 349d

347c

vs lses y otrs de(niiones se enuentrn en el rhivo ru'mnFr (never dened) F godi(r y deodi(r un seueni requiere de vris estruturs de dtosF v primer de ells es el propio rol de digosD el ul se de(ne del siguiente modoX miembros privados de codicador 347c (347a) 348f BinNode<string> * root;
Uses

BinNode

240.

348

4. rboles

348a

miembros privados de decodicador 348a


BinNode<string> * root;
BinNode
240. Uses

(347b)

348b

root esD en ms lsesD l rz de un rol de pre(josF osteriormente detllremos un lgoritmo pr onstruir este rol de mner ptim @ RFIQFQ @gF QSHAAF hel mismo modoD tmin plnteremos un riterio de e(ieni y demostrremos su optiE min @ RFIQFT @gF QSSAAF in el nterin hy que selr que el rol uy rz es root ontiene dens @stringA y no smolos egssF v rzn es que en lugr de smolos puntules puede estleerse lgun freueni de priin de frses enters y odi(rse entermente en un seueni de itsF xeesitmos un tl de smolos en l ul lmenemos sus freuenis de priE in y que nos permit onstruir un rol de pre(josF il tipo de est tl se de(ne sX Declaraciones Human 348b 348c
class Huffman_Node; typedef DynMapTree<Treap_Vtl, string, Huffman_Node *> Symbol_Map;

348c

v tl mpe smolos de tipo string nodos de un hep que usremos pr determinr ptimmente los pre(josF il prmetro Treap_Vtl es un lse espeil de rol inrio de squed llmdo repD el ul ser trtdo en TFQ @gF RTRAF i tenemos lgun di(ultd en eptr el tipo Treap_VtlD entones podemos utilizrD on l mism interfzD y prolemente on desempeo similrD el tipo BinTreeVtl previmente estudido en RFWFP @gF QIWAF or rzones que expliremos prontmenteD un rol de pre(jos se onstruye prtir de un hep del ul sus nodos son de tipo Huffman_Node y se de(nen de l siguiente formX Declaraciones Human 348b + 348b 348d typedef BinNode< Aleph::pair<string, size_t> > Freq_Node; struct Huffman_Node : public BinHeap<size_t>::Node { BinNode<string> * bin_node; };
Uses

BinNode

240.

348d

qrosso modoD Huffman_Node es un nodo inrio de un hep uy lveD edid medinte get_key()D es l freueni de priin o estdsti de un smoloF il nodo en uestin ontiene un puntdor un nodo dentro del rol de pre(josF il tipo de hep se de(ne de l siguiente mnerX Declaraciones Human 348b + 348c 348e typedef BinHeap<size_t> Huffman_Heap; in funin de este tipo de(nimos ls siguientes funiones uxiliresX Declaraciones Human 348b + 348d 349a static inline const size_t & get_freq(Huffman_Node * huffman_node) static inline void increase_freq(Huffman_Node * huffman_node) static inline void set_freq(Huffman_Node * huffman_node, const size_t & freq) ehor podemos de(nir el hep dentro del odi(dor y su tl de smolosX miembros privados de codicador 347c + (347a) 347c 349b Huffman_Heap heap; Symbol_Map symbol_map;

348e

348f

4.13. Cdigos de Human

349

349a

or ejemploD symbol_map["a"].get_key() retorn l freueni soid l smE olo "a"F v ltim estrutur de dtos es l tl de digosD l ul requiere l de(niin del siguiente tipoX Declaraciones Human 348b + 348e typedef DynMapTree<Treap_Vtl, string, BitArray> Code_Map;
Uses

BitArray

54a. (347a) 348f 349c

349b

miembros privados de codicador 347c +


Code_Map code_map;

ist tl se utiliz pr odi(r un textoF v ide es leer seuenilmente el texto y enontrr en l tl de digos el orrespondiente digo fetos de generr el texto odi(doF el igul que on l tl de smolosD l de digos se implement on un rep @ TFQ @gF RTRAAF ry otros triutos diionles que usremos en l lse Huffman_Encoder_EngineX
349c

miembros privados de codicador 347c +


string end_symbol; size_t text_len;

(347a)

349b 351b

end_symbolD que tmin se utiliz en Huffman_Decoder_EngineD es un smolo esE peil que denot l (nlizin de un textoY su de(niin oyud determinr undo ulmin un seueni de its orrespondiente un texto odi(doF text_len en l longitud del texto sin odi(rF
4.13.2 Decodicacin

349d

el to queD ojetivmenteD hemos denomindo interpretrD lo podemos denotr omo deodi(rF he este modoD sumiendo un rz root de un rol de pre(jos y un puntero pD de l siguiente form podemos deodi(r un seueni bit_stream de bit_stream_len its medinte l siguiente rutinX miembros pblicos de decodicador 349d (347b) void decode(BitArray & bit_stream, ostream & output) { const size_t & bit_stream_len = bit_stream.size(); BinNode<string> * p = root; for (int i = 0; i < bit_stream_len; ++i) { if (bit_stream.read_bit(i) == 0) p = LLINK(p); else p = RLINK(p);
if (is_leaf(p)) // es hoja? { // s ==> escribir smbolo y reiniciar a raz const string & symbol = p->get_key(); if (symbol == end_symbol) // se alcanza final? break; output  symbol;

350

4. rboles

}
Uses

p = root; // reiniciar a raz, pues se leer un nuevo cdigo

BinNode

240 and

BitArray

54a.

v ide es prtir desde l rz del rol yD segn el vlor de it ledoD desender hi l izquierd o dereh hst deprr en lgun hoj17 F in ese entonesD el pre(jo ledo se orresponde on un smoloF es puesD pr deodi(r un seueni de itsD el usurio dee instnir un ojeto de tipo Huffman_Decoder_EngineD uyo onstrutor reie l rz del rol digo y el smolo onsiderdo omo (n de l entrdF vuegoD se invo l mtodo decode()D el ul rroj su slid l prmetro outputF gonoido el rolD el proeso de deodi(in es reltivmente senilloF
4.13.3 Algoritmo de Human

350a

hdo un onjunto de n smolos queremos onstruir un rol de digos de extmente n hojsF riendo strin de que ests hojs fungen de nodos externosD entonesD por l proposiin RFPD ulquier rol de n 1 + n = 2n 1 nodosD on ulquier permutin de smolos omo hojsD onstituye un rol de digosF or l proposiin RFII semos que 1 2(2n1) diferentes roles de digoF urgen entones ls preguntsX existen C2n1 = 2n 2n1 ul esogercD mo onstruirloc ru'mn VI desuri un mtodo pr onstruir un rol de pre(jos el ul prte de un onjunto iniido on los smolos y sus freuenis de priinF is deirD un onjunto de nodos del tipo Huffman_Node y desritoF vlmemos este onjunto heapD el ul se implnt medinte un hepF r onstruir un nuevo nodo huffman_nodeD primero hy que seleionr los dos nodos on menores freuenis de l siguiente formX sacar del heap los dos nodos de menor frecuencia 350a (351a) Huffman_Node * l_huffman_node = (Huffman_Node*) heap.getMin(); // izq Huffman_Node * r_huffman_node = (Huffman_Node*) heap.getMin(); // der gon estos dos nodos se onstruye un surol de ru'mn de l siguiente formX crear un nuevo nodo de Human 350b (351a) BinNode <string> * bin_node = new BinNode <string>; Huffman_Node * huffman_node = new Huffman_Node (bin_node); LLINK(bin_node) = l_huffman_node->bin_node; RLINK(bin_node) = r_huffman_node->bin_node; const size_t new_freq = get_freq(l_huffman_node) + get_freq(r_huffman_node); Aleph::set_freq(huffman_node, new_freq);
Uses

350b

BinNode

240.

il nuevo nodo se onstruye omo pdre de los dos menores ontenidos en el hepF smportnte notr que el nuevo surol es de tipo BinNode<string>D que es el tipo del rol de ru'mn y no de tipo Huffman_NodeF
17
Notemos que un prejo guarda remembranza con el nmero de Deway de la hoja.

4.13. Cdigos de Human

351

351a

v mner de(nitiv pr onstruir un rol de pre(jos se efet sX miembros pblicos de codicador 351a (347a) 352a BinNode<string> * generate_huffman_tree( ) { while (heap.size() > 1) // hasta que quede solo un nodo {
delete l_huffman_node; delete r_huffman_node; heap.insert(huffman_node); } // nodo que queda en heap es la raz del rbol de prefijos Huffman_Node * huffman_root = (Huffman_Node *) heap.getMin(); root = huffman_root->bin_node; delete huffman_root; build_encoding_map(); // construir mapeo de cdigos }
Uses

sacar del heap los dos nodos de menor frecuencia 350a crear un nuevo nodo de Human 350b

return root;
BinNode
240.

351b

n vez que se gener el rol de ru'mn deemosD efetos de odi(rD geE nerr el mpeo de smolos digos pre(josF ist tre l efet l primitiv build_prefix_encoding()D l ul se instrument medinte un reorrido pre(jo sore el rol de ru'mnX miembros privados de codicador 347c + (347a) 349c 351c void build_prefix_encoding(BinNode<string> * p, BitArray & array) { if (is_leaf(p)) { const string & str = p->get_key(); code_map.insert(str, BitArray(array)); return; } array.push(0); build_prefix_encoding(LLINK(p), array); array.pop(); array.push(1); build_prefix_encoding(RLINK(p), array); array.pop(); }
Uses

BinNode

240 and

BitArray

54a.

351c

v rutin se orresponde on un reorrido pre(joD reursivoD del rol de ru'mn on rz rootF e medid que se v reorriendoD el pre(jo de root18 se v mnteniendo en el rreglo de its array y su longitud se mntiene en el prmetro lenF gundo se lnz un hojD es deirD undo y tenemos el pre(jo ompleto del smoloD insertmos en el mpeo code_map l dupl <smoloD array>F build_prefix_encoding() es tivd por l siguiente primitivX miembros privados de codicador 347c + (347a) 351b 352c void build_encoding_map() { BitArray array(0); symbol_map.empty();
18
Vale la pena recordar que este prejo es una palabra de Dick (vase 4.8.0.8 (Pg. 306)).

352

4. rboles

}
Uses

build_prefix_encoding(root, array);
BitArray
54a.

10

10

17

4
i c

6
b

10
e

15

16
a

4
i c

6
b

10
e

15

16
a

4
i c

6
b

10
e

15

16
a

58

25

25

33

25

33

10

15

16
a

17

10

15

16
a

17

10

15

16
a

17

4
i b

6
b

10
e

4
i b

6
b

10
e

4
i b

6
b

10
e

pigur RFSPX gonstruin de un rol de ru'mnF vs res de los suroles se enE uentrn en el hep il orden de mnipulin de l lse Huffman_Encoder_Engine es omo sigueX IF he(nir smolos on sus freuenis PF qenerr rol de pre(jos QF godi(r textos in est sein hemos llevdo o l segund fseF v primer ser explid en l siguiente suseinD mientrs que l terer ser explid en RFIQFS @gF QSQAF
4.13.4 Denicin de smbolos y frecuencias

352a

entes de onstruir el rol de pre(jos segn el lgoritmo nterior deemos indir los smolos y sus respetivs freuenisF ry dos mners de herloF v primer onsiste en espei(r diretmente el smolo y su orrespondiente freueniD lo ul se he medinte set_freq(str, freq)D donde str es el smolo de(nir y freq su freueni soidF il mtodo en uestin se espei( omo sigueX miembros pblicos de codicador 351a + (347a) 351a 352b void set_freq(const string & str, const size_t & freq) v otr form de indir freuenis es prtir de un textoD identi(r sus smolos y ontilizr sus freuenis de priinF isto se he medinte read_input(input)D donde input es el texto prtir del ul se dese ontilizr ls freuenisX miembros pblicos de codicador 351a + (347a) 352a 353b void read_input(char * input )

352b

read_input() suye sore l rutin update_freq(curr_token)D l ul se remite usr curr_token en el mpeo de smolosD rer un nuev entrd si no est mpedoD inrementr en uno l freueni y tulizr el hepX
352c

miembros privados de codicador 347c +


void update_freq(const string & str)

(347a)

351c 354

4.13. Cdigos de Human

353

Huffman_Node * huffman_node = NULL; Huffman_Node ** huffman_node_ptr = symbol_map.test(str); if (huffman_node_ptr == NULL) // smbolo definido previamente? { // No ==> crear una entrada en symbol_map e insertarlo en heap unique_ptr<BinNode<string> > bin_node_auto(new BinNode<string>(str)); huffman_node = static_cast<Huffman_Node*> (heap.insert(new Huffman_Node(bin_node_auto.get()))); symbol_map.insert(str, huffman_node); bin_node_auto.release(); } else huffman_node = *huffman_node_ptr; // ya definido, recuperarlo increase_freq(huffman_node); heap.update(huffman_node);
BinNode
240.

}
Uses

353a

uesto que el (n de los mtodos read_input() es mirr ls freuenis y onstruir l entrdD stos ulminn on l generin del rol de digosX Generar rbol 353a set_end_of_stream(""); generate_huffman_tree(with_freqs);
4.13.5 Codicacin de texto

353b

n vez onstruido un rol de ru'mn podemos odi(r el texto medinte ulquier de los mtodos encode(input, bit_stream)F input es el texto odi(r y bit_stream es un BitArray del tipo de(nido en PFIFS @gF SQAX miembros pblicos de codicador 351a + (347a) 352b size_t encode(char * input, BitArray & bit_stream) { char * curr_stream = input; char curr_token[Max_Token_Size]; curr_token[1] = '\0'; while (*curr_stream != '\0') { curr_token[0] = *curr_stream++; append_code(bit_stream, code_map[curr_token]); } append_code(bit_stream, code_map[""]);
}
Uses

return bit_stream.size();
BitArray
54a.

il segundo prmetro de encode() es el rreglo de its que ontiene el texto odi(doF il proesoD un vez generdo el mpeo on los pre(josD es muy senilloX usr el smolo ledo en el mpeo y ontenr l rreglo de its el pre(joF l tre l efet l primitiv

354

4. rboles

Muerte De Antoito El Camborio Federico Garca Lorca Voces de muerte sonaron cerca del Guadalquivir. Voces antiguas que cercan voz de clavel varonil. Les clav sobre las botas mordiscos de jabal. En la lucha daba saltos jabonados de delfn. Ba con sangre enemiga su corbata carmes, pero eran cuatro puales y tuvo que sucumbir. Cuando las estrellas clavan rejones al agua gris, cuando los erales suean vernicas de alhel, voces de muerte sonaron cerca del Guadalquivir. Antonio Torres Heredia, Camborio de dura crin, moreno de verde luna, voz de clavel varonil: quin te ha quitado la vida cerca del Guadalquivir?

Mis cuatro primos Heredias hijos de Benamej. Lo que en otros no envidiaban, ya lo envidiaban en m. Zapatos color corinto, medallones de marl, y este cutis amasado con aceituna y jazmn. Ay Antoito el Camborio, digno de una Emperatriz! Acurdate de la Virgen porque te vas a morir. Ay Federico Garca, llama a la Guardia Civil! Ya mi talle se ha quebrado como caa de maz. Tres golpes de sangre tuvo y se muri de perl. Viva moneda que nunca se volver a repetir. Un ngel marchoso pone su cabeza en un cojn. Otros de rubor cansado, encendieron un candil. Y cuando los cuatro primos llegan a Benamej, voces de muerte cesaron cerca del Guadalquivir.

pigur RFSQX n texto de qr vor privd append_code()X


354

miembros privados de codicador 347c +

(347a)

352c

static void append_code(BitArray & bit_stream, const BitArray & symbol_code) { const size_t symbol_code_size = symbol_code.size(); for (int i = 0; i < symbol_code_size; i++) bit_stream.push(symbol_code[i]); }
BitArray
54a.
1297

Uses

511

786

243

268

355

431

119 124 e a 60

125

143

175

180

208

223

65 n

66

77 r

86 o 45

94

101

107

110

113

29 m

31

33 t

33

49 u

49

52 53 c d

54

55 55 56 57 l s i

\n

15 b 8

16

16 . 8 8

17

22

23

24

25

26 v

28

11 11 g p

11

12 q

12

12

12

13

13 ,

15

4 V 2 2

5 C

5 h

6 A 3 f B 3

6 z

6 3 L 1 Z H 2 3

6 y

7 G

7 j

2 Y

2 1 D 1

2 F

2 !

2 T

2 M

2 E

1 ? 0

1 U 1 O

1 :

pigur RFSRX rol de ru'mn del texto de qr vor de l (gur RFSQ

4.13. Cdigos de Human

355

il rol de l (gur RFSR omprime el texto mostrdo en l (gur RFSQ 5942 ytesF
4.13.6 Optimacin de Human

reguntmosnosD es un rol de ru'mn ptimoc19 r onfrontr l pregunt deemos plnternos un riterio que nos pondere el oste de un smolo en funin de su freueni de priin y que nos onduz un form generl y ni de desurir el mejor rol de digosF e un rol inrio T en el ul d hoj ne T se le sign un oste o ponderin w(ne )F intonesD l longitud ponderd del minoD denotd omo wpl(T )D se de(ne omoX
Denicin 4.12 (Longitud ponderada del camino)

wpl(T ) =
ne es hoja

nivel(ne ) w(ne )

@RFSQA

r el rol de l (gur RFSSE tenemosX wpl(T ) = 2 (7 + 6) + 3 (15 + 16 + 10 + 4) = 161

13

7 b 15 16 a 10 e 4 i

6 c 15 16 a 10 e 4 i

=
c

(a) rbol de cdigos anterior

(b) Anterior sin hojas b y

pigur RFSSX roles pre(jos ejemplo gunto menor ltur teng un hojD menor ser su inideni sore el wplF v ide es onstruir un rol de digos uyo wpl(T ) se mnimoY este es el riterio de optiminF l rol se denomin de ru'mn en honor su desuridorD quien desuri l siguiente proposiinX
19
Segn D.R.A.E., optimacin signica

in y efeto de optimr .

El verbo optimar

-u

optimizar- connota, D.R.A.E. dixit, buscar la mejor manera de realizar una actividad .

Ahora bien,

en el estricto sentido de universalidad, existe una mejor manera de llevar a cabo una actividad?. Responder armativamente y dar cuenta sobre la supuesta mejor manera, es muy delicado. Si para un cierto asunto asumimos y mostramos una optimacin, entonces, en el asunto en cuestin, jams regresaramos a mejorarlo; para qu, si el ptimo ya es el mejor?. Lo que es mejor es relativo a las circunstancias, y stas ataen al momento, al lugar, pero, sobre todo, a quines. Asumir optimacin sin consideracin circunstancial conlleva peligro para las partes del contexto que no fueron sopesadas. Quiz un indicio del desdn que a menudo conlleva una optimacin se encuentra en su raz etimolgica. En latn

opt %mos

connotaba aristocrtico, perteneciente a los

opt %mtes ,

quienes eran los miembros

del senado romano, los precursores de los oligarcas de nuestra poca. Tal parece que en la antigua Roma, los que gozaban de plenos derechos, quienes tenan mayor capacidad de eleccin, o sea, eran los nobles.

optaban (opt tus ),

356

4. rboles

Proposicin 4.13 (Optimacin de Human - Human 1951 [80]) e N = {n1 , n2 , . . . , nn } un onjunto de nodos on pesos w(n1 ), w(n2), . . . , w(nn )F e T un rol pre(jo onstruido segn el lgoritmo de ru'mn @ RFIQFQ @gF QSHAAF intonesD T = T = wpl(T ) wpl(T )F vo nterior equivle deir que el rol de pre(jos T es mnimo segn su longitud ponderd del minoF

v prue se onstruir por induin sore l rdinlidd de T D y se vldr del siguiente lemF
Demostracin

e T un rol on pesos en sus hojsF en n1 y n2 ls dos hojs de T on peso mnimoF gonsideremos un rol T tl que ste onteng ls misms hojs que T D exepto que ls hojs n1 y n2 se sustituyen por un hoj n+ on w(n+ ) = w(n1 )+ w(n2 )F intonesD es posile onstruir un rol T tl que20 X
Lema 4.5

wpl(T ) wpl(T ) w(n+ )

@RFSRA

or ejemploD l (gur RFSSE ilustr un T posile en el ul se le suprimen ls hojs b y cF in este soD wpl(T ) = 13 + 3 (15 + 16 + 10 + 4) = 148
Demostracin

ry tres posiles situiones onsiderr pr n1 , n2 T X

IF n1 y n2 son hermnosX en este so los suprimimos y ponemos en su pdre n3 D que deviene en hojD w(n3 ) = w(n1 ) + w(n2 )F in este rolD n3 est en un nivel inferior i 1D por lo que wpl(T ) = wpl(T ) i (w(n1 ) + w(n2 )) + (i 1) (w(n1 ) + w(n2 ))

= wpl(T ) (w(n1 ) + w(n2 ))


w(n3 )

el ul di(ere extmente de wpl(T ) en w(n3 )F PF n1 y n2 estn en el mismo nivelX summos s1 omo el hermno de n1 @el so es simtrio on n2 AF intones podemos intermir s1 on n2 y s deprr en el so nteriorF QF n1 y n2 estn en niveles distintosX l igul que en el punto nteriorD summos s1 omo el hermno de n1 F hel mismo modoD summos que nivel(n1 ) > nivel(n2 )F odemos pitorizr est situin del modo mostrdo en l (gur RFSTF gonsideremos l inideni que tiene el surol s1 sore wpl(T )D l ul puede expresrse sX (s1 ) = w(nx ) nivel(nx )
nx hoja(s1 )

gundo hemos el intermio entre s1 y n2 D el vlor de (s1 ) disminuye (s1 )D pues nivel(s1 ) = nivel(n1 ) en T F or tntoD wpl(T ) = wpl(T ) + nivel(n1) w(n2 ) (s1 ) + (s1 ) wpl(T )
Es esencial distinguir la condicin de posibilidad en el enunciado del lema, es decir, puede encontrarse

20

una disposicin topolgica con los nodos restantes que satisfaga la desigualdad.

4.13. Cdigos de Human

357

n2 p s1 n1 p s1

intercambiamos n2
n2 con s1

n1

pigur RFSTX isquem de prue del terer so de l demostrin del lem RFS il so en que son igules es undo s1 es un hojF ehorD undo efetumos l fusin de n1 y n2 en n+ D regresmos l situin del primer soX wpl(T ) = wpl(T ) + (nivel(n1 ) 1) (w(n1) + w(s)) (s1) + (s1 )

wpl(T ) w(n+ )

il so undo nivel(n1 ) < nivel(n2 ) es simtrio iste lem es el fundmento mostrtivo que nos permitir evidenir que pr ulquier rol T T = wpl(T ) wpl(T )F etomemos l demostrin de l proposiin y plnteemos induin sore l rdiE nlidd del rol de ru'mn T X IF r |T | 2 el resultdo es diretoF PF ehor summos que l proposiin es iert pr todo rol de ru'mn y veriE (quemos su veridd pr Tn+1 Y es deir Tn+1 = Tn+1 = wpl(Tn+1 ) < wpl(Tn+1 )F en n1 y n2 ls dos primers hojs que seleion el lgoritmo de ru'mnF ehor onsideremos plir el lem RFS Tn+1 y Tn+1 on los nodos n1 y n2 y produir dos roles Tn y Tn F

uesto que n1 y n2 son los nodos on menos pesoD stos son hermnos en el rol de ru'mnF or tntoD wpl(Tn ) = wpl(Tn+1 ) w(n1 ) w(n2 )21 F r el rol Tn semosD segn el lem RFSD que wpl(Tn ) wpl(Tn+1 ) (w(n1 ) + w(n2 ))F ehor ienD unque quiz prez ovioD |Tn | = |Tn | < |Tn+1 | = |Tn+1 |F or tntoD podemos plir l hiptesis indutiv pr onluir que wpl(Tn ) wpl(Tn )
4.13.6.1 Conclusin

epitulemos el uso del lgoritmo de ru'mn medinte l dos lses que mos de presentrF il ente odi(dor se vle de un instni de Huffman_Encoder_EngineD mienE trs que el deodi(dor de su ontrprte de Huffman_Decoder_EngineF yvimenteD ms instnis deen ponerse de uerdo en usr el mismo rol de ru'mnF in emE rgoD qu pree un detlle interesnteX pr odi(r o deodi(r el texto no he
21
Esto se evidenci en la primera parte de la demostracin del lema 4.5.

358

4. rboles

flt el rol de ru'mnF isto es evidente en el odi(dorD puesD ste se remite leer los smolos del texto yD trvs del mpeo de digosD emitir los orrespondientes pre(josF eroD mo hr el deodi(dorc v respuest est dd por l teor de pre(jos imprE tid en RFVFHFU @gF QHPAF in efetoD un texto odi(do es un seueni de plrs de hik @ RFVFHFV @gF QHTAAD el ulD omo orolrio de l proposiin RFU @pgin QHQAD es pre(joF isto impli queD dd un seueni de pre(josD podemos reonoerlos entre sF v tni en uestin se deleg ejeriioF

4.14 rboles estticos ptimos


vos roles inrios son disedos pr emulr l squed inriF u ondd prinipl es que permiten inseriones y supresiones en O(lg(n))F ehor ienD si el onjunto de lves fuese esttioD es deirD no ourre inseriones ni supresionesD esD por ejemploD un rol inrio de ltur mnim e(ientec gonsideremos disponer ls lves en un rreglo ordendo y efetur l squed inriF gon este enfoque tenemos un rol de longitud de mino mnimoF edemsD horrmos espioD pues no requerimos utilizr punterosF gomo punto (nlD deemos remrr que el rreglo proveh los hes del omputdorF v squed inri sume que l freueni de eso es equittiv pr tods ls lves y esto no es ierto en lgunos sosF elguns lves se eden ms que otrsF ry situiones en que l freueni estdsti de eso puede onoerse ntes de onstruir el rolF in estos sosD un riterio de optimlidd onsiste en minimizr l ntidd totl esperd de squedsF sntuitivmenteD est minimizin se logr olondo los nodos de eso ms freuente ernos l rzF il onepto que nos permitir enontrr roles ptimos suye en l de(niin siguienteX
Denicin 4.13 (Longitud del camino interna ponderada)

dosF e P = {pi | pi es el peso del nodo ni T | mino intern ponderd se de(ne omoX
n

e un rol T de n noE p = 1 } F intonesD l longitud del i i

Ci ( T ) =
i=1 n

(nivel(ni ) + 1)pi
nivel(ni ) pi
i=1

@RFSSA

z y x

x y z x y z

x z y x y

(a)

(b)

(c)

(d)

(e)

pigur RFSUX roles inrios de squed de tres nodos hdo un onjunto de n lves on sus proiliddes de esoD el prolem onsiste en enontrr un rol de n nodos uyo Ci se mnimoF hiho de otro modoD ulD entre

4.14. rboles estticos ptimos

359

todos los posiles roles de n lvesD tiene el Ci mnimoc gomo ejemplo onsideremos el onjunto de nodos {X, Y, Z} on pesos {1/9, 3/9, 5/9}F egn l proposiin RFII existen 1 6 4 3 = 5 mners de disponer tres nodos en un rol inrio de squedD ls ules se ilustrn en l (gur RFSUF vs longitudes de mino ponderds pr d rol sonX

Ci

(a) (b) (c)

Ci

Ci Ci

(d) ( e)

Ci

1 3 5 14 = 3 +2 + = 9 9 9 9 1 3 5 21 = 1 +2 +3 = 9 9 9 9 1 3 5 15 = 2 + +2 = 9 9 9 9 1 3 5 20 = +3 +2 = 9 9 9 9 3 5 16 1 = 2 +3 + = 9 9 9 9

isto rroj l rol @A omo el ptimoD resultdo sorprendente y reveldor de que lo ptimo no neesrimente es lo trdiionlmente uenoD puesD en nuestro ejemploD el rol ptimo es el ms desequilirdo segn los riterios trdiionlesF il ejemplo nterior nos d un ide er de ls omplejiddes inherentes un lgoE ritmoF odrmos generr todos los roles de squed posiles on n lves y entones medir ls longitudes de mino ponderds pr seleionr l menorF yvimenteD est tni es muy ostos en tiempo y espioF il primer pso hi l onseuin de un lgoritmo es prehender que si un rol es ptimoD entones sus dos rms tmin lo sonF pormlizmos este heho en l siguiente proposiinX
Proposicin 4.14

R(T ) son ptimosF

e T B un rol inrio de squed ptimoF intonesD L(T ) y

Demostracin (Por contradiccin)

X e k1 , k2 , . . . , kl , . . . , kn el reorrido in(jo de un T ABB generl de n nodos on rz en lve kl F he este modoD L(T ) ontiene ls lves {k1 , k2 , . . . , kl1 } y R(T ) ls lves {kl+1 , . . . , kn }F odemos entonesD segn l de(niin RFIQD plnter Ci en funin de l rz kl D del siguiente modo22 X
l1 n

Ci (T ) = pl +
i =1

(nivel(ki ) + 1)pi +
i=l+1 l1

(nivel(ki ) + 1)pi
n

= pl + Ci (L(T )) +
i =1 n

pi + Ci (R(T )) +
i=l+1

pi
@RFSTA

=
i =1

pi + Ci (L(T )) + Ci (R(T ))

upongmos que el rol ptimo ontiene un L(T ) o R(T ) que no es ptimoF in este soD segn @RFSTAD Ci (T ) umentr de vlorD lo que ontrdie l suposiin de que T es ptimoF v proposiin esD puesD verdder
22
Recordemos que un nivel en L(T ) o R(T ) est desfasado en uno respecto a T . Por esa razn, n (ki )pi , en donde (ki ) se reere a T , es Ci (L(T )); el razonamiento es el mismo para Ci (R(T )) i=l+1 (

nivel

nivel

360

4. rboles

4.14.1

Objetivo

hdo un rreglo ordendo K = [k1 , k2 , . . . , kn ] de n lves y un rreglo prlelo P = [p1 , p2 , . . . , pn ] de proiliddes de esoD el prolem onsisteD reursivmente hlndoD en determinr ul lve kl D entre ls n posilesD dee olorse omo rz del rol (nl T F n vez que se hg est seleinD el resto de ls lves que irn en L(T ) y R(T ) qued totlmente de(nidoD pues sts deen stisfer l propiedd de orden de un rol inrioF vos suroles se onstruirn reursivmente plindo el mismo prinE ipio sore [k1 , k2 , . . . , kl1 ] y [p1 , p2 , . . . , pl1 ] pr L(T ) y [kl+1 , . . . , kn ] y [pl+1 , . . . , pn ]D pr R(T )F j isto nos ondue un de(niin reursiv del ostoX se pi,j = l=i pl y Ci,j el osto totl del rol inrio ptimo ompuesto por ls lves que vn desde ki hst kj F intonesX

Ci,j = min
l=i

pi,l1 (1 + Ci,l1 ) +
rbol izquierdo

pl
kl como raz

+ pl+1,j (1 + Cl1,j )
rbol derecho

1 pi,j

@RFSUA

il proedimiento es exponenil si lo plimos diretmenteF xo ostnteD los roles +1 ) ptimos deen stisfer l propiedd de orden yD en este sentidoD existen lo sumo n(n 2 diferentes mners de distriuir el onjunto K en un rol inrioF odemos entones diser un lgoritmo sendente que omiene por onstruir todos los n 1 roles ptimos de 2 nodosF e prtir de este resultdo onstruimos los n 2 roles ptimos de 3 nodos y s suesivmenteF vos ostes de los suroles ptimos se lmenn en un mtriz COST[] n nD donde d entrd COST(i,j) represent el osto del rol ptimo entre i y jF glulmos itertivmente est mtriz por digonles hst llegr l digonl COST(1,n)D l ul ontiene el osto ptimo del rol de n nodosF il lgoritmo tom omo entrd dos rreglos de dimensin nD donde n represent el nmero de lvesF el primero lo llmmos keys[] y ontiene ls lvesF el segundo lo llmmos [p] y ontiene ls freuenis de eso pr d lveF il lgoritmo requiere otr mtriz TREE[] que lmene ls res de los roles ptimosF hdo un osto ptimo COST(i,j)D TREE(i,j) ontiene el ndie de l rz del rol inrio ptimo dentro del rreglo keysF
4.14.2 Implantacin
360

360

smplntmos nuestro lgoritmo en el rhivo opfinreeFr siguienteX opBinTree.H 360

uy estrutur es l

Denicin macros opBinTree 361b Funciones auxiliares opBinTree 361d

template <class Node, typename Key> Node * build_optimal_tree(Key keys[], double p[], const int & n) { compute_optimal_costs(cost, p, n, tree); return compute_tree<Node, Key> (keys, tree, n, 1, n);

Declaracin de matrices internas 361a

4.14. rboles estticos ptimos

361

361a

il rhivo export un funin prinipl llmd build_optimal_tree()F v entrd de l funin es un rreglo ordendo de lves keys[]D un rreglo prlelo de proiliddes de eso por d iEsim lve y l dimensin n de los respetivos rreglosF v slid es l rz de un rol inrio ptimo onforme ls proiliddes ddsF vs lves y proiliddes se ponen en rreglos esttiosF e us de l grn eslD ls mtries interns son ms difiles de mntener esttisF or es rznD yD por didurD pr no limitrnos por l frgmentin de memori usremos rreglos dinmiosX Declaracin de matrices internas 361a (360) DynArray <int> tree((n + 1)*(n + 1)); DynArray <double> cost((n + 1)*(n + 1));
Uses

DynArray

34.

361b

tree[] es un mtriz que lmen ndies l prmetro rreglo keys de l funin build_optimal_tree()F cost[] es un mtriz que lmen ostes de los roles priles requeridos pr onstruir el rol ptimoF il eso omo mtriz un entrd de un rreglo dinmio se de(ne del siguiente modoX Denicin macros opBinTree 361b (360)
# define COST(i,j) (cost[(i)*(n+1) + (j)]) # define TREE(i,j) (tree[(i)*(n+1) + (j)])

361c

TREE(i,j) lmen el ndie l rz de un rol ptimo pril que ontiene ls lves entre i y jF el (nlD l rz del rol ptimo de(nitivo ser keys[TREE(1, n)]D l rz del rol izquierdo keys[TREE(1, TREE(1,n) - 1)]D etterF COST(i,j) lmen el osto del rol inrio on lves entre keys[i] y keys[j]F gomo es l ostumreD todo mro dee ser inde(nido l (nl del rhivoX Indenicin macros opBinTree 361c # undef COST # undef TREE
ehor de(nimos l funin compute_optimal_cost()D l ul se estrutur en dos loquesX Funciones auxiliares opBinTree 361d (360) 362b static inline void compute_optimal_costs(DynArray <double> & cost, double p[], const int & n, DynArray <int> & tree) {
}
Uses

361d

Iniciar estructuras internas 361e construir costes ptimos 362a


34.

DynArray

361e

compute_optimal_cost() lul ls mtries de ostes COST[] y los ndies de ls res de d surol ptimo en TREE[]F il primer loque sniir estruturs interns 361e D ui los vlores iniiles en ls respetivs mtriesX Iniciar estructuras internas 361e (361d) int i, j, k; for (i = 1; i <= n; ++i) { COST(i, i - 1) = 0;

362

4. rboles

TREE(i, i) = i;

362a

il segundo loque es el que lul los ostes de(nitivosF rimero on los suroles de 2 nodosD luegoD on los de 3D y s suesivmente hst otener el vlor de COST(0, n-1) y l rz resultnte en TREE(0, n-1)X construir costes ptimos 362a (361d) for (i = 0; i < n; ++i) for (j = 1; j <= n - i; ++j) { k = j + i; TREE(j, k) = min_index(cost, j, k, n); COST(j, k) = sum_p(p, j, k) + COST(j, TREE(j, k) - 1) + COST(TREE(j, k) + 1, k); }

362b

sum_p() efet l sum de ls proiliddes entre j y k y se de(ne omo sigueX Funciones auxiliares opBinTree 361d + (360) 361d 362c
static inline double sum_p(double p[], const int & i, const int & j) { double sum = 0.0; for (int k = i - 1; k < j; ++k) sum += p[k]; return sum; }

362c

min_index() retorn un ndie lD omprendido entre j y kD tl que COST(j, l - 1) + COST(l + 1, k) se mnimoF iste vlor se lul medinte rrido direto de l entre j y kX Funciones auxiliares opBinTree 361d + (360) 362b 363
static inline int min_index(DynArray <double>& cost, const int & j, const int & k, const int & n) { int ret_val; double min_sum = 1e32; for (int i = j; i <= k; ++i) { const double sum = COST(j, i - 1) + COST(i + 1, k); if (sum < min_sum) { min_sum = sum; ret_val = i; } } return ret_val; }
DynArray
34.

Uses

he l form plntedD min_index() es O(n)D uy llmd ourre dentro de dos lzos O(n)F vo nterior impli que nuestro lgoritmo es O(n3 ) un tiempo muho mejor que el exponenil que produir el lgoritmo fuerz rutD pero n uestionle pr vlores de n muy grndesF v squed del ndie mnimo luldo en min_index()

4.15. Notas bibliogrcas

363

puede mejorrse si logrmos demostrr que el surol mnimo se enuentr en el rngo TREE(j, k - 1) TREE(j, k) TREE(j + 1, k)F in este soD puede demostrrse que el lgoritmo es O(n2 )D lo que se deleg omo ejeriioF
54 38 29 24 7 3 0 42 63 66 69 71 98 108

pigur RFSVX rol inrio ptimo de 14 lves distriuids inomilmente on p = 0, 5 xos rest onstruir el rol prtir de l mtriz TREEF il ndie de l rz es TREE(1,n)D el de su surol izquierdo es TREE(1, TREE(1,n)) y s suesivmenteF istmos listosD puesD pr diser l rutinX Funciones auxiliares opBinTree 361d + (360) 362c template<class Node, typename Key> static inline Node * compute_tree(Key keys[], DynArray<int>& tree, const int & n, const int & i, const int & j) { if (i > j) return Node::NullPtr; Node * root = new Node (keys[TREE(i, j) - 1]); LLINK(root) = compute_tree <Node, Key> (keys, tree, n, i, TREE(i, j) - 1); RLINK(root) = compute_tree <Node, Key> (keys, tree, n, TREE(i, j) + 1, j); return root; }
Uses

363

DynArray

34.

4.15 Notas bibliogrcas


e podr deir que l noin mtemti de rol y sus oneptos fundmentles son resultdo de vris ers y generiones en l teor de onjuntosF il volumen I del ert of omputing progrmming de unuth WU reopil los indiios iliogr(os sore los orgenes mtemtios de los rolesF hel mismo modoD unuth es un de ls mejores refeE renis pr ompletr ls mtemtis soids los roles presentds en este texto y otros tipos de roles que no estudimosF hesrrollos mtemtios ms profundos pueden enontrrse en un texto forml sore teor de grfosF in l ourreni reomenE dmos el lsio de rrryD qrph heory UHF hesrrollos reientes pueden enontrrse en el texto gomintoril elgorithms de ureher y tinson IHPF vos digos de un rol inrioD el lenguje de vuksiewiz y l lere notin polD fueron estudidos por el mtemtio polo tn vuksiewiz IIPF v susein RFVFHFU

364

4. rboles

@gF QHPA fue inspird prtir de los puntes que este utor not y estudi del urso elgorithmique gomintoire de IWWQD de l niversidd ierre et wrie gurie en rsD prniD e imprtido por el exelente mestro ten ferstelF il orpus de ompresinD homnimmente llmdo de ru'mnD fue desuierto por hvid ru'mn en IWSPD en quel entones estudinte o(ilF ru'mn jms quiso ptentr sus desurimientosF egn unuth WWD los roles inrios de squed fueron desuiertos independienteE mente por vrios investigdores durnte l dd de IWSHF he nuevoD el letor es remitido l or de unuth WW pr onsultr ls referenis extsF odos los liros de estruturs de dtos onsgrn vrios ptulos los rolesF in ese sentidoD ulquier otro texto sirve de refereni diionlF in emrgoD en lo que roles se re(ereD ningn liroD inluidoD por supuestoD el presenteD puede onsiderrse ompletoF n texto reienteD ht trutures using g nd g++ de vngsmD eugenstein y nenum IHR exhie mplis re)exiones prtis y present pliiones relesD notlementeD l evluin de expresiones ritmtis medinte roles hildosF vos roles hildos fueron desuiertos por eF tF erlis y gF hornton IRIF eunque su uso es di(ultosoD est lse de rol es usd en pliiones estdstisD editores de textos y pliiones gr(s que mnejen grndes volmenes de informinF vos roles on rngo presentdos en RFII @gF QQSA fueron desrrolldos por este redtor pr el presente trjo omo instrumento didtioY on seguridd hn sido desrrolldos previmenteF vs ides sore el uso de rngos pr l vetorizin de rE oles es presentd pr un lse de rol equilirdo denomindo ev por grne QQF eprentementeD el trjo de grne es pionero en los lgoritmos de ontenin y prE tiinF vos hepsD junto on el hepsortD fueron presentdos por primer vez por tF F tF illims IVI y F F ployd SQF in opinin de este redtorD l ms utnti y mgistrl expliin sore heps l ofree fentley en rogrmming erls IWF v expliin es tn exels que desde he muhos os @IWVVAD undo este redtor estudi los hepsD ste no puede desprenderse de su esquem de presentin de los hepsF irvD puesD este presente prrfo omo pleites y itF il hor lsio de edgewikD elgorithms in gX rts I!R ISSD se rteriz por exponer muhos lgoritmosD de form muy onis pero vees inomplet y en detrimento del formlismoF e pesr de elloD el edgewik es un de ls mejores referenis pr indgr lgn lgoritmo espe(oF il volumen Q del ert of omputer progrmming de unuth WW ontiene un nlisis mtemtio stnte exhustivo de los roles inrios de squed y de los roles ptimosF il sntrodution to elgorithms de gormenD veiserson y ivest QP onsgr un pE tulo ls extensiones sore roles inriosF eunque este ptulo se s en un lse prtiulr de rol llmdo rojoEnegro @ver TFS @gF RWHAAD ls extensiones propuests pueden usrse sore prtimente ulquier lse de rol inrio de squedF il lgoritmo de inserin en l rz presentdo en RFWFU @gF QPTA fue desuierto por tepheson y reportdo en e method for onstruting inry serh trees y mking insertions t the root ITPF iste trjo mr un hito sore los roles inriosD pues dio pie nuevs ides y usosD notlementeD los lgoritmos de ontenin y prtiin

4.16. Ejercicios

365

presentdos en RFWFV @gF QPUA y RFIIFT @gF QRHA y los roles letorizdos que sern presentdos en TFP @gF RSSAF vos roles inrios de squed ptimos fueron propuestos y estudidos por ru y uker en IWUI UWF

4.16 Ejercicios
IF wodi(que el lgoritmo RFI pr que imprim un rol ritrrimente grnde que no quep en el medio de impresin @pntll o impresorA @CAF PF hisee un lgoritmo que tome omo entrd un seueni desordend @un list o un vetorD poo importA de pres <lor nodoD xmero de hewy> y retorne el rol representdo on lists enlzds y on rreglosF QF hisee un lgoritmo que tome de entrd un rol ulquier y retorne un seueni ordend de nmeros de hewyF gonsidere los dos tipos de representinX lists enlzds y rreglosF RF hisut y disee un estrutur de dto orientd hi l notin de hewyF hisut lgunos ontextos en los ules su diseo ser justi(doF SF hisee un lgoritmo que usque un lve en un rol nErio representdo medinte lists enlzdsF hisut sore ls diferentes estrtegis de squedF TF hisee un lgoritmo que uente el nmero de nodos en un rol nErio representdo medinte lists enlzdsF UF hisee un lgoritmo que reorr en su(jo un rol representdo on listsF VF hisee un lgoritmo que esri l representin prentizd de un rolF WF hisee un lgoritmo que onviert un rol representdo on lists enlzds en su equivlente representdo on rreglosF h dos respuestsX l primer onsiderndo onoido el orden del rolD l segund onsiderndolo desonoidoF IHF goni mo delimitr el reorrido pre(jo pr que onteng l informin requerid pr reonstruir el rol originlF IIF goni mo delimitr el reorrido su(jo pr que onteng l informin requerid pr reonstruir el rol originlF IPF hisee un lgoritmo que onstruy un rol inrio prtir de los reorridos in(jo y su(joF IQF wodi(que el reorrido por niveles level_order @ RFRFIP @gF PSIAA pr que use un funin de visit que rei el nivel y l posiin dentro del reorridoF IRF hisee un lgoritmo no reursivo que opie de roles inrios @CAF ISF hisee un lgoritmo no reursivo que destruy de roles inrios @CAF ITF hisee un lgoritmo que reorr en pre(jo un rol inrio hildoF

366

4. rboles

IUF hisee un lgoritmo que reorr en su(jo un rol inrio hildoF IVF hisee un lgoritmo que hile un rol inrioF v entrd es un rol inrio normlY l slid es el mismo rolD pero sus nodos estn hildos segn RFRFISF IWF hdo un rol inrioD disee un lgoritmo que efete l opi hildF PHF upong un rol inrio uyos nodos tienen un mpo diionl llmdo PLINK y que denot el nodo pdreF hdo un nodo ulquier pD disee lgoritmos no reursivos y sin pil prX @A heterminr el nodo predeesor yD @A heterminr el nodo suesorF PIF vos reorridos pseudohildos no onsidern l posiin del nodo en el reorrido ni su nivelF wodi(que ls funiones en uestin pr que se inluyn estos prmetros @CCAF PPF hisee un rutin reursiv que reorr por niveles un rol inrio y use espio O(1) @CAF PQF hisee un lgoritmo no reursivo que efete el reorrido pre(jo sore un roreseni espei(d medinte el eh Tree_Node F PRF hisee un lgoritmo no reursivo que efete el reorrido su(jo sore un roreseni espei(d medinte el eh Tree_Node F PSF gonsidere los siguientes reorridos sore un roreseniX

Prejo X R P I Q IV IT IP V S T U W IH II IR IQ IS IU IW PH Sujo X I P Q R S T U V W IH II IP IQ IR IS IT IU IV IW PH
hiuje l roreseniF PTF he(n e implnte l similridd entre dos roles espei(dos medinte el eh Tree_Node F PUF he(n e implnte l equivleni entre dos roles espei(dos medinte el eh Tree_Node F PVF hisee un lgoritmo reursivo que implnte l opi de un rol espei(do medinte el eh Tree_Node F PWF hisee un lgoritmo no reursivo que implnte l opi de un rol espei(do meE dinte el eh Tree_Node F QHF hisee un lgoritmo no reursivo que ejeute l squed por nmero de hewyF QIF gomplete l soluin de l euin @RFQHA @CCAF QPF gomplete l soluin de l euin @RFQIA @CAF QQF qenerlie l expresin nterior pr roles mEriosF

4.16. Ejercicios

367

QRF isri un lgoritmo que trnsforme un rol mErio ompletoD representdo on listsD en un rreglo seuenilF QSF isri un lgoritmo que trnsforme un rol inrio ompleto en un rreglo seuenilF QTF isri un versin no reursiv del lgoritmo que lul l ltur de un rol inrioF QUF hiuje l roreseni equivlente l rol inrio de l (gur RFSWF
9 6 4 1 2 3 11 12 5 7 8 10 13 14 15 17 16 18 19 20 23 21 22 24 25

pigur RFSWX n rol inrio QVF hiuje el rol inrio equivlente l roreseni de l (gur RFTHF
1 14 26 27

10

17

18

19

20

28

29

30

31

11

12

13

21

22

15

16

23

24

25

pigur RFTHX n roreseni QWF gonsidere ls siguientes lnes del lgoritmo presentdo en RFRFW @gF PSHA pr l opi de un rol inrioX
I(RLINK(tgt_root) == Node::NullPtr); if (LLINK(tgt_root) != Node::NullPtr) destroyRec(LLINK(tgt_root)); delete tgt_root;

@A or qu el serto tiene sentidoc @A il if y l destruin del surol izquierdo son redundntesD por quc RHF isri un versin reursiv del lgoritmo de destruin mostrdo en RFRFIH @gF PSHA que liere los nodos en pre(joF

368

4. rboles

RIF isri un versin reursiv del lgoritmo de destruin mostrdo en RFRFIH @gF PSHA que liere los nodos en in(joF RPF isri un versin no reursivD su(joD del lgoritmo de destruin mostrdo en RFRFIH @gF PSHA queD en so de que ourr un desorde de pilD deje el rol en un estdo onsistenteF RQF isri un progrm que reorr un rol inrio por niveles de dereh izquierdF RRF smplnte el reorrido su(jo medinte pseudohildo @CCAF RSF wodi(que el reorrido in(jo pseudohildo pr otener un reorrido in(jo inversoD es deE irD el reorrido in(jo de dereh izquierd @CAF RTF hisee un lgoritmo que rei omo entrd el nmero de hewy de un nodo ulquier y el rol inrio donde reside el nodo y retorne el nodo en uestinF RUF hisee un lgoritmo que tome de entrd un rol inrio y onstruy un onjunto ompuesto por todos los nodos representdos en nmeros de hewyF RVF gon se en lo plntedo l iniio de RFV @gF QHPAD lule el nmero de roresE enis posiles que se pueden plnter on n nodosF RWF hisee un lgoritmo que determine si un seueni de its orresponde un plr de vuksiewizF SHF hdo un rol inrioD disee un lgoritmo que genere l plr de vuksiewiz oE rrespondienteF SIF gonsidere el siguiente prototipo de funinX

string random_luka(const size_t & m)


il ul gener un plr letori de vuksiewiz de longitud mF isri l funin en uestinF SPF hemuestre que el lenguje de hik es pre(joF SQF il propsito de este ejeriio es generr un roreseni letori de n nodosF @A hemuestre que trvs de l generin de un rol inrio letorio de n nodos se puede otener un roreseni letori de n nodosF @A esum que se dispone de l funin siguienteX

int random(int n)
v ul gener un nmero letorio entre omprendido en el intervlo [0, n) ehor supong el prototipo de funin siguienteX

template <class Node> Node * random_tree(int n)

4.16. Ejercicios

369

v ul gener un rol inrio l zr de n nodosF isri l funin en uestinF uesto que slo interes l form del rolD no est permitido usr roles inrios de squedF @A gonsidere el siguiente prototipo de funinX

template <class Node> random_forest(int n)


il ul gener un roreseni letori de n nodosD y retorn l rz del primer rolF hisee un lgoritmo que instrumente l generin de un roreseni letori de n nodos e instrumnteloF SRF hisee un lgoritmo que imprim el reorrido por niveles inverso de un rol inrioF is deirD primero se listn de izquierd dereh los nodos del ltimo nivelY luegoD los del penltimo y s suesivmente hst llegr l rzF SSF hdo un rol inrio ulquierD el reorrido omplemento por niveles es de(nido omo el listdo de los nodos que fltn por nivel prtir de l rz hst el nodo de myor lturF or ejemploD pr el rol de l (gur RFTID el reorrido omplemento es 7, 8, 11, 14, 15D es deirD los nodos que fltrn pr que el rol este ompleto hst su lturF
1 2 4 8 9 10 5 11 12 6 13 14 3 7 15

pigur RFTIX rol inrio ejemplo

@A hisee un lgoritmo que lule el reorrido omplemento de un rol inrioF esum que los nodos estn etiquetdos por nivel prtir de l posiin ero @CAF @A hisee un lgoritmo que genere un rol omplementoF isto esD un rol uys hojs enjen on los nodos fltntes del rol pr que el rol est ompleto @CAF STF hisee un lgoritmo que pode un rol inrioD es deirD que elimine l mnim ntidd de nodos pr volverlo un rol ompletoF SUF hisee un lgoritmo que enuentre el ms lrgo mino por l dereh ontenido en un rol inrioF SVF hisee un lgoritmo que genere un rol inrio de n nodos donde n es un vlor onstnte @CAF SWF hisee un lgoritmo que determine si un expresin lgeri tiene sus prntesis lnedos @CAF

370

4. rboles

THF hisee un lgoritmo que genere un rol inrio letorio de n nodosF v ntidd n es un prmetro del lgoritmo y todos los roles deen tener l mism proilidd @CCAF TIF hisee un lgoritmo que onstruy un rol inrio de squed prtir de su reorrido su(joF TPF hdo un rol inrio de squedD disee un lgoritmo que onstruy un seueni de inserin que reproduz un rol inrio equivlenteF TQF hisee e implnte un lgoritmo que liste los rngos de lves que no se enuentrn en el rolF TRF hisee un nodo inrio queD dems de l lveD teng un enle dole DlinkF wodi(que ls rutins de inserin y eliminin en rol inrio de squed pr que el mpo Dlink funj de hilos explitosF il reorrido de l list dee orresponder l reorrido in(jo en el rol inrioF TSF hisee un versin itertivD insert_in_binary_search_tree()F TTF hisee un versin itertivD remove_from_search_binary_tree()F sin sin usr usr pilD pilD del del proedimiento proedimiento

TUF hisee un versin itertivD sin utilizr pilD del proedimiento split_key_rec()F TVF isri un versin de l eliminin de un rol inrio de squed queD undo se trte de suprimir un nodo ompletoD esoj l zr ul ser el nodo seleionr omo rz del join_exclusive() gules sern ls ventjs de este enfoquec TWF hisee un versin itertivD remove_from_binary_tree()F sin usr pilD del proedimiento

eyudX revise los fundmentos explidos en RFWFT @gF QPRAEIF UHF hemuestre que si no hy lves duplidsD entones join() y join_preorder() son equivlentesF is deirD produen extmente el mismo rolF UIF hiuje los roles inrios de squed orrespondientes l prtiin del rol inrio de l (gur RFTP segn l lve 250F UPF hiuje el rol inrio resultnte pr ls siguientes seuenis de inserinX
@A PPH IRHH QIS SQR IPPQ IQQW QPW SIR IPHU IHIW IVP IRT IQIU RQS TRT @A IPHU UPT SPH IHQV IH QQI QIT QI IPHQ IPUU RVH USS IRPP IPQI SUR @A IUH IPRU VWQ RII QUV IQUI IHS IVT WHT TVW URU IIS VSV RSQ IHUW @dA WU RHI VIS SR WW SVQ IHP TSR ISS UPS PST UQU IIWQ QSR VSR @eA TRW VSV TWW IRV SU WVT IRQV IIWR VPR WWT IIIW RQR IS PPT USV @fA QRT UVU VWI IRHS IIII IPHR IIVI RWT QIR IHIR SPW IHVU RVI IIRT IQRQ

UQF hiuje el rol inrio resultnte pr ls siguientes seuenis de inserin en l rzX


@A PUI IRSH IUI WQ WHU IPQ IQRI QPW UIR PQI IHUW TPV IPUH IPIR QPH

4.16. Ejercicios

371

244

122

279

41

203

266

293

49

156

214

255

270

291

297

36

66

163

245

264

65

73

159

189

63

72

54

pigur RFTPX n rol inrio de squed


@A WWH SHS VQR IIW QPW RU IPVQ IQHQ RTV WUH TWU PQW SWT UWR IPIS @A IRVR IRS QPH IHPS THW WQP PUH IIIS VRT IPII IPVU IHWS VSS IHSW IQRQ @dA PHI THU IIQU IHWW IIWU PHQ VRH URI SPT WPW IQUH IWH WWT PHS UIS @eA RPH UV PPI IRUS IISS IPHH IPIV IPSU IHTI IHSQ IIPR SQ TTS URQ IPQV @fA RPW IHUR RSW RQU IHRI WUW TUS IIPU PIQ TTR UIS IISV IIU VRR

URF hdos los siguientes reorridos pre(jos de roles inrios de squedX


@A IHSV QVV IHH IW VQ IPT ITI WRR SRW RSS TVI SWW WQU IIVT IQQQF @A IIST Q IVS IIW PVS PPS VIH RHW UVQ RPH IHHQ WUS IQSI IPWH @A VTV SPU PRH II PQH STP SVH THS URI WUP WHI IRSH IPUH IITR IRQI @dA VWV PHT IUQ ISI IQT RQ IWP PIV VSH UHH STH SUS IHWI IRUR IQPS @eA IIP TH VH IIPH TPS IQW PUU PTT WRP WHW WVI WTU IISH IRQW IQSR

@A hiuje el rol orrespondienteF @A glule el IPLF USF hdos los siguientes reorridos su(jos de roles inrios de squedX
@A IPQ RUV RHV WRU IHHW VQI QHQ IPSH IQTQ IQSP IPHT IRVU IQTW IHRQ PQH @A IS IIT SIP IHIR QRP IHRW IHVS IHPV IPTU IPWR IPVV IIIU IRTV IQRH RU @A RV VR RHV IRI VWV VIS UWV TIW RVV PT IHIQ IQRI IRIH IIRP IHQP @dA PQH QIV QIS IHW RQQ QTV QTU SSV SUT RTI QPU IIWQ VHI IPVV UQQ @eA QH VQ IWQ RST QVW RWS IHST IHHI STS IPUS IRWS IRPP SSV SPI IHQ

@A hiuje el rol orrespondienteF @A glule el IPLF @A hemuestre que l sumtori plnted en @RFQRA @ RFUFR @gF PVWAA esD en efetoD O(n)F

372

4. rboles

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

pigur RFTQX n hep trinrio UTF gonsidere un hep trinrioD es deirD un rol trinrio ompleto @on l propiedd tringulrA tl omo el de l (gur RFTQF D demsD on l propiedd de ordenD o seD que pr d lve del rolD ls lves desendientes siempre son myoresF gonsidere l siguiente operin sore un nodo ulquier p de un hep trinrioX
Node * child(Node * p, int i)

pD omo y se dijoD es un nodo de un hep trinrioF i es el ordinl del hijoY es deirX


@A i == 0X el hijo ms l izquierdF @A i == 1X el hijo del entroF @A i == 2X el hijo ms l derehF uede sumirD unque eso no es esenil l prolemD que en useni de un hijo child() retorn NULLF il ojetivo de este prolem es desurir un lgoritmo que enuentre l seueni de ordinlesD prmetros child()D tles que trvs de llmds suesivs se enonE trr el ltimo elemento del hep trinrioF or ejemploD pr l (gur nteriorD l seueni es 2, 0, 2D l ulD prtiendo desde l rz 1D permite child(1, 2) = 4 child(4, 0) = 11 child(11, 2) = 34D ls ules desemon en el nodo etiqueE tdo on 34F UUF qenerlie el prolem nterior pr heps nEriosF UVF ixplique mo puede ordenrse un list dolemente enlzd medinte el hepsort on onsumo de espio O(1)F UWF gon se en l re)exin del ejeriio nteriorD implnte el hepsort sore lists de tipo Dnode<T> @CCCAF VHF hisee un lgoritmo que reorr un seueni de n elementos y enuentre los m n menores elementosF ixplique detlldmente mo se utiliz el hep pr ontener y mntenerD extmenteD m elementos medid que se inspeion l seueniF VIF hisee un eh DynArrayHeap<T> fundmentdo en el eh DynArray<T> @ PFIFR @gF QRAAF hisut los tmos deudos del diretorioD segmento y loqueF heid un riterio ueno pr ortr el rreglo de mner tl que el onsumo de memori se mnimoF

4.16. Ejercicios

373

VPF wodi(que el eh BinHeap<Key> pr que d nodo presind del puntdor l pdreF VQF wodi(que el eh BinHeap<Key> pr presindir de l list de hojsF tilie permE nentemente un seueni que lergue el nmero de hewy de lastD de mner tl que d modi(in del hep l use pr uir los nodos tulizrF VRF hemuestre por induin que un hep de n de nodos tiene n/2 hojsF VSF gonsidere un list enlzd representd medinte el eh Dnode<int>F gonsidere l siguiente interfzX

Dnode<int> * los_mas_grandes(Dnode<int> & l, int m)


v ul retorn un nuev list ontentiv de ls opis de los m myores nmeros lmendos en lF hisee e instrumente l rutin en uestin de l mner ms e(iente sin que se teng que ordenr el l listF VTF hisee un lgoritmo que tome omo entrd el reorrido pre(jo e in(jo de un rol y retorne omo slid el reorrido por nivelesF xo se dee onstruir el rolF VUF hisee un lgoritmo que rei omo entrd el reorrido pre(jo de un rol inrio de squed y retorne su IPLF xo se dee onstruir el rolF VVF hisee un lgoritmo que rei omo entrd el reorrido su(jo de un rol inrio de squed y retorne su IPLF xo se dee onstruir el rolF VWF hisee un lgoritmo que uente l ntidd de nodos en el iEsimo nivel de un rol inrio @CAF WHF hisee un lgoritmo que uente l ntidd de nodos inompletos no hojs de un rol inrioF WIF hisee un lgoritmo que uente l ntidd de nodos llenos de un rol inrioF WPF upong que d nodo posee un mpo diionl nextF isri un lgoritmo que enle todos nodos del rol segn el reorrido in(joF WQF r los siguientes pres de roles representdos on sus reorridos pre(josD onstruy el rol produto de l operin join()F
@A  IRR TS PU PP SR QV UR TV UI WS VS UU IPQ IHV IPP  S IQV RT PI QQ UH SS IPS VT UV UT UP IHW IPW IRQ @A  IPR PS PQ PH IW II PI IHT VP QI VI SH UT IPI IPS  QQ PW SI IIW WU VR TR TV WP VW WH IIH IHV IRW IRP @A  IP PS SP QP UT IPQ IHH UU VI VH VQ IHR IIV IQV IQT  TP QU QI W PT RT TI IQI IIH VR TW IHS IIT IPW IRQ @dA  RH IQ II R IW PR IPP TT TR RQ SR UR UU IIS IRT  QQ PQ PP P IV U PI QW SQ RR VU TQ IHT IIV IQS @eA  SI IV V W PW IHI VW UP TT UT VH IRV IHS IIS IQW

374

4. rboles

 S IPV VS SR PQ RS UI SU IPQ IHQ WI WS IIW IPT IRH @fA  IPQ RU RS IS QQ IIP WU WT VH IHU IHS IHW IPI IPP IRW  TW PH W IW PW SQ TT IQV WR VP VI UV IHT WS IRP

WRF hdos 2 roles inrios T1 y T2 D se de(ne l relin es simtrioD denotd omo T1 T2 omoX
T1 T2 T1 = T2 = raiz(T1 ) T1 = T2 = T1 T2 raiz(T2 ) L(T1 )

R(T2 ) L(T1 )

R(T2 )

hisee un lgoritmo que tome omo entrd dos roles y determine si son simtriosF WSF hisee e implnte un versin itertivD sin usr pilD del lgoritmo inorder_position()F WTF wodi(que l primitiv insert_in_pos() explid en RFIIFQ @gF QQVA pr que vlide que l lve del nodo insertr no viole l propiedd de orden de un effF WUF hisee un lgoritmo reursivo que lule l posiin in(j de un lve del rolF WVF hdo un rol inrio de squed on rngos y un lve de squedD disee un lgoritmo que retorne l posiin in(j de l lve si st se enuentr en el rolD o l posiin in(j que tomr l lve despus de l inserinF WWF smplnte un lgoritmo reursivo que efete l unin generl de dos effiF IHHF smplnte un lgoritmo itertivoD que no use pilD que hg l unin generl de dos effiF IHIF hisee un eh sdo en roles on rngo que modele rreglos e(ientesF IHPF hisee un versin itertivD sin usr pilD del lgoritmo split_key_rec() y que deje el rol intto si l lve y se enuentr en el rol @CCAF IHQF hisee un versin itertiv de l funin split_pos_rec() explid en RFIIFT @gF QRHAF IHRF hisee un rutin que usque un lve en un rol inrio yD en so de enontrrlD rote el nodo hst l rzF IHSF hemuestre que el rol inrio produido por insert_in_binary_search_tree() on l seueni de inserin S =< k1 , k2 , . . . , kn > es extmente igul l produido por insert_root() sore l seueni invertid S =< kn , kn1 , . . . , k1 >F IHTF hisee un lgoritmo reursivoD sdo en rotionesD que efete l inserin por l rz en un effF il lgoritmo dee usr el nodo externo que lergr l nuevo nodo y despus rotr reursivmente su pdre hst que ste deveng en rzF IHUF @Sugerido por Andrs ArciaA ixplique l operin que ejeut l siguiente rutinX
Node * program(Node * root) { if (root == NullPtr) return NullPtr;

4.16. Ejercicios

375

while (RLINK(root) != NullPtr) root = rotate_to_left(RLINK(root)); program(LLINK(root)); return root;

IHVF hisee un rutin que seleione un nodo en l iEsim posiin y lo rote el nodo hst l rzF IHWF hemuestre que ls primitivs insert_root_rec() y insert_root() siempre produen roles equivlentesF IIHF hdo un rol inrio de squed y el lgoritmo de inserin presentdo en RFWFQ @gF QPHAD lule l vrinz sore el nmero de nodos visitdos en un squed @CCAF IIIF or qu el vlor de Node::MaxHeight = 80 es deudo pr roles inrios de squedc IIPF hdo un rol inrio de squed y el lgoritmo de inserin en l rz presentdo en RFWFU @gF QPTAD lule ls espernzs y vrinzs de ls ntiddes de nodos visitdos en squeds exitoss e infrutuoss @CCAF IIQF hdo un effiD disee un lgoritmo e(iente que extrig un rngo de lves entre i y jD j > i @CCAF IIRF hdos dos roles effi A1 y A2 D disee un lgoritmo e(iente que inserte A1 prtir de l posiin i de A2 F IISF gonsidere l primitiv remove_by_pos() explid en RFIIFW @gF QRPAF hisee un versin sd en eliminin de l rz y ontenin de los suroles restntesF IITF wodi(que los lgoritmos de inserinD elimininD ontenin y prtiin pr que funionen en roles inrios de squed extendidosF IIUF hisee un lgoritmo itertivo e(iente que efete l ontenin de dos roles inrios @CAF IIVF hisee un lgoritmo itertivo e(iente que efete l unin de dos roles inrios @CAF IIWF hisee un lgoritmo itertivo e(iente que efete l intersein de dos roles inE riosF @CA IPHF hisee un lgoritmo reursivo e(iente que efete l difereni de dos roles inrios T1 yT2 F isto esD T1 T2 dee retornr el rol inrio T1 D exepto quells lves que se enuentrn en T2 F IPIF isri un progrm que inserte ls n lves de mner que el rol quede equilirdo @CAF IPPF inuentre un expresin nlti que genere l suesin de inseriones pr que el rol quede equilirdo @CCAF
Ayuda:

gonsidere n = 2k D es deirD n es un poteni ext de dosF

376

4. rboles

IPQF isri un lgoritmo que efete l unin de dos roles inrios de squed extenE didosF il rol resultnte no dee tener lves repetidsF IPRF isri un lgoritmo que efete l intersein de dos roles inrios de squed extendidosF il rol resultnte no dee tener lves repetidsF IPSF wodi(que ls rutins insert_root_rec() e insert_root() presentds en RFWFU pr que mnejen roles inrios extendidosF IPTF ifete medids de rendimiento pr todos los reorridos implntdos en BinNode_UtilsF h un reporte detlldo de sus experimentos que sele por d versin de reorrido el nmero de nodos y el tiempo totl de reorridoF IPUF hisee e implnte un tipo strto de dto que represente un rol inrio que oupe espio mnimoF is deirD l implntin deer mnejr los tres tipos de nodos seldos en RFRFIS @gF PSSAEIX ompletoD inompleto y hojF IPVF hisee un eh de uso generl que modele roles nErios sdos en el eh DynArray<T>F IPWF hds n lvesD demuestre que existen ls n lvesF
n(n1 ) 2

roles inrios diferentes que lmenn

IQHF hdo el e rol de ru'mn de l (gur RFTRD deodi(que l siguiente den de itsX

0 0 0 1 0 1 0 0 0 0 1 1 1 1 0 1 0 1 1 0 1 1 1 1 0 0 0 0 1 0 0 0 1 1 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 0 1 1 0 1 0 1 0 0 0 1 0 1 1 1 0 1 1 0 1 1 0 1 1 1 1 0 0 1 0 1 0 0 0 1 1 1 1 1 1 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 1 0 1 0 1 1 0 0 0 0 1 0 1 0 1 0 1 0 0 0 1 1 1 1 1 1 1 0 1 1 0 1 1 0 1 1 1 0 1 0 0 0 1 0 1 1 0 0 1 1 0 1 1 0 0 0 1 0 0 0 1 0 1 1 0 1 1 0 0 1 0 1 0 1 1 1 1 0 1 0 0 0 1 1 1 1 1 1 1 1 0 0 1 0 1 1 1 1 0 1 0 1 1 0 0 1 0 1 0 0 0 1 1 1 1 1 1 0 1 0 0 0 0 1 1 0 0 0 0 1 0 1 0 0 0 1 0 0 1 0 0 0 1 1 1 1 0 0 1 0 0 1 1 1 0 0 1 0 1 0 1 1 1 1 0 1 1 1 1 1 1 1 0 0 0 1 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 1 1 1 1 0 1 1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0 0 1 0 1 1 1 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 0 1 0 0 1 0 1 1 1 0 0 1 1 1 1 1 1 0 1 0 0 0 0 1 1 1 0 0 1 0 1 0 1 1 1 1 1 0 1 1 1 0 1 1 0 0 1 0 0 0 1 1 1 0 0 0 1 0 1 1 1 1 0 1 1 1 0 0 0 1 1 0 0 0 1 1 0 1 1 0 0 1 1 1 0 0 1 0 1 0 1 1 1 1 0 1 1 1 1 1 1 1 0 1 0 0 0 0 1 1 1 1 1 0 1 1 1 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 1 0 1 1 0 0 1 1 0 1 1 0 0 1 0 1 0 1 0 1 1 1 1 0 1 1 1 0 0 0 1 0 1 0 0 1 0 1 1 1 0 0 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 1 1 1 1 1 0 0 1 1 0 1 0 1 1 0 1 1 0 1 1 1 0 0 0 0 0 0 1 1 0 1 0 0 1 1 1 1 0 0 0 0 1 1 1 0 1 1 0 0 1 0 1 1 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 1 0 1 1 1 1 1 0 1 0 1 0 1 0 1 1 0 0 1 0 1 0 1 1 1 1 0 1 1 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 1 0 0 0 1 1 0 0 1 1 0 1 0 1 1 0 1 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 1 1 1 1 1 1 0 0 1 1 0 1 0 1 1 0 1 1 0 1 1 1 0 0 0 0 0 0 1 1 0 1 0 0 1 1 1 1 0 0 0 0 1 1 1 0 1 1 0 0 1 0 1 1 1 0 1 0 1 1 0 1 1 1 1 1 0 1 0 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 0 0 1 0 1 0 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 1 1 0 1 1 0 1 1 0 0 1 0 1 0 0 1 0 1 1 1 1 1 0 1 1 1 1 0 1 0 1 0 1 1 1 0 1 0 0 1 0 1 0 1 0 0 1 1 0 1 0 1 0 0 0 0 1 1 0 1 1 0 0 0 1 1 0 1 1 1 0 0 0 1 0 1 1 0 1 0 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 0 0 0 0 1 0 0 1 0 1 1 1 0 0 1 0 0 1 1 0 0 1 1 1 1 0 1 1 1 1 1 1 1 0 0 0 0 1 1 1 0 1 1 0 0 1 0 1 1 1 1 0 1 1 0 1 1 0 1 1 1 1 0 0 1 1 1 1 1 0 0 1 0 0 1 0 1 0 1 1 0 1 1 1 1 0 0 1 1 0 1 0 1 0 1 0 1 0 1 1 0 0 0 1 0 1 0 1 1 0 0 0 0 1 1 1 1 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 0 1 0 1 1 1 0 0 0 1 1 1 0 0 1 1 1 1 0 1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0 1 0 1 0 1 0 1 1 1 0 0 0 0 0 0 1 0 1 1 1 0 0 0 1 1 1 0 0 1 1 1 1 1 0 0 0 0 0 1 0 0 1 0 0 0 1 0 1 1 0 1 1 1 1 0 0 1 1 0 1 0 0 0 0 0 1 1 1 0 1 1 0 0 1 0 1 1 1 0 0 0 1 0 1 1 1 1 0 1 0 1 1 1 1 0 1 0 0 1 1 0 1 0 0 0 0 0 0 0 0 1 0 1 1 1 1 0 1 0 1 1 1 0 0 0 0 0 0 1 0 1 1 1 1 0 1 1 1 0 1 1 0 1 1 0 0 1 0 1 0 0 1 1 0 0 1 0 1 1 1 1 1 1 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 1 1 0 1 1 0 1 1 0 1 0 1 1 1 0 0 0 1 1 0 0 1 0 1 0 0 1 0 1 1 1 1 1 0 1 1 0 0 1 1 0 0 1 1 0 1 0 1 1 0 1 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 1 1 1 1 1 1 0 0 1 1 0 1 0 1 1 0 1 1 0 1 1 1 0 0 0 0 0 0 1 1 0 1 0 0 1 1 1 1 0 0 0 1 1 1 0 0 1 0 1 0 1 1 1 1 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 1 0 1 1 1 1 0 1 1 1 1 1 1 1 0 0 0 1 1 1 0 0 1 1 1 1 0 0 0 1 1 0 1 1 0 1 0 0 1 1 1 0 0 1 1 0 1 0 0 0 0 0 0 0 1 0 1 1 1 0 0 0 1 1 1 0 0 1 1 1 0 1 0 1 0 0 0 1 1 0 1 1 1 1 0 0 0 1 1 0 1 0 1 0 1 1 1 1 1 1 0 0 1 1 1 1 0 1 1 1 1 1 1 1 0 0 0 1 0 1 1 1 1 0 1 0 1 1 1 1 0 0 0 1 1 0 1 0 1 0 1 0 1 1 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 1 1 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 1 0 1 0 1 0 1 1 0 1 0 0 0 0 0 1 1 1 0 1 1 0 0 1 0 1 1 1 1 0 0 1 0 1 1 1 0 1 0 1 1 0 1 1 1 1 1 0 0 0 0 0 0 1 0 1 1 1 0 0 0 1 1 1 0 0 1 1 1 0 0 1 0 1 0 1 1 0 0 1 0 1 0 0 1 1 0 0 1 1 1 0 0 1 1 1 0 0 0 1 0 1 1 1 1 0 1

4.16. Ejercicios

377

0 1 1 1 1 0 0 0 1 1 0 1 1 0 0 0 0 1 1 1 0 0 1 0 0 1 0 1 0 1 0 1 0 0 0 1 1 0 0 1 1 0 1 0 1 1 0 1 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 1 1 1 1 1 1 0 0 1 1 0 1 0 1 1 0 1 1 0 1 1 1 0 0 0 0 0 0 1 1 0 1 0 0 1 1 1 1 0 0 0 0 1 1 1 0 1 1 0 0 1 0 1 1 1 1 0 1 1 1 0 1 1 1 1 0 0 1 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1 0 1 1 0 0 1 0 1 1 1 1 0 1 0 0 0 1 1 0 0 1 1 1 1 0 0 0 1 0 1 0 1 0 1 0 1 1 1 0 0 1 0 0 0 1 0 1 1 0 1 1 0 0 1 0 1 0 1 1 0 1 0 0 1 1 1 0 0 0 0 1 1 0 0 1 1 0 1 0 1 0 0 0 0 1 1 0 0 0 0 1 1 1 0 1 0 0 0 0 1 0 1 1 1 1 1 1 0 0 1 0 1 0 0 1 1 1 0 1 1 1 1 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 0 0 1 1 0 0 1 1 1 1 0 0 0 0 1 0 0 0 0 0 1 1 1 0 1 1 0 0 1 1 1 1 1 1 1 0 0 1 0 0 0 1 1 0 1 1 1 0 0 0 0 0 0 1 0 1 0 1 0 0 0 1 1 1 0 0 0 1 0 1 1 0 1 1 0 0 1 0 1 1 0 1 1 0 1 0 0 1 1 1 0 0 1 1 0 1 0 1 0 1 1 1 1 1 1 1 0 0 1 0 0 0 1 1 0 1 1 1 0 0 1 1 1 0 0 0 1 0 1 1 0 1 1 0 0 1 0 1 1 0 1 1 0 1 0 0 1 1 1 0 0 0 0 1 1 1 1 1 1 1 0 1 1 0 1 1 0 1 1 1 1 0 0 1 0 0 0 0 0 0 1 1 1 0 0 1 0 1 1 1 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 0 0 0 1 1 1 0 1 1 0 1 0 0 1 1 1 0 0 0 0 1 1 0 0 1 1 0 1 0 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 0 0 1 1 1 1 0 0 1 1 0 0 0 0 0 0 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 1 1 0 0 1 1 0 1 0 1 0 1 1 1 1 0 0 0 0 1 1 1 1 0 1 1 1 1 0 0 1 1 0 0 0 0 0 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 1 1 0 1 0 0 0
539

217

322

103

114

143

179

48

55

55 e

59

68

75

88

91

24

24 l

26

29

29 i

30 o

33

35 r

37 s

38

44 a

44

12 d

12

13 m

13 t

14

15

16

17

18 u

20

21

23 n

\n
10 10 y

6 b

6 q

7 .

7 f

8 ,

8 g

9 p

3 v

4 D

5 c

2 E

2 L

3 h

1 T

1 R

1 S

1 J

1 B

1 x

1 P

pigur RFTRX n rol de ru'mn IQIF e S un seueni odi(d segn el lgoritmo de ru'mnF hisee un lgoritmo que le l seueniD disting los pre(jos distintos y retorne el rol de ru'mn orresE pondiente los pre(jos @CAF IQPF gul es l equivleni entre un plr de hik y un nmero de hewyc IQQF glule el rol ptimo pr los siguientes onjuntos de lves y proiliddesX
@A 10 17 30 31 63 68 74 80 88 93 99 103 114 143 14 0.00003 0.00046 0.00320 0.01389 0.04166 0.09164 0.15274 0.19638 0.19638 0.15274 0.09164 0.04166 0.01389 0.00320 0.00046 @A 17 39 42 53 54 66 75 85 89 90 96 98 115 119 143 0.00047 0.00470 0.02194 0.06339 0.12678 0.18594 0.20660 0.17708 0.11806 0.06121 0.02449 0.00742 0.00165 0.00025 0.00002 @A 6 8 12 40 59 62 65 69 90 103 109 118 128 134 138 0.00475 0.03052 0.09156 0.17004 0.21862 0.20613 0.14724 0.08113 0.03477 0.01159 0.00298 0.00058 0.00008 0.00001 0.00000 @dA 18 21 34 41 53 54 56 57 65 77 98 104 122 124 131 0.00000 0.00000 0.00001 0.00008 0.00058 0.00298 0.01159 0.03477 0.08113 0.14724 0.20613 0.21862 0.17004 0.09156 0.03052

378

4. rboles

IQRF glule ls distriuiones de proilidd pr d uno de los roles de l pregunt nteriorF IQSF vos roles esttios ptimos presentdos en RFIR @gF QSVA sumen que ls lves usr siempre estn presentesF gonsidere el prolem de onstruir un rol ptimo en el ul es posile efetur squeds infrutuossF is este soD se de(ne un rreglo diionl q de dimensin n + 1 donde d qi represent l proilidd de que un n lve de squed est omprendid entre ki y ki+1 tl que n i=0 qi = 1F i=1 pi + @A r est vriin del prolemD de(n l longitud del mino ponderdF @A wodi(que el lgoritmo presentdo en RFIR @gF QSVA pr que se onsideren squeds infrutuossF eyudX gonsidere que l squed infrutuos es relizd hi un nodo externo @CAF IQTF @Tomado y traducido de Lewis-Denenberg [108]A egn los trminos presentdos en RFIR @gF QSVAD se TREE(j,k)D 1 j k n l rz del rol inrio ptimo pr el onjunto de lves kj , . . . , kk F @A hemuestre que si 1 j k nD entones existen roles ptimos tl que TREE(j,k - 1) TREE(j,k) TREE(j,k)F sntuitivmenteD esto quiere deir que dir un nuev lve l extremo dereho de l seueni no us que l rz del rol ptimo se desple hi l derehF enlogmenteD suede lo mismo si l lve es insertd por el extremo izquierdoF @A hemuestre que l squed del surol ptimo es restringid TREE(j,k - 1) TREE(j,k) TREE(j,k)D entonesD pr d vlor de i del lgoritmo presentdo en RFIR @gF QSVAD el for (j = ...) es O(n) yD por endeD el lgoritmo glol es O(n2 )F
Ayuda:

xo se puede efetur l prue si se us un lmite pr el for (j = ...) y entones multiplir por nF in su lugrD deen sumrse por seprdo ls longitudes de los rngos usrF

Tablas hash
v tenolog h trnsformdo l fz del mundo fsioD omn e indispensle pr l vidD que omprende es totlidd llmd plnetF odrmos deir que hst he no menos de un sigloD tod person soi lo nturl l nturlezD es deirD l mundo lleno de ireD tierr y gu donde se distingun los tres grndes reinosX minerlD vegetl y nimlD y en el ul pens se notn prels de lo humnoF roy en dD prtimente no hy espio del plnet que no est permedo por lo humnoD tl extremo que pr muhosD un estrutur de onretoD on l que se onvive desde el nimientoD les pree ompletmente nturlF n mird re sore l fz terrestre nos proporion un uen ide er de unto l tenolog h trnsformdo el mundoF v vist est delined por polgonos y lnes regulresD pesr de que stos prtieron de striones mtemtisD que no son nturlesF he los diverssimos ojetos tenolgios de hoy en dD uno que h ontriuido deE isivmente ese mio del mundo lo enrn el utomvilF hetengmonos un reve momento y meditemos mo ser el mundo si no existiese este rteftoF il utomvilD que hoy nos es nturlD es un medio de trnsporte esenil pr nuestr form de vidF D sin emrgoD es impresionnte un liennte nos puede serF he mE ner un poo simplist podemos deir que undo un utomvil no est en movimientoD ste oup un espioF od tividd humn que uente on el utomvil prtiulr omo medio de trnsporteD en detrimento del trnsporte plioD dee onsiderr el estE ionmientoF vos entros omeriles de hoy dD ionos de un tipo soilmente prtiulr de uen vidD indidores del onsumismo desenfrendo de est po y rtersti peulir de un estrto soilD son uenos ejemplosF n prolem de inters undo se dise un or ivil en un miente donde no exist trnsporte plio Euestin que deer de ser muy exepionlE onsiste en interrogr por l ntidd de super(ie pr el estionmientoF n primer pso onsiste en estimr l ntidd esperd de utomviles y s deidir l pidd en lugres del estionmientoF qrosso modoD un estionmiento puede pitorizrse del siguiente modoX
11 6 2 7 M 2

.......................................

M 2 M 1

qenrimenteD el estionmiento tiene M puestos posiles numerdos seuenilmenteF vos utomviles rrin seuenilmente y se estionn en el primer puesto disponileF il onoimiento onsoliddo reomiend que tl pidd rroje un porentje de plenitud QUW

380

5. Tablas hash

entre el US7 y WH7F is deirD segn lo esperdoD dee her un sornte entre el PS 7 y IH 7F u tiene que ver l situin del estionmiento on los lgoritmos y estruE turs de dtosc gonsideremos un onjunto genrio K de lvesD dentro de un posile dominio KD y un estionmiento on pidd M que lergr ls lvesF ehor onE sideremos l existeni de un funin inyetiv1 h(k) : K [0, M 1]D l ul puede pitorizrse sX
K
1 2 i M 1 1

[0..M 1] 0 i 1 2

M 1 2

M 1

hiho lo nteriorD podemos introduir formlmente el onepto de tl hsh o de tl de dispersin 2 F
Denicin 5.1 (Tabla Hash)

e un onjunto de lves K perteneientes un dominio KF n tl hsh se de(ne omoX IF n rreglo de tipo K de M entrdsF or lo generlD |K| = MD unque podrn oinidirF PF n funin h(k) : K [0, M 1] llmd funin hshF e un registro lergnte de un lve en un tl hsh se le denomin cubeta o su equivlente nglosjn bucket F wedinte el rreglo y l funin h(k) podemos usr un tl hsh pr implntr el prolem fundmentl de estruturs de dtosF e A[M] un rreglo de pres de tipo K {0, 1}Y es deirD A[i].key indi l lveD mientrs que A[i].busy indi si l entrd est oupd o noF intonesD grosso modoD ls tres operiones sis se efetn del siguiente modoX
Insercin de clave

k:

IF i = h(k) mod M PF A[i].key = k QF A[i].busy = 1


Bsqueda de clave

k:

IF i = h(k) mod M PF if (A[i].busy == 1) return true; else return false;


1 2
llamada uno a uno.

h : D R

se dice que es inyectiva

x, y D = h(x) = h(y).

Una funcin inyectiva tambin es En el caso concreto, la

De por s, esta ha sido la decisin de algunos traductores al castellano.

traduccin castellana [8] de Data Structures and Algorithms de Aho, Hopcroft y Ullman [7].

5.1. Manejo de colisiones

381

Eliminacin de clave

k:

IF i = h(k) mod M PF A[i].busy = 0 xotemos que ningun de ls operiones ontiene iterionesF or tntoD el oste de ls tres operiones depende diretmente del oste de h(k)F gonseuentementeD si h(k) es O(1)D entones ls tres operiones son O(1)F re quD puesD l grndez de est estrutur de dtosF i h(k) no es inyetivD entones es posile que dos lves distints ki , kj K l funin hsh les signe el mismo vlorD o seD h(ki ) = h(kj )F in este soD deimos que existe un colisin F v myor de ls vees no onoemos on extitud el onjunto de lves K KD lo ul he ms posile un olisinF es ls ossD pr que un tl hsh on un funin h(k) no inyetiv stisfg operiones en O(1)D st dee ontemplr dos requerimientos esenilesX IF il mputo de l funin h(k) dee herse en O(1) on un muy poo oste onsE tnte y su omportmiento dee emulr un distriuin disret uniforme entre [0, M 1]F uesto que pueden her olisionesD sts deen reduirse l mnimo posileY este es el sentido de que h(k) emule l letorieddF PF or l mism posiilidd de tener olisionesD unque fuese mnimD se dee tener un estrtegi pr mnejrlsD es deirD se dee deidirD sistemtimenteD qu her on quells nuevs lves que olinden on otrs y presentes en l tlF v estrtegi dee ser tl que no sri(que el tiempo O(1) lmdo pr un tl hshF

5.1 Manejo de colisiones


gomo y lo hemos seldoD si no se onoe el onjunto de lves que se insertrn en l tlD entones son posiles ls olisionesF u tn proles sonc n mird un lere prolem nos indii su proiliddF
5.1.1 El problema del cumpleaos

eprenderemos l proilidd de olisin medinte un lsio prolem de l teor de proiliddesF upongmos un grupo de n personsD qu tn prole es que dos persons tengn l mism feh de umpleoscF elgunos textos sore proiliddes ofreen un soluin preis este prolem onoE ido omo el del umpleos o l prdoj del umpleos QD RF or eonom en simpliidd y espioD qu lo oremos medinte un v ms ortD unque ms imE preisD de(nid por gormen et l en su enilopdio texto sntrodution to elgorithms QPF e un xi,j un vrile letori de(nid del siguiente modoX

xi,j =

0 1

si ls persons i y j no umplen os el mismo d si ls persons i y j umplen os el mismo d

@SFIA

382

5. Tablas hash

ehor de(nmos l siguiente vrile letoriX

X=
i=i

xi,j

@SFPA

guy espernz E(X)D en virtud de ls de(niiones plntedsD nos proporion l ntidd esperd de pres de persons que umplen os el mismo dF or de(niinX

E(X) = E
l ul puede plnterse omoX
i=i

xi,j

@SFQA

E(X) =
i=i

E(xi,j ) .

@SFRA

isto nos plnte l neesidd de lulr E(xi,j )D l ul esD por de(niinD sX

E(xi,j ) = 0 P(xi,j = 0) + 1 P(xi,j = 1) = P(xi,j = 1) .

@SFSA

v uestin requiereD puesD lulr P(xi,j = 1)Y es deirD l proilidd de que dos persons prtiulres umpln os el mismo d y stD l inredulidd de lgunosD esX

P(xi,j = 1) =

1 . 365

xo sorprendentementeD lgunos inurren en el error de pensr que se trt de un proilidd ondiionlD lo ul no es el soF r prehenderloD imginmosnos que nos enontrmos en un grupo y nos preguntmos un prole es que t umpls os el mismo d que yoc v respuest es 1/365D pues el onoer mi feh de umpleos revel el sueso de inters prole entre todos los 365 posilesF es puesX n 1 n(n 1) E(X) = = . @SFTA 2 365 730 vo ulD l plnter l desiguldd E(xi,j ) 1D nos rroj omo resX 2921 1 2921 + 1 n1 = , n2 = 27, 523138 . 2 2 isto impli que pr un grupo de 28 persons es esperdo enontrr un pr on l mism 55 feh de umpleosY pr el dole de persons @n = 56, E(X) = 56 730 = 4.2192A podemos esperr utro pres de persons on el mismo umpleosF r un sueso en prieni letorio e independienteD tl omo l feh de nimientoD l proilidd de olisin es stnte ltD lo ul indii l neesidd de preprrse su eventuliddF in lo que sigue disutiremos vris estrtegis pr lmenr olisiones en un tl hshF
5.1.2 Estrategias de manejo de colisiones

gonsideremos un onjunto genrio de lves olindntes Kc = {k1 , k2 , . . . , kn }D o seD ki , kj Kc = h(ki ) = h(kj )F e onoen dos grupos de tnis pr lidir on onjuntos de olisionesX

5.1. Manejo de colisiones

383

Encadenamiento

X ls olisiones se enlzn en un o vris lists enlzds fuer o dentro de l mism tlF


3

Direccionamiento abierto

X ls olisiones se uin diretmente dentro de l propi

tlF gd un de ests tnis tiene sus ventjs y desventjs y se de su usoF


5.1.3 Encadenamiento

v ide fundmentl del endenmiento es que ls olisiones se gurden en un list simple o dolemente enlzdF gundo los nodos de l list se gurdn fuer de l tlD deimos que se trt de endenmiento seprdoF in el sentido inversoD undo los propios nodos de l list son prte de l tlD deimos que se trt de endenmiento errdoF
5.1.3.1 Encadenamiento separado

in su form ms simpleD el endenmiento seprdo se implnt medinte un tl de punteros lists simplemente enlzdsD uy representin puede visulizrse omo en l (gur SFID l ul muestr un onjunto de 12 lves ki donde i represent el orden de inserinF gd entrd en el rreglo es un puntdor l primer elemento de l list enlzd de olisionesF
0 1 2 3 4 5 6 7 8 9 10 k10 k8 k1

k9

k5

k2

k3 k7 k4

M 2 M 1

k11

k6

pigur SFIX n ejemplo de tl hsh on resoluin de olisiones por endenmiento seprdo ods ls operiones requieren lulr j = h(k) mod MD donde k es un lveY de est mnerD l entrd tabla[j] es el puntero l list enlzdF n vlor de puntdor nulo indi que l list est vD es deirD que no hy ningn elemento soido l ndie j en el rregloF he lo ontrrio existe un list enlzd de lves olindntes endendsF in el ejemplo l entrd 11 muestr dos lves k7 , k4 uyo vlor de funin hsh rroj el mismo resultdo @10AF
3
Esta es la traduccin literal del trmino usado en ingls open addresing.

384

5. Tablas hash

384a

in ALEPH este tipo de tl est implntdo en el rhivo tpllhshFr 384a D ul implnt y export vris lses prmetrizdsD de ls ulesD l ms importnte esX tpl_lhash.H 384a template <typename Key, class BucketType, class Cmp> class GenLhashTable { typedef BucketType Bucket;

};

Prototipo de puntero a funcin hash 385a Miembros dato de GenLhashTable 385b Mtodos pblicos de GenLhashTable 386a

Cubetas de LhashTable<Key> 384b

GenLhashTable<Key, BucketType> implnt todo el mnejo genrio de l tl hshD en l ulD ls uets son de tipo BucketTypeF
Cubetas

384b

v mner ms simple de mnejr un uet endenr seprdmente es medinte el tipo Dnode<T> estudido en PFRFV @gF VQAX Cubetas de LhashTable<Key> 384b (384a) 384c template <typename Key> class LhashBucket : public Dnode<Key> { LhashBucket(const LhashBucket & bucket) : Dnode<Key>(bucket) {}
LhashBucket() {} LhashBucket(const Key & key) : Dnode<Key>(key) {} };
Uses

Key & get_key() { return this->get_data(); }


Dnode
83a.

il empleo del tipo Dnode<T> nos filit grndemente ls operionesD en prtiulr l de elimininD l ulD en un list simpleD requerir mntener un puntero l elemento predeesorF ry dos mners de soir otros dtos l lve de tipo Key de(nid en l uetX IF e re un registroD por ejemploD de tipo RecordD que onteng todos los dtos de intersD inluid l lve de tipo KeyF hespus se delr un uE et @LhashBucket<Record> o LhashBucketVtl<Record> y se de(ne el operdor Record::operator==(const Record&) pr que slo ompre l lve de tipo ueyF v tl hsh puede de(nirse medinte ulquier de los tres tipos GenLhashTableD LhashTable o LhashTableVtlF vos dos ltimos tipos se orresponden on tls que mnejn uets sin o on destrutores virtules y se de(nen por espeilizin de GenLhashTableX
384c

Cubetas de LhashTable<Key> 384b +

(384a)

384b

template <typename Key, class Cmp = Aleph::equal_to<Key> > class LhashTable : public GenLhashTable<Key, LhashBucket<Key>, Cmp>

5.1. Manejo de colisiones

385

PF e deriv un lse Derivada de ulquier de ls lses uets LhashBucket<Key> o LhashBucketVtl<Key> en donde se inluyn los dtos que se requiern soir l tipo KeyF v tl hsh se instni medinte LhashBucket<Key> o LhashBucketVtl<Key>D segn se requier o no destrutores virtulesF v inserin y l eliminin eptn uets de tipo DerivadaD pues son uets por hereniF v squed retorn un uet de l fmili LhashBucket<Key>D l ul dee onvertirse explitmente Derivada si se requiere onoer l uet DerivadaF

385a

LhashTable<Key> yvimenteD un triuto esenilD del ul hlremos ms delnteD es l funin hshD que trnsform un lve de tipo Key un nturlF l funin dee tener el prototipo siguienteX Prototipo de puntero a funcin hash 385a (384a)
Atributos de

typedef size_t (*Hash_Fct)(const Key &);

385b

il tipo LhashTable<Key> mntieneD puesD un puntero de este tipoX Miembros dato de GenLhashTable 385b (384a) Hash_Fct hash_fct;

385c

385c

v misin de este tipo es mnejr de form genri l funin hshF odo onstrutor de tl hsh requiere est funinF il segundo triuto es l tl mismD es deirD el rreglo de punteros uetsX Miembros dato de GenLhashTable 385b + (384a) 385b 385d typedef Dnode<Key> BucketList;// Tipo lista cubetas typedef typename Dnode<Key>::Iterator BucketItor;// Iterador cubetas typedef Dnode<Key> Node; // Sinnimo nodo BucketList * table;
Uses

Dnode

83a.

385d

or didurD hy un delrin de un iterdorD l ul permite reorrer un list de olisionesF il resto de los triutos se de(nen omo sigueX Miembros dato de GenLhashTable 385b + (384a) 385c size_t M; // Tamao de la tabla size_t N; // Nmero de elementos de la tabla size_t busy_slots_counter; // Cantidad de entradas ocupadas bool remove_all_buckets; // liberar cubetas en destructor il triuto busy_slots_counter uent l ntidd de entrds del rreglo table[] que estn vsF is un informin muy importnte pr onoer el nivel de dispersin busy_slots_counter nos d ide de l de l funin hshF i N < MD entones el rdio N efetividd de l funin hsh en trminos de dispersinF n vlor pequeo indi que hy muhs olisionesF il usurio de LhashTable<Key> tiene l responsilidd de prtr l memori pr ls uetsD s omoD eventulmenteD l de lierrlsF hisutimos l rzn de ser de esto undo hlmos del prinipio (nEE(n @ IFRFP @gF PPAA y lo hemos plido lo lrgo de los distintos eh que hemos disedoF in ese sentidoD es stnte til tener un rutin equivlente remove_all_and_delete() de Dlink @ PFRFU @gF VPAA o destroyRec() de los roles inrios @ RFRFIH @gF PSHAAF es puesD el triuto remove_all_buckets le indi l destrutor de LhashTable<Key> que dee lierr tod l memoriF

386

5. Tablas hash

386a

i se dese vir l tlD entones puede invorse l mtodo empty()X Mtodos pblicos de GenLhashTable 386a (384a) 386b void empty() { for (int i = 0; i < M; ++i) for (BucketItor itor(table[i]); itor.has_current(); /* nada */) delete (Bucket*) itor.del(); busy_slots_counter = N = 0; }
Insercin

386b

n sunto de inters es el lugr de l list en que dee insertrse un nuev olisinX l prinipioD l (nl u ordenr l listF gulquier de ests vrintes no us grn reperE usin en el desempeoD pero si es simplemente enlzdD entones l prefereni es por el frenteD de modo que l inserin se lo ms onstntemente rpidF i l list es doleD entones el heho de que se inserte l prinipio o (nl es indiferente en tiempoF ytro ftor de inters es onsiderr o no repiteni de lvesF e difereni de los roles inrios de squedD en un tl hsh es preferile no veri(r repiteni porque sino se requiere un squed en l list de olisiones d vez que se efete un inserinF ehor podemos espei(r l inserin en LhashTable<Key>D l ul se instrumentD muy senillmenteD sX Mtodos pblicos de GenLhashTable 386a + (384a) 386a 386c Bucket * insert(Bucket * bucket) { const size_t i = (*hash_fct)(bucket->get_key()) % M;
if (table[i].is_empty()) // est vaca la lista table[i]? ++busy_slots_counter; // s ==> actualizar contador ocupacin table[i].append(bucket); // insertar cubeta al final ++N; } return bucket;

i l llmd (*hash_fct)(key) es O(1)D entones insert() esD on ertitud determiE nistD O(1)F
Bsqueda

386c

v squed onsiste en lulr l entrd de l tl medinte l funin hsh y luego en reorrer l iEsim list hst que se enuentre k o hst que se llegue l (nlD en uyo so se trt de un squed fllidX Mtodos pblicos de GenLhashTable 386a + (384a) 386b 387 Bucket * search(const Key & key) const { const size_t i = (*hash_fct)(key) % M;
if (table[i].is_empty()) return NULL;

5.1. Manejo de colisiones

387

for (BucketItor it(table[i]); it.has_current(); it.next()) { Bucket * bucket = static_cast<Bucket*>(it.get_current()); if (Cmp() (bucket->get_key(), key)) return bucket; } return NULL;

il desempeo de est rutin depende de l longitud de l list table[i]F


Eliminacin

387

v eliminin es diret y on durin extmente onstnte un vez que se onoe l direin de l uetX Mtodos pblicos de GenLhashTable 386a + (384a) 386c 410 Bucket * remove(Bucket * bucket) { // guarda prxima colisin Bucket * next = static_cast<Bucket*>(bucket->get_next()); bucket->del(); // eliminar de su lista de colisiones if (next->is_empty()) // la lista devino vaca? busy_slots_counter;// s ==> actualizar contador listas ocupadas
N; } return bucket;

5.1.3.2

Anlisis del encadenamiento separado

or simpliidd rti sumiremos un tl onsistente de un rreglo de nodos eer lists de olisiones irulres y dolemente enlzds del tipo Dnode<T> estudido en PFRFV @gF VQAF fjo el mismo esprituD tmin sumiremos que l inserin siempre se he l (nl de l listF il desempeo de l inserin es diretmente O(1) medinte l operin append() en l eer que rroje l funin hshF il desempeo de l eliminin depende del desempeo de l squedF e su vezD el desempeo de l squedD exitos o fllidD depende de l longitud de l listF or tntoD el desempeo esperdo estr domindo por l longitud esperd de l listF in lo que sigue de nuestro nlisisD M denot l longitud del rreglo interno y N el nmero de elementos que ontiene l tlF = N/M indi el ftor de rg de l tlD es deirD qu tn llen est l tlF gon est terminolog de se podemos introduir nuestro lem fundmentlF @Longitud esperada de una lista de colisionesA e h(k) : K [0, M 1] un funin hsh O(1) que distriuye uniformemente los elementos de K hi [0, M 1]F e T un tl hsh de longitud M on resoluin de olisiones por endenmiento seprdo y que ontiene N elementosF e |li | el nmero de nodos de l iEsim list en T [i]F intonesD l longitud esperd de li esX
Lema 5.1

388

5. Tablas hash

N = @SFUA M 1 Demostracin uesto que h(k) se distriuye uniformementeD P(h(k) = i) = M pr un lve ulquier k KF e P(k li ) l proilidd de que l lve se lergd en l iEsim list oE rrespondiente l entrd T [i]F glrmenteD segn l oservin del prrfo nteriorD 1 F es puesD tenemos N lves uniformemente reprtids en M P(k li ) = P(h(k) = i) = M 1 listsF gd list li se orresponde on un distriuin inomil on prmetro p = M y 1 N ntidd de ensyosF or tntoD l medi es N M li =
he este lem se derivn los dos siguientes que ontilizn l ntidd de uets que se visitn en un squed fllid y exitos respetivmenteF @Cantidad de cubetas inspeccionadas en una bsqueda fallida sobre una tabla hash con resolucin de colisiones por encadenamiento separadoA e h(k) : K [0, M 1] un funin hsh O(1) que distriuye uniformemente los elementos de K hi [0, M 1]F e T un tl hsh de longitud M on resoluin de olisiones por endenmiento seprdo y que ontiene N elementosF intonesD el nmero de uets que se inspeionn en un squed fllid esX
Lema 5.2

N @SFVA M Demostracin e k un lve que no est dentro de l tlF il primer pso de l squed es otener li = T [h(k)]F he este modoD el nmero de uets visitr se orresponde on el nmero de nodos de li D pues es neesrio reorrer entermente li pr estr seguros de que k no se enuentr en l tlF or el lem SFI semos que li = UN = =
@Cantidad de cubetas inspeccionadas en una bsqueda exitosa sobre una tabla hash con resolucin de colisiones por encadenamiento separadoA e h(k) : K [0, M 1] un funin hsh O(1) que distriuye uniformemente los elementos de K hi [0, M 1]F e T un tl de longitud M on resoluin de olisiones por endenmiento seprdo y que ontiene N elementosF e k K un lve ulquierF intonesD el nmero esperdo de nodos que se visitn en un squed exitos esX
Lema 5.3

1 @SFWA 2 2M Demostracin e K = {k0 , k1 , . . . , kN1 }D el onjunto de lves presentes en l tlD donde i represent el orden de inserinD es deir k0 es l primer lve insertdD mientrs que kN1 es l ltimF e efetos de l simpliiddD sumiremos que no se permiten lves duplidsD lo ul requiere un squed seuenil sore un list undo se he un inserinF e pi l proilidd de que se usque l lve presente ki F e lki el nmero de elementos que preeden ki en su list de olisionesF intones SN = 1 +
N 1

E(lki ) =
i=0

pi lki .

esumiendo que ulquier lve tiene igul proilidd de ser usdD entones pi = 1/NF hespus de insertr l lve ki D hy i elementos en l tlD lo queD segn el lem SFID he

5.1. Manejo de colisiones

389

que l longitud de l list donde reside ki se lki = i/MF y seD que pr enontrr ki i uets predeesorsD pues ki se insert l (nl de l list y no se hy que reorrer M i permiten duplidosF isto ontiliz un totl de M + 1D pues hy que eder l uet que ontiene ki F he este modoD el nmero de esperdo de uets exminr ser
N1

E(lki ) =
i =0

pi 1 1 N M

i +1 M
N 1

1 = N
N 1

N 1 i=0

i +1 M

i+
i=0 i=0

N1 1 +1 = +1 2M 2 2M

gon estos dos lemsD estmos listos pr enunir l proposiin siguienteF @ Desempeo esperado de una tabla hash con resolucin de colisiones por encadenamiento separadoA e h(k) : K [0, M 1] un funin hsh O(1) que distriuye uniformemente los elementos de K hi [0, M 1]F e T un tl de longitud M on resoluin de olisiones por endenmiento seprdo y que ontiene un mximo otdo de N elementosF intonesD el desempeo esperdo de ls operiones de inserinD squed y eliminin es O() = O(1)F
Proposicin 5.1

il punto ruil de l demostrin es prehender que tnto M omo N son vlores onstntemente otdosF or otdo entendemos que si ien N puede ser myor que MD stos vlores estn otdos mximos onoidosD rzn por l ul tmin est otdo un vlor mximo onstnteF elrdo estoD podemos seprr d un de ls operionesX
Demostracin Insercin:

en este so se efet un squed fllidD l ulD segn el lem SFPD esper inspeionr = O(1) uetsF

Bsqueda:

IF i l squed es fllidD entones el lem SFP pli y l espernz esX

= O(1)
PF i l squed es exitosD entones el lem SFQ pli y l espernz esX

@SFIHA

1+
Eliminacin:

1 = O(1) 2 2M

@SFIIA

en este so se he un squed exitosD l ulD en el item nterior se demostr que es O(1)

espeto l eh LhashTable<Key>D l demostrin slo te l squedD puesD por su funionliddD en este ehD tnto l inserin omo l eliminin son O(1)F n ventj del endenmiento seprdo es que el nmero de elementos N puede ser myor que el tmo de l tl MF v inserin no tiene entones por qu preouprse por el desordeD lo ul nos proporion )exiilidd de irunstnisF he los enfoques trdiionles pr mnejr olisionesD este es el nio que permite N > MF

390

5. Tablas hash

il desempeo del endenmiento seprdo es un prediinD qu tn prole escF n indiio de respuest nos ls proporion l vrinzD l ul es deduile de l prue del lem SFI en l que determinmos que l longitud de un list de olisiones se distriuye 1 inomilmente on prmetro p = M y N ensyosF or tntoD l vrinz esX var = 2 =

1 N 1 M M

@SFIPA

gunto myor se MD ms proximd es l vrinz l vlor = li F gunto myor se l ntidd de elementosD myor tiende ser l vrinzF in emrgoD est oservin desde el rdio yD justmenteD el propsito de l ltim expresin es re)ejr el heho de queD myor rdioD o seD myor plenitudD myor es l vrinzF
5.1.3.3 Encadenamiento cerrado

el igul que en el endenmiento seprdoD en est estrtegiD ls olisiones se endenn en lists enlzdsD pero l difereni estri en que ls uets residen en l propi tlF gundo ourre un olisin se sonde 4 linelmente l tl en squed de un uet vF v tl ejemplo de l susein nteriorD on ls misms lists de olisionesD se vislumr omo en l (gur SFPF xotemos l olisin {k6 , k11 }D l ul requiri ontinur el sondeo por el prinipio de l tl hst lnzr l urt entrd de l tlD es deirD el sondeo linel dee ser irulrF
0 1 2 3 4 5 6 7 8 9 10 k4 11 k7 k2 k5 k9 k3 k1 k10 k8 k11

M 1 k6

M 2

pigur SFPX n ejemplo de tl hsh on resoluin de olisiones por endenmiento errdo il sondeo requiere un form de distinguir si un uet est o no vF v mner genri trdiionl es usr un it on vlor BUSY pr indir oupinD o EMPTY pr indir disponiiliddF
Bsqueda

v squed es idnti l del endenmiento seprdoF


4
En ingls, a la bsqueda de una cubeta con status

EMPTY se le llama probing.

Sondear es el trmino

que usaremos en castellano para referirnos a la palabra anterior.

5.1. Manejo de colisiones

391

Eliminacin

v eliminin requiere l squed y se remite mrr l entrd que ontiene el elemento eliminr omo EmptyF i hy olisionesD entones se dee ortoiruitr el enle del elemento predeesor pr que punte l elemento suesorF n so espeilmente prtiulr ourre undo se elimin el primer elemento dentro de un list de olisionesF in est situinD el ortoiruito no se puede ejeutr direE tmenteD pues no se tiene un olisin que preed l elemento elimindoF r resolver estoD el segundo elemento en l list se mueve hi l posiin de eliminin yD prtir de est posiinD se efet el ortoiruito hi el terer elemento olindnteF r un hipottio onjunto de olisiones {ki , kj , kk , kl }D l situin se puede interpretr pitriE mente omo en l (gur SFQF uesto que on est tni los elementos pueden moverse de su posiin originl de inserinD este esquem de resoluin de olisiones no permite mntener punteros elementos del onjunto lmendo en l tlD situin indesele en lgunos sosF

ki kj

kj

kk kl

kk kl

pigur SFQX n ejemplo generl de eliminin en un tl hsh on resoluin de oliE siones por endenmiento errdo

Insercin

v inserin es l operin ms omplej y se efet omo sigueX IF i = h(k) mod M PF i A[i].busy == EMPTY = @A A[i].key = k @A A[i].busy = BUSY @A erminrF QF he lo ontrrio = @A eorrer l list enlzd hst el ltimo elementoY se k su posiin en l tlF @A e prtir de kD usr linelmente en l tl l primer entrd on vlor EMPTYY se i el ndie de est entrdF @A A[i].key = k @dA A[i].busy = BUSY @eA A[j].next = A[i]

392

5. Tablas hash

5.1.3.4

Anlisis informal del encadenamiento cerrado

hee sernos fil sumir que si M D entones el nlisis es proximdo l enE denmiento seprdoF ist suposiin lgo irrelist nos permite prehender que pr M ND segn los lems @SFPA y @SFQAD el nlisis puede proximrse X

1 +1 2 2M UN var M SN

@SFIQA @SFIRA @SFISA

in l susein SFIFRFQ @gF QWWA presentremos un nlisis ms forml plile est estrtegiF gunto menor se l rg D ms preis y relist es l proximinF rst que vlor de se umple l proximinc il nlisis de otr tniD explido en SFIFRFS @gF RHQAD nos permite vislumrr que l proximin es uen hst un ftor de rg = 0, 7D es deirD un porentje de oupin del UH7F vo nterior nos indi que si desemos instrumentr el prolem fundmentl on un tl hsh y desempeo esperdo O(1)D entones deemos estimr l ntidd esperd de elementos que vmos gurdr yD en funin de l estiminD esoger M de modo que nos stisfg el vlor de pr el ul los resultdos son uenosD ms un mrgen o ftor de errorF iD por ejemploD espermos 1000 elementosD entones esogemos M = 1465D lo ul ure el UH7 meniondo ms un S7 omo ftor de error ingenierl5 F n mejor pr este enfoque onsiste en empler un re ontigu de l tl exluE sivmenteF in este soD l tl tiene un tmo de M + C entrdsF gundo ourre un olisinD entones el sondeo linel se he entre el rngo [M..C)F esultdos emprios reportdos por IHV indiin que un vlor C 1.14M es su(iente pr esperr dens de olisiones de dos elementosF isto tiene sentido l luz de l prdoj del umpleosD l ul ptent lo stnte prole que es un olisin de dos elementosD pero un nlisis pr olisiones de tres o ms elementos nos indii muh menos proiliddF e este estdio de trtmiento de ls tls hshD prolemente lgn letor hy oservdoD omo desventj de este enfoqueD l limitin que se impone sore el mximo nmero de elementos que podemos gurdr en un tl hsh on resoluin de olisiones por endenmiento errdoF fjo l mism lne de pensmientoD tmin se podr oservrD omo ventj del endenmiento seprdoD que ste permite gurdr ms eleE mentos que el vlor de MF ul es entones el sentido de est tnic il somro y l sorpres hn emrgdo muhos estudintesD inlusive lgunos estudiososD undo se desure queD onsiderndo orretmente los ftores involurdosD en prtiulr el vlor esperdo de ND los enfoques que resuelven olisiones dentro de l mism tl tienden ser de mejor desempeo que el endenmiento seprdoF v prensin de est relidd se filit medinte ls siguientes oservionesX IF in el endenmiento seprdoD ls uets se prtn y liern trvs del mnejdor de memoriF il mnejo de memori dinmiD tnto pr reservrl omo pr lierrlD no slo tom un tiempo de ms respeto un enfoque de resoluin de olisiones que ls uique dentro de l mism tlD sino que su desempeo es vrile segn l rg
5
En ingeniera, suele usarse el trmino factor de seguridad para expresar un sobreclculo en consideracin a la incertidumbre del modelo y errores de clculo en sus diversas fases y facetas.

5.1. Manejo de colisiones

393

del mnejdorD rg que su vez depende de ondiiones tles omo freueni de reservin y lierdo y l ntidd tul de loques reservdosF r el endenmiento seprdoD el prtdo fet l operin de inserinD mienE trs que l lierin lo he sore l elimininF or el ontrrioD on el endeE nmiento errdo y dems estrtegis que uin ls olisiones dentro de l mism tlD no se us el mnejdor de memoriF elguien podr sugerir tener preprtdo un onjunto de uetsD peroD no es esto preido un enfoque errdocF PF in el endenmiento errdo y dems estrtegis que uiquen olisiones dentro de l mism tlD el sondeo linel se he sore uets que estn ontigus en memoriD lo ul proveh el he del hrdwreF or el ontrrioD on el endenmiento seprdoD ls uets estn en direiones de memori disontinusF or onsiguienteD pr el mismo onjunto de olisionesD su inspein dentro de l propi tl tiende ser onsiderlemente ms rpid que su inspein lo lrgo de un den de uets disontinus en l memoriD pues el primero proveh el he y el otro noF
5.1.4 Direccionamiento abierto

gomo y indimosD en el direionmiento iertoD tod olisin se resuelve dentro de l tlY sin puntdor hi l olisinF pundmentlmenteD ls elds ontienen registros on el vlor de lve y un mrD denomind sttusD on tres posiles vloresX
EMPTY BUSY

X l eld est disponile pr lmenr un lveF

X l eld est oupd por un lveF

DELETED

X l eld ontiene un entrd que en lgn momento ontuvo un lve y que luego fue orrdF ws delnte veremos por qu es neesri est mrF

n uet tabla[i] puede estr oupd omo resultdo direto de l funin hsh o porque es un olisin y fue esogid por lgun tni de sondeoF gulquier de los dos sos se distingue medinte omproin del predido h(tabla[i]) = iF i el predido es iertoD entones l lve no fue un olisinF
5.1.4.1 Sondeo ideal (sondeo uniforme)

uesto que ls olisiones deen estr dentro de l propi tlD l estrtegi se remite enontrr un uet uyo vlor se distinto EMPTYF uede deirse que l estrtegi de dispersin errd @direionmiento iertoA es un estrtegi de sondeoF gul es entones l estrtegi de sondeo idelc e presume que es quell que inspeion letorimente ls uetsD es deirD undo ourre un olisinD l prxim uet sonder en donde uir l olisin dee seleionrse letorimente en el interE vlo [0, M 1]F pimenteD est suposiin es onoid omo  hashing o dispersin universalD y se le die idel porque ideliz lo que ser el mejor desempeo de ulquier estrtegi errd de mnejo de olisionesF

394

5. Tablas hash

Lema 5.4

@Cantidad de cubetas inspeccionadas en una bsqueda fallida sobre

una tabla hash con resolucin de colisiones por direccionamiento abierto y sondeo ideal - Peterson 1957 [143]A

e h(k) : K [0, M 1] un funin hsh O(1) que distriuye uniformemente los elementos de K hi [0, M 1]F e T un tl hsh de longitud M on resoluin de olisiones por direionmiento ierto y que ontiene N elementosF e k K un lve ulquierF intonesD el promedio de uets que se visitn en un squed fllid esX

Demostracin

M+1 MN+1 inuniemos UN de l siguiente mnerX UN =

@SFITA

UN =

um de l ntidd de sondeos de i uets en squed fllid i = otl de on(guriones posiles de l tl hsh N

@SFIUA

i tenemos M uets numerds entre 1 y M ls reprtimos ls N lves insertdsD entones el totl de mners posiles de herlo es M N D o seD el totl de on(guriones posiles de l tl hshY esto esX N F e i l ntidd de uets que se inspeionn en un squed fllid on sondeo idelF r que se onsumn i sondeosD ls primers i 1 uets deen tener sttus BUSYD mientrs que el sttus de l ltim dee ser EMPTYF in i sondeos se revisn i 1 uets que ontienen lves mientrs que l iEsim uet sonded est vF v ntidd de disposiiones en que se sonden i 1 lves es equivlente l ntidd de mners de M i distriuir ls N i + 1 lves restntes en ls M k uets restntes6 D es deir N i+1 pr un disposiin de lves prtiulrF il totl posile es l sum pr todos los vlores posiles de iX
M

=
i=1

Mi Ni+1

=
i=1

Mi MN1

@or simetr

n k

n nk

M1 M2 +2 + + MN1 MN1 1 0 (M 1) +M MN1 MN1


M1

=
i=0

(M i)
M1

i MN1
M1

= M
i=0

i MN1

i
i=0

i MN1

ehorD efetos de plir l propiedd de l sumtori del ndie superior de los oe(E
6
Recurdese que
n k

n nk

pues de los

elementos combinados siempre sobran

n k.

5.1. Manejo de colisiones

395

ientes inomiles7 D vmos expresr el ftor i de l segund sum omo i + 1 1X


M1

M
i=0

i MN1
M1

M1

i=0

(i + 1 1)
M1

i MN1 i MN1
( B)

( M + 1)
i=0

i MN1

i=0

(i + 1)

@SFIVA

(A)

@eA es lulle diretmente por l propiedd de l sumtori del ndie superiorX


(A) = (M + 1) M MN = (M + 1) M N

@por simetrA

@SFIWA

il unto @fAD podemos sorer8 el ftor (i + 1) si multiplimos y dividimos por (M N) y luego plimos l propiedd de l sumtori del ndie superiorX
M+1

(B)

(M N)
i=0 M1

i i+1 MN MN1 i+1 MN = ( M N) M+1 MN+1

= =

(M N)
i=0

(M N)

M+1 N

@por simetrA

@SFPHA

ustituyendo @eA y @fA en @SFIVAX


i M N M = ( M + 1) N M = ( M + 1) N M = ( M + 1) N = ( M + 1) M+1 N (M + 1)! (M N) (M N + 1)!N! ( M + 1 ) M! (M N) (M N + 1)(M N)!N! MN M+1 M 1 = MN+1 MN+1 N (M N)
M N

@SFPIA

el sustituir @SFPIA y el vlor N =

en @SFIUA otenemos @SFITA

gonforme M, N D l invers de l expresin @SFITA tiende X

UN

MN+1 = (1 )1 M,N M+1


lim

@SFPPA

N il resultdo proxim M +1 D lo que en l relidd puede ser preisoD pues suele usrse un uet ms que el vlor previsto de M que funj de entinel pr detener el sondeo en todos los sosF
7
La propiedad en cuestin se se dene como
n

k=0

k m

n+1 m+1

n m

n n1 m m1

396

5. Tablas hash

sntuitivmenteD l proilidd de que l inserin ourr en el primer sondeo @el direto resultnte de l funin hshA es F hel mismo modoD l proilidd de requerirse dos sondeosD es 2 F in (nD generlmenteD l proilidd de requerirse k sondeos ideles es k F v ntidd de sondeos que se hen en un squed exitos est expresd por el lem siguienteF
Lema 5.5

@Cantidad de cubetas inspeccionadas en una bsqueda exitosa sobre

una tabla hash con resolucin de colisiones por direccionamiento abierto y sondeo ideal - Peterson 1957 [143]A

e h(k) : K [0, M 1] un funin hsh O(1) que distriuye uniformemente los elementos de K hi [0, M 1]F e T un tl hsh de longitud M on resoluin de olisiones por direionmiento ierto y que ontiene N elementosF e k K un lve ulquierF intonesD el promedio de uets que se visitn en un squed exitos esX

M+1 HM+1 HMN+1 @SFPQA N Demostracin e Si el promedio de uets que se sonden en un squed exitos sore un tl on i elementosF il fundmento de l demostrin es expresr un squed sore un tl que ontiene i elementos en funin de l squed fllid que huo de herse pr insertr el iEsimo elementoD o se Si = Ui1 F il promedio SN puede expresrseD en trminos de @SFITAD de l siguiente mnerX SN = Si = 1 N 1 N
N 1

Ui
i=0 N 1 i=0

= =

M+1 M+1 = Mi+1 N

N1 i =0

1 Mi+1

M+1 HM+1 HMN+1 N

fjo l mism proximin M, N y l proximin de los nmeros rmniE os9 X


M,N

lim

Si =

M+1 ln (M + 1) ln (M N + 1) N 1 M+1 = lim ln M,N MN+1 1 1 = ln 1


M,N

lim

@SFPRA

gomo y hemos indidoD el sondeo idel es lo que se presume que rrojr el mejor desempeoF in l prti es irrel porqueD prte de que es demsido difil generr sondeos letorios e independientes pr ulquier onjunto de lvesD es posileD unque muy improle en l medid en que M se ms grndeD que el sondeo idel no enuentre un uet disponileF il sondeo idel y ls ots expresds por @SFPPA y @SFPRA nos proporionn un refereni de desempeo pr otros enfoques de sondeo que estudiremos inmeditmenteF
9

Hn ln n + O(1).

5.1. Manejo de colisiones

397

5.1.4.2

Sondeo lineal

il sondeo linel es muy similr l del endenmiento errdoX si ourre un olisinD entones l prxim eld sonder ser l siguiente disponileD uy mr se distint de EMPTYD resultnte de l inspein seuenil prtir del ndie ddo por l funin hshF v tl ejemplo que hemos mostrdo pr ls dos estrtegis nteriores se pitoriz omo en l (gur SFRF xotemos que l distriuin de ls lves es idnti l del endenmiento seprdoD pues son resultntes del mismo tipo de sondeoF
0 1 2 3 4 5 6 7 8 9 10 11 k1 k10 k8 k11 k2 k5 k9 k3 k4 k7
E B E B E B B B B E B B E

M 2 M 1 k6

E B

pigur SFRX n ejemplo de tl on resoluin de olisiones por direionmiento ierto

397a

ALEPH tiene un ehD denomindo OLHashTableD que implnt un tl hsh on resoluin de olisiones por direionmiento ierto y sondeo linelF il eh en uestin se export en el rhivo tplolhshFr 397a X tpl_olhash.H 397a template <typename Key, typename Record, class Cmp = Aleph::equal_to<Key> > class OLhashTable { Miembros pblicos de OLHashTable 397b };

OLHashTable represent un tl hshD on resoluin de olisiones iert y sondeo linel de uetsD indizd por lves de tipo Key y que gurd registros de tipo RecordF
Bsqueda
397b

v squed de un lve se remite X Miembros pblicos de OLHashTable 397b (397a) 398a Record * search(const Key & key) { // Comenzar desde ndice hash y sondear hasta encontrar cubeta EMPTY for (int i = (*hash_fct)(key) % M, c = 0; c < M and table[i].status != EMPTY; ++c, ++i) if (table[i].status == BUSY) // Hay una clave en la cubeta? if (Cmp() (table[i].key, key)) // Comparar la clave return &table[i].record;
} return NULL; // No se encuentra la clave

il lzo se detiene undo se sonde un eld uyo sttus se EMPTYF n eld on sttus igul BUSY se revis pr veri(r si ontiene l lve de squedF n eld on

398

5. Tablas hash

sttus DELETED no ontiene lveD pero omo est en el mino de un olisinD hy que ontinur el sondeo sore l siguiente uetF
Insercin

398a

v inserin se remite enontrr l primer uetD se resultnte diret de l funin hsh o del sondeo linelD on sttus distinto BUSYF isto se plnte medinte el siguiente mtodoX Miembros pblicos de OLHashTable 397b + (397a) 397b 398b Record * insert(const Key & key, const Record & record) { if (N >= M) throw std::overflow_error("Hash table is full");
int i = (*hash_fct)(key) % M; while (table[i].status != BUSY) // sondo lineal de cubetas disp. i = (i + 1) % M; // i contiene table[i].key = table[i].record = table[i].status = N++; } celda con DELETED o EMPTY ==> ocuparla key; record; BUSY;

return &table[i].record;

Eliminacin

v eliminin es l operin polmi de est estrtegiD pero es fundmentlmente simpleX @IA enontrr l uet que ontiene l lve eliminr y @PA mrrl on DELETEDF vs uets mrds omo DELETED representn un oste diionl l squedD pues sts deen inspeionrse unque no ontengn lvesF isto plnte un prolem de entrop medid que ument l ntidd de eliminionesD pudiendo ourrir l deE sfortund situin de tener que revisr tods ls uets de l tl en un squed fllid unque l tl onteng muy poos elementosF gonseuentementeD on direE ionmiento iertoD ls eliminiones deen ser exepionlesF
Mejoras a la eliminacin

398b

v entrop usd por l umulin de uets on sttus DELETED puede ontrrE restrse medinte un tni que ierre l reh dejd por l uet elimind dentro de l den de olisionesF he este modoD l ltim uet de l den puede mrrse on el vlor EMPTYF uesto que l eliminin requiere un squedD l interfz pr eliminr se plnte en funin de un puntero l registro que se dese eliminrF he este modoD el usurio puedeD eventulmenteD horrr l repetiin del trjo de squedF hiho estoD no dee resultr difil omprender l rutin de elimininX Miembros pblicos de OLHashTable 397b + (397a) 398a void remove(Record * record) { Bucket * bucket = record_to_bucket(record);

5.1. Manejo de colisiones

399

const int i = bucket - &table[0]; // ndice de brecha for (int switch { case if j = (i + 1) % M; true; ++j) // cerrar la brecha i (table[j].status)

BUSY: (Cmp () ((*hash_fct)(table[j].key), bucket->key)) { // hay colisin ==> mover su contenido hacia table[i] table[i].key = table[j].key; table[i].record = table[i].record; table[i].status = BUSY; table[j].status = DELETED; // deviene DELETED, quiz // candidata a EMPTY i = j; // table[j] deviene cubeta brecha } break; case DELETED: // en este caso cubeta i no puede marcarse con // EMPTY porque si no rompe cadena de sondeo i = j; // table[j] deviene cubeta brecha break; case EMPTY: // en este caso j es cubeta que detiene bsqueda, // pero como que i est ms atrs y no interrumpe // bsqueda se marcam EMPTY y terminamos table[i].status = EMPTY; N; return; // terminar }

ist rutin ierr l reh on sttus DELETED y mr l ltim uet de l den de olisiones omo EMPTYF eunque est mejor perfeion el proeso de squedD rlentiz sin emrgo el de elimininF i ls eliminiones son exepionlesD entones es preferile utilizr el muy simple lgoritmo de mrr l uet on DELETED y derementr NF v mejor plnte el mismo prolem de movimiento de uets que tiene el endeE nmiento errdoF gonseuentementeD tmpoo se pueden mntener punteros elementos de l tlF
5.1.4.3 Anlisis informal del sondeo lineal

il nlisis que presentremos en est susein est sdo en los resultdos presentdos por edgewik y pljolet ISU y se fundmentn en l siguiente proposiinD ul fue el primer lgoritmo que unuth nliz exitosmenteF @Cantidad de cubetas accedidas en direccionamiento abierto y e h(k) : K [0, M 1] un funin hsh O(1) que distriuye uniformemente los elementos de K hi [0, M 1]F e T un tl hsh de longitud M on resoluin de olisiones por direionmiento ierto y sondeo linelF e k K un lve ulquierF intonesD el promedio de uets que se visitn en un
Proposicin 5.2 sondeo lineal - Knuth 1962 [99]A

400

5. Tablas hash

squed fllid esX

UN =

1 1 + 2 2

N1 i =0

Mi (N

(N 1)! 1 1 1+ = i 1)! 2 1

+O

1 N

@SFPSA

y el promedio pr un squed exitos esX

SN =
Demostracin

1 1 + 2 2

N 1

i
i=0

Mi (N

N! 1 1 1+ = i)! 2 (1 )2

+O

1 N

@SFPTA

or su omplejiddD l demostrin es dejd en ejeriioF gonsltese edgewik y pljolet ISU y unuth WWD IHH pr los detlles

@Desempeo esperado de una tabla hash con resolucin de colisiones por direccionamiento abierto y sondeo linealA e h(k) : K [0, M 1] un funin hsh O(1) que distriuye uniformemente los elementos de K hi [0, M 1]F e T un tl de longitud M on resoluin de olisiones por direionmiento ierto y sondeo linelF intonesD el desempeo esperdo de ls operiones de inserinD squed y eliminin es O() = O(1)F
Corolario 5.1 Demostracin

M est otdo un vlor onstnteF uesto que l tl es errdD N <= MD lo ul impli que es onstnteF in virtud de este hehoD ls expresiones @SFPSA y @SFPTA son onstntesF v inserin est determind por l squed fllid yD puesto que @SFPSA es onstnteD el desempeo esperdo tmin es onstnteF irgoD l inserin es O(1)F v squed fllid enj en l mism situin que l inserinF v squed exitos depende de @SFPTAD l ul tmin es onstnteF v eliminin on el eh OLHashTable es determinstimente onstnteF gulquier otro eh sdo en el sondeo linel que requier un squed enj en los sos nteE riores
ehor que hemos mostrdo l proposiin que nos rteriz el desempeo del sondeo linelD meditemos er de lo que ell nos revelF v (gurs SFS y SFT ilustrn los desemE peos pr del endenmiento seprdoD sondeo linel y sondeo idel pr l squed fllid y exitos respetivmenteF
+ + + 4.5 + + + 4 + + + 3.5 + + + + 3 + + + + + + 2.5 + + + + + + + + 2 + + + + + + + + + + + + + 1.5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1+ 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 5 Sondeo ideal Encadenamiento separado Sondeo lineal

0.9

pigur SFSX gntidd de uets inspeionds en un squed fllid

5.1. Manejo de colisiones

401

il sondeo linel se degrd pr l squed exitos undo l tl se enuentr en un VH7 de plenitudY prtir de llD l pendiente deviene importnte y l ntidd de uets que se inspeionn ument notlementeF entes del VH7 l ntidd de inspeiones es en promedio menor que tresD lo ul es eptilsimo hid uent del heF in unto l squed fllidD el sunto empeor ntes pr el sondeo linelF e prtir del TH7 se inspeionn en promedio utro uets en un squed fllidD lo ul es equivlente deir que se sonden utro uets en un inserinF enemos pues un mrgen entre el TH7 y el VH7 en el ul el sondeo linel es en promedio eptleF gul es el porentje de plenitud en que podemos trjr on el sondeo linel de mner segurc v pregunt nterior requiere uestionr ulD entre ls dos urvsD es l ms repreE senttivcD o quizD mejor dihoD ul entre ls dos squeds es l ms importntec or lo generl l squed o onsult de lo que y est en un onjunto es ms freuente que l squed fllidF in este sentidoD l gr( SFT es l ms importnteF fjo este riterio y el onoimiento emprio podemos deir que el sondeo linel es ordle hst un mximo entre el UH y VH7 de plenitudF u tnto uest el QHEPH7 de desoupinc n perspetiv interesnte pr ordr est pregunt nos l proporion omprr el espio oupdo por el endenmiento seprdoF
5 4.5 4 Sondeo ideal Encadenamiento separado Sondeo lineal + + +

+ + + + 3.5 + + + 3 + + + + + 2.5 + + + + + + + + + 2 + + + + + + + + + + + + + + + + + 1.5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1+ 0.9 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8

pigur SFTX gntidd de uets inspeionds en un squed exitos u es lo que degrd el sondeo linelD tn notle en ls gr(sD respeto l sondeo idelc v respuest es onoid jo el rtulo de grupmiento primrioF is evidente que ulquier lve olisin h(k1 ) = i poteni un olisin h(k2 ) = i + 1F egn ument l ntidd de elementos se formn dens lineles de olisiones en torno l posiin iF in emrgoD en l prtiD ests dens son tolerles hst el porentje de plenitud expresdo @VH7AD pues su ontigidd en el rreglo proveh el he del omputdor10 F gon nuestr implntin del endenmiento seprdo tenemos un oupin en memori deX SL = 2MSp ST + 2NSp ST . @SFPUA honde Sp es el espio oupdo por un puntero y ST es el espio oupdo por l lveF in el mismo sentidoD on el direionmiento ierto tenemos un oupin de memoE ri deX SO = M(ST + 1) @SFPVA
10
Estos porcentajes pueden corroborarse (o refutarse) mediante

cachegrind

[129].

402

5. Tablas hash

glrmenteD SO < SL D lo que no signi( que no pued reduirse el onsumo de memori del endenmiento seprdoF or ejemploD podemos usr lists simples y un tl de puros punterosF vs gr(s SFS y SFT muestrn ontundentemente l superioridd teri del enE denmiento seprdo en unto l ntidd de sondeos que se efetn pr ulquier squedF eroD omo y indimos en SFIFQFR @gF QWPAD el sondeo linel proveh el he del omputdorD un plno de ejeuin que es vrios rdenes de mgnitud ms veloz que el eso frgmentdo l memoriD sin provehr el heD que requerir el endenmiento seprdoF or didurD l inserin e eliminin requieren pelr l mnejdor de memori dinmiD mientrs que el direionmiento ierto no lo neesitF gundo se tin l ntidd esperd de lves mnejrD el direionmiento ierto on sondeo linel esD prole pero sorprendentementeD un on los rgumentos en mnoD el mejor enfoque pr mnejr un tl hshF vs rzones se pueden resumir enX  is muy simple de implntrD lo ul impli un jo oste onstnteF  xo utiliz el mnejdor de memori dinmiF  eproveh el he del omputdorF gundo es imprtio el sondeo linelc gomo desventjs podemos enunirX  il direionmiento ierto est supeditdo un estimin orret del nmero de elementos mnejrF i esto fllD entones el grupmiento degrd onsiderE lemente el desempeoF in osiones no es posile disponer de un uen estiminF in estos sosD s omo si se dese un tl hsh generlD es preferile el endenmiento seprdoF  v eliminin en el sondeo linel onllev eventules inonvenientesF il lgoritmo de eliminin que desrrollmos tiene l desventj de mover @por opiA los ontenidos de ls uetsF xo podemosD puesD mntener punteros los elementos de un tl on sondeo linelF i pelmos l eliminin ms simpleD es deirD slo mrr l uet on DELETEDD entones no podemos permitir muhs eliminionesD pues sts degrdn l squedF is posile superr el sondeo linelc v uestin equivle enontrr un form de evitr el grupmiento primrioF eordjes est pregunt en ls suseiones susiE guientesF
5.1.4.4 Sondeo cuadrtico

il sondeo udrtio es fundmentlmente simpleF i ourre un olisin en l posiin iD entones l prxim uet sonder est dd por i2 mod MF v ide de est estrtegi es evitr el grupmiento primrio y l formin de dens lineles de olisiones que son ls que degrdn el desempeo en el sondeo linelF ero est estrtegi onllev el prolem de que es difil grntizr que tods ls uets sen sondedsD pues i2 mod M no neesrimente ure todo el rngo [0, M)F

5.1. Manejo de colisiones

403

gundo l tl lnz el SH7 de plenitudD no hy grnt solut de que el sondeo udrtio enuentre un uet disponileF eiss IVH muestr que es posile enontrr tl uet si M es primoF or didurD on M primo y M = 4k + 3D el sondeo udrtio inspeion tod l tlF il sondeo udrtio impide l formin de dens lineles de olisinD pero no emul el sondeo idel porque l operin i2 no es letori ni simul un omportmiento letoE rioF gonseuentementeD on el sondeo udrtio se present el grupmiento seundrio y l formin de dens en torno ls olisiones i2 mod MF iene l desventjD demsD de ser ms omplejo de implntr y de imponer restriin l selein de M un nmero primoD lgo que no siempre es posileF
5.1.4.5 Doble hash

403

is posile instrumentr el sondeo idelc gonsideremos disponer de M distints funiones hsh {h1 (k), h2 (k), . . . , hM (k)} on omportmientos letorios e independientesF in est situin podemos sonder idelmente si invomos primigenimente h1 (k) yD si hy olisinD entones sondemos ls uets en el orden h2 (k), h3 (k), . . . , hM (k) hst enonE trr un uet disponileF iste esenrio es perfetmente ftileD pero y dee sernos evidente su di(ultdD no slo en unto l esl de MD sino en unto su generlidd respeto l tmo MD s omo el tipo de lve pr el ul se instrumente l fmili de funiones hshF e pesr de ls onsideriones nteriores hy un exelente y reltivmente rt mE ner de emulr el sondeo idel onsistente en utilizr dos funiones hsh pr los primer y segundo sondeos respetivmenteF i los dos sondeos letorizdos usn olisinD enE tones usmos sondeo linelF v ide fundmentl es emulr el sondeo idel pr l primer olisinF sntuitivmenteD si reordmos l prdoj del umpleosD esto tiene sentido porque l proilidd de triple o ms olisin deree exponenilmente @3 , 4 , . . . y s suesivmenteAF iventulmenteD es perfetmente relizleD unque en tiempo onstnte ms ostosoD un triple yD en generlD un mEhshF in ALEPHD un tl hsh on resoluin de olisiones por direionmiento ierto y dole funin hsh es exportd por el eh ODhashTableD el ul se espei( en el rhivo tplodhshFr 403 X tpl_odhash.H 403 template <typename Key, typename Record, class Cmp = Aleph::equal_to<Key> > class ODhashTable { Miembros privados de ODhashTable 404 Miembros pblicos de ODhashTable 405b }; in l prtiD ODhashTable es en interfz idnti OLHashTableD l ni difereni estri en que el onstrutor requiere l segund funin hshF
El problema de la eliminacin con el doble hash

gundo estudimos el sondeo linelD explimos el prolem que plnte l desempeo el heho de que ls uets den mrrse on el vlor DELETEDF in quel entones

404

5. Tablas hash

desrrollmos un tni reminisente l errdur de rehD que plimos l eh OLHashTable y que nos permite pultinmente ir eliminndo el sttus DELETEDF gon el dole hsh no es posile est tni porque pueden existir lves tles que h1 (k) = h2 (k)D lo ul puede rrer un situin en l que se imposile determinr si l lve olision en el primer o segundo sondeoF in generlD el prolem es el mismo si usmos tres o ms funiones hsh oD si se desuriese el soD emplemos sondeo idelF or didurD el mtodo de errr rehs de uets on sttus DELETED @ SFIFRFP @gF QWVAA mueve los ontenidos de ls uetsD movimiento indesele en lguns situE ionesF i usmos dole hshD moD entonesD trtmos on l elimininc ry dos enfoquesD desuiertos por primer vez por dos investigdores jponeses TVD que no mueven ls uets y que su vez eliminn l entrop usd por ls uets DELETEDX IF e mntiene l uent de ls uets on sttus DELETEDF gundo el nivel de rg de uets DELETED lne un umrl ddoD por ejemploD un QH7D tods ls uets on vlor DELETED se mrn on vlor EMPTYF vuegoD se reorre entermente l tl y se exmin ules uets on sttus BUSY se enuentrn en un den de sondeo tl que se requier mrr uets intermedis on sttus DELETEDF ist tni tiene el inonveniente de que onsume tiempo O(M)D lo ul es stnte notle respeto l desempeo esperdo de O(1)F edemsD es difil posiilitr l ejeuin de ls dems operiones mientrs se efet est limpiezF iventulmenteD en menoso de tener que mover lguns uetsD quells olinE dntes on sttus BUSYD que sen produto del sondeo linelD pueden relolizrse medinte simple reinserinF PF v otr tniD en lne y on durin onstnteD es mntener un ontdor de sondeos en d uet que denominremos probe_counterF sniilmenteD d uE et tiene sttus EMPTY y ontdor en eroF egn ourrn inseriones y ls uets estn en un den de sondeoD se inrementn los ontdores de ls uets ompoE nentes de l denF enlogmenteD undo ourren eliminiones se derementn ls uets entre el primer sondeo y l uet elimindF gundo el ontdor de un uet on sttus DELETED deviene eroD entonesD puesto que l uet no rompe ningun den de sondeoD st puede mrrse on seguridd omo EMPTYF r el tipo ODhashTable empleremos l segund tniF
Atributos de

404

ODhashTable in funin de l tni de eliminin que rein hemos presentdo y seleiondoD lo primero que deemos her es de(nir l estrutur de l uetX Miembros privados de ODhashTable 404 (403) 405a
struct Bucket { Key key; // Record record; // unsigned status : 4;// unsigned probe_type : 4;// clave registro status EMPTY, DELETED o BUSY FIRST_PROBE SECOND_PROBE LINEAR_PROBE

5.1. Manejo de colisiones

405

};

unsigned short probe_counter; // contador de sondeos

405a

vos tres primeros triutos se de(nen de form idnti l uet de OLHashTableF il triuto probe_type indi si un lve lmend en l uet es resultnte del primero @FIRST_PROBEA o segundo @SECOND_PROBEA sondeos o del sondeo linel @LINEAR_PROBEA prtir de l terer olisinF xotemos que status y probe_type son mpos de its @nilsA y que mos onformn un yte extoF il ltimo triutoD probe_counterD indiD tl omo mos de explirD l ntidd de lves que olindn en un den de olisiones que prte desde el primer sondeo on l primer funin hshD hst el ltimo sondeo on l segund funin hsh o on lgun ntidd de sondeos linelesF or ejemploD probe_counter == 4D entones esto indi que es uet est en el mino de sondeo que omienz por l primer funin hshD luegoD por l segund funin hshD ms dos uets sondeds linelmenteF vos triutos de l propi tl se de(nen de l siguiente mnerX Miembros privados de ODhashTable 404 + (403) 404 406a Bucket * table; // arreglo de cubetas Hash_Fct first_hash_fct; // primera funcin hash Hash_Fct second_hash_fct; // segunda funcin hash size_t M; // tamao de la tabla size_t N; // nmero de cubetas ocupadas size_t deleted_entries_counter; // nmero de cubetas DELETED size_t empty_entries_counter; // nmero de cubetas EMPTY los ules se iniilizn en el onstrutor de l siguiente mnerX Miembros pblicos de ODhashTable 405b (403) 405c ODhashTable(Hash_Fct __first_hash_fct, Hash_Fct __second_hash_fct, const size_t & len) : table(new Bucket[len]), first_hash_fct(__first_hash_fct), second_hash_fct(__second_hash_fct), M(len), N(0), deleted_entries_counter(0), empty_entries_counter(M) {}
Bsqueda

405b

405c

he ls operiones que requieren sondeosD l squed es l ms simpleX Miembros pblicos de ODhashTable 405b + (403) 405b 406b Record * search(const Key & key) { int i = (*first_hash_fct)(key) % M; // 1er sondeo (1ra fun hash) if (table[i].status == EMPTY) return NULL;
if (table[i].status == BUSY and Cmp() (table[i].key, key)) return &table[i].record; i = (*second_hash_fct)(key) % M; // 2do sondeo (2da fun hash) if (table[i].status == BUSY and Cmp() (table[i].key, key)) return &table[i].record; // sondeo lineal a partir de ndice de 2da funcin hash for (int count = 0; count < M and table[i].status != EMPTY; ++count)

406

5. Tablas hash

} return NULL; // sondeo no encontr la clave

advance_index(i); if (table[i].status == BUSY and Cmp() (table[i].key, key)) return &table[i].record;

Insercin

406a

r mejorr l ompresin del lgoritmo de inserinD ondiin esenil pr l legiE ilidd y orretitudD enpsulremos l reservin de l uet en l siguiente rutinX Miembros privados de ODhashTable 404 + (403) 405a 407a Record* allocate_bucket(Bucket & bucket, unsigned char probe_type, const Key & key, const Record & record) { if (bucket.status == EMPTY) empty_entries_counter; else deleted_entries_counter;
++N; bucket.key = key; bucket.record = record; bucket.status = BUSY; bucket.probe_type = probe_type; bucket.probe_counter++; } return &bucket.record;

406b

v rutin reie un uet en l ul se dese insertr por opi el pr @key,recordA on sondeo de tipo probe_type @FIRST_PROBED SECOND_PROBE o LINEAR_PROBEAF v rutin nterior permite onentrr l inserin en el sunto inters de este estudioX l mner de sonder on dos funiones hsh y luego linel si ourren tres o ms olisioE nesF fsimenteD independientemente de su sttusD d uet sonded durnte l inserinD dee inrementrsele su ontdor de olisionesX Miembros pblicos de ODhashTable 405b + (403) 405c 408 Record* insert(const Key & key, const Record & record) { if (N >= M) throw std::overflow_error("Hash table is full");
int i = (*first_hash_fct)(key) % M; // sondeo con 1ra funcin hash if (table[i].status != BUSY) // cubeta disponible? return allocate_bucket(table[i], FIRST_PROBE, key, record); table[i].probe_counter++; // por aqu sondear colisin i = (*second_hash_fct)(key) % M; // sondeo con 2da funcin hash if (table[i].status != BUSY) // cubeta disponible? return allocate_bucket(table[i], SECOND_PROBE, key, record); do // sondear linealmente a partir de ndice de segundo sondeo e // incrementar cada contador de cubeta sondeada

5.1. Manejo de colisiones

407

} while (table[i].status == BUSY); // parar si DELETED o EMPTY }

// por esta cubeta se sondear una colisin ==> ++contador table[i].probe_counter++; advance_index(i);

return allocate_bucket(table[i], LINEAR_PROBE, key, record);

Eliminacin

407a

v eliminin es l operin ms delid de este ehF st esD en lo que onierne l sondeoD invers l inserinX los ontdores de ls uets sondeds deen deremenE trseF or didurD es durnte est operin undo se detetn uets que pueden mrrse omo EMPTY l veri(r que sus ontdores devienen en eroF es puesD efetos de expresr l eliminin slo en trminos del sondeoD el dereE mento del ontdor de un uet y su eventul mrdo omo EMPTY se he medinte l siguiente rutinX Miembros privados de ODhashTable 404 + (403) 406a 407b void decrease_probe_counter(Bucket * bucket) { bucket->probe_counter; if (bucket->probe_counter == 0) // marcar EMPTY sobre la cubeta? { // s bucket->status = EMPTY; deleted_entries_counter; ++empty_entries_counter; } } hel mismo modoD l uet eliminr es desElierd medinte un rutin simtri l allocate_bucket() empledo pr l inserinX Miembros privados de ODhashTable 404 + (403) 407a void deallocate_bucket(Bucket * bucket) { bucket->probe_counter; if (bucket->probe_counter == 0) { bucket->status = EMPTY; bucket->probe_type = NO_PROBED; ++empty_entries_counter; } else { bucket->status = DELETED; ++deleted_entries_counter; } N; } el igul que en ls tls hsh nterioresD l eliminin reie un puntero l registroD lo ul he ms simple el lgoritmoD pues horr digo pr l squed de l uetF istoD undo ls dos rutins nterioresD nos permitir diser un eliminin que slo

407b

408

5. Tablas hash

408

se onentre en derementr los ontdores entre el primer sondeo y l uet eliminrF he quD puesD l utilidd del triuto probe_typeD pues ste nos permite determinr en que punto de l den de sondeo se enuentr l uetX Miembros pblicos de ODhashTable 405b + (403) 406b 409 void remove(Record * record) { Bucket * bucket = record_to_bucket(record); if (bucket->probe_type != FIRST_PROBE) { const int i_fst_probe = (*first_hash_fct)(bucket->key) % M; decrease_probe_counter(&table[i_fst_probe]); if (bucket->probe_type == LINEAR_PROBE) { // cubeta apartada durante sondeo lineal ==> decrementar 2do // sondeo y a partir de aqu decrementar todas las cubetas // hasta llegar a la que vamos a eliminar const int i_snd_probe = ((*second_hash_fct)(bucket->key) % M); decrease_probe_counter(&table[i_snd_probe]);
int i = i_snd_probe; const int last_index = bucket_to_index(bucket); for (advance_index(i); i != last_index; advance_index(i)) decrease_probe_counter(&table[i]);

} deallocate_bucket(bucket);

5.1.4.6

Anlisis informal del doble hash

gomo y hemos reiterdoD el dole hsh emul el sondeo idelF yserviones empriE s WW indiin que est emulin es stnte erterF es puesD en l prtiD el omportmiento del dole hsh es equiprle l del sondeo idel y ls urvs mostrds en ls (gurs SFS @pgF RHHA y SFT @pgF RHIA orroorn es severinF el WH7 de plenitudD el dole hsh efet IH sondeos pr un squed fllid yD muy importnteD PDS sondeos pr un squed exitosF ists otsD expresds en funin de e independientes del vlor de MD hen que el desempeo esperdo de l squedD exitos o fllidD se onstnteF gonseuentementeD l inserin y l squed on el dole hsh son O(1) hst un WH7 de plenitudF hespus de este umrlD el desempeo puede degrdrse O(M)F i esogemosD por seguriddD un WH7 omo tolerni de plenitudD entones el IHE PH7 de difereni respeto l sondeo linel puede ofreernos un gnni importnte en espio que vr segn se el tmo de l lve y del registroF gul es l gnni en tiempoc eordr l pregunt nterior es delido porque el dole hsh no slo es en tiempo onstnte ms ostoso que el sondeo linelD sino que es stnte prole que el segundo sondeo use un ruptur del heF es queD por su simpliidd y uen desempeo generlD el sondeo linel es l esogeni de fto pr onjuntos pequeos y medinos en los ules se estimle el tmoD o en situiones de progrmin rpid tles omo el prototipeo o l ontingeniF

5.1. Manejo de colisiones

409

v ondd del dole hsh se prei unto myores sen M y N en los ules los IH sondeos que tom l squed fllid y l inserinD son notilsimmente mejores que los TQ sondeos que en promedio tomr l squed fllid si l tl estuviese l WH7 de plenitudF in unto l espioD myores vlores de M y ND myor es el desperdiio en uets vs que requerirmos on el sondeo linelF sdo el WH7 de plenitudD el dole hsh exhie grupmiento seundrio y se degrdn sus operionesF is extremdmente importnte grntizr est otF in sntesisD los riterios que onduen esoger dole hsh omo estrtegi de sondeo se resumen enX IF qrn ntidd de lvesD lo ul impli que el vlor esoger de M es lto y el desperdiio en uets desoupds es myor on el sondeo linelF PF oo mrgen de desperdiioD por ejemploD po memoriF i el estimdo sore N es preiso y no muy grndeD entones el sondeo linel es l seleinY si es N es grndeD entonesD dole hshF i el estimdo de N es impreisoD entones el endenmiento seprdo es l mejor estrtegiF
5.1.5 Reajuste de dimensin en una tabla hash

409

vuego de los nlisis relizdosD no dee ostrnos prehender queD independientemente de l estrtegi pr trtr on ls olisionesD unto ms pequeo se D menor es l proilidd de olisin yD onseuentementeD mejor es el desempeo de l estrtegiF or otr prteD unque se osionlD l ml suerte existe yD eventulmenteD o el onjunto de lves super l estimin de ND o el ml zr us un ntidd lt de olisionesF uede herse lgo l respetoc ry dos mners de trtr on l ml suerteF v primerD sd en el endenmiento seprdo y que ser explid en SFIFU @gF RIPAD reui el rreglo y ls uets pr grntizr un longitud mxim de d list de olisionesF v segundD ojeto de est suseinD onsiste simplemente en prtr un nuevo rreglo on M myor y reuir ls lvesF he este modoD el rejuste on el dole hsh puede plnterse de l siguiente mnerX Miembros pblicos de ODhashTable 405b + (403) 408 const size_t & resize(const size_t & new_size) { Bucket * new_table = new Bucket [new_size]; // aparta nuevo arreglo Bucket * old_table = table; // respaldar valores de antigua tabla const size_t old_M = M; table = new_table; // tabla a nuevo arreglo M = new_size; empty_entries_counter = M; deleted_entries_counter = N = 0;
for (int i = 0; i < old_M; ++i) // reinsertar en nueva tabla if (old_table[i].status == BUSY) insert(old_table[i].key, old_table[i].record); delete [] old_table;

410

5. Tablas hash

return M;

410

v operin esD oneptul y estruturlmenteD senill e idnti pr el sondeo linelF il riterio pr invorl lo determin el que el vlor de supere o se proxime l umrl en que se predie un uen desempeoF in el so del dole hshD podrmos invor el rejuste undo nos proximemos l WH7 de plenitudF is plusile rejustr segn un plenitud de desperdiio de uetsY est estrtegi tiene stnte sentido si ls inseriones esn y l tl se us priniplmente pr l squedF in este so podrmos rejustr l tl un M inferior de mner que disminuymos el desperdiio en uets y respetemos el umrl de desempeoF ry dos uestionmientos est operinF il primero de ellos es su oste O(M) + O(M )D durin en l ul ser prohiitivo ejeutr ulquier otr operinF iste evenE tul prolem se mitigD ms no se evit del todoD ontilizndo lgn tiempo de oioD es deirD un vez que deveng ern l umrlD entones espermos por un tiempo pruE dente ver si no ourren operionesY si expir el tiempo de esperD entones proedemos rejustr jo l espernz de que no estoremos ls otrs operionesF il segundo uestionmientoD vlido slo pr ls tls errdsD es que se mueven los ontenidos de ls uetsF gon el endenmiento seprdo no tenemos este prolemF il rejuste en el endenmiento seprdo tiene dos ventjsF v primerD y menE iondD es l posiilidd de N > MF v segund rdi en simpliidd de tomr previE siones pr permitir l inserin durnte el proeso de rejusteF Mtodos pblicos de GenLhashTable 386a + (384a) 387 size_t resize(const size_t & new_size) { BucketList * new_table = new BucketList [new_size]; BucketList * old_table = table; // guardar estado tabla actual const size_t old_size = M; table = new_table; // tabla vaca con nuevo arreglo M = new_size; busy_slots_counter = N = 0;
for (int i = 0; i < old_size; ++i) // reinsertar cubetas // recorrer lista colisiones en old_table[i] for (BucketItor it(old_table[i]); it.has_current(); /* Nada */) insert((Bucket*) it.del()); // eliminar e insertar en table[] delete [] old_table; // liberar memoria antigua tabla } return M;

5.1.6

El TAD

DynLhashTable

(cubetas dinmicas)

gul es l mner ms generl de exportr un eh sdo en un tl hshc e trtr de un mpeo entre lves y registrosD uy interfz y uso son stnte similres los mpeos que relizmos on roles inrios de squed @tipo DynMapTreeE RFIH @gF QQPAAF

5.1. Manejo de colisiones

411

411a

vos tipos de tls hsh OLHashTable y ODhashTable stisfen este requerimiento on l slvedd de que stos limitn l ntidd de lves l vlor de M seleiondo en onstruinF il eh LhashTable<Key> no tiene este prolemD pero steD no mnej registros diretmente ni trt on l memori dinmiF ry un lterntiv queD en detrimento de un poo de tiempo onstnteD desrrollE remos en SFIFU @gF RIPAF or los momentosD en est sein extenderemos el tipo LhashTable<Key> pr que mneje un rngo soido el onjunto de lves y trte on l memori dinmiF il tipo en uestin lo llmmos DynLhashTableD el ul modeliz un tl hshD on resoluin de olisiones endendD que soi elementos de tipo key on registros de tipo Record y que se espei( en el rhivo tpldynvhshFr 411a D uy estrutur generl es omo sigueX tpl_dynLhash.H 411a template <typename Key, typename Record, class Cmp = Aleph::equal_to<Key> > class DynLhashTable : public LhashTable<Key> { Miembros privados de DynLhashTable 411b
typedef typename DynLhashTable<Key, Record>::Hash_Fct Hash_Fct; };

Miembros pblicos de DynLhashTable 411c

v tl hsh puede ederse omo un rreglo donde los ndies son lves de tipo key y los ontenidos del rreglo son registros de tipo RecordF e tl (nD DynLhashTable export sorergs l operdor []F gomo se veD DynLhashTable heredD tnto prte de su interfz omo prte de su imE plntinD de LhashTable<Key>F wtodos omo los oservdores y el rejuste y estn implntdos por LhashTable<Key>F vo mismo se puede deir pr el mnejo de l esE trtegiF v lor de DynLhashTable se remite entones l de(niin del rngo y l mnejo de memoriF v de(niin del rngo se reliz medinte un uet derivd de LhashTable<Key>::BucketX
411b

Miembros privados de DynLhashTable 411b

(411a) 412b

struct DLBucket : public LhashTable<Key>::Bucket { Record record; DLBucket(const Key & key, const Record & _record) : LhashTable<Key>::Bucket(key), record(_record) { /* Empty */ }

};

411c

n vez de(nid l uetD ls operiones priniples son oneptulmente senillsD pues el mnejo de l estrtegi y est instrumentdo en LhashTable<Key>F v inserin esD puesD omo sigueX Miembros pblicos de DynLhashTable 411c (411a) 412a Record * insert(const Key & key, const Record & record) { DLBucket * bucket = new DLBucket (key, record); LhashTable<Key>::insert(bucket); return &bucket->record; }

412

5. Tablas hash

412a

il digo es linel porque l estrtegi y est implntd en LhashTable<Key>F v squed se remite un wrpper l squed de LhashTable<Key>X Miembros pblicos de DynLhashTable 411c + (411a) 411c 412c Record * search(const Key & key) { DLBucket * bucket = (DLBucket*) LhashTable<Key>::search(key); return bucket != NULL ? &bucket->record : NULL; } v eliminin requiere trnsformr un registro un uetX Miembros privados de DynLhashTable 411b + (411a) static DLBucket * record_to_bucket(Record * rec) { DLBucket * ret_val = 0; size_t offset = (size_t) &ret_val->record; return (DLBucket*) (((size_t) rec) - offset); } gon este mtodoD l eliminin tmin es muy simpleX Miembros pblicos de DynLhashTable 411c + void remove(Record * record) { DLBucket* bucket = record_to_bucket(record); LhashTable<Key>::remove(bucket); delete bucket; }
(411a)

412b

411b

412c

412a

v filidd on se instrument el eh DynLhashTable indiiD un vez msD l ondd del prinipio (nEE(n @ IFRFP @gF PPAAF
5.1.7 Tablas hash lineales

n ondiin sore l ul se sustentn ls prediiones de desempeo que nos ofreen ls diverss estrtegis pr trtr on ls olisiones es que el ftor de rg no exed el umrl pr el ul se umple l prediinF gunto myor se l rgD independienE temente de l estrtegi pr trtr on ls olisionesD myor ser l proilidd de que se degrde el desempeoF emos que el ftor de rg puede disminuirse si rejustmos l tl un myor vlor de M y reuimos ls uetsF eroD omo y semosD este rejuste tiene un preio O(M) + O(M )F v estrutur que trtremos en est susein te l uestin puede irse umentdo el rreglo dinmimentec sntuitivmente deemos ser que esto es posile si usmos un rreglo dinmio del tipo estudido en PFIFR @gF QRAF or este ldoD no tenemos ostes importntes Emyores que O(1)E que pgr por el heho de relolizr l tlF il sunto se releg enontrr un mner de mir dinmimente el vlor de MF el enfoque de tl hsh que estudiremos e instrumentremos en est suseinD ul reliz l gestin de dinmi de MD se le llm dispersin linel @liner hshingAF v tni fue desuiert por vez primer pr lmenmiento seundrio IIH y est presentin est sd en l de vrson IHSF

5.1. Manejo de colisiones

413

il enfoque utiliz un rreglo dinmio DynArray<T>F il vlor de M vr dinmiE mente en funin de F he este modoD ls prediiones de desempeo siempre se umplen sin neesidd de pgr por el rejusteF v tl hsh linel est implntd medinte el tipo LinearHashTable<Key> D el ul se espei( en el rhivo tpllinrshFr 413a D uy espei(in de se es l siguienteX
413a

tpl_linHash.H 413a

template <typename Key, template <class> class BucketType, class Cmp = Aleph::equal_to<Key> > class GenLinearHashTable { Miembros privados de LinearHashTable<Key> 413b Miembros pblicos de LinearHashTable<Key> 418a }; template <typename Key, class Cmp = Aleph::equal_to<Key> > class LinearHashTable : public GenLinearHashTable<Key, LhashBucket, Cmp>

vs estruturs de ls uets son extmente ls misms que ls del tipo LhashTable<Key> estudido en SFIFQFI @gF QVQAF
5.1.7.1 Expansin/contraccin de una tabla hash lineal

413b

iendo table[] un rreglo dinmioD su dimensin se ument y se ontre dinmimente en tiempo O(1)F r ello se mnejn los siguientes triutos umrlesX Miembros privados de LinearHashTable<Key> 413b (413a) 413c float upper_alpha; // factor de carga superior float lower_alpha; // factor de carga inferior

413c

LinearHashTable<Key> mntiene permnentemente el ftor de rg = N/MF hespus de un inserinD se ompr on upper_alphaY si upperalphaD entones l tl se expnde tnts uniddes omo se neesrio pr llevr l rg un vlor inferior upperalphaY durnte este proesoD lguns uets son reuidsF imtrimenteD si luego de un elimininD loweralphaD entones l tl se ontre un o ms vees hst que l rg est por dejo de loweralphaY igulmenteD lguns uets se reuinF il truo de l dispersin linel estri pues en l mner en que linelmente se expnde y ontre l tlD s omo en l form en que se mnej l funin hshF vos vlores iniiles de upper_alpha y lower_alpha se espei(n durnte l onsE truin de un ojeto LinearHashTable<Key> D el ul export modi(dores que perE miten justr dinmimente los vlores umrles de rgF il estdo de expnsin o ontrin de l tl se mntiene medinte los siguientes dos triutosX Miembros privados de LinearHashTable<Key> 413b + (413a) 413b 414a
size_t p; // ndice de la lista que se particiona (o aumenta) size_t l; // cantidad de veces que se ha duplicado la tabla

il rreglo siempre ree o deree por su extremo derehoF il ndie p se refereni de dos mnersX IF table[p + M] es l entrd del rreglo por donde ste se expnde o ontreD segn se l operin y el vlor del ftor de rg F

414

5. Tablas hash

PF table[p] ontiene l list de olisiones que se prtiionr si ourriese un expnE sinF gundo st ourreD lguns uets de l list table[p] se psn l list table[M + p]F imtrimenteD undo ourre un ontrinD tods ls uets de table[M + p] se trsldn table[p]F gundo se expnde se inrement el ndie pY simtrimenteD se derement undo se ontreF
M 0 p 1 2 3 4 5 0 1 p M 2 3 4 5 6

(a) Estado inicial

(b) Luego de la primera expansin

M 0 1 2 3 4 p 5 6

M 7 8 9 0 p 1 2 3 4

M 5 6 7 8 9 10

(c) Luego de 5 expansiones

(d) Luego de 6 expansiones (el valor de

se duplica)

pigur SFUX roeso de expnsin lgi de l tl pr M = 5 r poder lulr el ftor de rg deemos onoer en todo momento el tmo lgio tul de l tl @M AY este vlor lo mntendremos en el siguiente triutoX
414a

Miembros privados de LinearHashTable<Key>


size_t MP; // guarda el valor p + M

413b

(413a)

413c 414b

or didurD este triuto nos pone diret disposiin el lulo p + MF gundo p = 2MD el tmo lgio de l tl se dupli y se reiniin M = 2MD p = 0 y MP = MF in todo momentoD 0 p 2l M 1F v funin del triuto l es entones otr l ontrin l vlor originl de M que hy sido espei(do en onstruinF in d expnsinGontrin hy que estr pendiente del predido p == 2MF r gnr un poo de tiempo de luloD el produto 2M se gurd en el triuto MM = 2MX
414b

Miembros privados de LinearHashTable<Key>


size_t MM; // producto 2*M

413b

(413a)

414a 415b

il proeso de expnsin se ilustr en l (gur SFU pr M = 5F in virtud de lo explidoD l momento de expndir l tl los vlores de pD lD M], [[MP y MM se tulizn de l siguiente mnerX Actualizar estado de expansin 414c (417a)
++p; ++MP; if (p == M) // (p == 2*M) debe duplicarse el tamao de la tabla? { // s ==> modificar el tamao de la tabla a 2*M ++l; // Cantidad de veces que se ha duplicado la tabla p = 0; MP = M = MM; // se les asigna 2*M MM = multiply_by_two(MM); }

414c

5.1. Manejo de colisiones

415

0 0 70 10

70

10

1 11 1676 86 2

206

11

p=1

1 2

206

266

p=2 M=6

M=5

3 13 77

13

77

4 14

99

94

14

99

94

435

15

35

435

15

35

266

1676

86

(a) Antes de expandir

table[2]

(b) table[2] table[6]

expandida

pigur SFVX ijemplo de prtiinGontrin de un list imtrimenteD l ontrin de l tl es el proeso inversoX Actualizar estado de contraccin 415a (417c) if (p == 0) // debe dividirse entre 2 el tamao de la tabla? { // s ==> actualizar tamao de la tabla a M/2 l; // Cantidad de veces que se ha duplicado la tabla disminuye MM = M; // se divide entre dos M = divide_by_two(M); p = M - 1; } else p; // no ==> slo reducir ndice p
MP;

415a

il enfoque dinmio de expnsinGontrin plnte un prolem on l determiE nin del ndie en l tl y el vlor que rroje l funin hshF hd un lve kD trdiionlmenteD el ndie en l tl se determin medinteX

h(k)

mod M ;

415b

pero este vlor r el rngo de entrds [0, M 1] y dej por fuer el rngo de entrds expndids [M, M + p]F il prolem se resuelve medinte el vlor de p y modi(ndo l llmd l funin hsh de l siguiente mnerX Miembros privados de LinearHashTable<Key> 413b + (413a) 414b 417a size_t call_hash_fct(const Key & key) const { const size_t hash = (*hash_fct)(key); const size_t i = hash % M; return i < p ? hash % MM : i; }
Denes:

call_hash_fct,

used in chunk 418.

eordemos que p es el ndie de l list de expnsinGontrinF in el rngo [0, M 1]D l tl ontiene uets signds por

(*hashfct)(key) mod M

@SFPWA

416

5. Tablas hash

mientrs que en el rngo [M, M + p]D ls uets se signn por

(*hashfct)(key)

mod 2M

@SFQHA

416

gundo p = 2MD entones todo el rngo [0, 2M 1] puede ser uierto on el mdulo de 2MF gundo ourre un expnsin se prtiion l list de olisiones uyo ndie en l tl es pF v list l list de olisiones table[p] se reorre entermente y se invo call_hash_fct() pr d lveF equells lves uyo ndie es el mismo de su entrd p permneen en l listD mientrs que quells uyo ndie es distinto M + p son movids hi table[M + p]F v (gur SFV ilustr los estdos ntes y despus de un expnsinF il proeso de prtiin de un entrd desrito puede instrumentrse de l siguiente formX Particionar lista 416 (417a) BucketList * src_list_ptr = table.test(p); if (src_list_ptr != NULL) // table[p] est escrita? if (not src_list_ptr->is_empty()) // table[p] no est vaca' { BucketList * tgt_list_ptr = NULL;
// recorrer lista colisiones y mover cubetas de table[p+M] for (BucketItor it(*src_list_ptr); it.has_current(); /* nada */) { Bucket * bucket = static_cast<Bucket*>(it.get_current()); it.next(); // avance al siguiente elemento de la lista const Key & const int i if (i == p) continue; key = bucket->get_key(); = (*hash_fct)(key) % MM; // pertenece esta clave a table[p]? // s ==> clave sigue en table[p] ==> siguiente

if (tgt_list_ptr == NULL) tgt_list_ptr = &table.touch(MP); // bucket no pertenece a table[p] sino a table[p+m] ==> // eliminar bucket de table[i] e insertarlo en table[p+m] bucket->del(); tgt_list_ptr->append(bucket);

if (src_list_ptr->is_empty()) // table[p] qued vaca? busy_slots_counter; // s ==> un slot vaco } ++busy_slots_counter; // uno nuevo por table[p+M]

il loque onsider l posiilidd de que l list table[p] est v oD inlusiveD que jms hy sido referenidF hel mismo modoD si ninguno de los elementos de table[p] ps table[MP]D entones es posile que l entrd table[MP] no oupe memoriF intendids @se presumeA ls viisitudes de l expnsinD podemos esriir un rutin que l ejeute y que se invod d vez que ourre un inserinX

5.1. Manejo de colisiones

417

417a

Miembros privados de LinearHashTable<Key>

413b + (413a) 415b 417c void expand() { // expandir la tabla hasta que la carga est debajo de upper_alpha for (float alpha = 1.0*N/MP; alpha >= upper_alpha; alpha = 1.0*N/MP) {

Particionar lista 416 Actualizar estado de expansin 414c

Denes:

expand,

used in chunks 418b and 444b.

417b

xotemos que l expnsin slo se d lugr si se exede el ftor de rgF il proeso de ontrin puede interpretrse l invers del de expnsinX psr los elementos de l list table[M + p] hi l list table[p]Y tmin se ilustr en l (gur SFV si se interpret de dereh izquierdF in este soD el proeso Ede ontrinE es muho ms rpidoD pues no es neesrio reorrer ningun de ls listsD slo ontenrle table[M + p] table[p]D l ul l efet diret y onstntemente un operin del eh Dlink @ PFRFU @gF UPAAX Fusionar lista 417b (417c) if (MP < table.size()) // Existe table[MP]]? { BucketList * src_list_ptr = table.test(MP); if (src_list_ptr != NULL) // existe entrada para table[p+M]? { if (not src_list_ptr->is_empty()) // table[p+M] est vaca? { // no ==> fusionar las listas BucketList & tgt_list = table.touch(p);// aparta table[p] tgt_list.concat_list(src_list_ptr); busy_slots_counter; // table[p+M] devino vaca } table.cut(MP); // eventualmente liberar memoria de table[p+M] } } v rutin de ontrinD ul se invo on d elimininD se de(ne entones de l siguiente formX Miembros privados de LinearHashTable<Key> 413b + (413a) 417a void contract() { // contraer la tabla hasta que carga est debajo de lower_alpha for (float alpha = (1.0*N)/MP; alpha <= lower_alpha and MP > len; alpha = (1.0*N)/MP) {
}

417c

Actualizar estado de contraccin 415a Fusionar lista 417b

Denes:

contract,

used in chunk 418c.

vo novedoso de un tl hsh linel es el proeso de expnsinGontrinF or lo demsD estruturlmenteD ls operiones son idntis ls del resto de los enfoques estudidosF

418

5. Tablas hash

5.1.7.2

Bsqueda en

LinearHashTable<Key>

418a

v squedD omo es trdiin de un tl hshD es l operin ms simpleX Miembros pblicos de LinearHashTable<Key> 418a (413a) 418b Bucket * search(const Key & key) { const int i = call_hash_fct(key); BucketList * list = table.test(i); if (list == NULL) // Ha sido escrita alguna vez table[i]? return NULL; // No ==> el elemento no se encuentra en la tabla
if (list->is_empty()) return NULL; // buscar key en la lista de cubetas for (BucketItor it(*list); it.has_current(); it.next()) { Bucket * bucket = static_cast<Bucket*>(it.get_current()); if (Cmp() (key, bucket->get_key())) return bucket; } return NULL;

}
Uses

call_hash_fct

415b.

v didur de est squed respeto los otros tipos de tl hsh es el heho de queD puesto que el rreglo dinmio prt memori en funin de l primer esriturD es prole que hy entrds que no hyn sido prtdsF
5.1.7.3
418b

Insercin en

LinearHashTable<Key>

Miembros pblicos de LinearHashTable<Key>

418a + (413a) 418a 418c Bucket* insert(Bucket * bucket) { const int i = call_hash_fct(bucket->get_key()); BucketList & list = table.touch(i); // aparta memoria table[i] if (list.is_empty()) ++busy_slots_counter;

list.append(bucket); ++N; expand(); }


Uses

return bucket;
call_hash_fct
415b and

expand

417a.

5.1.7.4
418c

Eliminacin en

LinearHashTable<Key>
418a

Miembros pblicos de LinearHashTable<Key>

(413a)

418b

5.1. Manejo de colisiones

419

Bucket * remove(Bucket * bucket) { Bucket * next = static_cast<Bucket*>(bucket->get_next()); bucket->del(); // elimine de lista de colisiones if (next->is_empty()) // lista de colisiones vaca? busy_slots_counter; // s ==> un slot vaco N; contract(); }
Uses

return bucket;
contract
417c.

5.1.7.5

Anlisis de la dispersin lineal

entes de enunir l proposiin fundmentlD es menester notr queD slvo ls expnsiones y ontrionesD un tl hsh linel es similr un tl hsh trdiionl on resoluin de olisiones por endenmiento seprdoF gomo tlD no nos dee ser extro el nlizr l dispersin linel prtir del nlisis relizdo on el endenmiento seprdoF @Cantidad de cubetas revisadas en una bsqueda sobre una tabla hash lineal - Larson 1988 [105] A e h(k) : K [0, M 1] un funin hsh O(1) que distriuye uniformemente los elementos de K hi [0, M 1]F e T un tl hsh linel de longitud M on N elementosF intonesD el promedio de uets que se visitn en un squed fllid esX
Proposicin 5.3

UN
y el promedio pr un squed exitos esX

9 + ; 16

@SFQIA

1 1 1 9 + SN 1 + + . @SFQPA M M 16 Demostracin e l l longitud de d un ls lists de olisiones en el endeE nmiento seprdoF egn el lem SFI @euin @SFUAD pgF QVVAD l = N/MF vos lems SFP @euin @SFVAD pgF QVVA y SFQ @euin @SFWAD pgF QVVAD que estudimos on el endenmiento seprdoD plnten los promedios undo no ourren expnsiones o ontrionesF in este sentidoD sumiendo un ftor de rg yD podemos de(nir ls siguientes funionesX u(y) = y ; @SFQQA 1+
pr el promedio de uets que se inspeion en un squed infrutuos yX

s ( y) = 1 +

1 1 + y M

@SFQRA

pr el el promedio de uets que se inspeion en un squed exitosF n mird ms uios permite interpretr u(y) y s(y) en el mismo sentido undo p = 0D es deirD undo no h ourrido ningun expnsinD l expnsin de duplir

420

5. Tablas hash

el vlor M @vse etulizr estdo de expnsin 414c A o l ontrin de dividir entre M @vse etulizr estdo de ontrin 415a AF r tl hsh linel de tmo MD sus M lists de olisiones pueden distriuirse enX  p primers lists que hn sido prtiiondsF  M P lists que no hn sido prtiiondsD y  p lists resultntes de her prtiiondo ls primers p listsF v situin se puede pitorizr de mner prtiulr @p = 2AD s omo tmin de mner generlD sX
p p+M

...
M

vs lists que no hn sido prtiionds ontienenD en promedioD l uetsF fjo l suposiin de letoriedd pr l funin hshD un list de longitud promedio l se prtiion en dos lists de tmo equittivo l/2F in funin de lo de(nidoD el totl de uets se reprte entones enX

N=

l 2

+ (M p)l +
no particionadas

l 2

= pl + (M p)l = Ml

@SFQSA

particionadas

resultantes de particin

il ftor de rg de un tl hsh linel est entones de(nido porX

Ml p+M = l = p+M M

@SFQTA

e x = p/MD o seD l proporin de lists que hn sido prtiiondsF he este modoD @SFQTA se de(ne omoX l = (1 + x) @SFQUA he @SFQUA proviene l lineliddX l ntidd esperd de uets en un list que no h sido prtiiond ument linelmente de hi 2F gulquier squedD exitos o fllidD tiene proilidd x de herse sore un list prtiiond o resultnte de un prtiinF hel mismo modoD hy un proilidd (1 x) de que l squed depre en un list que no h sido prtiiondF i de(nimos U(x) omo l ntidd esperd de uets visitr en un squed fllid undo un proporin x de ls lists de l tl hn sido prtiiondsD entonesD segn @SFQQAD ul nos indi l ntidd de esperd de uets que se visitrnD U(x) se de(ne omoX

U(x) = x u(l/2) + (1 x) u(l) = x u = (2 + x x2 ) 2

(1 + x) 2

+ (1 x) u((1 + x))
@SFQVA

he l mism mnerD si de(nimos S(x) omo l ntidd esperd de uets visitr en un squed exitos undo un proporin x de ls lists de l tl hn sido prtiE iondsD entonesD segn @SFQRAD ul nos indi l ntidd de esperd de uets que

5.1. Manejo de colisiones

421

se visitrnD S(x) se de(ne omoX

S(x) = x s(l/2) + (1 x) s(l) = x s = x 1+

(1 + x) 2

+ (1 x) s((1 + x))

1 1 (1 + x) (1 + x) + (1 x) 1 + + + M 22 M 2 1 + (2 + x x2 ) = 1+ M 4

@SFQWA

in mos tipos de squedD el mnimo esperdo de uets revisds ourre undo l tl no se h expndido @x = 0A o undo l expnsin h duplido el tmo de l tl @x = 1AF he este modoD ls ots inferiores estn de(nids porX

UN = U(0) = SN = S(0) = 1 + 1 + M 2

xotemosD omo r esperrseD que ests son ls misms ots que pr el endeE nmiento seprdo sin expnsinGontrinF enlogmenteD el mximo esperdo de uets revisds ourre undo x = 1/2 = p = M/2D pues @SFQVA y @SFQWA son mximos undo x x2 es mximoF isto equivle deir que M/2 lists hn sido prtiionds en M/2 lists diionlesD mientrs que quedn M/2 lists sin prtiionrF es puesX

UN = U(0) =

9 8 1 9 + M 16

SN = S(0) = 1 +

il oste lo lrgo de un ilo de expnsin est determindo por l proposiin siE guienteF
Proposicin 5.4 1988 [105]A

@Coste promedio de bsqueda en una tabla hash lineal - Larson e T un tl hsh linel de longitud M on N elementosF intonesD el oste promedio de squed lo lrgo de un ilo de expnsin est determindo porX

UN
pr un squed fllid yX

13 ; 12

@SFRHA

SN
pr un squed exitosF
Demostracin

(13 + 12)M + 12 12M

@SFRIA

il resultdo sle diretmente de integrr @SFQVA y @SFQWAX

UN
yX
1

=
0

(2 + x x2 ) dx 2

@SFRPA

SN

=
0

1+

1 + (2 + x x2 ) dx M 4

@SFRQA

422

5. Tablas hash

es puesD en este tipo de tlD el ftor de rg siempre permnee onstntemente otdoD lo ul posiilit enunir el orolrio siguienteF e h(k) : K [0, M 1] un funin hsh O(1) que distriuye uniformemente los elementos de K hi [0, M 1]F e T un tl hsh linel de longitud M on N elementos y ftor de rg l alpha alphaF intonesD el desempeo esperdo de ls operiones de inserinD squed y eliminin es O(1)F
Corolario 5.2 Desempeo de las operaciones en una tabla hash lineal Demostracin
13 12

v inserin requiere un squed fllidD l ul requiere reorrerD uets en promedioF uesto que es onstnteD @SFRHA es onstnte y segn @SFRHAD l inserin es O(1)F vo mismo ourre pr l squed fllidF 12)M+12 uetsD ntidd r un squed exitos se reorrenD segn @SFRQAD (13+ 12M que tmin es onstnteD pues es onstnteF v squed exitos es por tnto O(1)F i l eliminin es omo l disemosD entones st es O(1) de form deterministF i se s en l squedD entones est rterizd por l squed exitosD l ul y demostrmos es O(1) v grn ondd de este tipo de tl es que no hy neesidd de ejeutr el osE toso rejuste pr mntener el ftor de rg l vlor que ofrez el desempeo espeE rdoY l rg es dinmimente justd en tiempo onstnteF sndependientemente de l ntidd de elementosD l rg siempre estr otd yD por tntoD el desempeo ser onstntemente esperdoF isD puesD este enfoque idneo pr tods ls situiones en que se requier un tl hshc or supuesto que noD por vris rzonesF in primer lugrD us del rreglo dinmioD por ms que nos hymos esforzdo en un ejeuin de lto desempeo undo disemos el tipo DynArray<T>D ste rre ostes onstntes myores que el del rreglo ontiguo trdiionl que emplemos on el endenmiento seprdoF es puesD pr situiones en ls ules se estime orretmente el vlor de ND l dispersin linel es el enfoque ms lento de todos los que hemos estudidoF hiho de otro modoD si se est en pidd de estimr orretmente ND un on un ierto mrgen de inertidumreD entones es preferile doptr lguno de los enfoques que y hemos estudido en funin de ls onsideriones hehs en SFIFRFT @gF RHVAF vos rgumentos son simplesX simpliidd y mejor desempeoF urge entones l pregunt undo deemos usr dispersin linelcF ry dos esenrE ios fundmentlesX IF gundo no se onoz l estimin de ND ul es l situin undo se mnejn onjuntos de mner generlF PF gundoD unque se onoz un estimin mxim de ND ste )ute freuenteE mente entre vlores extremosF in sntesisD l dispersin linel tiene l dole ondd de exhiir desempeo esperdo de O(1) on un onsumo de memori proporionl l ntidd de elementos que se mnejnF hee ser l opin undo se trten onjuntos generlesD por ejemploD los mpeos de lengujes omo python o perl o l propuest l estndr C++ de mpeo hshD llmd hash_mapF

5.2. Funciones hash

423

5.2 Funciones hash


odos los resultdos nltios de desempeo sore los esquems de resoluin de olisioE nes sumen que h(k) : K [0, M 1] es O(1) y que st emul un distriuin de proilidd uniformeF in ests premissD ninguno de quellos resultdos es verzF is ovimente esenil entones que l funin hsh umpl estos requisitosF ero hy muho ms que estos meros requisitos undo se dise un funin hshF
5.2.1 Interfaz a la funcin hash

eplnteemos h(k) : K [0, M 1] en trminos omputionles jo el siguiente tipoE interfzX


template <typename Key> size_t hash_fct(const Key & key);

sdelmenteD l funin tom un lve genri de tipo Key y l trnsform un entero entre 0 y el ms grnde entero que pued representrse en el tipo size_tF eordemos que el ndie dentro de l tl se lul medinteX
(*hash_fct)(key) mod M;

v nturlez de Key no neesrimente es numriD en uyo so deemos enonE trr un trnsformin de key hi el tipo size_tF es que estleemos el siguiente protoolo pr el resultdo de (*hash_fct)(key)X IF i Key no es numrioD trnsformrlo entones l tipo size_tF PF esumiendo que key y se enuentr en el dominio size_t Epor v diret o por l trnsformin nteriorED dispersr key lo ms que se puedD en lo posile on emulin letoriD hi el dominio size_tF ist dispersin es en s l trnsforE minF in ALEPH siempre ulminmos l determinin de h(k) : K [0, M 1] on l llmd (*hash_fct)(key) mod MF es est operinD omo veremos prontmenteD tmin puede ser prte de l dispersinF
5.2.2 Holgura de dispersin

il myor entero posile est supeditdo l myor vlor que se pued representr on el tipo size_tF e l ntidd posile de distintos vlores que puede rrojr h(k) : K [0, M 1] se le llm holgur de dispersinY unto myor se l ntiE dd de nmeros distintos que pued generr l funin hshD myor ser su holgur de dispersinF es puesD en nuestro ontextoD un requerimiento de l funin hsh es tener l myor holgur de dispersin posileF in progrminD l (n de uentsD todo tipo de dto puede representrse omo un seueni de itsF gulquier que se l ndole del dominio KD ki , kj K, ki = kj = ki y kj tendrn seuenis de its distintsF in este sentido es stnte desele que h(k) : K [0, M 1] onsidere todosD los its de un lveD pues de est mner se filit mejor el reprtir K en el espetro size_t y por tnto se ument l pidd de dispersinF ero no st on onsiderr todos los itsF r omprender estoD exminemos un tpi situin del mundo rel de progrminF

424

5. Tablas hash

gonsideremos omo lves simples dens de rteres @char*A y h(k) omo l 1 sum de los rteres de l denF h(k) enj en el rngo [0, n i=0 si ]F i size_t est representdo on 32 itsD el vlor mximo representr on size_t es 232 = 4294967296 n 1 i=0 si F i tenemos lves lftis uy longitud es de 30 rteresD entonesD on vlores de rteres entre [65, 90] [61, 122]11 D el rngo de h(k) es [61 30, 122 30] = [1950, 3660]F isto impli que dejmos de ldo 232 3660 + 1950 vlores posiles que podr tomr h(k) representdo on size_tY si M > 1710D entonesD on ertitudD M 1710 entrds jms sern edids y ulquier se l tni que lidie on ls olisiones ompletmente vnF n tl hsh on es funin puede llmrse un tl mshF
5.2.3 Plegado o doblado de clave

424

gonsiderr todos los its de un lve est supeditdo l tmo del tipo size_t 12 D el ul est determindo por ls rterstis de hrdwre y el ompildorF minD si efetumos operiones ritmtis omo l ejempli(d en l susein preedenteD podemos tener un desordeF e l tni trdiionl pr onfrontr este prolem se le onoe jo el prtiipio plegdo o doldoF legr un lve onsiste en seionrl en pedzos ms pequeos y ominrlos on sumsD oes exlusivos o desplzmientosF n lve de n ytes dee plegrse en sizeof(size_t) ytesF egn l ndole de l lve podemos seleionr pedzos deD por ejemploD n/sizeof(size_t) en un orden esogido pr evdir lgn prtiulr sesgoF or ejemploD si tenemos un lve de PH ytesD y sizeof(size_t) == 4D entones podemos onsiderr ls nils ms signi(tivs de los V ytes entrlesX Plegado de una cadena key de n bytes 424 char buf[sizeof(size_t)]; char * ptr = (char*) key + 6; // comienzo del centro en 20 bytes for (int i = 0; i < 4; ++i) { buf[i] = (ptr[0]4) | (ptr[1]4); ptr += 2; } in pos de un uen dispersinD en el diseo de un uen plegdo es onveniente indgr l zon de l lve en l ul se present ms diversiddD pues es es l zon on myor potenil pr emulr l desed letorieddF imtrimenteD ls zons on menor vriedd son ms usntes de repitenisF
5.2.4 Heursticas de dispersin

in sntesisD pr lulr h(k) : K [0, M 1] tenemos los siguientes requerimientosX IF ue se muy rpidD no slo O(1)D sino que su tiempo onstnte se joF PF ue teng su(iente holgur de dispersinF QF ue los resultdos rterien un distriuin de proilidd uniformeF
11 12
Estos son los valores ASCII para los smbolos latinos no acentuados. O del tipo que se utilice como rango segn sea el caso.

5.2. Funciones hash

425

he estos tres requerimientosD el ms difil es el tereroD pues ls leiones prendids en l generin de nmeros letorios WV indiin que es hrto difilD por no deir imposileD generr nmeros letorios prtir de dtos que no los son13 F xdie hst el presente h desuierto un tni de dispersin generl que emule un distriuin uniformeD pero s se onoen exelentes heurstis queD operds sore un representin numriD emuln l letorieddF
5.2.4.1 Dispersin por divisin

il mtodo de dispersin ms populr es justmente el que hemos empledo trvs de todos los tipos desrrolldosX h(k) = k mod M @SFRRA ero en este tipo de funin es rti l selein del divisorD o seD el vlor de MD el ulD menudoD es el propio tmo de l tl14 F emos que ulquier entero k de n dgitos puede expresrse omo
n1

k=
i=0

di bi

donde d di es un dgito y b es l se del sistem numrioF in este sentidoD l divisin enter k/M puede expresrse omoX

k = M

n 1 i=0 di

bi

@SFRSA

il resto de l divisinD k mod MD puede interpretrse omoX k mod M = k k k/M D lo ulD segn @SFRSAD puede expresrse omoX

k mod M = k
n 1

n 1 i=0 di

bi
n 1 i=0 di

=
i =0

di bi

bi

@SFRTA

ist expresin nos permite ver que los sumndos menos signi(tivosD quellos tles que di ni < MD siempre onformn prte de k mod MD pues stos no sonD en trminos literlesD entermente divisiles por MF es puesD @SFRTA puede expresrse reursivmente omoX
k mod M =
i|di

bi <M

d i bi +

i|di

bi M

di bi

mod M
@SFRUA

i|di bi <M

d i bi +

i|di bi M

di bi M

mod M mod M ,

Indivisible

Resto de restos

13 14

En programacin, decir imposibilidad es muy aventurado, pues lo virtual da espacio para mucho En lo que sigue debemos estar pendientes del hecho de que

posible.

no necesariamente es el tamao de la

tabla.

426

5. Tablas hash

o seD todos los sumndos de k que no son entermente divisiles por M ms el resto de l sum de los restos15 F el primer sumndo de @SFRUA lo llmremos lo indivisile y l segundo el resto de restosF ist interpretin del resto nos filit prehender l trsendeni que tiene l deE ud selein del divisor M sore l onsiderin de dgitos de l seueni que expres kF he @SFRTA se puede ver que los nios dgitos que se ontilizrn on seguridd son los del omponente indivisileF il resto de restos depende de l multipliidd respeto MF egn se el vlor de MD l operin mdulo tomr en uent o no lgunos dgitos de kF n ejemplo puede yudr quellos que n no lo hn relizdoF i tenemos M = 100 y se deimlD entones el resto slo est determindo por lo indivisileD pues los restos restntes son nulos y on ellos el resto de restosF gon M = bw no import ul se el vlor de kD el resto slo onsider los w ltimos dgitos de kF iD por ejemploD los ltimos dgitos de k estn sesgdos estr entre 20 y 30 y M = 100D entones h(k) estr sesgdo ese rngoD lo ul derrum tods ls expettivs de desempeoD pues h(k) distr muho de ser letoriF mpoo st M = 2w D pues podr existir lgn ptrn de multipliidd en los sumndos di bi F or ejemploD 75312 mod 150 = 12 = 75312 mod 100Y undo mirmos que 150 = 10 5 3D no slo vemos un multipliidd omo pr undo M = 100D sino queD omo d sumndo del resto de restos es mltiplo de 5 l inideni de un dgito es su multipliidd por 3Y en trminos ms simplesD d dgito tiene proilidd 1/3 de no ser onsiderdoF or didurD l sum de restos tmin tiene uen proilidd de ser mltiplo de tresF vs onsideriones sore l multipliidd que hemos llevdo o son vlids pr ulquier se numriD en prtiulr pr l inriF gundo seleionmos el mtodo de divisin omo funin hshD deemos estr sumE mente pendientes de est multipliiddD pues el zr puede jugrnos en ontrF i no disponemos de tiempo o nimo pr estudir l multipliiddD entones podemos seleE ionr M omo un nmero primoD lo ul segur que ninguno de los sumndos de k teng lgun relin de multipliiddF il mtodo de divisin undo un selein de MD omo divisor y l vez omo tmo de l tlD es el mtodo de dispersin ms populrF il enfoque de ALEPH onllev diretmente este mtodoD unque no l selein de M omo primoD ul se deleg l usurio del ehF in sD este mtodo es stnte senillo y rpidoD pero no se de tods ls irunstnisY por ejemploD si lo usmos diretmenteD no siempre es fil en funin de tmo originl o del rejuste segurr que M se primoF
5.2.4.2 Dispersin por multiplicacin

iste mtodo tiene l ventj de que puede dptrse pr ulquier tmo de tlF
Denicin 5.2 (Fraccional de un nmero real)
15
Es de notar que
n1

e x un nmero rel positivoD el

k mod M = k mod M = k k/M

i=0

(di bi ) mod M

mod M

o sea, el resto se puede denir simplemente como el resto de los restos. Desarrollamos la representacin segn porque consideramos que permite aprehender mejor.

5.2. Funciones hash

427

frionl de xD denotdo omo {x}D es l prte frionl de xF or ejemploD {1, 6252345} = 0, 6252345F il mtodo de multipliin de(ne un funin hsh del siguiente modoX

h(k) = {k } M

@SFRVA

donde es un ftor de multipliinF gul dee ser el vlor del ftor cF i desemos emulr l letorieddD entones tiene sentido deir que pr fvoreerl l esogeni dee ser lgo irrionlF ues ienD result que l mtemti nos desure un lse in(nit de nmeros llmdos irrionles en el sentido de que no pueden expresrse omo un rzn @frinA yD y hehs ls onsideriones sore l multipliidd de M en l susein nteriorD semos que ls rzones @frionesA tienden sesgr ls lvesF e un nmero irrionl y n un entero positivoF intonesD los n + 1 frionles {}, {2}, {3}, . . . , {n} tienen lo sumo tres longitudes distints y el prximo frionl {(n + 1)} se lej en un de ls myores longitudesF
Proposicin 5.5 (Turn-1958)
16

Demostracin

er unuth WW

il onoimiento que nos port este teorem se trdue en l siguientes oservionesX IF {k} y {(k + 1)} pueden estr seprdos por tres distnis posiles yD PF {k} y {(k + 1)} distn en entre s entre ls dos myores longitudesF ist seprin es lo que emul l letorieddF
1 0.9 0.8 0.7 0.6 {k } 0.5 0.4 0.3 0.2 0.1 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 k

pigur SFWX lores del frionl {k ^} unuth WW sugiere que

51 2 es un uen selein en muhos sos y denomin est dispersin de pioniF eroD por qu es ueno este nmeroc ^ es el reproo de lo que se onoe omo l proporin re o el rdio divinoD pues desde tiempos inmemoriles se die que es l = ^ =
1

16

Citado por Knuth [99].

428

5. Tablas hash

proporin on que los dioses forjron l mundo17 F v proporin D queD omo vemosD es irrionlD lo que indirD quizD sumiendo un hios rionlD que hy lgo de irrionl en lo divinoD no slo es uiu en l nturlezD sino que h omprodo ser stnte uen en un mpli gm de dominiosX msiD rquiteturD ingeniersD etterF le l pen onsttr l distriuin multiplitivD on unos poos vlores de kD trvs de oservin de l gr( SFWD de l ul onsttmos que lves seueniles distn en l dispersinX por ejemploD h(5) = 0 y h(6) = 4D peroD demsD l prieni de l propi gr( ien podr ser l de un distriuin uniformeF vemos pues que l dispersin por multipliin reprte los produtos on su(iente distniD los interl sin lgn orden prente y es independiente del vlor de MF or didurD este mtodo tiene l ventj de tender ser ms rpido que el de divisinD pues es ms rpido multiplir que dividirF ry dems un truo pr multiplir rpidmenteD que nos horr el oste de pelr l ritmti en punto )otnteF

p1 = k h(k)

w bits k = 2w p0 = {k }

,
z bits

pigur SFIHX isquem generl de hsh por multipliin rpid e w l longitud de l lve en its y esojmos M = 2z F uesto que M = 2z D h(k) puede representrse on z itsF e = k representdo en w itsF il produto entero k Eno en punto )otnteE tiene un longitud de 2w its dividid en dos plrs de w its p0 y p1 tles que k = p1 k + p0 {k}F itrimenteD podemos mirr el sunto en l (gur SFIHF he este modoD los z its ms signi(tivos de p0 representn el vlor de h(k)Y h(k) se otiene on desplzr z its hi l izquierd p0 o on un  and ritmtio entre p0 y l plr on formX 11 . . . 1 00 . . . 0 F or grndios didurD si nos segurmos de que se imprD entones este mtodo grntiz que l plr p0 se distriuy uniformementeD tl omo evideni el siguiente teoremF @Aleatoriedad de {k} [108]) e = 2z tl que es imprF e K el onjunto de lvesD el ul est representdo on plrs de w itsF e k = p1 k + p0 {k} | k KF intonesD pr ulquier pr de lves distints k1 , k2 KX
Proposicin 5.6
z veces wz veces

k1 mod 2w = k2 mod 2w
hiho de otro modoD segn l (gur nteriorX

@SFRWA

k1 , {k1 } = k2 , {k2 }
p1 p0 p1 p0

@SFSHA

v proposiin es equivlente enunir que pr ls plrs menos signi(tivs {k1 } = {k2 }F


17
En 6.4.2.2 (Pg. 488) se explica un poco ms el clculo de este nmero y su relacin con los nmeros de Fibonacci. En 6.8 (Pg. 523) se hacen algunas referencias histricas del uso de esta proporcin.

5.2. Funciones hash

429

Demostracin

esummos k1 < k2 y se Dk = k2 k1 F il rgumento de l prue estri en demostrr que (k2 mod 2w ) (k1 mod 2w ) = (k2 k1 ) mod 2w = Dk mod 2w = 0D lo ul tiene sentido porque Dk = 0 y el mdulo exhie l propiedd distriutivF w 1 1 i i en = w i=0 di 2 F il produto Dk puede expresrse omoX i=0 i 2 y Dk =
w 1 w 1

Dk =
i=0

i 2i
i

di 2i
i=0

= =

2w2 i=0

0 20 + 1 21 + + w1 2w1 d0 20 + d1 21 + + dw1 2w1 j dij 2i


j =0

@SFSIA

e dp el primer it menos signi(tivo de Dk uyo vlor es 1Y de este modoD dp1 = dp2 = = d0 = 0F hee sernos lro que l sumtori intern de @SFSIA es nul pr i < pF ehor ienD pr i = p
p

j dpj = 0 dp
j =0

pues los sumndos restntes son nulos ddo que dpj = 0 pr j < pF he este modoD el it p de Dk es 1D lo ul impli que Dk = 0 y k1 mod 2w = k2 mod 2w pr todo k1 = k2 il teorem nterior impli que tods ls lves posiles de w its se distriuyen uniformemente en l plr de p0 = {k}F or supuestoD hr olisiones entre los z its ms signi(tivos que onformn h(k)F ist tni se deu muy ien pr un tl hsh linel en l ul el tmo M se dupliF edemsD no es difil dptrl plrs de its de longitud ritrriF
5.2.5 Dispersin de cadenas de caracteres

ry un vst ntidd de situiones en que l indizin se efet por un den de rteresF is pues importnte meditr sore l dispersin de densD prte de queD omo lo ejempli(mos en SFPFP @gF RPQAD es reltivmente fil onstruir un psim funin hshF i no se dispone del tiempo y nimoD entones es onveniente trnsr por ien onoids y e(ientes funiones hshF vs siguientes son plis y de uen desempeoX IF
429

Hash de Berstein [20] 429

size_t berstein_hash(unsigned char * str) { size_t hash = 5381; int c; while (c = *str++) hash = ((hash  5) + hash) + c; /* hash * 33 + c */ return hash; }

430

5. Tablas hash

vs rzones sore l esogeni del vlor iniil 5381 y el nmero mgio 33 n no hn sido desuiertsF PF
430

Hash del sistema sdbm [137] 430

size_t sdbm_hash(unsigned char * str) { size_t hash = 0; int c; while (c = *str++) hash = c + (hash  6) + (hash  16) - hash; return hash; }

5.2.6

Dispersin universal

or muy uen que se un funin de dispersinD st puede deprr en un serie de olisiones yD onseuentementeD degrdr serimente el desempeo de un tl hshF v ml suerteD improle en el zr pero posileD no neesrimente podr ser l usnte de un serie de olisionesF upongmosD por ejemploD que se tiene onoimiento exto de l funin hsh que se emple en lgun determind pliinF odr ourrir que ese onoimiento se utilizse pr generr inseriones olindntes que degrden el desempeoF guriosmenteD tl omo lo estudimos on el quiksort @ QFPFPFR @gF IUWAAD un mner de evitr l ml suerteD s omo tminD en este soD l mliiD es medinte letorizinD lo que quiz equivlg deir que l ml suerte se omte on el zr18 F n simple mner de letorizr es usr dos funiones de dispersin h1 (k) y h2 (k)F gundo ourr un inserin se seleion l zr entre h1 y h2 l funin hsh que se emplerF gundo se requier usrD se omienz on ulquier de ls funionesF i l lve se enuentrD entones quell es l funin on que pudo herse insertdo19 Y de lo ontrrio se prue on l otr funinF yvimenteD est tni enlentee los lgoritmosD pero omte lgn ml sesgo en l seueni de inserin de lvesF in el mismo espritu de letorizinD en lugr de usr y esoger simultnemente dos o ms funiones de dispersinD podrmos seleionr un l zr d vez que l tl deE veng vF ist tti no degrd en lo soluto el desempeo y rompe ompletmente lgn sesgo desfortundo o mliiosoF v siguiente de(niin estlee un requerimiento que he un onjunto de funiones de dispersin eptlesF
Denicin 5.3 (Familia universal de funciones hash)

e H = {h0 (k), h2 (k), . . . , hW 1 (k)} un olein de funiones de dispersin desde un dominio K l rngo [0, M)F e die que H es universl si y slo siX

k1 , k2 K =
18 19
Notemos que puede ocurrir

|{hi , hj H | hi (k1 ) = hj (k2 )}| 1 |H| M


razn por la cual no se puede saber cul fue la funcin

Azar proviene del rabe zahr que signica dado, pero tambin ores.

h1 (k) = h2 (k),

usada para insertar.

5.3. Otros usos de las tablas hash y de la dispersin

431

hiho de otro modoD el mximo permitido de olisiones que pueden ourrir on dos pres de lves es lo sumo H/MF r sido demostrdo que pr un fmili universl de rdinlidd |H|D el desempeo es ompletmente equiprle en tods ls estrtegis de resoluin que hemos estudido 20 F sgulmente se h demostrdo21 que pr K = {0, 1, . . . , M 1} | |K| = L y

hi,j (k) = (ik + b) mod L mod M


entonesX

@SFSPA @SFSQA

H = {hi,j (k) | 1 i L 1 j L}

enemos pues un mtodo pr disponer de L funiones hsh y her letorizinF


5.2.7 Dispersin perfecta

ry osiones en que el onjunto de lves indizr es (nito y onoidoF in este soD es posile diser un funin hsh iyetiv y ompletD on e(ieni de mputo O(1)D que mpee todo el onjunto de lves hi el rngo [0, M)F il tiempo de eso est grntizdo ser O(1) y no se requiere mnejr olisiones @l funin hsh es iyetivAF e un funin hsh omo l desrit se le llm perfet y existen vrids tnis y progrms onsumdos pr generr l funin en uestinF i ien ls situiones en que se onoe todo el onjunto de lves son osionlesD tmpoo son exepionlesF gonsideremos por ejemplo un diionrio grnde ser grdo esttimente en un hhF in este so vle perfetmente l pen rgr en memori un funin hsh perfet que mpee l plr hi l uiin fsi en el hhF in GNU existe un exelente y generl progrmD llmdo gperf SD pr generr funE iones hsh perfets de ulquier tipo de lveF

5.3 Otros usos de las tablas hash y de la dispersin


5.3.1 Identicacin de cadenas

431

egn l ondd de un funin de dispersinD st puede utilizrseD on proilidd de tino en funin de lidd de l funin hshD pr reonoer un suseueni dentro de otrF v ide fundmentl es que pr dos seuenis s1 = s2 D l proilidd de que h(s1 ) = h(s2 ) es stnte j si l funin hsh es uenF iste es el prinipio de lgoritmos de squed de ptrones inspirdos en un lere lgoritmo llmdo de inEurp WI en honor ls primers persons que lo desE urieronF pue originlmente oneido pr l squed de sudens de rteresF v ide es lulr previmente un huell dtilr @(ngerprintA en el siguiente ontexto lgortmio CGC++ X Algoritmo cndido de Rabin-Karp 431 int rabin_karp_search(char * str, char * sub) { // guardar longitudes de las cadenas involucradas const size_t m = strlen(sub);
20 21
Puede consultarse Cormen, Leiserson y Rivest [32] o Knuth [99]. Consltese Lewis-Denenberg [108] para detalles.

432

5. Tablas hash

const size_t n = strlen(str);

// recorrer la cadena str en bsqueda de la subcadena sub for (int i = 0; i < n - m + 1; ++i) { if (fp_sub == fp_curr) // coinciden las huellas digitales? { // s ==> verificar si &str[i] corresponde con subcadena for (char * aux = str[i], int k = 0; k < m; ++k) if (aux[k} != sub[k]) break; // falso positivo return i; // str[i] contiene la cadena } } return -1; // subcadena no se encuentra

Calcular en fp_sub y fp_curr huellas dactilares sub y de str[0] 433a Multiplicando fact de huella dactilar 433c

Calcular huella dactilar fp_curr para str[i+1] 433b

gomo vemosD el lgoritmo es estruturlmente simple y muy similr l squed en ruto de l sudenD l ul es O(n m)F he esto se desprende oservr que pr que el lgoritmo de inEurp vlg l pen respeto l de fuerz rutD se den umplir dos ossX IF il lulo del loque glulr huell dtilr fpurr pr striCI ser rpidoD O(1)D preferilementeF
433b

dee

PF v ntidd de flsos positivos dee ser pequeD pues su ourreni rre omE prr los m rteres de l sudenF gonseuentementeD en l medid en que se detetn ms flsos positivoD el lgoritmo de inEurp tender hi O(n m)Y simtrimenteD menos flsos positivos hrn l lgoritmo O(n)F il lulo de l huell dtilr no es otr os que un funin hsh de(nidD sore un den de rteres genri str de l siguiente mnerX
| str |1

h(str) =
i=0

stri B| str |1i

mod M

@SFSRA

donde B es l se del sistem de odi(in @rdixA de un smolo perteneiente un den de rteres y stri es el iEsimo smolo de l seueni strF is menester reordr de SFPFRFI @gF RPSA l propiedd distriutiv que nos indi que el resto de l sum es igul l resto de l sum de los restos22 D o se

(i + k) mod M = (i mod M) + (k mod M)

mod M

@SFSSA

v propiedd distriutiv del mdulo tmin se pli l produtoY es deir

(ik) mod M = (i mod M)(k mod M)


22
Vase tambin (5.47) y la nota a pie de la pgina 425.

mod M

@SFSTA

5.3. Otros usos de las tablas hash y de la dispersin

433

eprehender el rter distriutivo del mdulo nos es muy til porque nos permite lulr @SFSRA en funin de los mdulosX
h(str) =
| str |1 | str |1

i=0

stri B| str |1i mod M mod M mod M mod M

mod M mod M mod M


(5.57)

=
i=0 | str |1

(stri mod M) B| str |1i

=
i=0

(stri mod M) (B| str |1i

mod M) mod M

433a

lo ul es summente grndiosoD pues nos evit preouprnos por el eventul desorde numrio de ls sums y potenisF in y urp WI demuestrn mo h(str) dispers muy ien onforme el vlor de M se seleion omo un nmero primoF gon el onoimiento de @SFSUAD podemos odi(r el loque iniilX Calcular en fp_sub y fp_curr huellas dactilares sub y de str[0] 433a (431) const size_t radix = 256; // radix de un smbolo size_t fp_sub = 0; size_t fp_curr = 0; for (int i = 0; i < m; ++i) { fp_sub = (radix*fp_sub + sub[i]) % M; fp_sub = (radix*fp_curr + str[i]) % M; } il loque tom O(m)F v huell dtilr pf_sub slo se lul un vezD pero l de l suden de str en l posiin i dee lulrse n i veesF i usrmos el mismo proedimiento que pr el loque glulr en fpsu y fpurr huells dtilres su y de strH 433a D entones el lgoritmo de inEurp ser O(n m) on un oste onstnte myor que el lgoritmo fuerz rutF il truo del lgoritmo reside en que l huell digitl pr l suden stri+1 de longitud mD que resumiremos omo h(stri+1 )D puede lulrse en tiempo independiente de m en funin del vlor previo de h(stri )Y todo lo que deemos her es restrle h(stri+1 ) el primer sumndo de h(stri )D pues ste y no es prte de l huell digitlD y dirle el nuevo sumndo pr stri+1 F he esto se dedue omputr h(stri+1 ) segnX

h(stri+1 ) = B h(stri ) + stri+m Bm stri mod M ;

@SFSVA

433b

est tni es llmd dispersin enrolld @hsh rolled AF fjo estos trminosD el vlor de fp_curr pr l iEsim iterin se lul sX Calcular huella dactilar fp_curr para str[i+1] 433b (431) fp_curr = (radix*(fp_curr - str[i]*fact) + str[i + m]) % M;

433c

Multiplicando fact de huella dactilar 433c

(431)

const size_t fact = (size_t) pow(radix, m - 1); // radix^(m-1)

il mtodo de huell dtilr se pli un mpli ntidd de situionesF in primer lugrD el lgoritmo puede herse ms generl pr reonoer ptrones i o triE dimensionles si los ojetos en el plno o espio se onsidern omo mtries o rreglos tridimensionlesD los ulesD l (n de uentsD deprn en seuenisF

434

5. Tablas hash

n gnni de este lgoritmo es que l longitud de l suseueni usr no inide durnte el rrido de l seueni en l que se usY esto ontrst on otros lgoritmos que se enlenteen medid que l seueni usr es de myor longitudF il vlor de M puede seleionrse letorimenteD de mner tl que un hipottio dversrio no pued tr el lgoritmo olondo omo un entrd un seueni usr que use muhs olisionesF gomprtir liremente el onoimiento es un ondiin esenil pr ser ser humnoF ero djudirse el mrito de otroD no slo puede rrer explotin del prjimoD sino que v ontr l eseni de l vid en omuniddF il djudirse flsmente un desurimiento sin herlo heho se le denomin plgioF in el desurimiento de idesD s omo en ulquier otro orrD se puede plgirF r lo esritoD y en generl pr tod produin representle omo un seueniD puede modi(rse el lgoritmo de inEurp pr veri(r utomtimente si eventulmente se h ometido lgn plgioF in este so se dise un funin hsh que modelie l seueni sospehos de plgioF
5.3.2 Supertraza

v omputin est llen de prolems que mnejn onjuntos de dtos muy grndesY muhos de ellos intrtles en el sentido de que l ntidd de dtos es exponenilF ry osiones en ls ules un dto o resultdo dee gurdrse efetos de no repetir su lulo yD sore todoD de no repetir los dtos que sueden l rein desuiertoF gonsideremos un seueni genri de dtos < d1 d2 d3 dn > tl que d2 depende del lulo de d1 y s seuenil y genrimente pr todo dto di+1 D que requiere lulr di F v ide de gurdr d dto di en un tl hsh es queD segn l ndole del prolemD puede ourrir que el lulo de un dto di prez repetidoY si ste es el soD entones el lulo de tod l seueni susiguiente di @di+1 di+1 di+k >A se repite de nuevoF omemos omo ejemplo un lgoritmo que fuerz rut desur mners de uir n reins en un tlero de jedrez sin que sts se menenF is deirD omenzmos por poner un rein en el esque a1 y proseguimos reursivmente poner l siguiente en l seueni de esques de b sin que st mene a1F gomenzndo por b1D vemos que l rein menz l puest en a1Y lo mismo ourre si l ponemos en b2F ists dos ominionesD que de(nitivmente no onduen l soluinD es onveniente gurdrls efetos de que en un tlero de n n esques no repitmos el lulo en vnoF r elloD l seueni explord se gurd en un tlF eunque el prolem nterior puede resolverse sin neesidd de un tlD ste ilustr dos spetos de intersX @IA l ide de gurdr estdo de lulo pr evitr repetiinD y @PA el heho de que onforme ument l dimensin del tlero y l ntidd de reins ument l ntidd de estdosF v ntidd de posiiones de menz que deemos gurdr pr no repetir lulos ument exponenilmente segn l dimensin nF in trminos prtiosD no podemos mntener un tl que gurde tods ls posiiones de menzD pero s podemos mrr lguns posiiones medinte un funin hsh y notrls en un tl de itsF tms sremos si un posiin prtiulr ontiene olisionesD pero l ide de no repetir los lulos se mntieneF gon est tni no es neesrio gurdr l posiin de menz en siF is l funin

5.3. Otros usos de las tablas hash y de la dispersin

435

hsh y el mrje en 1 en l tl lo que expres el gurdr l posiinF il prolem de est tni es que dejremos de lulr posiiones de olisinD pero esto se puede tr letorimente repitiendo el lgoritmo on distints funiones hshF v ide es urir proilstimenteD medinte diverss funiones hshD tods ls posiE iones posilesF ist muy interesnte tniD llmd supertrz UUD se desuri en el dominio de l explorin de grfos dinmios de estdoF in lugr de gurdr entermente el estdo de luloD se dise un funin de dispersin y se mr en un tl de its su priinF iste mrje ument onsiderlemente l pidd de lmenmientoD pues slo se requiere un it por estdoD lo que ument l pidd de trtr on l esl del prolemF in emrgoD no hy mner determinist de ser si un hsh lmendo en l tl orresponde l estdo tul de lulo o se trt de otro estdo que us olisinF in otrs plrsD es imposile grntizr que todos los estdos se urnF smposiilidd en grntizr no exluye su proiliddF he ll que l inertidumre nterior se tque ejeutndo l tni on distints funiones hsh de mner de ofreer un uen expettiv de urir todos los estdos posilesF
5.3.3 Cache (el TAD

Hash_Cache

no de los priniples usos de ls tls de dispersin es l instrumentin de hesF n he es un tl soitivD (nit pero de eso rpidoD que se olo entre un progrm y un onjunto de dtosF r que se reompense l utilizin de un heD ste dee ser muho ms rpido que el simple eso l onjunto de dtosF itrimenteD el sunto puede interpretrse del siguiente modoX

Programa a velocidad Vp

Cache a velocidad Vc

Medio contentivo de datos a velocidad Vd

in un situin lgortmiD el progrm se ejeut un veloidd vp y ede dtos de un onjunto que oper veloidd vd F il he oper veloidd vc | vp < vc < vd F he este modoD undo se dese usr un dto se revis primero el he yD si se enuentrD entones se reuper el dto sin neesidd de pgr el oste que rre ederlo veloidd vd F v ide se sustent en l regl VHEPH meniond en QFSFI @gF PIPAF v plr he proviene del vero glo her que signi( esonder y he lgo de lusin porque vees ste se mnej trnsprentementeD es deirD el progrm ede los dtos sumiendo que se enuentrn en un medio esperdo sin onoimiento er de l existeni del heY est es l situinD por ejemploD en hrdwreF vos frneses tmin le llmn ntememori @ntememoire AD sore todo pr el hrdwreF ry un vst ntidd de irunstnis en que el uso de un he he l difereni entre un muy lto y pore desempeoF vmpson IHQ he un exelente exposiin l respeto desde l perspetiv del diseo de sistemsF vs situiones tpis se pueden resumir omo sigueF

436

5. Tablas hash

5.3.3.1

Medio de almacenamiento de datos distinto a memoria principal

lys niveles de lmenmientoD en orden reiente l veloidd y dereiente l piE ddD pueden lsi(rse omoX IF wemori priniplF PF wemori seundri @disos durosAF QF wemori teriri @ghEywD hhD memoris )shD intsAF RF wemori remot @disponile por redAF gundo los dtos que ed un progrm se enuentren en un nivel de memori ms lento que l memori priniplD entones un he entre l memori prinipl y el medio de lmenmiento puede elerr sustnilmente l ejeuinF
5.3.3.2 Estructuras de datos estticas

or rzones de divers ndole puede ourrir que hy que empler un estrutur de dtos que no es deud ierto estilo de reuperinF or ejemploD supongmos que mntenemos en un rol inrio de squed un onE junto de registrosF il rol se indiz por lgun lve prinipl numriD por instniD un nmero de dulD lo ul permite un reuperin esperd de O(lg(n)) pr ulquier registroF gon menos freueni se requiere reuperr por lgun lve lfti seundriD un pellidoD omo lsio rquetipoF in este so puede ser muy ostosoD y prolemente inneesrioD indizr medinte un segundo rol inrioF in su lugr podemos gurdr en un heD indizdo por pellidoD los registros ms reientemente onsultdosD sen por dul o por pellidoD de modo tl que eventulmente nos horremos un squed seuenil sore el onjunto de lvesF
5.3.3.3 Clculos que puedan repetirse

in muhs osiones se requieren her lulos omplejos suseptiles de repetirseF in este so podemos gurdr en un he l seueni originri del lulo y su resultdoF he este modoD si l dinmi del progrm requiere de nuevo el luloD ste y se enuentr disponileF in est situin suele usrse prte de l seueni originri de lulo omo lve de un funin de dispersinF
5.3.3.4 Implementacin

n rtersti muy importnte de un he es que es (nitoD es deirD tiene un piE dd mximD onsiderlemente menor que l del onjunto ojeto de l gestinF gundo se requiere insertr un dto en un he llenoD entones hy que seleionr uno de sus dtos ontenidos y sustituirlo por el nuevoF gul dee seleionrsec i esogemos un dto que ser referenido en un futuro ernoD entonesD en lo que onierne l dto sdoD perdemos l ondd del heF in este sentidoD l lolidd de refereni sugiere seleionr el dto ms ntiguoF

5.3. Otros usos de las tablas hash y de la dispersin

437

437a

rolemente l tl hsh es l estrutur de dtos idne pr implntr un he en memori priniplF isenilmente por un rznX es en promedio el esquem de reuE perin ms rpido que se onoeF n he es un yud l desempeoD pero su ondd depende del ptrn de esoF xo esD puesD rtio el tener un desempeo grntizdoD pues si ste fuese el soD entones no deermos de usr un heF or didurD l funin hsh puede representr prte de lo que se pretend gurdrF gomo ejemplos teneE mos los usos desritos en ls dos suseiones nteriores y el dispersr lulos que puedn repetirseF ALEPH ontiene un ehD llmdo Hash_Cache uy espei(in est ontenid en el rhivo tplhshheFr 437a X tpl_hash_cache.H 437a template <typename Key, typename Data, class Cmp = Aleph::equal_to<Key> > class Hash_Cache { Entrada de Hash_Cache 437c Miembros privados de Hash_Cache 437b Miembros pblicos de Hash_Cache 440b };

437b

Hash_Cache implement un he indizdo por lves de tipo KeyD que gurd dtos de tipo Data y est implntdo medinte un tl hshF uesto que un he est destindo ser (nito y lo ms rpido posileD el uso de un tl hsh linel no pree onsejleF reh est otin podemos deir que ulquier enfoque de resoluin de olisiones @y sus tipos reliondosA puede usrse omo trsfondo de implntinF or su simpliiddD usremos el tipo LhashTable<Key>X Miembros privados de Hash_Cache 437b (437a) 438a LhashTable<Key, Cmp> hash_table;
isto impli de(nir un lse de uetD l ul se de(ne del siguiente modoX Entrada de Hash_Cache 437c (437a) class Cache_Entry : public LhashTable<Key, Cmp>::Bucket { Data data; Miembros privados de entrada de Hash_Cache 437e Miembros pblicos de entrada de Hash_Cache 437d }; // fin class Cache_Entry
Denes:

437c

Cache_Entry,

used in chunks 438a, 440, 441, and 44345.

437d

il oservdor de l lve se hered de LhashTable<Key, Cmp>::BucketD y el del dto se de(ne omoX Miembros pblicos de entrada de Hash_Cache 437d (437c) Data & get_data() { return data; } r determinr ul de los elementos ontenidos en el he es el ms ntiguoD ls uets de l tl hsh se ordenn en un ol desde l entrd ms ntigumente edid hst l menos reientemente usdF in lugr de usr un ol seprd de(nimos el siguiente triuto interno l entrd del heX Miembros privados de entrada de Hash_Cache 437e (437c) 438b Dlink dlink_lru; // enlace a la cola lru
Denes:

437e

dlink_lru,

used in chunk 438.

438

5. Tablas hash

438a

i tenemos un puntero l mpo dlink_lruD entones el siguiente mro de Dlink @ PFRFU @gF VHAA gener un funin de onversinX Miembros privados de Hash_Cache 437b + (437a) 437b 438c LINKNAME_TO_TYPE(Cache_Entry, dlink_lru);
Uses

Cache_Entry

437c and

dlink_lru

437e.

438b

y un puntero l triuto dlink_lru se otiene medinteX Miembros privados de entrada de Hash_Cache 437e + Dlink* link_lru() { return &dlink_lru; }
Uses

(437c)

437e 438d

dlink_lru

437e.

438c

v es rnimo ingls de lest reently usedD ul literlmente signi( menos reientemente utilizdoF in nuestro disurso stellno empleremos l frse ms ntigumente edidoF dlink_lru es un dole enle dentro de un list doleE mente enlzd irulrD uyo estdo se mntiene desde el ojeto Hash_Cache medinte los siguientes triutosX Miembros privados de Hash_Cache 437b + (437a) 438a 439b Dlink lru_list; // cabecera de la lista lru size_t num_lru; // nmero de elementos en lista lru
Denes:

lru_list,

used in chunks 440, 441, and 444b.

438d

or ms ntigu que pued ser un entrd en el heD hy situiones en ls ules se requiere que st no se sustituy undo est lleno e ingrese un nuev entrdF iste tipo de entrd se mr omo trnd @lockedA y se identi( medinte el siguiente triutoX Miembros privados de entrada de Hash_Cache 437e + (437c) 438b 438e bool locked; // indica si la entrada est trancada gundo otenemos l entrd ms ntigumente edid neesitmos ser si est o no ontenid en l tl hshF r eso mntenemos un triuto que indi este estdoX Miembros privados de entrada de Hash_Cache 437e + (437c) 438d 439a bool is_in_hash_table; // indica si entrada est contenida dentro // de tabla hash vos triutos de Cache_Entry onformn l estrutur mostrd en l (gur SFIIF on
dlink de hash key data locked is in hash table dlink inside dlink lru

438e

pigur SFIIX istrutur de uet de un entrd en el he tres doles enlesX el de l uet de l tl hsh @dlink de hshAD dlink_lruD que es el de l ol ordend por tiempo de esoD y dlink_insideD que es el de l list de uets que estn dentro de l tl hshF e est ltur de l expliinD quiz lguien y hy plntedo omo ojein el usr el endenmiento seprdo en lugr de un enfoque errdoF i utilizsemos el sondeo

5.3. Otros usos de las tablas hash y de la dispersin

439

439a

linelD entones tendrmos el prolem de que ls entrds se pueden mover y eso impide que otr estrutur de dto punte un ojeto Cache_EntryF es puesD hremos que el eh Hash_Cache no prte ni liere memori pr ningun entrd cache_entryY sts se prtn en un rreglo ontiguo en tiempo de onstruinF he este modo provehmos el propio he del omputdor y no desperdiimos tiempo en llmds l mnejdor de memori sniilmenteD ests entrds estn enolds jo el siguiente enleX Miembros privados de entrada de Hash_Cache 437e + (437c) 438e Dlink dlink_inside; // enlace a la lista de entradas que uyo estdo es mnejdo en Hash_Cache medinte los triutosX Miembros privados de Hash_Cache 437b + (437a) 438c 439c Dlink inside_list; // lista de cubetas apartadas y metidas en tabla size_t cache_size; // mx nmero de entradas que puede tener cache
Denes:

439b

cache_size, used in chunks 440b and 444b. inside_list, used in chunks 443a and 445.

cache_size lru_list inside_list

.....

pigur SFIPX istdo iniil del rreglo ontiguo de uetsF ods ls entrds perteneen l list lruF vos enles ls ols de un Cache_Entry se mnejn del siguiente modoX IF lru_listX ol de entrds ordends desde l ms ntigumente edid hst l ms reientemente edidF sniilmenteD el he est vo y tods sus entrds preEprtds enlzds por est olF PF inside_listX list de entrds insertds en l tl hshF sniilmenteD est list est vD pues el he no ontiene ningn elementoF vs entrds en est list tmE in estn ordends desde l ms ntigumente edid hst l ms reientemente edidF xotemos sin emrgo que puesto que est ol slo ontiene entrds lgiE mente perteneientes l heD su estdo no neesrimente es el mismo que el de l ol lru_listD l ul orden entrds que perteneen o no l heF v ni funin de l list inside_list es proveer un iterdor simple sore los elementos del heF i l tl est llenD entones inside_list deviene vF QF locked_listX vs entrds trnds se sn de lru_list y se introduen en un terer list de(nid sX
439c

Miembros privados de Hash_Cache

437b + (437a) 439b Dlink locked_list; // lista de entradas trancadas size_t num_locked; // nmero de elementos trancados

440a

440

5. Tablas hash

il enle dlink_lru es exluyenteX o l uet est en lru_list o en locked_list iventulmenteD unque no deer de ser el soD puede umentrse el tmo del heF r eso se prt un nuevo rreglo de Cache_EntryF r poder lierrlosD los loques de rreglos de Cache_Entry se enlzn en un list que de(nimos del siguiente modoX Miembros privados de Hash_Cache 437b + (437a) 439c 440c typedef Dnode<Cache_Entry*> Chunk_Descriptor; Chunk_Descriptor chunk_list;
Denes: Uses

440a

chunk_list, used in chunks 440b and Cache_Entry 437c and Dnode 83a.

444b.

440b

chunk_list es el ltimo triuto de Hash_Cache y de(ne l list de loques @rreglos de Cache_EntryAF istmos listos pr de(nir el onstrutorX Miembros pblicos de Hash_Cache 440b (437a) 443a
Hash_Cache(size_t (*hash_fct)(const Key&), const size_t & __hash_size, const size_t & __cache_size) : hash_table(hash_fct, __hash_size, false), num_lru(0), cache_size(__cache_size), num_locked(0) { // apartar entradas del cache Cache_Entry * entries_array = new Cache_Entry [cache_size]; // apartar el descriptor del arreglo std::unique_ptr<Chunk_Descriptor> chunk_descriptor (new Chunk_Descriptor (entries_array)); chunk_list.insert(chunk_descriptor.get()); // insertar cada Cache_Entry en lista lru for (int i = 0; i < cache_size; i++) insert_entry_to_lru_list(&entries_array[i]); }
Uses

chunk_descriptor.release();
Cache_Entry
437c,

cache_size

439b,

chunk_list

440a, and

insert_entry_to_lru_list

440c.

oservemos que el onstrutor pel un mtodo interno insert_entry_to_lru_list()D el ulD junto on otros mtodos privdos en torno lru_listD se de(nen del siguiente modoX
440c

Miembros privados de Hash_Cache

437b + (437a) 440a void insert_entry_to_lru_list(Cache_Entry * cache_entry) { num_lru++; lru_list.insert(cache_entry->link_lru()); } void remove_entry_from_lru_list(Cache_Entry * cache_entry) { num_lru; cache_entry->link_lru()->del(); }

441a

5.3. Otros usos de las tablas hash y de la dispersin

441

Denes:

insert_entry_to_lru_list, used in chunks 440b, 443d, remove_entry_from_lru_list, used in chunk 443c. Uses Cache_Entry 437c and lru_list 438c.

and 444b.

v mism lse de rutins se de(ne pr l list locked_listF il (n de l ol lru_list no es otro que instrumentr el orden segn el esoF ry vris situiones en l ules est ol tiene que tulizrseX IF gundo se insert un nuevo elemento en el heD otenemos su Cache_Entry del frente de lru_listD el ul ontiene l elemento ms ntigumente edido Ereordemos que tods ls entrds Cache_Entry se meten en est ol durnte l onstruin del heEF PF gundo referenimos un elemento dentro del he deemos espei(r que ste es el ms reientemente edidoY pr eso eliminmos su Cache_Entry trvs del dole enle dlink_lru y lo reEinsertmos en el trseroF isto lo ejeut l siguiente rutinX
441a

Miembros privados de Hash_Cache

437b + (437a) 440c 441b void do_mru(Cache_Entry * cache_entry) { cache_entry->link_lru()->del(); // elimine de posicin actual lru_list.insert(cache_entry->link_lru()); // llvela a trasero }

Denes: Uses

do_mru, used in Cache_Entry

chunks 441c and 443b. 437c and

lru_list

438c.

do_mru() he cache_entry l entrd ms reientemente edidF


QF gundo eliminmos un elemento del he lo uimos en el frenteD in que instrument l siguiente rutinX
441b

Miembros privados de Hash_Cache

437b + (437a) 441a 441c void do_lru(Cache_Entry * cache_entry) { cache_entry->link_lru()->del(); // elimine de posicin actual lru_list.append(cache_entry->link_lru()); // llvela al frente }

Uses

Cache_Entry

437c and

lru_list

438c.

do_lru() he cache_entry l entrd ms ntigumente edidF


ehor estmos prestos pr mostrr un rutin rtiD l ul seleion l entrd ms ntigu @ontenid o no en el heA y l he l ms reientemente edidX Miembros privados de Hash_Cache 437b + (437a) 441b void remove_entry_from_hash_table(Cache_Entry * cache_entry) { cache_entry->link_inside()->del(); hash_table.remove(cache_entry); cache_entry->is_in_hash_table = false;

441c

442

5. Tablas hash

do_lru(cache_entry); } Cache_Entry * get_lru_entry() { // obtenga entrada ms antigua; menos recientemente accedida Dlink * lru_entry_link = lru_list.get_prev(); Cache_Entry * cache_entry = dlink_lru_to_Cache_Entry(lru_entry_link); // si cache_entry contenida en tabla ==> eliminarlo if (cache_entry->is_in_hash_table) remove_entry_from_hash_table(cache_entry); do_mru(cache_entry); // entrada deviene ms recientemente accedida } return cache_entry;

Denes:

get_lru_entry, used in chunk 443a. remove_entry_from_hash_table, used in chunk 444a. Uses Cache_Entry 437c, do_mru 441a, and lru_list 438c.

remove_entry_from_hash_table() elimin cache_entry de l tl hsh y l torn omo l entrd ms ntigumente edidF get_lru_entry() es l rutin rti que seleion

45 lru_list false true inside_list false false 1 0

0 1 2 3 4 5 6 7 8 9

false false 375 true true

false false 58 false true

false false 479 false true

locked_list

pigur SFIQX istdo de un he de tmo V on tl hsh de tmo IHF e muestr el rreglo de l tl hsh y el rreglo preprtdo de uetsF vos enles de l tl hsh son ontiguos y los de l list de entrds que estn dentro de l tl puntedos y los de l list vD trzdosF v entrd on lve QUSD que es olisin en l tl hsh on l lve RSD est trndD por eso pertenee l list locked_list

5.3. Otros usos de las tablas hash y de la dispersin

443

443a

l entrd ms ntigumente edid y l ul se invo undo se insert un nuevo elemento en el heF ixplido estoD podemos mostrr l inserinX Miembros pblicos de Hash_Cache 440b + (437a) 440b 443b Cache_Entry * insert(const Key & key, const Data & data) { Cache_Entry * cache_entry = get_lru_entry(); // entrada ms antigua cache_entry->get_key() = key; // escribirle el par cache_entry->get_data() = data; inside_list.insert(cache_entry->link_inside()); hash_table.insert(cache_entry); cache_entry->is_in_hash_table = true; return cache_entry; }
Uses

Cache_Entry

437c,

get_lru_entry

441c, and

inside_list

439b.

443b

il he mntiene un suonjunto de los ltimos cache_size elementos edidos on l espernz de queD si se referenin de nuevoD entones no se pgue un oste lto por su squed en el onjunto priniplF r usr en el he proveemos l siguiente rutinX Miembros pblicos de Hash_Cache 440b + (437a) 443a 443c Cache_Entry * search(const Key & key) { // buscar en la tabla hash Cache_Entry * cache_entry = (Cache_Entry*) hash_table.search(key); if (cache_entry != NULL) // fue encontrada la clave? { // s ==> hacerla la ms recientemente usada do_mru(cache_entry); move_to_inside_front(cache_entry); } return cache_entry; }
Uses

Cache_Entry

437c and

do_mru

441a.

443c

v squed refres l entrd en el he en el sentido de que l he l ms reienE temente edidF r trnr un entrdD es deirD pr segurr que ell no se sd del he undo ourr un inserinD se emple el siguiente mtodoX Miembros pblicos de Hash_Cache 440b + (437a) 443b 443d void lock_entry(Cache_Entry * cache_entry) { remove_entry_from_lru_list(cache_entry); insert_entry_to_locked_list(cache_entry); cache_entry->lock(); }
Uses

Cache_Entry

437c and

remove_entry_from_lru_list

440c.

443d

enlogmenteD l entrd se puede destrnrX Miembros pblicos de Hash_Cache 440b + void unlock_entry(Cache_Entry * cache_entry) { remove_entry_from_locked_list(cache_entry); insert_entry_to_lru_list(cache_entry); cache_entry->unlock();

(437a)

443c 444a

444

5. Tablas hash

}
Uses

Cache_Entry

437c and

insert_entry_to_lru_list

440c.

444a

v eliminin de un elemento en el he puede preer un operin redundnte e inneesriD pues slo st on no eder ms un entrd pr que st slg del heF in emrgoD el onoimiento ertero de que un lve jms ser edid no slo permite disponer su entrd pr un inserinD sino que poteni otrs lves de ene(irse del heF or esoD segn l ndole de l pliinD puede o no ser muy vlios l siguiente primitiv de elimininX Miembros pblicos de Hash_Cache 440b + (437a) 443d 444b void remove(Cache_Entry * cache_entry) { remove_entry_from_hash_table(cache_entry); }
Uses

Cache_Entry

437c and

remove_entry_from_hash_table

441c.

444b

v selein del tmo del he puede ser rti pr el desempeo glol de un sistemF n pidd insu(iente puede her que ls inseriones reemplen entrds que sern referenidsF i esto ourreD entones l squed siempre ser vn y el desempeo del eso glol se degrdr un punto peor que si no se tuviese el heF e este fenmeno se le llm thrshing 23 y puede ser summente ostoso si el he se emple en el mino rtio de un sistemY uestin que suele ser el soF es puesD undo se opt por el empleo de un heD se deeD en l myor medid posileD disponer de un estimin preis de l relin de refereni l onjuntoF in esto puede ser muy importnte l relin VHEPH @ QFSFI @gF PIPAAD pero uent hid del oste que puede rrer un mio o error en l estiminD es reomendle que el tmo del he pued justrse en tiempo de ejeuinF v ide es que si durnte l ejeuin se revel neesrio her un justeD entones ste se posileD lo ul dist de ser un enfoque dinmio omo el de un tl hsh linelF in virtud de esto disemos l siguiente rutin de expnsinX Miembros pblicos de Hash_Cache 440b + (437a) 444a 445 void expand(const size_t & plus_size) { const size_t new_cache_size = cache_size + plus_size;
// apartar plus_size nuevas entradas Cache_Entry * entries_array = new Cache_Entry [plus_size]; std::unique_ptr<Chunk_Descriptor> // apartar el descriptor chunk_descriptor (new Chunk_Descriptor (entries_array)); // Calcular nuevo tamao de tabla y relocalizar sus entradas const float curr_hash_ratio = 1.0*cache_size/hash_table.capacity(); const size_t new_hash_capacity = new_cache_size/curr_hash_ratio; hash_table.resize(new_hash_capacity); // meter nuevas entradas en lru_list
23
La traduccin literal de este trmino es difcil porque pensamos que no existe un equivalente directo castellano. En el contexto del cache, thrashing alegoriza agelar, pues, por lo general, cuando un cache entra en este estado acarrea una penalidad demasiado severa sobre el sistema que lo usa.

5.4. Notas bibliogrcas

445

for (int i = 0; i < plus_size; i++) insert_entry_to_lru_list(&entries_array[i]); chunk_list.insert(chunk_descriptor.release()); cache_size = new_cache_size;


Cache_Entry 437c, cache_size lru_list 438c.
439b,

}
Uses

chunk_list

440a,

expand

417a,

insert_entry_to_lru_list

440c, and

445

xos flt un ltimo detlleX un iterdor sore los elementos del heX Miembros pblicos de Hash_Cache 440b + (437a) 444b class Iterator : public Dlink::Iterator { Iterator(Hash_Cache & cache) : Dlink::Iterator(&cache.inside_list) {}
Cache_Entry * get_current() { Dlink * dl = Dlink::Iterator::get_current(); return Cache_Entry::dlink_inside_to_Cache_Entry(dl); }
Cache_Entry
437c and

};
Uses

inside_list

439b.

uesto que se iter sore l list inside_listD slo los elementos ontenidos en el he son vistosF uesto que est list est ordend por tiempo de esoD el orden de visit es desde el ms reientemente edido hst el menos reientemente edidoF

5.4 Notas bibliogrcas


in su exelso liro sore progrminD vn der vindenIUI menionD metfrimenteD que si l le tose estr en un isl desiert y le diesen esoger un sol estruE tur de dtosD entones st ser l tl hshF por qu un progrmdor virtuoso onE sider tn vitl est estruturc uiz porque l no se un ser domindo por un ide determinist del mundoF in lo onreto de l progrmin podemos deir que l dispersin es un tni ompletmente sd en l proiliddD es deirD rudmente hlndoD en eso que nestrlmente llmmos l suerte o zrD y que hoy se mir on desdnF gmo ser de extr est (li por el determinismo que muy poos progrmdores se pertn de que empler un uen funin de dispersin pr usr en un rregloD sin preouprse de ls olisiones ni de mrr ls eldsD tiene muhs mejores proiliddes de enontrr rpidmente un lve que l mer squed seuenilF il homre que dijoX preferir ser fortundo que uenoD ten un profund perspetiv de l vidF v gente teme reonoer que un grn prte de l vid depende de l suerteF h miedo pensr en todo lo tnto sore lo que no tenemos ontrolF ry momentos durnte un prtido en que l pelot golpe l redD y por un frin de segundo puede seguir hi delnte o ien er hi trsF gon un poo de suerteD sigue hi delnte y gns FFF o quiz noD y pierdes 24 F ist it de un pelul de oody ellen nos indii un poo el desdn que en est po tenemos hi el zrF re
24
Prembulo de la pelcula Match Point.

446

5. Tablas hash

unos PSHHD os hemritoD quiz uno de los primeros que pens en l ide tul de tomoD de que en el zr y l espontneidd hy onsieni F wquivelo vio en l suerte un ftor determinnte pr el destino de los goernntesF elegoriz l vid omo un ro uyo )uir otidino l suerte pod mirY un inunE dinD por ejemploF fjo ese sentido legrioD l reomend preprrse pr undo l suerte tornse y lo legoriz on l onstruin de un diqueF in l vid modernD esto puede trduirse l horroF in l vid de l progrminD un estrtegi de resoluin de olisionesF egn unuthD l ide de dispersin fue desuiert independientemente por rF F vuhn y emdhl et l en IWSQ WWF il endenmiento seprdo y el mtodo de divisin pree primero desuierto por humey QWF il sondeo linel fue sugerido por irshov RUD uyo nlisisD extremdmente di(ulE tosoD fue desuierto por primer vez por unuth en IWTPD omo l mismo expli en un not pie de pgin de WW pgF SQTF il modelo de sondeo idelD extremdmente til omo mro de nlisis de ls tnis de sondeoD fue introduido por eterson en IWSU IRQF v prdoj del umpleos es un prolem lsio de l teor de proiliddesF n presentin riguros puede enontrrse en el lsio peller RVD RWF ist prdoj fue generlizd en l lere funin Q de mnujn SIF n nlisis de su pliin en l progrmin puede enontrrse en SHF v tni presentd en este texto pr eliminr ls elds mrds DELETED on el dole hsh fue presentd por primer vez en TVF n implntin onretD prte de l qu expuestD no es onoid plimenteF v dispersin universl fue desuiert en IWUU por grter y egmn PVF v dispersin linel fue populrizd por el ul vrson IHS y su desurimiento fue reportdo por primer vez en IWVH por itold vitwin IIHD en el dominio de ls ses de dtosF v dispersin perfet pree (nles de los os setentF n rtulo prdigmtio es de gihelli PWF

5.5 Ejercicios
IF isri un lgoritmo de eliminin de un tl hsh on olisiones seprdmente endends en lists simplemente enlzdsF PF v funin de eliminin de los eh LhashTable<Key> y DynLhashTable no veri( si el registro eliminr pertenee l tlF hisut diferentes enfoques pr efetur est veri(inF QF hemuestre l proposiin SFPF @CA RF ixplique detlldmente l onstruin de l expresin @SFPUAF SF esumiendo endenmiento seprdo on lists simples y un tl de puros punterosD lule el onsumo de espioF e prtir de ul vlor de y ST el direionmiento errdo es menos ostoso en espioc

5.5. Ejercicios

447

TF gonsidere un tl hsh on resoluin de olisiones por endenmiento seprdo @on lists enlzdsAD un tmo de tl de M = 13 y un funin hsh h(k) = k mod MF @A hiuje l tl resultnte de l siguiente seueni de inserin

23, 13, 20, 5, 7, 2, 40, 50, 30, 45, 12, 21, 33, 34
@A esumiendo que ls lves estn entre I y IHHD que no se repiten y que d lve tiene l mism proilidd de usrseD luleX iF roilidd de que un lve se enuentre en l tlF iiF roilidd de que un lve se enuentre en l tl y que se requier reorrer dos @PA o ms nodos durnte su squedF UF esum un tl hsh on resoluin de olisiones on endenmiento seprdoF esum un ntidd esperd de lves de 105 on un desviin de 104 F ugier un tmo de tl tl que el ftor de rg no exed del 97 7F glule l longitud esperd de d list de olisin li y su desviin tpiF VF v estrutur de uet utilizd por el eh ODhashTable utiliz un mpo espeil denomindo probe_typeF heduz l mner en que se puede determinr en tiempo de ejeuin l informin portd por este mpoF hiho de otroD omo puede presindirse de este mpoc WF in el eh ODhashTableD deduz un mner de presindir de los mpos de l uet status y probe_typeF @CA IHF hd un tl hsh on resoluin de olisiones por direionmiento iertoD deduz un lgoritmo generl de dos fses que reduz l mnimo l ntidd de uets on estdo DELETEDF il lgoritmo dee poder ser plido pr ulquier estrtegi de resoluin por direionmiento iertoF v primer fse onsiste en exminr l tl y mrr on EMPTY tods ls entrds on vlor DELETEDF v segund fse estudi ls uets on vlor BUSY y determin ules uets on estdo EMPTY deen ser mids l estdo DELETED de mner que l lve pued ser lolizdF xo est permitido mover los registros ontenidos en ls uetsF @CA IIF inunie ls ventjs y desventjs del lgoritmo enunido en l pregunt nteriorF IPF glule un expresin similr @SFPUA que ompre el oste en espio del eh ODhashTable on el de OLHashTableF IQF e un tl hsh de tmo m = 23 on resoluin de olisiones por direionmiento ierto y uso de dos funiones hshX @A h1 (k) = k mod 23 @A h2 (k) = 1 + (k mod 19) esum omo esquem de signin de elemento l frmul (h1 (k) + i h2 (k)) mod m, m = 23D donde i es el nmero de olisiones de k l momento de l inserinF is

448

5. Tablas hash

deirD si h1 (k) no tiene olisin @i = 0AD entones el elemento es insertdo en l posiin h1 (k)F i hy un olisinD entones el elemento es insertdo en h1 (k) + h2 (k)Y si hy dos olisionesD entones el elemento es insertdo en h1 (k) + 2h2 (k)D y s suesivmenteF @A isri l posiin dentro de l tl @o diuje l tlA luego de l siguiente seueni de inserin
4 13 27 31 28 26 40 23 47 1

@A esum que ourre un onsult entre un totl de 20 posiles lvesF iF gul es l proilidd de enontrr l lvec iiF gul es l proilidd de no enontrr l lvec iiiF gul es l proilidd de que un squed exitos se resuelt on l primer funin hshc ivF gul es l proilidd de que un squed exitos se resuelt on l segund funin hshc IRF rg un nlisis omprtivo entre los eh DynLhashTable y ODhashTableF inunie ventjsD desventjsD similitudes y diferenisF ISF hd un tl hsh linelD lule l ntidd esperd de llmds l funin hsh d vez que ourre un inserin o squedF @CA ITF v implntin de DynLhashTable hered de LhashTable<Key> l implntin y prte de su interfzF uesto que DynLhashTable es derivd plimente de LhashTable<Key>D hy mtodos de LhashTable<Key>D que no son prte de l interfz de DynLhashTableD que pueden llmrse desde un instni de DynLhashTableF or ejemploD el usurio podr invor l inserin de LhashTable<Key> desde un ojeto de tipo DynLhashTableX
DynHashTable<int, Record> table; LhashTable<int>::Bucket bucket = new LhashTable<int>::Bucket (key); table.insert(bucket);

ixplique un menismo pr evitr que esto ourrF is deirD pr impedir oD en el peor de los sosD pr detetr que el usurio llm l inserin de LhashTable<Key> y reportr un error en tiempo de ejeuinF IUF gonsidere el prolem de l existeni de un ojetoF isto esD ddo un puntero un ojeto de tipoD digmos ObjectD se dese veri(r si l direin de memori punt efetivmente un ojeto de ese tipoF hisut tods ls lterntivs posiles pr diser un sistem generl de veri(in de existeni de ojetosF IVF smplnte ls lses LhashTable<Key> y LhashTableVtl<Key> pr que utilien lists simplemente enlzds en lugr de dolemente enlzdsF

5.5. Ejercicios

449

IWF smplnte ls lses LhashTable<Key> y LhashTableVtl<Key> pr que utilien lists enlzds ordendsF rg un estudio omprtivo on l implntin trdiionl explid en SFIFQFI @gF QVQAF PHF glule l proilidd de que l operin k mod 150 slo tome en uent los dos dgitos menos signi(tivosF PIF gonsidere un tl hsh linel on vlor iniil M = 5 y un ftor de rg mximo permitido de u = 0, 9F r l siguiente seueni de inserinX
181 186 10 6 5 58 191 22 113 7 83 118 138 122 16 18 150 39 48 157

hiuje el estdo resultnte de l tl luego de ls inserionesF

rboles de bsqueda equilibrados


uiz lgun vez l noin de equilirio se nos hy preido jo un ide nestrlE mente inmemorle y uyo speto visul es el siguienteX

v imgen pitoriz un rtefto ntiqusimoD on tendeni tul l desusoD pero n vigente en lgunos essos ontextosD uy (nlidd es pesrD o seD medir pesosF v ide es poner en uno de los pltillos lo que se dese pesrD mientrs que en el otro se ponen pesos de refereni tulmente llmdos plomdsF gundo los pltillos lnzn igul ltur se de que h qu %l %r %um Y de equus D que signi( igulD y l %r D que er el nomre romno de l plomd y n vigente omo un medid rel de peso o vlor eonmioF il rtefto en uestinD hogo se le denomin lnzD pero nto los romnos tmin lo mentron omo lir D pues stos re(nron el menismo de tl form que el rzo de l lnz pod desplzrse y sustituir lguns plomds de refereniF hesde entonesD l lnz o lir h simolizdo situiones en ls ules se nhel lgun espeie de iguldd o equilirioY en prtiulrD h sido el smolo de l justiiD quiz l virtud ms difil de ultivrF in el mito de los roles inriosD el equilirio se pitoriz jo l y ien onoid imgen siguienteX
T

L(T )

R(T )

vs rms del rol T tienen pesos equivlentesD es deirD ontienen ls misms ntiddes de nodosF T estrD entonesD en equilirio o equilirdoF eursivmenteD si todos los nodos de T estn equilirdosD entones l ltur de T tiende O(lg(n))D lo ul he que el rendimiento de l squed sore un rol se tmin O(lg(n))F el igul que ourre on ls virtudesD los roles strtos son uenos en l medid en que stos estn equilirdosF RSI

452

6. rboles de bsqueda equilibrados

6.1 Equilibrio de rboles


in un primer instni podemos intentr lnzr un equilirio sdo en l siguiente de(niinX
Denicin 6.1 (Equilibrio fuerte de Wirth [182])

n rol inrio es equilirdo

ni T , | | L(ni )| | R(ni )| | 1
fjo est de(niin podemos diser un primer lgoritmo que nos equilire un rolF xuestro lgoritmo utiliz los roles extendidos @effiA explidos en RFII @gF QQSAF vs operiones requerids ls inluimos en el rhivo tpllnetFr (never dened) F n de ls ventjs de un effi es l operin de selein @ RFIIFI @gF QQUAAF wedinte est operin podrmos seleionr l lve del entro y herl rz del rE olF il nmero de nodos en mos ldos diferir lo sumo en unoF i plimos este proedimiento reursivmente otenemos un rol equilirdo segn irthF equerimos un funin que seleione un nodo segn su posiin in(j y lo su hst l rzF l operin se de(ne omo sigueX Rutinas de equilibrio 452a 452b template <class Node> inline Node * select_gotoup_root(Node * root, const size_t & i) { if (i == COUNT(LLINK(root))) return root;
if (i < COUNT(LLINK(root))) { LLINK(root) = select_gotoup_root(LLINK(root), i); root = rotate_to_right_xt(root); } else { RLINK(root) = select_gotoup_root(RLINK(root), i - COUNT(LLINK(root)) - 1); root = rotate_to_left_xt(root); } return root;

452a

452b

select_gotoup_root() seleion el iEsimo nodo del rol on rz root y lo sue hst l rzF i tommos un rol de n nodosD seleionmos el nodo orrespondiente l posiin n/2 y lo suimos hst l rzD entonesD nivel del nodo n/2D l difereni de nodos entre su surol izquierdo y dereho es lo sumo unoF i plimos el mismo prinipio reursivmenteD deduimos el lgoritmo siguienteX Rutinas de equilibrio 452a + 452a
template <class Node> inline Node * balance_tree(Node * root) { if (COUNT(root) <= 1) return root;

6.1. Equilibrio de rboles

453

root = select_gotoup_root(root, COUNT(root) / 2); LLINK(root) = balance_tree(LLINK(root)); RLINK(root) = balance_tree(RLINK(root)); } return root;

select_gotoup_root() puede relizrse medinte l prtiin por posiin explid en RFIIFU @gF QRIAF isto es delegdo ejeriioF

(a) Antes de balancear

(b) Despus de balancear

pigur TFIX ijemplo de equilirdo de un rol letorio medinte balance() i el rol originl fue onstruido prtir de un seueni letoriD entones su ltur tiende O(lg n) y el desempeo de select_gotoup_root() llmdo desde balance_tree() es O(lg n)F in este momentoD el rol qued prtiiondo en dos prtes equittivsD d un on un onsumo de tiempo proporionl l mitd de l enE trdF odemosD puesD plnter l siguiente euin reurrente pr el desempeo de balance_tree()X 1 si n 1 T (n) = . 2T (n/2) + O(lg n) si n > 1

uponiendo que n es un poteni ext de 2D relizmos l trnsformin n = 2k = k = lg nF isto nos plnteX T (2k ) = 2T (2k1 ) + k . hividiendo l euin entre 2k D tenemosX

T (2k ) 2k

= = =

T ( 2 k 1 ) k + k 2 k 1 2 T ( 2 k 2 ) k 1 k + k 1 + k k 2 2 2 2 T ( 2 k 3 ) k 2 k 1 k + k 2 + k 1 + k = 1 + 2 k 3 2 2 2
k k i=1

i 2i

=
@TFIA

T (n) n

= 1+
i=1

i 2i

= T (n) = n + n
i=1 Sk

i . 2i

454

6. rboles de bsqueda equilibrados

v soluin de l reurreni dependeD puesD del vlor de l sumtori Sk = ul puede resolverse por perturinX
k

k i i=1 2i D

Sk = k+1 2k+1
i=1 k

i = 2i i+1 2i+1 i 2i+1


Sk 2

Sk +

=
i=0 k

=
i=0

+
i=0

1 2i+1

Sk 2

=
i=0

1 2i+1

k+1 . 2 k +1

@TFPA

Qk

e l vezD @TFPA depende de l soluin deX


k

Qk =
i=0

1 2i+1

1 1 1 + 2 + + k +1 . 2 2 2

@TFQA

wultiplindo @TFQA por 2 tenemosX

2Qk = 1 +

1 1 1 + 2 + + k . 2 2 2 1 2 k +1

@TFRA

ehor restmos @TFRA menos @TFQA lo que nos d omo soluin de @TFQAX

Qk = 1
uyo vlorD l sustituirlo en @TFPA nos rrojX

@TFSA

Sk = 2

1 k+1 k+2 k =2 k 2k 2 2
lg n + 2 n

@TFTA

ustituyendo @TFTA en @TFIA tenemosX

T (n) = n + n 2

k+1 2k

= n+n 2

= 3n lg n 2, n 1 ;

@TFUA

resultdo que es O(n lg n)F balance_tree() esD puesD O(n lg n)D un tiempo ostoso si l funin se invo freE uentementeF rst el presenteD ndie h desuierto un lgoritmo eptle que moE di(que un eff y grntie un ondiin de equilirio fuerteD rzn por l ul se h optdo por reljr ls ondiiones de equilirio pr herls menos restritivsF egn ls tnis lgortmisD podemos plnter l siguiente lsi(in de los menismos de equilirio onoidosX  Equilibrio probabilstico: este enfoque onsiste en tomr deisiones letoris tenE dientes restleer el equilirioF vos roles otenidos ofreen un tiempo esperdo de O(lg n) pr tods ls operionesF

he est lse de equilirio estudiremos dos estrutursX los roles letorizdos y los trepsF

6.2. rboles aleatorizados

455

 Equilibrio garantizado: en este enfoque se plnten ondiiones de equilirioD menos restritivs que l fuerteD que permiten modi(iones O(lg n) sore un rol inrio y que otn l ltur O(lg n)F vos mtodos de este tipo ofreen un grnt O(lg n) en tods ls operionesF fjo este tipo de equilirio estudiremos dos estrutursX los roles ev y los roles rojoEnegrosF

 Equilibrio amortizado: este enfoque onsiste en ejeutr operiones espeiles durnte l ejeuin de ulquier operin de mner tl que el rol tiend estr equilirdoF fjo est onepin se grntiz un oste mortizdo de O(p lg n) pr p operiones suesivs sore el rolF in este grupoD l ni tni mortizd onoid pr equilirr roles es el desplegdo @splayAD empled en los roles splyF

6.2 rboles aleatorizados


n rol inrio de squed letorizdo @effeA es un rol inrio de squed extendido @effi en RFII @gF QQSAA on operiones espeiles que grntizn que el effe se un rol letorioF eordemos que un effi es un rol en el que d nodo lmen l rdinlidd del rol del ul l es rzF xotemos l distinin que hemos entre letorio y letorizdoF snformlmenteD un rol letorio es equivlente un rol inrio de squed onstruido prtir de seuenis de inserin letorisD mientrs que uno letorizdo es uno tl que sus operE iones grntizn que ste siempre se letorioD independientemente del tipo de operinF
Denicin 6.2 (rbol binario de bsqueda aleatorio (ABBA))

e T un rol iE

nrio de squed on rdinlidd |T | = nF  i n = 0D entones T = es un effeF  i n > 0D entones T es un effe si y slo si L(T ) y R(T ) son effe independientesD y 1 @TFVA P(| L(T )| = i | |T | = n) = , 0 i < n, n > 0 n il punto ruil de l de(niinD espe(mente l euin @TFVAD es que ulquier de ls lves del rol tiene extmente l mism proilidd de ser l rz del rolF ist propiedd es fundmentl pr el diseo de los lgoritmos de inserin y elimininF r produir un effeD ulquier lve insertr dee tener lgun posiilidd de devenir l rz del rolD o l rz de lguno de sus surolesF hel mismo modoD undo se elimin un lveD ulquier de ls restntes dee tener posiiliddes de devenir rz del rol o de sus surolesF
6.2.1 El TAD

Rand_Tree<Key>

entes de explir los lgoritmos requerimos lguns ses pr un eh que nos modelie un effeF l eh se denomin Gen_Rand_Tree<Key> y se enuentr en el rhivo

456

6. rboles de bsqueda equilibrados

456a

tpl_rand_tree.H 456a

tplrndtreeFr

456a

uy estrutur fundmentl es l siguienteX

template <template <typename> class NodeType, typename Key, class Compare> class Gen_Rand_Tree { typedef NodeType<Key> Node; miembros privados de Gen_Rand_Tree<Key> 456d miembros pblicos de Gen_Rand_Tree<Key> 456c }; clases pblicas de Rand_Tree<Key> 456e

456b

il primer pso pr implntr Gen_Rand_Tree<Key> es de(nir l estrutur del nodo que onform un effeX tpl_randNode.H 456b DECLARE_BINNODE_SENTINEL(RandNode, 80, BinNodeXt_Data);
Uses

DECLARE_BINNODE_SENTINEL.

456c

snternmenteD el eh Gen_Rand_Tree<Key> trj on el mismo tipo de nodo emE pledo pr los roles on rngo estudidos en RFII @gF QQSAX los nodos gurdn l rdinlidd del rol y NullPtr es un nodo entinel uy rdinlidd es eroF v lse Gen_Rand_Tree<Key> requiere un generdor de nmeros pseudoletoriosF r eso nos vlemos de l iliote gsl1 F sremos el generdor torndo @wistedAD tulmente onoido omo el mejor generdor onoido de nmeros seudoEletorios IIWD IIVD IPHF n puntero l ojeto gslD generdor de nmeros letoriosD puede otenerse medinteX miembros pblicos de Gen_Rand_Tree<Key> 456c (456a) 457b gsl_rng * gsl_rng_object() { return r;} e trvs de este punteroD el usurio puede lterr el generdor su pleno riesgoF vos miemros dto de Gen_Rand_Tree<Key>X miembros privados de Gen_Rand_Tree<Key> 456d (456a) 456f Node * tree_root; gsl_rng * r;

456d

456e

tree_root es un puntdor l rz de rol letorizdoF r es un puntdor l ojeto de generin de nmeros pseudoletorios de l iliote gslF v lse que se export l usurioX clases pblicas de Rand_Tree<Key> 456e (456a)
template <typename Key, class Compare = Aleph::less<Key> > class Rand_Tree : public Gen_Rand_Tree<RandNode, Key, Compare> {};
Insercin en un ABBA

6.2.1.1

456f

v ide si del lgoritmo de inserin es efetur deisiones letorisD en funin de l de(niin TFPD que determinen si el nodo insertr deviene o no rz y grntien que el rol inrio resultnte se letorioF r eso presentmos el lgoritmo siguienteX miembros privados de Gen_Rand_Tree<Key> 456d + (456a) 456d Node * random_insert(Node * root, Node * p) { const long & n = COUNT(root);
1

Gnu Scientific Library

[66].

6.2. rboles aleatorizados

457

Genere rn aleatorio entre 0 y n 457a ; if (rn == n) // Gana p el sorteo de ser raz? return insert_root_xt <Node, Compare> (root, p); // s
Node * result; if (Compare () (KEY(p), KEY(root))) // KEY(p) < KEY(root) ? { // s ==> insertar en rbol izquierdo result = random_insert(LLINK(root), p); if (result != Node::NullPtr) // hubo insercin? { // si ==> actualizar rama y contadores LLINK(root) = result; ++COUNT(root); return root; } } else if (Compare() (KEY(root), KEY(p))) // KEY(p) > KEY(root) ? { // insertar en rbol derecho result = random_insert(RLINK(root), p); if (result != Node::NullPtr) // hubo insercin? { // si ==> actualizar rama y contadores RLINK(root) = result; ++COUNT(root); return root; } } return Node::NullPtr; // clave duplicada ==> no hay insercin

Denes:

random_insert,

used in chunk 457b.

457a

il punto entrl de l inserin es el sorteo efetudo en qenere rn letorio entre H y n 457a D el ulD en onson on l de(niin TFPD deide si el nodo insertr devendr rz o noX Genere rn aleatorio entre 0 y n 457a (456f) const size_t rn = gsl_rng_uniform_int(r, n + 1); v inserin en l rz es relizd por l rutin insert_root_xt() explid en RFIIFS @gF QRHAF random_insert() implnt l inserin letorizdF v versin pli de l inserin pr el tipo Gen_Rand_Tree<Key> se espei( omo sigueX miembros pblicos de Gen_Rand_Tree<Key> 456c + (456a) 456c 458a Node * insert(Node * p) { Node * result = random_insert(tree_root, p); if (result == Node::NullPtr) return NULL; return tree_root = result; }
Uses

457b

random_insert

456f.

458

6. rboles de bsqueda equilibrados

6.2.1.2

Eliminacin en un ABBA

458a

in l eliminin en un rol inrio de squedD l deisin de esoger l rz resultnte de l unin exlusiv siempre es l rz del suErol izquierdo @ RFIIFV @gF QRPAAF isto introdue un sesgo en el equilirio proilstio en ontr de l letorieddF orter uniformemente ul de ls res Eizquierd o derehE dee reemplzrse no funionD pues no se ponder l ntidd de nodos que teng d rmF il truo pr que l unin exlusiv produz un rol letorio es sorterD en funin de ls rdinliddesD ul de ls res devendr l rz del resultdoF ist ide se plsm en el lgoritmo siguienteX miembros pblicos de Gen_Rand_Tree<Key> 456c + (456a) 457b 458c Node * random_join_exclusive(Node * tl, Node * tr) { if (tl == Node::NullPtr) return tr;
if (tr == Node::NullPtr) return tl; const size_t & m = COUNT(tl); const size_t & n = COUNT(tr);

if (rn <= m) { // rama izquierda gana sorteo COUNT(tl) += COUNT(tr); RLINK(tl) = random_join_exclusive(RLINK(tl), tr); return tl; } else { COUNT(tr) += COUNT(tl); LLINK(tr) = random_join_exclusive(tl, LLINK(tr)); return tr; }

Genere rn aleatorio entre 1 y m + n 458b

Denes:

random_join_exclusive,
458b

used in chunk 458c. (458a)

Genere rn aleatorio entre 1 y m + n 458b

const size_t rn = 1 + gsl_rng_uniform_int(r, m + n);

458c

n vez relizd l unin exlusiv letorizdD l eliminin letori en rol inrio de squed on rngos es estruturlmente idnti l de un effX miembros pblicos de Gen_Rand_Tree<Key> 456c + (456a) 458a 459a Node * random_remove(Node *& root, const Key & key) { if (root == Node::NullPtr) return Node::NullPtr;
Node * ret_val; if (Compare() (key, KEY(root)))

6.2. rboles aleatorizados

459

} else if (Compare() (KEY(root), key)) { ret_val = random_remove(RLINK(root), key); if (ret_val != Node::NullPtr) COUNT(root); return ret_val; } // clave encontrada ret_val = root; root = random_join_exclusive(LLINK(root), RLINK(root)); ret_val->reset(); } return ret_val;

ret_val = random_remove(LLINK(root), key); if (ret_val != Node::NullPtr) COUNT(root); return ret_val;

Denes: Uses

random_remove, used in chunk 459a. random_join_exclusive 458a.

459a

v lgi del lgoritmo es desender reursivmente hst el nodo eliminrF n vez enontrdo este nodo se efet un ontenin letori entre l rm izquierd y l derehD l ul es el resultdo de l elimininF gulminmos est sein on l estrutur de l rutin pli de elimininX miembros pblicos de Gen_Rand_Tree<Key> 456c + (456a) 458c 459b Node * remove(const Key & key) { Node * ret_val = random_remove(tree_root, key); return ret_val != Node::NullPtr ? ret_val : NULL; }
Uses

random_remove

458c.

6.2.1.3

Acceso por posicin

459b

n ventj diret de los roles letorizdos es que ellos soportn el eso por posiin estudido en RFII @gF QQSAF in este sentidoD ls implntiones de ls operiones select() y position() son diretsX miembros pblicos de Gen_Rand_Tree<Key> 456c + (456a) 459a Node * select (const size_t & i) { return Aleph::select(tree_root, i); } size_t size() const { return COUNT(tree_root); }
Aleph::pair<int,Node*> position (const Key & key) { Aleph::pair<int,Node*> ret_val;

460

6. rboles de bsqueda equilibrados

ret_val.first = Aleph::inorder_position <Node,Compare> (tree_root, key, ret_val.second); return ret_val;

e destr el vlor de retorno Aleph::pair<int,Node*> pr l rutin position()D el ul es un pr uyo primer mpo es l posiin y segundo el nodo que lerg l lveF
6.2.2 Anlisis de los rboles aleatorizados

v ide entrl en este nlisis es demostrr que los lgoritmos de inserin TFPFIFI y de eliminin TFPFIFP produen roles letorios en el sentido de l de(niin TFPF en T< y T> los roles inrios de squed produidos por l llmd split_key_rec_xt(T , x, T< , T> ) implntd segn el lgoritmo explido en RFIIFR @gF QQWAF i T es un rol letorioD entones T< y T> son roles letorios independientesF
Lema 6.1 (Martnez y Roura 1998 [117])
split_key_rec_xt(R(T ), x, T< , T> )

T< T
y y

y>x L(T ) R(T< ) T>

L(T )

R(T )

=
(b) Despus de particionar

(a) Antes de particionar

pigur TFPX split_key_rec_xt(T , x, T< , T> )

Demostracin (Por induccin sobre

n = |T |)

 n = 0X si T = D entones split_key_rec_xt(T , x, T< , T> ) produe T< = T> = D el ul es por de(niin un rol letorizdoF il lem esD puesD ierto pr n = 0F  n > 0X hor sumimos que el lem es ierto pr todo n y veri(mos si el lem es ierto pr n + 1F e y = KEY(raiz(T ))F i x > yD entones b raiz(T< ) = raiz(T ) y el rE ol T> y el surol dereho R(T< ) se luln reursivmente on l llmd split_key_rec_xt(R(T ), x, T< , T> ) or premis del lemD L(T ) es letorio e independienteD pues T tmin lo esF or l hiptesis indutivD los roles R(T< ) y T> son letorios e independientesD pues son el resultdo de l llmd split_key_rec_xt(R(T ), x, T< , T> )F hel rzonmiento nterior podemos onluir que que T> es letorio e independienteF u er de T< c emos que sus rms izquierd y dereh son letoris e indeE pendientesF xos flt entones demostrr que l euin TFV se stisfe pr T< F r 1 eso deemos veri(r que z T< , P(raiz(T< ) = z) = m donde m = |T< |F isto es

6.2. rboles aleatorizados

461

equivlente plnterX

P(raiz(T< ) = P(raiz(T ) = z| raiz(T ) < x) = = 1 1/n = m/n m

P(raiz(T ) = z raiz(T ) < x) P(raiz(T ) < x)

imtrimenteD el mismo rzonmiento se pli si x < yD intermindo los roles de T< y T> D respetivmente il lem TFI es til porque l prtiin es un operin intern de l inserinD uy vlidez est demostrd por l proposiin siguienteF e T un rol letorio y se p un nodo insertr on lve kF intonesD l llmd insert(T , p) implntd en TFPFIFI @gF RSTA produe un rol letorioF
Proposicin 6.1 (Martnez y Roura 1998 [117]) Demostracin (Por induccin sobre

n = |T |)

 n = 0X si T = D entones insert(, p) = pF vos suroles L(p) y R(p) son vosD los 1 ulesD por de(niinD son letoriosF ore p se veri( que P(raiz(p) = k) = 1 = |p |F es puesD insert(, p) = p es un rol letorio y el lem es ierto pr n = 0F  n > 0X hor sumimos que el lem es ierto pr todo n y veri(mos si lo es pr n + 1F e T =insert(T , p)D se x = KEY(p) e y = raiz(T )F entes de insertr 1 D pues T es letorioF x, P(raiz(T ) = y) = n e prtir de ests suposiiones podemos distinguir dos sos despus de l inserinX @IA que y ontinue omo rz de T D o @PA que x se l rz de T X IF i raiz(T ) = yD entones x dee perder en el sorteo qenere rn letorio entre H y n 457a efetudo por el lgoritmo de inserin y el predido rn == n dee ser flsoF v proilidd de que el predido rn == n se flso es nn +1 @el omplemento 1 proilstio de n+1 D que es l proilidd de que x se rz de T AF es puesX

y T , P(raiz(T ) = y) =

1 n
P(raiz(T )=y)

n n+1
P(raiz(T )=y)

1 n+1

in este soD x ser insertdo en lguno de los suroles de T yD por l hiptesis indutivD el resultdo ser un rol letorioF PF i raiz(T ) = xD entones x el predido rn == n dee ser iertoY esto suede on 1 proilidd P(raiz(T ) = x) = n+ 1 D que es lo esperdo segn el lgoritmoF or otr prteD T = < T< , x, T> >D donde T< y T> son los roles resultntes de random_join(T , x, T< , T> ) los ules sonD por el lem TFID letorios hel resultdo nterior podemos estleer el orolrio siguienteF e K = {k1 , k2 , . . . , kn } un onjunto de lves ulquierF e T un rE ol letorizdoF intonesD ulquier permutin de inserin de K sore T D segn el lgoritmo desrrolldo en TFPFIFI @gF RSTAD produe un rol letorizdoF
Corolario 6.1

462

6. rboles de bsqueda equilibrados

il orolrio onllev impliiones importntesF in primer lugrD ulquier que se el orden de inserinD siempre otendremos un rol letorizdoF in otrs plrsD el rol resultnte es equivlente un eff onstruido prtir de un seueni de inserin letoriF gonseuentementeD todos los resultdos onoidos pr un eff son plilesY el ms importnte de ellos es l proposiin RFIP que nos promedi l ltur del rol O(lg n)F in unto l elimininD el primer pso pr nlizrl es estudir l unin exlusiv letoriD l ul se nliz en el lem siguienteF
Lema 6.2 (Martnez y Roura 1998 [117])

en T< y T> dos roles letorios indeE pendientes tl que kl T< , kr T> , kl < kr D es deirD tods ls lves de T< son estriE tmente menores que ls lves de T> F intonesD T = random_join_exclusive(T< , T> ) es un rol letorioF
Demostracin (por induccin sobre

m = |T< | y n = |T> |)

 m = 0 o n = 0X jo este predidoD tenemos dos sosX IF i m = 0 y n = 0D entones random_join_exclusive(T< , T> ) = D el ul esD por de(niinD letorioF PF i m = 0 o n = 0D entones random_join_exclusive(T< , T> ) retorn el rol no vo del prD el ul esD por premis del lemD letorioF il lem esD puesD ierto pr m = 0 o n = 0F  m > 0 y n > 0X se
  

a = KEY(raiz(T> ))D b = KEY(raiz(T> )) y T = random_join_exclusive(T< , T> )

esummos que a gn el sorteo qenere rn letorio entre I y m C n 458b efetudo en el random_join_exclusive() desrrolldo en TFPFIFP @gF RSVAD o seD que el predido rn <= m es iertoF isto impli que a ser l rz de T F odemos osquejr el rol resultnte del siguiente modoX
T =
random_join_exclusive(T< ,

T> ) T> )

random_join_exclusive(R(T< ),

L(T< )

T>

or l estrutur del lgoritmo y el resultdo del sorteoD l rm izquierd de T es L(T )D mientrs que l dereh es l llmd reursiv random_join_exclusive(R(T< ), T> )F ehor ienD L(T ) es un rol letorio puesD por premis del lemD T tmin lo esF sgulmenteD por l hiptesis indutivD T> tmin es letorioF L(T ) y T> son inE dependientesD pues L(T ) y R(T ) sonD por premis del lemD independientes y T> = random_join_exclusive(R(T< ), T> ) esD por l hiptesis indutivD independienteF rE iendo demostrdo que ls rms de T son letoris e independientesD slo nos flt 1 demostrr que x T< , P(raiz(T ) = x) = m+ n F isto esX

P(raiz(T ) = x) = P(raiz(L(T )) = x) P(rn <= M se ierto) 1 m 1 = = m m+n m+n

6.2. rboles aleatorizados

463

gon este lem estmos en pidd de estudir l elimininD l ul es nlizd en l proposiin siguienteF
Proposicin 6.2 (Martnez y Roura 1998 [117])

e T un rol letorio y x un lve ontenid en T F e l llmd remove(T , x) y se T el rol letorio resultnte despus de l llmd remove()F intonesD T es un rol letorioF
Demostracin (por induccin sobre

n = |T |)

 n = 1X entones T = D el ul esD por de(niinD letorioF  n > 1X entones sumimos que el lem es ierto pr todo |T | < n y veri(mos si tmin es ierto pr nF equ podemos seprr dos sosX IF i raiz(T ) = xD entones x es elimindo de uno de los suroles de T yD por l hiptesis indutivD est eliminin rroj un rol letorioF PF i raiz(T ) = xD entones remove(T , x) efet l llmd random_join(L(T ), R(T )) l ulD por el lem TFPD es un rol letorioF odemos (rmr entones que L(T ) y R(T ) son roles letorios independientesF xos flt por ompror que y 1 T , P(raiz(T ) = y) = n 1 D lo ul se veri( omo sigueX
P(raiz(T ) = y) = P(raiz(T ) = y |

raiz(T ) = x) P(raiz(T ) = x) + raiz(T ) = x) P(raiz(T ) = x) 1 P(raiz(random_join(L(T ), R(T ))) = y) + n


P(raiz(T ) = y | P(raiz(T ) = y | 1 raiz(T ) = x) n n 1 1 1 n1 1 + = n1 n n1 n n1

pigur TFQX n rol letorizdo de 512 nodos he ls proposiiones mostrds podemos enunir el siguiente orolrioF
Corolario 6.2 i T es un rol letorizdo ulquierD entones ulquier seueni de inseriones y eliminiones produe un rol letorioF

egn el orolrio nteriorD ulquier que se l seueni de inserinD on eliminE iones interlds ritrrisD el rol resultnte siempre es letorioF odemosD puesD onluir que en promedio l ltur del rol letorizdo es O(lg n)F uesto que el tiempo de ls operiones de inserin y eliminin depende de l lturD podemos onluir tmin que en promedio l inserin y l eliminin son O(lg n)F

464

6. rboles de bsqueda equilibrados

vos roles letorizdos tienen dos ostes diionles respeto los inrios lsiosF in primer lugrD l estrutur de nodo de un effe requiere espio diionl pr lE menr l rdinliddF in segundo lugrD un effe requiere operiones diionles respeto un effF hurnte l inserinD es neesrio efetur un prtiin y tulizr ls rdinliddesF e pesr de ls restriiones nterioresD un effe tiene l ventj de eliminr el peligro representdo por el sesgo en l seueni de inserin y ls inseriones interldsF or didurD el ontdor presente en d nodo filit perfet y nturlmente el eso por posiinD on tods sus operiones soidsD tl omo se expli en RFII @gF QQSAF isto ltimo es quiz l grn ondd de este esquem de equilirioF

6.3 Treaps
ehor estudiremos otro enfoque de letorizin rdilmente diferente un effeX l estrutur trepF
Denicin 6.3 (Treap)

e T un rol inrio en ul d nodo ni tiene dos mpos

serX IF KEY(ni ) K es l lve de squedD donde K es un onjunto ordenle ulquierF PF PRIO(ni ) P es l prioridd del nodoD donde P es un onjunto ordenle ulquierF intonesD T es un trep si y slo siX  T ABB segn ls lves KF  ni T, PRIO(ni ) PRIO(L(ni )) y PRIO(ni ) PRIO(R(ni )) . v segund propiedd se llm relin del nestroF i ls prioriddes son nisD es deirD si sts no se repitenD entones el trep es denomindo puroF

v primer propiedd orresponde l de orden de un effY l segund l de orden de un hepF he llD puesD el nomre trepX tree y hepF odemos rterizr un trep omo un seueni de pres @lveD prioriddA orresE pondiente los ontenidos de d nodoF or ejemploD el trep de l (gur TFR puede rterizrse omoX (6, 792)D (8, 538)D (10, 602)D (11, 478)D (13, 704)D (17, 844)D (20, 807)D (21, 663)D (22, 459)D (23, 652)D (24, 622)D (26, 600)D (35, 499)D (37, 536)D (38, 434)D (43, 666)D (46, 656)D (53, 761)D (54, 542)D (59, 696)D (60, 642)D (61, 803)D (66, 852)D (69, 526)D (76, 538)D (80, 609)D (81, 655)D (96, 533)D (97, 440)D (100, 435) F n trep tiene un propiedd muy interesnte rterizd por el siguiente lemF e K = {k1 , k2 , . . . , kn } un onjunto de lves y P = {p1 , p2 , . . . pn } un onjunto de prioriddesF intonesD el onjunto {(k1 , p1 ), (k2 , p2 ), . . . (kn , pn ), } K P tiene un nio trepF
Lema 6.3 (Lema de la unicidad del treap -Seidel - Aragon 1996 [158])

6.3. Treaps

465

38 434 22 459 11 478 8 538 6 792 10 602 13 704 20 807 17 844 23 652 43 666 21 663 24 622 46 656 53 761 59 696 26 600 35 499 37 536 54 542 60 642 61 803 66 852 76 538 80 609 81 655 69 526 96 533 97 440 100 435

pigur TFRX ijemplo de trepF gmpos superiores representn ls lvesY inferiores prioriE ddes
Demostracin (Por induccin sobre

n)

 n = 1X in este so existe un nio trep onformdo por un pr nioF il lem es ierto pr n = 1F  n > 1X ehor sumimos que el lem es ierto pr todo n y veri(mos su veridd pr n + 1F uesto que ls prioriddes son nisD el trep de n + 1 nodos slo puede tener un rz uy prioridd es l menor de todsF e (ki , pi ) el nodo rz del trepF n vez determind l rz del trep y us de l propiedd de orden de un effD el onjunto de nodos de ls rms izquierd y dereh qued determindo en K< = {(k1 , p1 ), . . . , (Ki1 , pi1 )} y K> = {(ki+1 , pi+1 ), . . . , (kn , pn )}D respetivmenteF or l hiptesis indutivD K< y K> D uys rdinliddes son inferiores n + 1D tienen treps niosF il lem es ierto pr todo n in qu onsiste l letoriedd de un trepc v respuest se enuentr en l selein de l prioriddF gundo se re un nuevo nodoD se seleion l prioridd letorimenteD se insert el nodo segn el lgoritmo lsio de inserin en eff y ls violiones eventules l relin del nestro se orrigen medinte rotionesF
6.3.1 El TAD

Treap<Key>

465

il primer pso en el diseo de un eh que nos modelie un trep es determinr l estrutur del nodo que lo onformF ry dos mners generles de implntr un trepX reursiv o itertivmenteF emos enfoques son muy senillos y omprten l estrutur del nodoF or es rzn mntendremos l estrutur del nodo en un rhivo seprdo denomindo trepxodeFr 465 D el ul se estrutur omo sigueX treapNode.H 465 const long Max_Priority = ULONG_MAX;

466

6. rboles de bsqueda equilibrados

const long Min_Priority = 0; class TreapNode_Data { unsigned long priority; TreapNode_Data () : priority (Max_Priority) {} unsigned long & getPriority () { return priority; } }; DECLARE_BINNODE_SENTINEL(TreapNode, 80, TreapNode_Data); # define PRIO(node) ( (node) -> getPriority () )
Uses

DECLARE_BINNODE_SENTINEL.

466a

equ se de(ne el nodo inrio TreapNode<Key> que lmen un prioridd edid medinte el mtodo getPriority() o el mro PRIOF il rhivo export dos onstntes Min_Priority y Max_Priority que orresponden los vlores mnimo y mximo que puede tener un prioriddF n TreapNode<Key> tiene un vlor de Node::NullPtr puntdo un entinel on prioridd mximF iste nodo funge de entinel pr detener rotiones desendentes hi hojs del rolF xuestr implntin del trep requiere de un nodo eer pdre de l rzF l nodo tmin funge de entinel pr detener rotiones sendentes hi l rzF ehor proedemos desrrollr el eh Treap<Key>X tpl_treap.H 466a template <template <typename> class NodeType, typename Key, class Compare> class Gen_Treap { Miembros de Gen_Treap<Key> 466b }; Clases pblicas de Gen_Treap<Key> 467a entes de implntr los onstrutores es neesrio de(nir los triutos internos de Gen_Treap<Key>X Miembros de Gen_Treap<Key> 466b (466a) 466c Node head; Node * head_ptr; Node *& tree_root;

466b

466c

head es un nodo eerD pdre entinel de l rzD head_ptr es un puntdor l nodo eer y tree_root es un refereni puntdor l rz del trepF n trep requiere un funin que genere nmeros letorios orrespondientes ls prioriddesF r eso nos vlemos de l iliote gsl2 F sremos el generdor torE ndo @wistedAD tulmente onoido omo el mejor generdor de nmeros seudoE letorios IIWD IIVD IPHX Miembros de Gen_Treap<Key> 466b + (466a) 466b 468a gsl_rng * r;
v lse Gen_Treap<Key> no es pr uso direto del lienteD pues su rol es implntr un trep genrio que se independiente de que sus nodos sen virtules o noF il liente
2

Gnu Scientific Library

[66].

6.3. Treaps

467

467a

dee usr lgun de ls siguientes lsesX Clases pblicas de Gen_Treap<Key> 467a (466a) template <typename Key, class Compare = Aleph::less<Key> > class Treap : public Gen_Treap<TreapNode, Key, Compare> {};
6.3.2 Insercin en un treap

goneptulmenteD l inserin de un nodo p puede rterizrse en dos prtesX IF ifetur un inserin omo en effD es deirD sustituir el nodo externo por pF PF otr pD de form que ste su de nivelD hst que su prioridd no viole l relin nestrlF istmos preprdos pr implntr el lgoritmo de inserinX Insercin en Gen_Treap<Key> 467b static Node * insert(Node * root, Node * p) { if (root == Node::NullPtr) return p;
Node * insertion_result = NULL; if (Compare() (KEY(p), KEY(root))) { insertion_result = insert(LLINK(root), p); if (insertion_result == Node::NullPtr) return Node::NullPtr; LLINK(root) = insertion_result; if (PRIO(insertion_result) < PRIO(root)) return rotate_to_right(root); else return root;

467b

} else if (Compare() (KEY(root), KEY(p))) { insertion_result = insert(RLINK(root), p); if (insertion_result == Node::NullPtr) return Node::NullPtr; RLINK(root) = insertion_result; if (PRIO(insertion_result) < PRIO(root)) return rotate_to_left(root); else return root;

} return Node::NullPtr;

insert() efet un squed reursiv de l lve ontenid en el nodo pF i se enuenE tr un nodo on tl lveD entones se retorn Node::NullPtr F

468

6. rboles de bsqueda equilibrados

468a

iD por el ontrrioD no se enuentr l lveD entones l reursin se detiene en el nodo externo donde iniilmente se insert el nodoF v seueni reursiv de retornos veri( si hy un violin de l relin nestrlD l ul es eventulmente orregid on un rotinF v versin nterior de insert() es un miemro privdoD esttioD uyo rol es her l inserin y orregir ls violiones de l relin nestrlF v selein letori de l prioridd y l invoin iniil l mtodo reursivo son efetudos por l versin pli de insert() uy de(niin es omo sigueX Miembros de Gen_Treap<Key> 466b + (466a) 466c 468b Node * insert(Node * p) { PRIO(p) = gsl_rng_get(r); // seleccin aleatoria de prioridad Node * result = insert(tree_root, p); if (result == Node::NullPtr) return NULL;
tree_root = result; } return p;

6.3.3

Eliminacin en treap

468b

v eliminin es oneptulmente ms simple que l lsi en un effF rimero se us el nodo on l lve de intersF n vez uidoD el nodo se rot de mner que su hijo de menor prioridd su de nivelF il proeso ontinu hst que el nodo eliminr deveng hojY en ese momento el nodo se sustituye por Node::NullPtr F orprendentementeD un versin itertiv de l eliminin es filmente relizleD l ul se estrutur en dos prtes que se presentn omo sigueX Miembros de Gen_Treap<Key> 466b + (466a) 468a Node * remove(const Key & key) {

Buscar nodo a eliminar p 468c

if (p == Node::NullPtr) return NULL; // clave no fue encontrada

Rotar p hasta que devenga hoja 469a


p->reset(); } return p;
468c

468c

il primer loque fusr nodo eliminr p p y se de(ne omo sigueX Buscar nodo a eliminar p 468c Node ** pp = &RLINK(head_ptr); Node * p = tree_root; while (p != Node::NullPtr)

se enrg de uir el nodo suprimir


(468b)

6.3. Treaps

469

if (Compare() (key, KEY(p))) { pp = &LLINK(p); p = LLINK(p); } else if (Compare() (KEY(p), key)) { pp = &RLINK(p); p = RLINK(p); } else break;

469a

iste loque delr dos vrilesF v vrile p gurd l direin del nodo suprimirF uesto que en l segund fse el nodo p ser rotdo hst que deveng hojD es neesrio en prinipio gurdr l direin del nodo pdre de tl que mner ste se tulie en d rotinF gomo el lgoritmo es itertivoD es preferile gurdr l direin de l eld dentro del nodo pdre que punt pY tl puntdor es mntiene en l vrile ppF il segundo loque otr p hst que deveng hoj 469a se espei( del siguiente modoX Rotar p hasta que devenga hoja 469a (468b) while ( p no sea hoja 469b ) if (PRIO(LLINK(p)) < PRIO(RLINK(p))) { *pp = rotate_to_right(p); pp = &RLINK(*pp); } else { *pp = rotate_to_left(p); pp = &LLINK(*pp); } *pp = Node::NullPtr; v ltim lne es l que (nlmente elimin el nodo p l signrle l eld del nodo que punt p el nodo externo Node::NullPtr F il predido p no se hoj 469b onsiste en veri(r si los suroles de p son externosF isto se llev o de l siguiente mnerX p no sea hoja 469b (469a) not (LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr) is el momento de her un oservin interesnteX l eliminin de un nodo ourre extmente en el mismo sitio donde ste se huiese insertdoF eordemos que l inserin omienz por poner el nuevo nodo omo hojF i deidimos eliminr un lve y luego insertrlD l hoj del nodo de inserin es extmente l mism que undo fue elimindF n ejemplo de est situin se ilustr on el nodo 38 de l (gur TFSF sntuitivmenteD este fenmeno es evidenido por el lem de l uniidd del trep @lem TFQAF r que el trep se nio trvs de tods ls modi(ionesD l inserin y eliminin siempre deen ver el mismo trepF

469b

470

6. rboles de bsqueda equilibrados

5 8 5 8 1 70 0 24 8 38 21 69 22 89 42 42 43 81 42 97 12 28 28 54 38 26 39 30 40 36 64 97 21 69 22 89 43 81 0 24 1 70 8 38 28 54 12 28 38 26 39 30 40 36 64 42

(a)

(b)

5 8 1 70 0 24 8 38 38 26 28 54 21 69 22 89 42 97 43 81 12 28 39 30 40 36 64 42 0 24 1 70

5 8 12 28 8 38 28 54 21 69 22 89 42 97 38 26 43 81 39 30 40 36 64 42

(c)

(d)

pigur TFSX ijemplo de eliminin de l lve 38 en un trepF v posiin (nl del 38 ntes de suprimirlo es l mism que l posiin iniil de inserin
6.3.4 Anlisis de los treaps

in nlisis de los treps requiere estleer un propiedd muy soid l letorieddX l propiedd de useni de memori en ls deisiones letorisF l propiedd est dd por l siguiente proposiinX n trep T es un rol inrio letorioF in otrs plrsD un trep es equivlente un eff onstruido prtir de un seE ueni de inserin letoriF
Proposicin 6.3

uesto que ls prioriddes son seleionds letori e independienteE menteD podemos sumir que tods ls prioriddes son esogids ntes de que se iniie l seueni de inserinF e K = {k1 , k2 , . . . , kn } un seueni de inserin ulquier y se P = {p1 , p2 , . . . , pn } un onjunto de prioriddes seleionds letori e independientemente que son signds ls lves K tl que d pr (ki , pi ) ompondr un nodo del trepF or el lem TFQ @de l uniiddAD semos que dds ls lves y sus prioriddes el trep es nioF isto impli que el orden de inserin no fet el trep resultnteF he este modoD sin prdid de generliddD podemos sumir un seueni de inserin SABB que v desde l menor hst l myor prioridd de l ul podemos relizr ls siguientes oservionesX
Demostracin

6.4. rboles AVL

471

IF espeto l onjunto de lves KD l proilidd de que SABB se el vlor de un 1 permutin espe( es |K |! pues el orden de l permutin est ddo por el orden de ls prioriddes que son signds letorimente d lveF or tntoD l seueni SABB ordend por prioridd es letoriD pues ls prioriddes fueron esogids letori e independientementeF PF SABB no us rotiones en el trepD pues d nodo es insertdo omo hoj yD puesto que fue insertdo por prioridd sendenteD l relin nestrl jms es violdF he lo nterior podemos onluir que l inserin de SABB ourre de l mism mner que en un effF uesto que SABB es un seueni letori y que l inserin ourre omo en un effD podemos onluir que un trep es equivlente un eff onstruido prtir de un seueni de inserin letori

pigur TFTX n trep de 512 nodos v proposiin nterior nos grntiz que el tiempo esperdo pr l squed en un trep es O(lg n)F u er de ls inseriones y supresionesc yservemos que ms operiones estn dominds por l ltur del rol y que sts resultn en trepsF v ntidd mxim de rotiones tmin es funin de l lturF he est mnerD podemos onluir que ls operiones de inserinD squed y eliminin son O(lg n)F
6.3.5 Prioridades implcitas

vos treps son roles letoriosF gonseuentementeD el desempeo de l squed es equivlente los roles letorizdosF in unto l espioD los ostes tmin son equivlentesD pues mos roles requieren lmenr un entero diionl por nodoX en los roles letorizdos es l rdinliddD en los trepsD l prioriddF orprendentementeD en un trep podemos ovir l prioridd si l sustituimos por un funin hsh que trnsforme l lve un vlor de prioriddF he est mnerD l prioridd no neesit lmenrseD pues puede lulrse implitmente d vez que se requierF il trep oupr entones un espio equivlente l de un effF r que este enfoque se e(zD es neesri un uen funin hshF in este sentidoD tod l teor de funiones hsh imprtid en SFP @gF RPQA es plileF

6.4 rboles AVL


n rol evD o un eevD es un lse espeil de rol inrio de squed de(nido omo sigueF

472

6. rboles de bsqueda equilibrados

Denicin 6.4 (rbol AVL)

e T un rol inrio de squedF e die que T es

ev si y slo siX is deirD pr todo nodoD l difereni de ltur entre l rm izquierd y dereh no dee exeder de l uniddF r futuros disursosD l difereni de ltur de un nodo ni se llm (ni ) = h(R(ni )) h(L(ni ))F in ontextos de digoD (ni ) se denot omo DIFF(n)F

ni T,

1 h(R(ni )) h(L(ni )) 1

@TFWA

pigur TFUX n rol ev de 512 nodos v ondiin @TFWA se llm ondiin ev y es menos fuerte que el equilirio fuerte de irth de(nido en TFI @gF RSPAF v ide es perder un poo de equilirio en rs de lgoritmos ms e(ientes que grntien l ondiin evF ws delnte demostrremos que l ltur de un eev est logrtmimente otdF v gnni estri entones en logrr lgoritmos de modi(in logrtmiosF isto es ftile si lmenmos en d nodo informin sore el equilirioF e onoen dos forms de implntr un eevF v primerD que es l ms populr y e(ienteD pero tmin l ms difilD onsiste en lmenr en d nodo l difereni de ltursF r ello slo se requieren dos itsD los ulesD jo los requerimientos de linein de plr impuestos por ls rquiteturs modernsD deen extenderse hst l longitud de l plr de l rquiteturF v segund implntin onsiste en lmenr en d nodo su lturF uesto que el rol es logrtmimente otdoD un yte es su(ienteF ist lterntiv ondue lgoritmos ms senillosD pero menos e(ienteD pues undo se modi( el rol se requieren tulizr ms nodos on su lturF in este texto doptremos el primer estilo de implntinY es deirD lmenremos l difereni de lturs en d nodoF v estrutur de un nodo ev se de(ne en el rhivo vlxodeFr 472 D el ul tiene l estrutur siguienteX
472

avlNode.H 472

class AvlNode_Data { signed char diff; // diferencia de altura signed char & getDiff() { return diff; } }; DECLARE_BINNODE(AvlNode, 40, AvlNode_Data); # define DIFF(p) ((p)->getDiff())
AvlNode
and

Uses

DECLARE_BINNODE.

6.4.1

El TAD

Avl_Tree<Key>

il eh Gen_Avl_Tree<Key> de(ne un lse genri de rol ev independiente de que el nodo se virtul o noF v lse en uestin se de(ne en el rhivo tplvlFr 473a D

6.4. rboles AVL

473

473a

que se de(ne ontinuinX tpl_avl.H 473a template <template <typename> class NodeType, typename Key, class Compare> class Gen_Avl_Tree { typedef NodeType<Key> Node; miembros privados de Gen_Avl_Tree<Key> 473b miembros pblicos de Gen_Avl_Tree<Key> 474a }; template <typename Key, class Compare = Aleph::less<Key> > class Avl_Tree : public Gen_Avl_Tree<AvlNode, Key, Compare> {};
Uses

AvlNode.

473b

eunque por lo generl los lgoritmos sore roles son nturlmente expresles en form reursivD los roles ev no enjn en est tegorF vs implntiones reurE sivs que se onoen estn sds en lmenr en d nodo su ltur y tulizrl reursivmente en d modi(inF in nuestro soD en rs de logrr un implntin ms e(iente que l reursivD utilizremos un pilD l ul se espei( omo sigueX miembros privados de Gen_Avl_Tree<Key> 473b (473a) 473c FixedStack<Node *, Node::MaxHeight> avl_stack;
Uses

FixedStack

101a.

avl_stack siempre gurdr el mino de squed desde l rz hst el nodo inE sertdo o elimindoF uesto que l ltur de un eev est otdD l pil no requiere veri(iones de desordeF
473c

miembros privados de Gen_Avl_Tree<Key> 473b +


Node Node * Node *& Compare head_node; head_ptr; root; cmp;

(473a)

473b 473d

473d

head_node es un nodo uxilir que ser pdre del nodo rzF head_ptr es un puntdor l nodo uxilirF il uso del nodo eer es muy til pr generlizr ls rotionesF i no ussemos est eerD entones l rotin de l rz deer trtrse seprdmenteF head_ptr siempre estr insertdo en l pilF e efetos lgortmiosD se onsiderr que l pil est v undo st slo onteng el nodo eerF lntemosD entonesD ls siguientes funionesX miembros privados de Gen_Avl_Tree<Key> 473b + (473a) 473c 474b
bool avl_stack_empty() { return avl_stack.top() == head_ptr; } void clean_avl_stack() { avl_stack.popn (avl_stack.size() - 1); }

avl_stack_empty() retorn ierto si avl_stack est lgimente vF clean_avl_stack() limpi l pilY es deirD extre todos sus elementosF or onveninD l rz root ser l hij dereh del nodo eer head_ptrF xotemos que root es un refereni RLINK (head_ptr) y no un punteroF iste rdid nos permite trjr diretmente on RLINK (head_ptr) medinte el nomre rootF

474

6. rboles de bsqueda equilibrados

6.4.1.1

Insercin en un rbol AVL

474a

gonsideremos un eev en el ul se reliz un inserin lsi en un effY es deirD el nodo se insert omo hoj en el lugr oupdo por el nodo externo resultdo de l squedF l inserin l reliz el lgoritmo siguienteX miembros pblicos de Gen_Avl_Tree<Key> 474a (473a) 479a Node * insert(Node * p) { if (root == Node::NullPtr) return root = p;
Node *pp = search_and_stack_avl(KEY(p)); if (cmp (KEY(p), KEY(pp))) LLINK (pp) = p; else if (cmp (KEY(pp), KEY(p))) RLINK(pp) = p; else { // clave duplicada clean_avl_stack(); return NULL; } restore_avl_after_insertion(p); } return p;

474b

v funin search_and_stack_avl() us l lve ontenid en p y l vez gurd todo el mino de squed en l pil avl_stackX miembros privados de Gen_Avl_Tree<Key> 473b + (473a) 473d 476a Node * search_and_stack_avl(const Key & key) { Node * p = root; do // desciende en bsqueda de key y empila camino de bsqueda { avl_stack.push(p); if (cmp(key, KEY(p))) // key < KEY(p)? p = LLINK(p); else if (cmp(KEY(p), key)) // key > KEY(p)? p = RLINK(p); else return p; // clave duplicada } while (p != Node::NullPtr);
} return avl_stack.top();

i KEY(p) y se enuentr en el rolD entones search_and_stack_avl() retorn el nodo que ontiene l lveF v dupliin se detet en el primer ifF in so ontrrioD pp es el pdre del nodo insertr pF il nodo p se insert fsimente y se tuliz el ftor de lne de ppF
Restauracin de la condicin AVL

6.4. rboles AVL

475

hespus de l inserin fsi se veri( si ourre un violin de l ondiin evD l ul se rteriz en dos sos generlesF il primero de ellos se ilustr en l (gur TFV@AF sniilmenteD el nodo y se enuentr perfetmente equilirdoD mientrs que su pdre x est ligermente desequilirdo hi l derehF yurre entones l inserin de un vlor myor que yD el ul he que l rm umente de lturF il nodo x sufre un desequilirio que viol l ondiin evF
T x 2 y 1 h h+1 h x 0 h+1 T y 0

=
(a) (b)

pigur TFVX rimer so de inserin en un rol ev v violin desrit en l (gur TFV@A se orrige medinte un rotin hi l izquierd del nodo yD uyo resultdo generl se ilustr en l (gur TFV@AF xotemos que en ls dos (gurs ETFV@A y TFV@AE el vlor de ltur glol h + 2 permnee inttoF or lo tntoD si l sendeni de T es ev ntes de l inserinD tmin lo es despusF in otrs plrsD pr el so de desequilirio de l (gur TFV@AD l orrein resultnte despus de l rotin produe un rol entermente evF il desequilirio ilustrdo en l (gur TFV@A tiene un so simtrio que ourre undo l inserin se produe por l izquierdF qr(menteD el desequilirio y su orrein se ven igul que ls (gurs TFV@A y TFV@A re)ejds en un espejoF vos vlores de los ftores permiten identi(r l situin de desequilirio mostrd en l (gur TFV@AF hdo un nodo x on un desequilirio podemos rterizr ls siguientes situiones y sus orrespondientes ionesX IF i DIFF(x) == 2 and DIFF(y) == 1 = se efet un rotin simple hi l izquierdF PF i DIFF(x) == -2 and DIFF(y) == -1 = se efet un rotin simple hi l derehF vos mtodos rotateLeft() y rotateRight() rotn el nodo p hi l izquierd y dereh respetivmenteF vos mtodos deen tulizr los ftores de equilirio de los nodos involurdosF el respeto existe un so que slo ourre durnte l elimininD evludo en el if y que expliremos posteriormenteF he lo ontrrioD los ftores de lne se ponen en eroF is posile deduir los mios en los ftores y justrlos trvs de operiones ritmtisD empero se requieren vrios if pr herloF or lo tntoD es ms simple diferenir los sos y signr los ftores diretmenteF il segundo so de violin de l ondiin ev se ilustr en l (gur TFW@AF il rol ev T sufre un desequilirio por l dereh en el nodo xD usdo por un umento

476

6. rboles de bsqueda equilibrados

de ltur del nodo z que est perfetmente equilirdoF v inserin puede ourrir por ulquier de los ldos de zF
T x 2 y 1 z 1 h1 h h h1 T z 0 x 0 y 1

=
(a) (b)

pigur TFWX egundo so de inserin en un rol ev il desequilirio se orrige medinte dos rotiones suesivs del nodo zF rimeroD el nodo z se rot hi l derehD luegoD hi l izquierdF v orrein se ilustr en l (gur TFW@AF entes y despus de l orreinD l ltur glol del rolD h + 2D es l mismF gonseuentementeD si l sendeni de T es evD entonesD despus de l inserin y posterior orreinD l sendeni tmin es evF il so ilustrdo en ls (gurs TFW@A y TFW@A tiene su orrespondiente simtrio por l izquierdD el ul es equivlente re)ejr ls (gurs en un espejoF v identi(in de l situin de desequilirio de l (gur TFW@AD junto on su orreinD se rteriz de l siguiente mnerX IF i DIFF(x) == 2 and DIFF(y) == -1 = primero se rot el nodo z hi l dereh y luego hi l izquierdF PF i DIFF(x) == -2 and DIFF(y) == 1 = primero se rot el nodo z hi l izquierd y luego hi l derehF vos mtodos doubleRotateLeft() y doubleRotateRight() relizn ls doles rotE iones l izquierd y dereh respetivmenteF vos sos presentdos en ls (gurs TFV@A y TFW@AD junto on sus equivlentes simtriE osD rterizn situiones de violin de l ondiin ev que ourren durnte l inserinF glsi(remos ls iones de orrein en el siguiente rngoX miembros privados de Gen_Avl_Tree<Key> 473b + (473a) 474b 476b enum Rotation_Type { ROTATE_LEFT, ROTATE_RIGHT, DOUBLE_ROTATE_LEFT, DOUBLE_ROTATE_RIGHT }; iste tipo de vlor es devuelto por un rutin que exmin un nodo desequilirdo y determinD en funin del tipo de desequilirioD ul lse de rotin dee ser plidX miembros privados de Gen_Avl_Tree<Key> 473b + (473a) 476a 477a static Rotation_Type rotation_type(Node * p) { Node * pc; // guarda hijo de p if (DIFF(p) == 2) // hacia la izquierda { pc = RLINK(p);

476a

476b

6.4. rboles AVL

477

if (DIFF(pc) == 1 or DIFF(pc) == 0) return ROTATE_LEFT; return DOUBLE_ROTATE_LEFT; } pc = LLINK(p); if (DIFF(pc) == -1 or DIFF(pc) == 0) return ROTATE_RIGHT; } return DOUBLE_ROTATE_RIGHT;

477a

rotation_type() es llmd por un funin de uso generl que restur l ondiin evF u estrutur generl orresponde veri(r los utro tipos de rotin en funE in del nodo violtorio de l ondiin ev y del ftor de su hijoF xotemos que rotation_type() efet un veri(in diionlD DIFF(pc) == 0D orrespondiente otro so que slo se present en l eliminin y que expliremos posteriormenteF vo nterior proporion tod l utiler requerid pr resturr l ondiin ev en ulquier de los sos de inserinX miembros privados de Gen_Avl_Tree<Key> 473b + (473a) 476b 477b static Node * restore_avl(Node * p, Node * pp) { Node ** link = LLINK(pp) == p ? &LLINK(pp) : &RLINK(pp); switch (rotation_type(p)) { case ROTATE_LEFT: return *link = rotateLeft(p); case ROTATE_RIGHT: return *link = rotateRight(p); case DOUBLE_ROTATE_LEFT: return *link = doubleRotateLeft(p); case DOUBLE_ROTATE_RIGHT: return *link = doubleRotateRight(p); } return NULL; }
Uses

doubleRotateLeft, doubleRotateRight, rotateLeft,

and

rotateRight.

477b

il mtodo restore_avl() tom dos nodos omo prmetrosF il primeroD pD es el nodo que sufre el desequilirioY el segundoD ppD es el pdre de pF in funin del tipo de desequilirio determindo por rotation_type()D restore_avl() emprende ls iones neesris pr resturr l ondiin evF rst el presente hemos desrrolldo un serie de rutins enrgds de orregir un violin de l ondiin ev en un nodoF xos flt determinr ul es el nodo que sufre el desequilirioF r l inserinD st on memorizr el ltimo nodo desequilirdo en el mino de squedD pues ste es el nio suseptile de sufrir un desequilirioF ido este nodoD se tuliz su ftor y se veri( si se requiere emprender iones orretivs on el mtodo restore_avl()F ehor slo nos rest un rutin que usque dentro de l pil el nodo desequilirdoD tulie el ftor yD eventulmenteD efete l orreinX miembros privados de Gen_Avl_Tree<Key> 473b + (473a) 477a 480 void restore_avl_after_insertion(Node * p) // ERROR const Key & key) { Node * pp = avl_stack.pop(); // padre del nodo insertado

478

6. rboles de bsqueda equilibrados

Ajustar factor del padre del nodo insertado 478a


if (avl_stack_empty()) return; // pp es raz Node *gpp; // padre de pp clean_avl_stack();

Actualizar ancestros de pp 478b

478a

il loque ejustr ftor del pdre del nodo insertdo 478a extre el primer nodo en l pilD tuliz su ftor y veri( si ste no es l rzX Ajustar factor del padre del nodo insertado 478a (477b) if (LLINK(pp) == p) // ERROR cmp (key, KEY(pp))) // ajuste el factor del padre del nodo insertado O DIFF(pp); else DIFF(pp)++;
if (DIFF(pp) == 0) { // en este caso, altura del ascendiente de pp no aumenta clean_avl_stack(); return; }

478b

etulizr nestros de pp 478b revis d nestro gpp de pp y tuliz su ftorF i el ftor de lgn gpp es eroD entones l ltur de gpp permnee igul yD puesto que l sendeni de gpp es evD el resto del rol es ev y el lgoritmo terminF in so ontrrio se revis si hy un violin de l ondiin evD l ul se orrigeF in este ltimo soD el lgoritmo tmin terminD pues semos que en l inserin el rol ompleto es ev luego de efetur l primer orreinX Actualizar ancestros de pp 478b (477b) do // buscar nodo con factor igual a 0 { gpp = avl_stack.pop(); // actualizar factores de equilibrio if (LLINK(gpp) == pp) // ERROR cmp (KEY(p), KEY(gpp))) // ERROR if (Compare () (key, KEY(gpp)) DIFF(gpp); else DIFF(gpp)++;
if (DIFF(gpp) == 0) break; // no se necesita reajuste else if (DIFF(gpp) == -2 or DIFF(gpp) == 2)// es AVL? { // s ==> se requiere reajuste Node *ggpp = avl_stack.pop(); restore_avl(gpp, ggpp); break; } pp = gpp; // ERROR; aadir

} while (not avl_stack_empty());

6.4. rboles AVL

479

6.4.1.2

Eliminacin en un rbol AVL

479a

istruturlmenteD l eliminin se divide en tres psosX @IA usr el nodo eliminrD @PA eliminrlo y @QA revisr l ondiin ev y eventulmente resturrlF in ese sentidoD el proedimiento se plnte del siguiente modoX miembros pblicos de Gen_Avl_Tree<Key> 474a + (473a) 474a Node * remove(const Key & key) { if (root == Node::NullPtr) return NULL;
Node * p = search_and_stack_avl(key); if (no_equals<Key, Compare> (KEY(p), key)) { // clave no fue encontrada clean_avl_stack(); return NULL; }

Eliminacin fsica de p 479b

restore_avl_after_deletion(left_deficit); // ERROR } return p;

Eliminacin fsica del nodo

479b

iliminin fsi de p 479b se fundment en el esquem lterntivo de eliminin explido en RFWFTEI @pgin QPRAD el ulD reordemosD onsiste en grntizr que el nodo eliminr se inompletoD y en el so de que se ompletoD entones sustituirlo por el suesor o el predeesorF in nuestro so optmos por el suesor y plntemos el siguiente lgoritmoX Eliminacin fsica de p 479b (479a) Node * pp = avl_stack.top(1); // obtener padre de p bool left_deficit; // ERROR Key removed_key = KEY(p); while (true) { left_deficit = LLINK(pp) == p; // ERROR Aadir if (LLINK(p) == Node::NullPtr) // incompleto por la izquierda? { // S, ate a pp el hijo de p if (LLINK(pp) == p) LLINK(pp) = RLINK(p); else RLINK(pp) = RLINK(p); break; } if (RLINK(p) == Node::NullPtr) // incompleto por la izquierda? { // S, ate a pp el hijo de p if (LLINK(pp) == p) LLINK(pp) = LLINK(p); else RLINK(pp) = LLINK(p); break; }

480

6. rboles de bsqueda equilibrados

} if (pp == head_ptr) // verifique si se elimin la raz { // factores quedan inalterados ==> no se viola condicin AVL clean_avl_stack(); return p; }

// aqu p es un nodo completo ==> intercambiar por sucesor swapWithSuccessor(p, pp); // removed_key = KEY(succ); // ERROR eliminar

480

i ourre un intermio del nodo eliminr on su suesor in(joD entones el nodo elimindo no sirve pr tulizr el ftor del nodo suesorD pues existe un violin temporl de l propiedd de orden de un effF or est rznD l vrile removed_key lmen l lve segn l ul se tulizrn los ftores en el mino de squedF gomo su nomre expresD l rutin swapNodeWithSuccessor() intermi p on su suesor in(joF e l exepin de los spetos pertinentes los roles evD l siguiente implntin es estruturlmente idnti pr l eliminin en tod lse de rol iE nrio de squed que suyz en el intermio del nodo elimindo on su suesor @o prdeesorA in(joX miembros privados de Gen_Avl_Tree<Key> 473b + (473a) 477b 483 Node* swapWithSuccessor(Node * p, Node *& pp) { // Referencia al tope de la pila, pues p ser intercambiado con // sucesor y la posicin en la pila la ocupar el sucesor de p Node *& ref_to_stack_top = avl_stack.top(); // encuentre el sucesor a la vez que actualiza la pila Node *fSucc = p; // padre del sucesor Node *succ = RLINK(p); // bsqueda comienza desde RLINK(p)
avl_stack.push(succ); while (LLINK(succ) != Node::NullPtr) // descender lo ms a la izq { fSucc = succ; succ = LLINK(succ); avl_stack.push(succ); } // actualice antigua entrada de pila ocupada por p. Equivale // a intercambiar antiguo tope (antes de buscar suc) con actual ref_to_stack_top = succ; avl_stack.top() = p; if (LLINK(pp) == p) // actualice el nuevo hijo de pp (sucesor) LLINK(pp) = succ; else RLINK(pp) = succ; LLINK(succ) = LLINK(p); // intercambie las ramas izquierdas LLINK(p) = Node::NullPtr; if (RLINK(p) == succ) // actualice ramas derechas { // sucesor es exactamente el hijo derecho de p RLINK(p) = RLINK(succ); RLINK(succ) = p; pp = succ;

6.4. rboles AVL

481

} else { // sucesor es el descendiente ms a la izquierda de RLINK(p) Node *succr = RLINK(succ); RLINK(succ) = RLINK(p); LLINK(fSucc) = p; RLINK(p) = succr; pp = fSucc; } DIFF(succ) = DIFF(p); // intercambie factores de equilibrio } return succ;

Restauracin de la condicin AVL

v (gur TFIH@A ilustr el primer so de desequilirio usdo por un elimininF v (gur supone un eliminin en l rm que le us un prdid de lturF v situin es idnti l (gur TFV@A y su orrein similrD es deirD un rotin hi l izquierd uyo resultdoD idntio l (gur TFV@AD se present en l (gur TFIH@AF
T x 2 y 1 h T x 0 h+1 h+1 h h+1 y 0

=
(a) (b)

pigur TFIHX rimer so de eliminin en un rol ev hdo el nodo en el ul ourre l violinD l identi(in del primer so es idnti l de l inserinD es deirD ftores on el mismo signo y un unidd de difereniF r este soD entonesD podemos reutilizr l rutin rotation_type()F in emrgoD difereni de l inserinD el rol T sufre un prdid generl de lturF in efetoD ntes de l elimininD el rol T tiene ltur generl h + 3D mientrs que despus de eliminr l ltur generl es h + 2F gonseuentementeD l sendeni de T puede sufrir un desequilirio violtorio de l ondiin evF v (gur TFII@A muestr el segundo so de eliminin en un eevD el ul tmin es similr l segundo so de l inserin mostrdo en l (gur TFW@AF in l (gur TFII@AD l rm sufre un prdid de ltur deid un eliminin o un juste de equilirioF e difereni de l (gur TFW@AD el nodo z puede estr perfetmente equilirdo o sufrir un ligero y no violtorio desequilirioF in todo soD l ltur de z es h + 1F v orrein se present en l (gur TFII@AD que es l mism que pr l inserin presentd en l (gur TFW@AX un rotin doleD ruzdD del nodo z hi l dereh y luego hi l izquierdF

482

6. rboles de bsqueda equilibrados

T x 2 y 1 h z h h1 T z 0 x y h

=
(a) (b)

pigur TFIIX egundo so de eliminin en un rol ev imilr l primer soD el segundo tmin redue l ltur generl del rol T de h + 3 h + 2F gonseuentementeD tmin es neesrio revisr l sendeni de T en squed de violiones de l ondiin ev usds por el justeF hdo un nodo violtorio de l ondiin evD el segundo so es unvomente identi(leX los signos del nodo violtorio y su hijo son inversosF uesto que est es l mism situin que on el segundo so de violin en l inserinD tmin podemos reutilizr l rutin rotation_type()F il terer y ltimo so de violin usdo por un eliminin se ilustr en l (gur TFIP@A @gF RVPAF equD l rm pierde ltur deido un eliminin o un juste previoF iste so y su soluin son preidos l primer so ilustrdo en ls (gurs TFIH@A @gF RVIAF v difereni estri en que el nodo y est equilirdoF iste so tmin es unvomente identi(leX el hijo del nodo violtorio est equilirdo y fue onsiderdD pero hst hor no explidD en el diseo de l rutin rotation_type()F v orrein del terer so onsiste en un rotin simple hi l izquierd que rroj omo soluin l situin desrit en l (gur TFIP@AF heido que y est iniilmente equilirdoD l ltur generl de T no miF or lo tntoD si l sendeni de T es evD el rol resultnte de l orrein tmin lo es y l eliminin puede ulminr nte este soF
T x 2 y 0 h h h x 1 h T y 1

=
(a) (b)

pigur TFIPX erer so de eliminin en un rol ev gd uno de los tres sos tiene sus equivlentes simtrios filmente interpretles imginndolos re)ejdos en un espejoF he mner generlD despus de l eliminin fsi deemos retroeder en el mino de squedD tulizr d ftor y revisrlo pr ver si existe lgun violinF i

6.4. rboles AVL

483

483

se enuentr un ftor que represente un violinD entones deemos orregirl segn los sos presentdosF i l orrein orresponde l terer soD entones el lgoritmo terminF he lo ontrrio deemos repetir el proedimiento hst enontrr un ftor que no represente un violin o hst enontrrnos on l rzF ist ondut se expres en l siguiente funinX miembros privados de Gen_Avl_Tree<Key> 473b + (473a) 480 void restore_avl_after_deletion(bool left_deficit) // ERROR const Key & key) { Node * pp = avl_stack.top(1); // padre de p Node * ppp = avl_stack.popn(3); // elimina de pila p, padre y abuelo while (true) { // actualice factores de equilibrio if (left_deficit) // ERROR Compare () (key, KEY(pp))) DIFF(pp)++; else DIFF(pp);
if (DIFF(pp) == -2 or DIFF(pp) == 2) // es vlido? pp = restore_avl(pp, ppp); // no! if (DIFF(pp) != 0 or pp == root) break; // altura global de rbol no ha cambiado ==> terminar left_deficit = LLINK(ppp) == pp; pp = ppp; // avance al prximo ascendiente ppp = avl_stack.pop();

}
6.4.2

} clean_avl_stack();

Anlisis de los rboles AVL

gomenzremos nuestro nlisis por l presentin de l siguiente proposiin y disusin de sus onseuenisF
Proposicin 6.4 (Adelson Velsky - Landis, 1962 [6])

e T un rol ev on n noE @TFIHA

dosD entonesX lg (n + 1) h(T ) < 1.4404 lg (n + 2) 0.3277


Demostracin

er TFRFPFP @gF RVVAF

v demostrin es lgo di(ultos y se desrrollr en detlle en ls seiones susiE guientesF ero sus onseuenis pr el nlisis de ls operiones de inserin y elimiE nin son muho ms evidentesF v primer oservin que onllev l proposiin TFIH es que l ltur mxim de un rol ev es O(lg n)F xo import unto rez el rolD el umento de l ltur siempre es logrtmioF espeto l oste onstnte tenemosD en el peor de los sosD un ltur un 447 myor que l de un rol perfetmente equilirdoF in ls situiones restntesD l ltur es

484

6. rboles de bsqueda equilibrados

menor y el tiempo de squed es mejorF ehor ienD qu tn ostoso es este 447c i reordmos los 1300 millones de hinos onsiderdos en en RFW @gF QIQAD el nomre de hng hunnien gheung u puede ser lolizdo en lo sumo 1.44 lg 1300000000 = 44 intentosD 13 ms que on un rol perfetmente equilirdoD y esto slo si somos muy desfortundosF v ot impuest por l proposiin TFIH te diretmente l squedF u er de l inserin y elimininc v inserin requiere un squed queD por l proposiin TFIHD es O(lg n)F vuegoD se retroede en el mino de squed pr veri(r si hy lgn desequilirioD que no tom ms de tres nodosD y que lo heD puesD onstnteE mente otdoF i se enuentr un desequilirioD entones ste se orrige enD lo sumoD dos rotionesD ls ules tmin estn onstntemente otdsF odemos onluir entones que l inserin es O(lg n) + O(1) + O(1) = O(lg n)F il primer pso de l eliminin es un squedD l ul y onluimos que tom O(lg n)F hespusD deemos retroeder en el mino de squedD veri(r si hy desequiE lirio yD si es el soD orregirloF eordemos que un orrein de desequilirio puede usr otro desequilirio en l sendeni del nodo orregidoF in el peor de los sosD l primer orrein puede usr un den de orreiones suesivs que puede llegr hst l rzF uesto que l ltur es O(lg n)D l den de orreiones es lo sumo O(lg n) si st llegse hst l rzF v eliminin esD puesD O(lg n) + O(lg n) = O(lg n)D ms ostos que l inserinD pero tmin O(lg n)F in onlusinD tods ls operiones de un rol ev son O(lg n) pr el peor soF i se requieren grnts de desempeo y se dispone de un implementinD los roles ev son un uen esogeniF
6.4.2.1 rboles de Fibonacci

r demostrr l proposiin TFIHD es onveniente estudir un lse espeil de rol denomindo de pioniF
Denicin 6.5 (rbol de Fibonacci)

n rol de pioni de orden kD denomindo si k = 0 si k = 1 si k 2

Tk D se de(ne reursivmente omoX Tk =

, 0, T , Fib(k + 1) 1, T k 1 k2 + Fib(k + 1)

il ltimo trminoD Tk1 , Fib(k + 1) 1, Tk2 + Fib(k + 1) D dee interpretrse uiddosE menteF v rm izquierdD Tk1 es el rol de pioni de orden k 1F v rz de Tk est etiquetd on Fib(k + 1) 1 donde Fib(i) es el iEsimo nmero de pioniF v rm dereh es el rol de pioni de orden k 2D pero on todos sus nodos sumdos en Fib(k + 1)F v (gur TFIQ muestr el rol de pioni pr k = 8F v rm izquierd es el rol T7 F e su vezD l rm izquierd de T7 es el rol T6 quien su vez tiene de rm izquierd T5 y s suesivmenteF v rm dereh de Tk tiene extmente l mism form que Tk1 D pero d nodo es inrementdo en Fib(k + 1)F or ejemploD en l (gur TFIQ se puede veri(r que l rm dereh prinipl tiene extmente l mism form que T6 D exepto que los vlores de d nodo son inrementdos en Fib(9) = 34F

6.4. rboles AVL

485

33 20 12 7 4 2 1 0 3 5 6 8 9 10 11 13 14 15 16 18 21 17 19 22 23 24 26 25 27 29 34 30 28 31 32 35 36 37 39 38 40 42 43 41 44 45 47 48 49 50 52 46 51 53

pigur TFIQX rol de pioni de orden 8 he l (gur TFIQ se oserv que l etiquet de d nodo es extmente su posiin in(jF iste truo 3 nos permite intuir l rdinlidd de un rol de pioniF v rz del rol de pioni de orden 8 mostrdo en l (gur TFIQ es Fib(8 + 1) 1 = 33F uesto que los nodos estn etiquetdos on su posiin in(jD Fib(7 + 2) = 33 es l ntidd de nodos que preeden l rol izquierdoF eroD por de(niinD L(T8 ) = T7 D por lo que podemos deduir que |T7 | = Fib(7 + 2) 1F odemos oservr diferentes roles de pioni y orroorr est intuiin medinte l siguiente proposiinX
Proposicin 6.5

il nmero de nodos de un rol de pioni de orden k es

Fib(k + 2) 1F
Demostracin (por induccin sobre

k)

 k = 0X in este soD |T0 | = Fib(0) = 0F v proposiin es iert pr k = 0F  k > 0X ehor sumimos que l proposiin es iert pr todo k y veri(mos si n lo es pr k + 1F or de(niinX

|Tk+1 | = |Tk | + 1 + |Tk1 |

@TFIIA

es deirD el nmero de nodos de l rm izquierd ms l rz ms el nmero de nodos de l rm derehF eplindo l hiptesis indutiv l euin @TFIIAD tenemosX

|Tk+1 | = Fib(k + 1) 1 + 1 + Fib(k + 1) 1 = Fib(k + 2) + Fib(k + 1) 1 = Fib(k + 3) 1


v proposiin es entones iert pr todo k v ltur de un rol de pioni tmin es filmente sugerile por oservinF in el so del rol de orden 8 mostrdo en l (gur TFIQ es 8Y es deirD su ordenF
Proposicin 6.6
3

v ltur del rol de pioni de orden k es kF

En realidad, el inters primario de los rboles de Fibonacci es topolgico, pero la manera en que los

etiquetamos nos hace ms aprensible las demostraciones.

486

6. rboles de bsqueda equilibrados

Demostracin (por induccin sobre

k)

 k = 0X este so es diretoD pues el rol vo tiene ltur nulF  k > 0X hor sumimos que l proposiin es iert pr todo k y veri(mos pr k + 1F e Tk+1 el rol de pioni de orden k + 1F intonesD h(Tk+1 ) = 1 + max(h(Tk ), h(Tk1 ))F eplindo l hiptesis indutivD max(h(Tk ), h(Tk1 )) = h(Tk ) = kD por lo que h(Tk+1 ) = 1 + k

pigur TFIRX rol de pioni de orden 13 v proposiin nterior es fundmentl pr demostrr que un rol de pioni es evD uestin que responde l proposiin que sigueX
Proposicin 6.7 Demostracin

n rol de pioni es evF

e Tk el rol de pioni de orden kF gonstruiremos l demostrin por induin sore kX

 k = 0X este so es diretoD pues el rol vo es evF  k = 1X en este soD T1 D ompuesto por un solo nodoD es un rol evF  k > 0X hor sumimos que l proposiin es iert pr todo k y veri(mos pr Tk+1 F r que Tk+1 se evD l difereni de lturs de todos sus nodos no dee exeder de unoF or de(niinD ls rms de Tk+1 son roles de pioniD los ulesD por l hiptesis indutivD son evF es puesD el nio nodo en que hy que veri(r l ondiin ev es en l rz de Tk+1 F v difereni de lturs de raiz(Tk+1 ) est dd por (raiz(Tk+1 )) = h(R(Tk+1 )) h(L(Tk+1 )) = h(Tk1 ) h(Tk )D l ulD por l proposiE in TFTD es k 1 k = 1F uesto que todos los nodos de Tk+1 stisfen l ondiin evD Tk+1 es ev y l proposiin es iert pr todo k gulquier rol de pioni es evF hesde est perspetivD los roles de pioni son de lto intersD pues nos rterizn roles ev de ltur mximF r preir est uestin requerimos l siguiente de(niinX
Denicin 6.6 (rbol AVL crtico)

e T un rol ev de ltur hF e die que T es rtio siD y slo siD l eliminr un nodoD el rol dej de ser ev o pierde lturF v siguiente proposiin nos estlee l ritiidd de un rol de pioniF
Proposicin 6.8

n rol de pioni es un rol ev rtioF

6.4. rboles AVL

487

Demostracin (por induccin sobre

k = |T |)

 k = 0X en este soD T0 = queD si ien es por de(niin evD no dmite elimininF  k = 1X en este soD T1 es un rol onformdo por un slo nodoF el efetur l ni eliminin posile se depr en T0 D el ulD por l proposiin TFTD tiene menor ltur que T1 F il lem esD puesD ierto pr este soF  k = 2X en este so se trt de T2 D del ul slo es posile eliminr dos nodosF sndeE pendientemente del nodo que eliminemosD el rol depr en T1 D o seD que se pierde lturF  k = 3X entones tenemos T3 X
T3 T2 T1
0 1 2 3

T0

he qu tenemos utro sosX IF i eliminmos el nodo 0D entones el rol pierde lturF PF i eliminmos el nodo 3D entones el rol dej de ser ev y ulquier juste que se hg onllev un prdid de lturF QF i eliminmos el nodo 1D entones l tr l rz 2 on l hoj 0 el rol pierde lturF RF pinlmenteD si eliminmos l rz 2D entones tenemos dos lterntivs pr sustiE tuirlX @A golomos el nodo 1 omo rzD lo que rre que el rol pierd lturF @A golomos el nodo 3 omo rzD lo que us que el rol deje de ser evF  k > 3X ehor sumimos que el lem es ierto pr todo k y veri(mos si n lo es pr k + 1F il rol Tk+1 puede pitorizrse omoX
Tk+1

Tk

T k 1

or l hiptesis indutivD los roles Tk y Tk1 son rtiosD s que l eliminr ulquier nodo de ellos el rol dejr de ser ev o perder lturF es puesD el nio punto de dud lo onstituye l eliminin de l rz de Tk+1 F el eliminr l rzD que es un nodo ompletoD deemos sustituirl por lguno de los nodos de Tk o Tk1 F enemos dos sosX IF ustituimos l rz por un nodo de Tk X si Tk pierde lturD entones Tk+1 tmin pierde lturF i Tk dej de ser evD entones Tk+1 tmin dej de ser evF PF ustituimos l rz por un nodo de Tk1 X si Tk1 dej de ser evD entones Tk+1 tmin dej de ser evF i Tk1 pierde lturD entones ourre un violin de l ondiin ev en l rz de Tk+1 D pues (Tk+1 ) = 2F Tk+1 dej pues de ser evF

488

6. rboles de bsqueda equilibrados

uesto que Tk+1 es un ev rtioD entones l proposiin es iert pr todo k istudidos los roles de pioniD tenemos tods ls herrmients requerids pr l demostrin de l proposiin TFRF
6.4.2.2 Demostracin de la proposicin 6.4

v ltur mnim de un rol ev es l mism que pr ulquier rol inrioD l ul fue demostrd en l proposiin RFIF or tntoD nos onentrremos en estudir l ltur mxim que puede lnzr un rol evF istmos interesdos en enontrr un mner de disponer n nodos en un rol ev de mner tl que su ltur se mximF in otrs plrsD deemos disponer los n nodos en un rol rtioF gomo semos de l proposiin TFVD un rol de pioni es rtioF hel mismo modoD por l proposiin TFUD un rol de pioni es evF gon seguridd podemos usr l ot de l ltur mxim trvs de un rol de pioniF hd un ltur nominl hD por l proposiin TFTD el rol de pioni Th D ev y rtioD tieneD segn l proposiin TFSD Fib(h + 2) 1 nodosF es puesD plntemosX

n |Th | = Fib(h + 2) 1

@TFIPA

gulquier rol ev de ltur h tiene que tener igul o ms nodos que |Th |D pues Th es rtioF he este modoD lo nio que nos rest es enontrr un expresin que nos denote el nEsimonmero de pioni y despejr h de l desiguldd @TFIPAF e prtir del onoimiento de que Fib(0) = 0, Fib(0) = 1D deemos resolver l euin de reurreniX Fib(k) = Fib(k 1) + Fib(k 2) = Fib(k + 2) = Fib(k + 1) + Fib(k) = @TFIQA @TFIRA

v euin @TFIRA es un euin reurrente homogne de segundo ordenF e llm de est mner porque es reminisente un euin diferenil homogne de segundo ordenF he hehoD ls euiones de reurrenis menudo se llmn euiones de diferE enis por su similitudes on ls euiones diferenilesF in este sentidoD l euin @TFIRA es reminisente un euin diferenil linel homogne de segundo orden on  + a1 y _ + a2 y = 0F oe(ientes onstntesD es deirD de form y ehor podemos resolver l euin reurrente @TFIRA medinte un mtodo nlogo de resoluin de un euin diferenilF r elloD l igul que on un euin diferenil homogne de segundo ordenD plimos l trnsformin siguienteX Fib(k) = c k ,

c, = 0, k 2 .

@TFISA

ustituimos @TFISA en @TFIRAD lo que proporion l euin rtersti siguienteX

c k+2 = c k+1 + c k ,
l ulD l dividir por c k D puede simpli(rse l legendri euin divinX

@TFITA

2 1 = 0 ,
uys res sonX

@TFIUA

1 5 . = 2

@TFIVA

6.4. rboles AVL

489

istos nmeros son legendriosD el nmero y ^ uyos vlores sonX 1+ 5 1.61803 , = 2 1 5 ^ = 0.61803 2 he est mnerD l soluin generl esX Fib(k) = c1 k + c2 ^k

@TFIWA @TFPHA

@TFPIA

r enontrr los vlores de c1 y c2 D hemos lo mismo que on un euin diferenE ilX plntemos un sistem de euiones on vlores onoidos de Fib(k)F in este so utilizmos Fib(0) = 0 y Fib(1) = 1X Fib(0) = 0 = c1 0 + c2 ^ 0 = c1 + c2 Fib(1) = 1 = c1 + c2 ^ = c1 + c2 ^
1 1

@TFPPA @TFPQA @TFPRA

he l euin @TFPPA tenemosX

c2 = c1
y sustituyendo @TFPRA en @TFPQAX

c1 c1 ^ = 1 = c1 ( ^ ) = 1 = c1 =
gominndo @TFPSA y @TFPRA en @TFPIAX

1 1 = ^ 5

@TFPSA

1 1 k ^k Fib(k) = k ^k = 5 5 5

@TFPTA

uesto que ^ < 1D el trmino ^ k deviene exponenilmente muy pequeo onforme ree kD ergo ^ es despreile en @TFPTA pr vlores de k muy grndesF gonseuentementeD Fib(k) es stnte erno k / 5 onforme ree kF es puesD podemos tener un expresin ms simple pr lulr el kEsimo nmero de pioniX

k Fib(k) = 5

redondedo l entero ms prximo

@TFPUA

lo ul nos permite ompletr l demostrin de l proposiin TFRF ehor retommos l desiguldd @TFIPAX

n |Th | = Fib(h + 2) 1 = h+2 > redondedo l entero ms erno 1 = 5 h+2 n > 2 5

@TFPVA @TFPWA @TFQHA

xotemos que l euin @TFPUA estlee que l funin redondeo l entero ms erno dee plirseF r despejr h de l ineuin @TFPWAD ser neesrio onoer l invers

490

6. rboles de bsqueda equilibrados

de l funin de redondeoF or es rzn restmos un unidd del ldo dereho de l ineuin @TFPWA yD prtir de llD expresmos un desiguldd estritX 5 (n + 2) = h+2 < h + 2 < log [ 5 (n + 2)] = h < log (n + 2) + log ( 5) 2 = lg (n + 2) h < 0.3277 = lg h < 1.4404 lg (n + 1) 0.3277

6.5 rboles rojo-negro


ehor estudiremos un lse de rol inrio uyo esquem de lne tmin es grnE tizdoF il esquem es romtio en el sentido de que los nodos son oloredos de rojo o negroD respetivmenteF vs regls de olorin proporionn rgumentos omintoriosD en funin de ls posiles ominiones de oloresD que grntizn un equilirioF n rol rojoEnegroD o efxD es un rol inrio de squedD on un triuto diionl en d uno de sus nodos llmdo olorD que stisfe ls siguientes ondiiones denominds romtisX
Denicin 6.7 (rbol rojo-negro)

 Condicin cromtica primariaX un nodo es rojo o negroF  Condicin rojaX si un nodo es rojoD entones sus dos hijos deen ser negrosF isto grntiz que dos nodos rojos nun pueden estr ontiguos en el mino de squedF  Condicin negraX ulquier mino desde l rz hst un nodo externo ontiene el mismo nmero de nodos negrosF  Nodo externo negroX los nodos externos son negrosF ist de(niin y los lgoritmos resultntes estn fuertemente inspirdos de l exels presentin de los roles rojoEnegro de herik ood IVRF u de(niin di(ere ligerE mente de otros estudiosos que exigen que l rz siempre se negrF v (gur TFIS ilustr un ejemplo de un rol rojoEnegro en l ul los nodos rojos estn somredosF v ondiin negr justi( un nuevo oneptoX l ltur negrD l ul se de(ne omo sigueF e T un rol rojoEnegro y ni T un nodo ulquier de T F e de(ne l ltur negr de ni D denotd omo bh(ni )D omo el nmero de nodos negros desde ni hst ulquier nodo externo de T F
Denicin 6.8 (Altura negra en un nodo rojo-negro)

xotemos que l ltur negr est de(nid pr ulquier mino desde raiz(T )F isto es un onseueni diret de l ondiin negr que nos grntiz que est ltur es l mism independientemente de l hoj que se onsidereF

6.5. rboles rojo-negro

491

491

il primer pso hi el diseo de un tipo strto de dto es espei(r un nodo rojoEnegroX rbNode.H 491 typedef unsigned char Color; # define COLOR(p) ((p)->getColor()) # define RED (0) # define BLACK (1) class RbNode_Data { Color color; // RED o BLACK
RbNode_Data() : color(RED) {} RbNode_Data(SentinelCtor) : color(BLACK) {} }; DECLARE_BINNODE_SENTINEL(RbNode, 128, RbNode_Data);
Denes: Uses

Color & getColor() { return color; }

RbNode, used in chunk 492a. DECLARE_BINNODE_SENTINEL.

v lse RbNode est dised pr umplir ls ondiiones de seF il onstrutor por omisin siempre re un nodo rojoF n nuevo nodo rojo no lter l ltur negrD por onsiguienteD se preserv l ondiin negrF e efetos de stisfer l ltim ondiin y filitr los lgoritmosD los roles rojoEnegro usn un nodo nulo entinel que es negroF sntuitivmente podemos preir el equilirio de un rol rojoEnegroX todo nodo est perfetmente negroEequilirdoD es deirD pr todo nodoD l difereni de lturs negrs entre sus dos rms es nulF he hehoD el rol rojoEnegro mostrdo en l (gur TFIT est eptlemente equilirdoF
6.5.1 El TAD

Rb_Tree<Key>

iv eh Gen_Rb_Tree<Key> de(ne un rol rojoEnegro uys operiones priniples son en funin de nodos rojoEnegro de(nidos nteriormenteF v estrutur prinipl es omo
36

15

65

30

47

90

12

23

33

46

63

82

94

11

20

29

31

34

61

64

76

88

92

98

57

69

79

86

pigur TFISX n rol rojoEnegro

492

6. rboles de bsqueda equilibrados

pigur TFITX n rol rojoEnegro de 512 nodos sigueX


492a

tpl_rb_tree.H 492a

template <template <typename> class NodeType, typename Key, class Compare> class Gen_Rb_Tree { typedef NodeType<Key> Node; miembros privados de Gen_Rb_Tree<Key> 492b miembros pblicos de Gen_Rb_Tree<Key> 493 }; template <typename Key, class Compare = Aleph::less<Key> > struct Rb_Tree : public Gen_Rb_Tree<RbNode, Key, Compare> {};
RbNode
491.

Uses

492b

vos fundmentos de implntin son muy similres los dems roles inrios esE tudidosX un nodo eerD uno entinel y diluidin de uso o no de l reursividdF vos lgoritmos son ms senillos que los de un rol evD pero no lo su(iente omo pr permitir un implntin nturlmente reursivF n de ls deisiones que tommos priori es her un implntin itertiv sistid de un pilD l ul justi( los siguientes triutosX miembros privados de Gen_Rb_Tree<Key> 492b (492a) 492c Node head_node; // cabecera centinela Node * head; // puntero a centinela Node *& root; FixedStack<Node*, Node::MaxHeight> rb_stack;
Uses

FixedStack

101a.

492c

v inserin y eliminin requieren empilr el mino de squedF ist in es efetud por un rutin espe(X miembros privados de Gen_Rb_Tree<Key> 492b + (492a) 492b 494 Node * search_and_stack_rb(const Key & key) { Node * p = root; rb_stack.push(head); do { rb_stack.push(p); if (Compare () (key, KEY(p))) p = LLINK(p); else if (Compare () (KEY(p), key)) p = RLINK(p); else return p; }

6.5. rboles rojo-negro

493

while (p != Node::NullPtr); } return rb_stack.top();

Denes:

search_and_stack_rb,
6.5.1.1

used in chunks 493 and 497.

Insercin en un rbol rojo-negro

493

in prinipioD l inserin es extmente igul l inserin en un rol inrio estndrF vuegoD si es neesrioD se efetn los justes pr preservr el lneX miembros pblicos de Gen_Rb_Tree<Key> 493 (492a) 497 Node * insert(Node * p) { if (root == Node::NullPtr) return root = p; // insercin en rbol vaco
Node * q = search_and_stack_rb(KEY(p)); if (Compare () (KEY(p), KEY(q))) LLINK(q) = p; else if (Compare () (KEY(q), KEY(p))) RLINK(q) = p; else { rb_stack.empty(); return NULL; // clave duplicada } fix_red_condition(p); } return p; if (root == Node::NullPtr) return root = p; // insercin en rbol vaco Node * q = search_and_stack_rb(KEY(p)); if (Compare () (KEY(p), KEY(q))) LLINK(q) = p; else if (Compare () (KEY(q), KEY(p))) RLINK(q) = p; else { rb_stack.empty(); return q; // clave duplicada } fix_red_condition(p); return p; } Node * insert_dup(Node * p) { I(COLOR(p) == RED);

494

6. rboles de bsqueda equilibrados

if (root == Node::NullPtr) return root = p; // insercin en rbol vaco Node * q = search_dup_and_stack_rb(KEY(p)); if (Compare () (KEY(p), KEY(q))) LLINK(q) = p; else RLINK(q) = p; fix_red_condition(p); } return p;

bool verify() { return is_red_black_tree(root) ; }


Uses

fix_red_condition

494,

is_red_black_tree,

and

search_and_stack_rb

492c.

494

v rutin implnt l inserin fsi lsiF fix_red_condition() veri( violiones de ls ondiiones romtis y ls orrige si es el soF in el so de l inserinD el truo es insertr un nodo rojoD pues ste no lter l ondiin negrD ergoD el lne de lturs negrsF imperoD l inserin de un nodo rojo puede usr un violin de l ondiin roj si el pdre del nodo insertdo es rojoF i el pdre del nodo insertdo es negroD entones el rol resultnte es rojoEnegro y el lgoritmo terminF he lo ontrrio es neesrio restleer l ondiin roj sin lterr l ondiin negrF v estrutur de fix_red_condition() es omo sigueX miembros privados de Gen_Rb_Tree<Key> 492b + (492a) 492c 499 void fix_red_condition(Node * p) { while (p != root) { Node * pp = rb_stack.pop(); // padre de p if (COLOR(pp) == BLACK) // padre de p negro? break; // s ==> no hay rojos consecutivos ==> terminar
if (root == pp) // p es hijo directo de la raz? { // s ==> colorear raz de negro y terminar COLOR(root) = BLACK; break; } Node * ppp = rb_stack.pop(); // abuelo de p Node * spp = LLINK(ppp) == pp ? RLINK(ppp) : LLINK(ppp); // to if (COLOR(spp) == RED) // to de p rojo? { // intercambiar colores entre los niveles COLOR(ppp) = RED; COLOR(pp) = BLACK; COLOR(spp) = BLACK; p = ppp; continue; // ir prximo ancestro, verificar violaciones }

6.5. rboles rojo-negro

495

} rb_stack.empty();

Node * pppp = rb_stack.pop(); // bisabuelo de p if (LLINK(pp) == p and LLINK(ppp) == pp) { rotate_to_right(ppp, pppp); COLOR(pp) = BLACK; } else if (RLINK(pp) == p and RLINK(ppp) == pp) { rotate_to_left(ppp, pppp); COLOR(pp) = BLACK; } else { if (RLINK(pp) == p) { rotate_to_left(pp, ppp); rotate_to_right(ppp, pppp); } else { rotate_to_right(pp, ppp); rotate_to_left(ppp, pppp); } COLOR(p) = BLACK; } COLOR(ppp) = RED; break; // rbol es rojo-negro ==> terminar

Denes:

fix_red_condition,

used in chunk 493.

il lgoritmo tom omo entrd un nodo pD que es el nodo insertrF v slid es un rol rojoEnegro on el nodo p insertdoF el iniio del whileD p es un nodo rojo rein insertdoF elguns orreiones pueden usr otrs violiones sore l sendeni de pF gundo esto ourreD p se tuliz que punte sore un nodo rojo que viole l ondiin rojF i el pdre de p es negroD entones el nuevo nodo no us ningun violin y el lgoritmo terminF ist es l primer veri(in del whileF iD por el ontrrioD pp es rojoD entones tenemos dos nodos rojos onseutivos que violn l ondiin rojF v orrein se efet segn los siguientes sosX IF p es hijo direto de l rzX est situin se veri( en el segundo if y se resuelve olorendo l rz de negroX
root root pp p

il rol resultnte es rojoEnegro y el lgoritmo terminF

496

6. rboles de bsqueda equilibrados

PF o de p es rojoX est irunstniD detetd por el terer ifD se sorte on un intermio de olores entre los nivelesF is deirD el uelo p deviene rojo y sus dos hijos devienen negrosF vos dos sos posiles se muestrn en l (gur TFIU @gF RWTAF
ppp pp p spp p pp ppp spp


ppp pp p

=
spp

ppp pp p spp

pigur TFIUX sntermio de olores entre los niveles vuego de este juste el pdre de ppp es podr ser rojoD lo que rrer un violin de l ondiin rojF or es rznD ejeutmos p = ppp y vnzmos un nuev iterinF QF o de p es negroX en este so hemos rotiones que trnsformen el prolem en uno de los nterioresF ry dos posiles situiones generlesX @A ist situin se muestr en l (gur TFIV @gF RWTA y se detet porque pD pp y ppp estn ompletmente linedosD se hi l izquierd o hi l derehF u detein y proesmiento oupn los urto y quinto ifF v orrein onsiste en efetur un rotin simple de pp hi el ldo de sppY esto he que pp deveng l rz del surolF or ltimoD se intermin los olores de pp y pppF
ppp pp p spp p pp ppp spp

pigur TFIVX otin y olorin pr resturr ondiin roj @A ist situin se ilustr en l (gur TFIW @gF RWUAD y se present undo pD pp y ppp no estn ompletmente linedosF v soluin onsiste en un dole rotin ruzd de p hi el ldo de sppF in este soD p deviene l rz del surol y los olores de p y de ppp son intermidosF

6.5. rboles rojo-negro

497

ppp pp p spp pp

p ppp spp

pigur TFIWX hole rotin de p y olorin pr resturr ondiin roj in ls dos situiones nterioresD el rol resultnte es rojoEnegro y el lgoritmo terE minF elguns iteriones pueden ourrir undo se e en el segundo soD pudiendo ser neesrio suir hst l rzF gundo esto ourreD l eventul violin de l ondiin roj disminuye dos nivelesF he este modoD el nmero mximo de iteriones est otdo por l ltur del rol dividid entre dos @h/2AF
6.5.1.2 Eliminacin en un rbol rojo-negro

497

in prinipioD l eliminin es similr l de un rol inrio estndrF vuegoD si es neesrioD se hen los justes que resturen ls ondiiones romtisF miembros pblicos de Gen_Rb_Tree<Key> 493 + (492a) 493 Node* remove(const Key & key) { if (root == Node::NullPtr) return NULL;
Node * q = search_and_stack_rb(key); if (no_equals<Key, Compare> (KEY(q), key)) // clave no encontrada? { rb_stack.empty(); return NULL; } Node * pq = rb_stack.top(1); // padre de 1 Node * p; // hijo de q luego de que ste ha sido eliminado while (true) // eliminacin clsica rbol binario de bsqueda { if (LLINK(q) == Node::NullPtr) { if (LLINK(pq) == q) p = LLINK(pq) = RLINK(q); else p = RLINK(pq) = RLINK(q); break; // goto end; } if (RLINK(q) == Node::NullPtr) { if (LLINK(pq) == q) p = LLINK(pq) = LLINK(q);

498

6. rboles de bsqueda equilibrados

} if (COLOR(q) == BLACK) // se elimin un nodo negro? fix_black_condition(p); q->reset(); rb_stack.empty(); }


Uses

} find_succ_and_swap(q, pq);

else p = RLINK(pq) = LLINK(q); break; // goto end;

return q;
find_succ_and_swap, fix_black_condition
499, and

search_and_stack_rb

492c.

v rutin us l lve l vez que empil el mino de squedF il nodo eliminr es llmdo q y su pdre pqF il while implnt l eliminin fsi del nodoD l ulD ests lturs del estudioD dee ser ompresile pr el letorF hespus de l eliminin fsi existe el riesgo de violin de l ondiin negrD pues el nodo elimindo puede ser sido negroD lo que provo un prdid en ltur negrF in delnte llmremos p ese nodo elimindoD el ul puede tener un d(it en nodos negrosF find_succ_and_swap() intermi q on su suesor in(joF v rutin es estruturlE mente idnti l versin pr roles ev @ TFRFIFP @gF RUWAAF il nio punto onsiderr es que si se elimin un nodo ompletoD entones el suesor Eo predeesorE que se sustituye dee heredr el mismo olor del nodo elimindoF he est mnerD l violin eventul ourre sore un nodo que on ertez es inompletoF
pp

sp


snp np

pigur TFPHX on de fmilires donntes de nodo rojo v eliminin estndr en un eff siempre se remite l eliminin de un nodo uyo pdre se inompletoF v ide es efetur un ortoEiruito E RFWFT @gF QPRAE hi el hijo de q l ul denominmos pF i q es rojoD entones el rol resultnte es rojoEnegroF il prolem surge undo q es negroD pues se viol l ondiin negrF in este so diremos que existe un d(it de un nodo negro en el mino desde el pdre del nodo elimindo hst pF he mner generlD l estrtegi de resturin de l ondiin negr es enontrr un nodo rojo en ls inmediiones de p tl omo se indi en l (gur TFPHF i se enuentr tl nodoD entones ste puede psrse hi el ldo del d(it y olorerlo de negro pr s ompensr el d(itF il trjo es efetudo por l rutin fix_black_condition()D l ul tom omo entrd un nodo p on un d(it en un nodo negro que dee ser resturdoF v slid es un rol rojoEnegroF

6.5. rboles rojo-negro

499

499

v estrutur de l rutin es l siguienteX miembros privados de Gen_Rb_Tree<Key> 492b + void fix_black_condition(Node * p) { if (COLOR(p) == RED) // p es rojo? { // s ==> lo pintamos de negro y terminamos COLOR(p) = BLACK; // esto compensa el dficit return; }

(492a)

494

Node * pp = rb_stack.popn(2); // padre de p while (p != root) { Node * sp = LLINK(pp) == p ? RLINK(pp) : LLINK(pp); // hermano p if (COLOR(sp) == RED) // hermano de p es rojo?

rotar sp hacia el lado de p e intercambiar sus colores 500a

calcular los sobrinos de p (hijos de sp) 500b


if (COLOR(np) == RED) // np es rojo? { return;

rotar sp hacia p, heredar color pp y pintar negro a np y pp 501a

} if (COLOR(snp) == RED) // snp es rojo? { return;

rotar doble a snp y pintar de negro a pp 501b ;

} if (COLOR(pp) == RED) // pp es rojo? { intercambiar colores de p y pp 502 ; return; } // no hay nodo rojo en las adyacencias de p ==> desplazar el // dficit hacia pp y repetir la iteracin COLOR(sp) = RED; p = pp; pp = rb_stack.pop();

Denes:

fix_black_condition,

used in chunk 497.

v rutin omienz por evlur si el nodo de(itrio es rojoY en ese so st on pintr p de negro y el rol generl es rojoEnegroY situin y orrein ilustrds en l (gur TFPIF in el so ontrrioD el lgoritmo entr en un ilo que us un nodo rojo en l zon enmrd en l (gur TFPH @gF RWVA pr intentr sustituir l nodo negro y s ompensr el d(itF v iterin exmin los nodos de l zon en el orden spD npD snp y ppD segn los siguientes sosX

500

6. rboles de bsqueda equilibrados

pq RN q p pq RN p

Nodo a eliminar

=
pigur TFPIX iliminin de un nodo negro on hijo rojo

IF sp rojoX l situin y su orrein se muestrn en l (gur TFPPF


500a

rotar sp hacia el lado de p e intercambiar sus colores 500a


{ Node *& ppp = rb_stack.top(); // abuelo de p if (LLINK(pp) == p) { sp = LLINK(sp); ppp = rotate_to_left(pp, ppp); } else { sp = RLINK(sp); ppp = rotate_to_right(pp, ppp); } COLOR(ppp) = BLACK; COLOR(pp) = RED;

(499)

ist in ument el nodo de(itrio en un nivelD pero he que el nuevo hermno de p se negro y que entre en l zon de fmilires donntes desrit en l (gur TFPH @gF RWVAF
sp pp p sp p pp

pigur TFPPX gso undo sp es rojo i sp es negroD entones hy que revisr sus sorinosD pero ntes es menester lulrlos de l siguiente mnerX
500b

calcular los sobrinos de p (hijos de sp) 500b


Node * np, * snp; // sobrinos de nodo p if (LLINK(pp) == p) // p es hijo izquierdo?

(499)

6.5. rboles rojo-negro

501

{ } else { }

// s ==> que sp es hijo derechos np = RLINK(sp); snp = LLINK(sp);

np = LLINK(sp); snp = RLINK(sp);

PF np rojoX l situin se ilustr en l (gur TFPQ y se identi( porque np est linedo hi l dereh on spF v soluin onsiste en rotr sp hi el ldo de p y olorer de negro np y ppF gon esto gnmos el nodo negro pp en el mino hi pD lo ul ompens el d(itF
501a

rotar sp hacia p, heredar color pp y pintar negro a np y pp 501a


Node * ppp = rb_stack.top(); if (RLINK(sp) == np) rotate_to_left(pp, ppp); else rotate_to_right(pp, ppp); COLOR(sp) = COLOR(pp); COLOR(pp) = BLACK; COLOR(np) = BLACK;
pp p RN sp np p pp sp RN

(499)

np

pigur TFPQX gso undo np es rojo

QF snp rojoX l situin se ilustr en l (gur TFPR @gF SHPAY es muy similr l nterior exepto que no hy linein omplet hi l derehF v soluin tmin es similrX rotr snp dos vees hi el ldo de p y luego olorer de negro pp y spF el igul que en el so nteriorD l gnni del nodo negro pp en el mino hi p ompens el d(itF
501b

rotar doble a snp y pintar de negro a pp 501b


Node * ppp = rb_stack.top(); if (LLINK(sp) == snp) { rotate_to_right(sp, pp);

(499)

502

6. rboles de bsqueda equilibrados

} else { }

rotate_to_left(pp, ppp);

rotate_to_left(sp, pp); rotate_to_right(pp, ppp);

COLOR(snp) = COLOR(pp); COLOR(pp) = BLACK;


pp p RN sp snp np p pp snp RN sp np

pigur TFPRX gso undo snp es rojo

RF pp rojoX l situin se muestr en l (gur TFPS @gF SHPA y se resuelve intermindo los olores de pp on spF hespus de este justeD el mino hi p gn un nodo negro trvs de su pdreD mientrs que el mino hi sp permnee on l mism ntidd de nodos negrosF iste juste slo puede herse si se hn evludo los sos nterioresD pues se podr violr l ondiin roj si lguno de los sorinos de p fuese rojoF
502

intercambiar colores de p y pp 502


COLOR(pp) = BLACK; COLOR(sp) = RED;

(499)

pp p snp sp np p

pp sp np

snp

=
pigur TFPSX gso undo el pdre de p es rojo

SF xinguno de los fmilires es rojoX si los sos nteriores fllnD entones no hy nodos rojos en l zon enmrd en l (gur TFPH @gF RWVAF ente est situinD l ni slid es desplzr el d(it hi el pdre de p y luego repetir el proedimiento nterior on p = ppF il desplzmientoD ilustrdo en l (gur TFPTD onsiste simplemente en olorer sp de rojoF gon esto eliminmos un nodo negro prtir de sp y trsldmos el d(it hi ppF il lgoritmo iter si no se enuentrn nodos rojos en l zon enmrd en l (gur TFPH @gF RWVAF v ntidd mxim de iteriones depende de si hy o no nodos rojos en ls inmediiones del mino de squed l lve elimindF in el peor de los sos

6.5. rboles rojo-negro

503

pp p snp sp np p

pp sp np

snp

=
pigur TFPTX hesplzmiento del d(it hi pp

puede ser neesrio suir hst l rzF in est situinD el d(it ourre pr todos los minos desde l rz hst ulquier nodo nuloD por lo que no hy violin de l ondiin negrF il mino ms lrgo se d undo l eliminin ourre en un de ls hojs ms profunds en ltur negrF isto impli que del ldo opuesto p el rol dee estr perfetmente lnedoD pues si noD l zon no ser ompletmente negrF il lem TFU nos mostrr que l ltur de l zon ompletmente negr es h/2 pr el peor rolF v proposiin TFW nos mostrr que l ltur mxim es 2 lg (n + 2) 2F es puesD l eliminin es O(lg n) pr el peor soF
6.5.2 Anlisis de los rboles rojo-negro

gomenemos por reordr que l ondiin negr grntiz por si mism un lne nivel de nodos negrosF i slo se uentn los nodos negrosD entonesD pr d nodoD l difereni de lturs entre ls dos rms es eroF fjo l ltur negrD el rol est perfetmente equilirdoF il nlisis se enfo entones en estudir el impto de los nodos rojos sore l ltur glol del rolF or l ondiin rojD l ltur dee expresrse en funin de nodos negrosD pues no puede her dos nodos rojos onseutivosF il nmero mximo de nodos rojos involurdos no puede exederD puesD l nmero de nodos negros ms unoF he mner intuitiv podemos deir que en el peor soD l ltur mxim de un rol rojoEnegro est determind por l longitud mxim en nodos negros multiplid por dosF is deirD sumimos que el mino de l rm ms lrg est repleto de nodos rojos interldos entre nodos negrosF gon ests oserviones en menteD estmos listos pr enunir l proposiin siguienteF @quis y edgewik E IWUVA e T un rol rojoEnegro on n nodos y ltur hF intonesX h 2 lg (n + 2) 2 @TFQIA
Proposicin 6.9 Demostracin

il enfoque es similr l utilizdo en los roles ev @proposiin TFRAF is deirD vmos determinr ul es el rol rojoEnegro de ltur h on el mximo nmero de nodosF r eso deemos identi(r un rol rojoEnegro rtioF
Denicin 6.9 (rbol rojo-negro crtico)

e T un rol rojoEnegro de ltur h(T )F e die que T es rtio siD y slo siD l quitrle un hoj el rol dej de ser rojoEnegro o pierde lturF el igul que on los roles evD l rdinlidd de un rol rojoEnegro rtio es mnim l ltur h(T )D es deirD si T es rtioD no es posile tener un rol l mism ltur on menor ntidd de nodosF

504

6. rboles de bsqueda equilibrados

ehor proedemos estudir untos nodos tiene un rol rtio en funin de su lturF rimero omenemos por oservr ls diferenis de ltur en los nodos de un rol rtioF
Lema 6.4

e T un rol rojoEnegro rtio de ltur h(T ) > 1 on rms L(T ) y R(T ) respetivmenteF intones h(L(T )) = h(R(T ))F upongmos que existe un rol rojoE negro rtio on h(L(T )) = h(R(T ))F uesto que h(T ) > 1D podemos reemplzr ulquier de ls rms por otro rol rojoEnegro ms pequeo en ltur y rdinliddD lo ul rrojr un rol rojoEnegro de rdinlidd inferiorF isto us un ontrdiinD pues hemos diho que T es rtioF il lem es pues ierto
Demostracin (por reduccin al absurdo)

ehor vemos untos suroles rtios hy dentro de un rol rojoEnegro rtioF


Lema 6.5

e T un rol rojoEnegro rtio de ltur h(T ) > 1F intonesD h(R(T )) = h(T ) 1 = R(T ) es rtio y por lo tnto mnimoF v situin simtriD es deirD si h(L(T )) = h(T ) 1D es equivlenteF
Demostracin (por reduccin al absurdo) upongmos que T es rtio y que R(T )) no lo esF intonesD R(T ) podr ser reemplzdo por un surol T , h(T ) = h(T ) 1 tl que |T | < | R(T )|F isto implir que T tiene menos nodos l mism lturD lo ul es un ontrdiin on l suposiin de que T es rtio

gon este lem podemos estudir l omposiin romti de d uno de los surE oles de un rol rojoEnegro rtioF
Lema 6.6

e T un rol rojoEnegro rtio de ltur h(T ) > 1F intonesD h(R(T )) = h(T ) 1 =X IF L(T ) no tiene nodos rojosF PF L(T ) es un rol perfetmente equilirdo y ompletoF
Demostracin

IF i L(T ) tiene un nodo rojoD entones este nodo puede ser suprimido y sustituido por el rol voF il rol resultnte es rojoEnegro pero tiene menos nodosD lo ul viol l suposiin de que T es rtioF PF uesto que L(T ) slo ontiene nodos negrosD l ni form de preservr l ondiin negr es que L(T ) se perfetmente equilirdo y ompleto

h/2 h1

pigur TFPUX porm de un rol rojoEnegro rtio

6.5. rboles rojo-negro

505

iste lem demuestr que l form de un rol rojoEnegro rtio es l de l (gur TFPUF is deirD l rm de menor ltur es entermente negr y perfetmente lnedF xote que el lem TFT tmin indi que l form del surol dereho de l (gur TFPU esD en trminos reursivosD similr l (gur TFPUF ist oservin es muy importnte porque nos permitir lulr un ot l ntidd de nodos de nodos que tiene un rol rtio en funin de su lturF i T es rojoEnegroD entones bh(L(T )) = bh(R(T ))F iD demsD T es rtioD entones bh(R(T )) = h(L(T ))D puesD por el lem TFTD L(T ) slo tiene nodos negrosF or el lem TFS semos que h(R(T )) = h(T ) 1F hel mismo modoD tmin por el lem TFSD si R(T ) es rtioD entones ste dee tener l form demostrd por el lem TFTF
Lema 6.7

e T un rol rojoEnegro rtio de ltur h(T ) = hF intonesD bh(T ) =

h 2 h)

@TFQPA

Demostracin (por induccin sobre la altura

 h = 0X en este so 0/2 = 0 y l hiptesis de se es vlidF  h > 0X hor suponemos que el lem es vlido pr todo rol Th rojoEnegro rtio de ltur h y veri(mos si n lo es pr el rol Th+1 de ltur h + 1F v demostrin depender de que h se pr o imprX IF i h es impr = h + 1 es prF in este soD si oloremos de negro l rz de Th+1 tenemosX bh(Th+1 ) = bh(Th ) + 1 =

= =
il lem es vlido pr h imprF

h1 h +1= + 1 = 2 2 h+1 h+1 = 2 2


@TFQQA

PF i h es pr = h + 1 es imprF in este soD si oloremos de rojo l rz de Th+1 tenemosX bh(Th+1 ) = bh(Th ) =

=
il lem es vlido pr hD pr o impr

h+1 h = 2 2

@TFQRA

v demostrin del lem TFU he prensile el heho de que el olor de l rz de un rol rojoEnegro puede ser negro solmente si l ltur del rol es prF il lem TFU permite ompletr l prue del teorem porque hor podemos lulr un expresin que indique l ntidd totl de nodos de un rol rojoEnegro rtioF

506

6. rboles de bsqueda equilibrados

i Th es un rol rojoEnegro rtio de ltur hD entonesX

|Th | = 1 + | L(Th )| + | R(Th )|


or los lems TFT y TFU semos que L(Th ) slo tiene nodos negrosD por endeX

@TFQSA

| L(Th )| = 2

(h1)/2

@TFQTA

or otr prteD por el lem TFSD semos que R(Th ) es rtio y que su ltur es h 1F ustituimos @TFQTA en @TFQSA y otenemos un euin reurrente filmente resoluleX

|Th | = |Th1 | + 2
l ulD l expndir |Th1 |X

(h1)/2

@TFQUA

|Th | = |Th2 | + 2
 i h es pr =

(h2)/2

+2

(h1)/2

@TFQVA

|Th | = |Th2 | + 2(h2)/2 + 2(h2)/2 = |Th2 | + 2h/2 =


h/2

|Th | =
i=1

2i = 2h/2+1 2

@TFQWA

 i h es impr =

|Th | = |Th2 | + 2(h3)/2 + 2(h1)/2 = |Th | = |Th2 | + 21 . 2(h1)/2 + 2(h1)/2 | = |Th | = |Th2 | + 3 . 2(h3)/2 =
(h3)/2

|Th | = |Th2 | + 3 .
i =0

2i = 1 + 3 . 2(h3)/2 3 = 3 . 2(h3)/2 2

@TFRHA

r ompletr l demostrinD se n el nmero de nodos de un rol rojoEnegro de ltur hF n dee ser myor o igul l nmero de nodos del rol rojoEnegro rtio de ltur hF omndo el menor trmino dereho de ls euiones @TFQWA y @TFRHA plntemosX

n + 2 2h/2+1 = h + 1 = lg (n + 2) 2 h 2 lg (n + 2) 2
v mxim ltur de un rol rojoEnegro es proximdmente un PV7 ms grnde que l mxim ltur de un rol ev @2 lg (n + 2) versus 1.4404 lg (n + 2)AF es puesD nltimenteD el desempeo de l squed deer ser superior en los roles ev que en los roles rojoEnegroF imperoD est difereni no es signi(tivF il desempeo de mos roles es muy similrF

n 2h/2+1 2 =

6.6. rboles splay

507

6.6 rboles splay


vos roles letorizdos y los treps sn sus equilirios sore l tom de deisiones letorisF in promedioD l ltur de estos roles deviene logrtmiD on proiliddes muy eszs de tener un ml soF vos roles ev y rojoEnegro sn sus equilirios en regls espeiles que se mntienen en tiempos logrtmiosF in est lse de rolesD l ltur mxim yD por endeD el tiempo de esoD estn logrtmimente otdosF ixiste un terer lterntiv de equilirio sd en efetur modi(iones estruturles sore el rolD que tiendn volverlo equilirdoF l lterntiv es el ojeto de estudios de est seinX los roles splyF gonsideremos ls tres operiones lsis sore un tl de smolos y un rreglo que lmen los elementos desordendmenteF gomo vimos en PFIFI @gF PWAD en un rregloD ls tres operiones son O(n)F ehor onsideremos un modi(in sore l implntin trdiionlX d vez que se efet un esoD se por squedD inserin o elimininD el elemento es uido en l primer posiinF fjo est reglD l inserin y eliminin devienen O(1) pr todos los sos y l squed  O(n) pr el peor soF i l pliin exhie lolidd de refereniD entones l squed tiende ser O(1)D pues lo elementos reientemente edidos se enuentrn en ls primers posiiones del rregloF u tn uen es est tnic vos nlisis formles y emprios demuestrn que es muy uen en muhos sosF gundo no hy lolidd de refereniD l squed es O(n) pr los sos promedio y peorD un desempeo eptle hst esls medinsF e puede plir l tni nterior pr los roles inrios de squedc v resE puest es (rmtiv y l primer tentin es mover el nodo reientemente edido hst l rzF v inserin onsistir en insertr en l rz segn los lgoritmos estudidos en RFWFU @gF QPTAF hel mismo modoD podrmos diser un rutin similr l select() estudido en RFIIFI @gF QQUA que usque un lve y medinte rotiones suesivs su el nodo enontrdo hst l rzF el igul que on los rreglosD est tni h prodo tener un desempeo ueno pr pliiones que exhin lolidd de referenE iF vmentlementeD puesto que l tni no llev o ningn juste de equilirio sore el rolD steD prolementeD no ser muy equilirdoF eor nD si los esos son sesgdos hi un extremo del orden de ls lvesD el rol puede devenir severmente desequilirdoF letor y rjn ITH desurieron un tni de juste que grntiz que el osto promedio de n operiones es O(lg n)F u tni es llmd splying y los roles resultntes son denomindos roles sply 4 F fsimenteD el splying onsiste en llevr un nodo edido hst l rz medinte operiones espeiles que fvoreern futuros esosF v primer de ls operiones se llm zigEzig y se ilustr en l (gur TFPVF ist de izquierd derehD l operin se llm zig_zig_rightD mientrs que en el sentido ontrrio se llm zig_zig_leftF v operin sue el nodo A tres niveles y se de(ne omo sigueX operaciones zig 507 (509a) 508
4
En castellano no existe un trmino que adecuadamente reeje la palabra splay. Encontramos en plegado y en desplegado las aproximaciones ms representativas, pero, a nuestro juicio, rboles desplegados o rboles plegados no expresan los mismos signicados que splay trees. Por esa razn preferimos utilizar el trmino original.

507

508

6. rboles de bsqueda equilibrados

p
C B A A B

p
C

=
pigur TFPVX yperin zigEzig

static Node * zig_zig_right(Node* p) { Node * q = LLINK(p); Node * r = LLINK(q); LLINK(p) = RLINK(q); LLINK(q) = RLINK(r); RLINK(q) = p; RLINK(r) = q; return r; }

v operin simtri es equivlente oservr l (gur TFPV de dereh izquierd y se llm zig_zig_left()D l ul se instrument simtrimente similrF
C A

p
B

p
B

pigur TFPWX yperin zigEzg v segund operin se llm zigEzg y se ilustr en l (gur TFPWF ist operin es equivlente un dole rotinF el igul que el zigEzigD el nodo p sue tres niveles y se de(ne omo sigueX operaciones zig 507 + (509a) 507 static Node * zig_zag_right(Node* p) { LLINK(p) = rotate_to_left(LLINK(p)); return rotate_to_right(p); } il equivlente simtrio se denomin zig_zag_left()F v ltim operinD que se llm zigD onsiste en efetur un rotin simple y slo se llev o si el nodo que devendr rz se enuentr en el nivel 1D es deirD extmente un nivel inferior l rz5 F hdo un nodo x en un rol inrio de squedD el splying del nodo x onsiste en suirlo hst l rz medinte ls operiones zigD zigEzig y zigEzgF vos nlisis posteriores
5
Vase 4.50 (Pg. 344).

508

6.6. rboles splay

509

demostrrn que si esto se efet por d esoD entones el osto promedio de n esos es O(lg n)F
6.6.1 El TAD

Splay_Tree<Key>

509a

il eh Gen_Splay_Tree<Key> modeliz un rol inrio de squed en el que ulquier de ls operiones us un splying del nodo edidoF il eh se de(ne en el rhivo tplsplytreeFr 509a D el ul se de(ne omo sigueX tpl_splay_tree.H 509a template <template <typename> class NodeType, typename Key, class Compare> class Gen_Splay_Tree { typedef NodeType<Key> Node;

};

operaciones zig 507 miembros privados de Gen_Splay_Tree<Key> 509b miembros pblicos de Gen_Splay_Tree<Key> 512a

template <typename Key, class Compare = Aleph::less<Key> > struct Splay_Tree : public Gen_Splay_Tree<BinNode, Key, Compare> {};
Uses

BinNode

240.

509b

il eh Gen_Splay_Tree<Key> no requiere de(nir un nuev lse de nodo inrioD pues no es neesrio lmenr informin de estdo en d nodoF vs operiones zigEzig y zigEzg involurn 4 nodos que son exmindos jo dos perspetivsF rimero requerimos determinr ul de ls seis operiones posiles dee ejeutrseF egundoD deemos ejeutr l operin en uestinF il splying de un nodo involur entones todos los nodos del mino de squed desde l rz hst el nodo donde se reliz el splyingF or tntoD usmos un pil que lmene el mino ntegro de squedX miembros privados de Gen_Splay_Tree<Key> 509b (509a) 509c struct Node_Desc { Node * node; Node ** node_parent; }; ArrayStack<Node_Desc, Node::MaxHeight> splay_stack;
Uses

ArrayStack

101a.

509c

gd entrd de l pil gurd registros de tipo Node_DescD el ul su vez gurd dos vloresX el nodo prte del mino de squed y un dole puntdor su pdreF il puntero dole permite efetur ls rotiones sin neesidd de preguntr de ul ldoD izquierdo o derehoD se enuentr el pdreF v in de sply tiende equilirr el rolD pero no exluye un so muy desforE tundoF iventulmenteD splay_stack puede tener un desorde que dee ser mnejdoF or es rzn de(nimos un mtodo espeil que insert un nodo en l pil y que veri( el desordeX miembros privados de Gen_Splay_Tree<Key> 509b + (509a) 509b 510a void push_in_splay_stack(Node * p, Node ** pp) {

510

6. rboles de bsqueda equilibrados

try { splay_stack.push(Node_Desc(p, pp)); } catch (std::overflow_error) { splay_stack.empty(); throw; }

Denes:

push_in_splay_stack,

used in chunks 51012.

510a

v ni responsilidd de push_in_splay_stack() es trpr l exepin std::overflow_errorF i esto ourreD lo nio que se he es vir l pil ntes de propgr l exepinF push_in_splay_stack() es utilizd d vez que se efete un squedD l ul es efetud por l rutin siguienteX miembros privados de Gen_Splay_Tree<Key> 509b + (509a) 509c 510b void search_and_push_in_splay_stack(const Key & key) { splay_stack.empty(); Node ** pp = &RLINK(head); Node * p = root; while (p != NULL) // buscar iterativamente key { push_in_splay_stack(p, pp); if (Compare () (key, KEY(p))) { pp = &LLINK(p); p = LLINK(p); } else if (Compare()(KEY(p), key)) { pp = &RLINK(p); p = RLINK(p); } else return; } }
Denes: Uses

search_and_push_in_splay_stack, push_in_splay_stack 509c.

used in chunks 512 and 513.

510b

search_and_push_in_splay_stack() es un rutin muy importnteD l ul es indisE pensle omprenderF fsimenteD l rutin us un nodo on lve key y empil el mino de squed independientemente de que se enuentre o no l lveF i l squed es exitosD entones el tope de l pil ontiene el nodo enontrdoF he lo ontrrioD el tope ontiene el ltimo nodo ntes del externo detuvo l squedF v rutin se emple pr ls tres operiones sisX inserinD squed y elimininF vos triutos restntes y son fmilires l letorX miembros privados de Gen_Splay_Tree<Key> 509b + (509a) 510a 511a
Node head_node;

6.6. rboles splay

511

Node *head; Node *&root;

511a

v eseni de l implntin suye en un rutin splay() que efet el splying del nodo situdo en el tope de l pilF splay() requiere determinr el tipo operin ejeutr segn l linein del mino de squedF isto es llevdo o por l siguiente rutinX miembros privados de Gen_Splay_Tree<Key> 509b + (509a) 510b 511b enum Zig_Type { ZIG_LEFT, ZIG_RIGHT, ZIG_ZAG_LEFT, ZIG_ZAG_RIGHT, ZIG_ZIG_LEFT, ZIG_ZIG_RIGHT }; Zig_Type zig_type(Node *& p, Node **& pp) { Node_Desc first = splay_stack.pop(); Node_Desc second = splay_stack.pop(); Zig_Type ret = RLINK(second.node) == first.node ? ZIG_LEFT : ZIG_RIGHT;
if (splay_stack.is_empty()) { IG(LLINK(second.node) == first.node, ret == ZIG_RIGHT); p = second.node; pp = second.node_parent; return ret; } Node_Desc third = splay_stack.pop(); pp = third.node_parent; p = third.node; if (ret == ZIG_LEFT) return RLINK(third.node) == second.node ? ZIG_ZIG_LEFT : ZIG_ZAG_RIGHT; else return LLINK(third.node) == second.node ? ZIG_ZIG_RIGHT : ZIG_ZAG_LEFT;

Denes:

zig_type,

used in chunk 511b.

511b

zig_type() retorn el tipo de operin que dee herse sore el nodo en el tope de l pilF ediionlmenteD l rutin devuelve los vlores p y pp orrespondientes l ltimo nodo en l den de l operin y su pdreF istmos listos pr l rutin splay()D l ul es muy senill un vez de(nid l mquinri neesriX miembros privados de Gen_Splay_Tree<Key> 509b + (509a) 511a
void splay() { if (splay_stack.is_empty() or splay_stack.top().node == root) return; Node **pp, *p; while (true) { switch (zig_type(p, pp)) { case ZIG_LEFT: *pp case ZIG_RIGHT: *pp case ZIG_ZIG_LEFT: *pp case ZIG_ZIG_RIGHT: *pp

= = = =

rotate_to_left(p); break; rotate_to_right(p); break; zig_zig_left(p); break; zig_zig_right(p); break;

512

6. rboles de bsqueda equilibrados

case ZIG_ZAG_LEFT: *pp = zig_zag_left(p); break; case ZIG_ZAG_RIGHT: *pp = zig_zag_right(p); break; } if (splay_stack.is_empty()) break; push_in_splay_stack(*pp, pp);

Denes: Uses

splay, used in chunks 512 and 513. push_in_splay_stack 509c and zig_type

511a.

512a

splay() es l rutin fundmentl del eh Gen_Splay_Tree<Key>F ill sume que se efetu un llmd previ search_and_push_in_splay_stack() y que el tope de l pil ontiene el nodo sore el ul se dese efetur el splyF gd vez que se ejeut ulquier operin de inserinD squed o elimininD se dee her un sply del rolF v ide de est operin es mortizr los sos desfortundos y equilirr el rolF he ls tres operiones fundmentlesD l ms simple es l de squedD l ul se de(ne omo sigueX miembros pblicos de Gen_Splay_Tree<Key> 512a (509a) 512b
Node * search(const Key & key) { if (root == NULL) return NULL;

search_and_push_in_splay_stack(key); splay(); if (are_equals<Key, Compare>(key, KEY(root))) return root; }


Uses

return NULL;
search_and_push_in_splay_stack
510a and

splay

511b.

v squed es muy senill porque tod l infrestrutur se enuentr implntd por los mtodos privdos search_and_push_in_splay_stack() y splay()F xote que el sply siempre se efetD independientemente de que l squed se fllid o noF v inserin es ligermente ms omplid pero l igul que on l squed todo el trjo es implntdo por search_and_push_in_splay_stack() y splay()X
512b

miembros pblicos de Gen_Splay_Tree<Key> 512a +


Node * insert(Node * p) { if (root == NULL) return root = p;

(509a)

512a 513

search_and_push_in_splay_stack(KEY(p)); Node * pp = splay_stack.top().node; if (Compare () (KEY(p), KEY(pp))) {

6.6. rboles splay

513

} else if (Compare () (KEY(pp), KEY(p))) { RLINK(pp) = p; push_in_splay_stack(p, &RLINK(pp)); } else { // clave duplicada splay(); // de todos modos hacemos el splay return NULL; } splay(); }
Uses

LLINK(pp) = p; push_in_splay_stack(p, &LLINK(pp));

return root;
push_in_splay_stack
509c,

search_and_push_in_splay_stack

510a, and

splay

511b.

513

r l eliminin se tienen dos lterntivsX l eliminin lsi que nte un nodo ompleto seleion el suesor o predeesorD o medinte l operin join() desrrolld en RFWFV @gF QPUAF or ser l ms senill y posilemente l ms e(zD esogemos l segund lterntivX miembros pblicos de Gen_Splay_Tree<Key> 512a + (509a) 512b Node * remove(const Key & key) { search_and_push_in_splay_stack(key);
splay(); // Suba el nodo hasta la raz mediante el splay if (no_equals <Key, Compare> (KEY(root), key)) return NULL; // key no est Node * p = root; root = join_exclusive(LLINK(root), RLINK(root)); p->reset(); }
Uses

return p;
join_exclusive
324,

search_and_push_in_splay_stack

510a, and

splay

511b.

il lgoritmo efet l squed del nodo eliminr y he un sply independientemente de que l squed hy sido exitos o noF i l lve se enuentr en el rolD entones l rz ontiene el nodo eliminr y el rol resultnte es l ontenin de sus rmsF in so ontrrioD el lgoritmo terminD pues no es neesri otr operinF
6.6.2 Anlisis de los rboles splay

il nlisis de un rol sply es prdigmtio del mortizdoF

514

6. rboles de bsqueda equilibrados

ods ls operiones llevn o un squedD uyo desempeo depende de l profundidd del nodoY posteriormenteD se he el sply del nodoD uyo desempeo tmin depende de l longitud del mino entre l rz y el nodoF v inserin y l squed tienen O(nivel(ni )) + O(nivel(ni )) = O(nivel(ni ))D mientrs que l eliminin tiene O(nivel(ni )) + O(nivel(ni )) + O(nivel(ni )) = O(nivel(ni ))D siendo nivel(ni ) el nivel del nodo sujeto l operin splyF isto nos sugiere que l funin potenil de onsideE rr el nivel de los nodos omo prte del osteF v longitud del mino internoD presentd en l de(niin RFS @gF PUUAD nos rroj un mtri que onsider el nivelF ehor ienD el rter de emulin l squed iE nriD s omo ls ino lses nteriores de roles inrios que hemos estudidoD sugieren que onsideremos l logritmo en l funin potenil que nos pondere el nivelF
Denicin 6.10 (Rango de un rbol)

e un rol inrio T de n nodosF e C(ni ) l ntidd de nodos del suErol on rz en ni F intonesD el rngo de T D denotdo omo r(T )D se de(ne omoX r(T ) = lg C(T ) @TFRIA letor y rjn ITH seleionron un funin potenil sd en el rngo de un rol del siguiente modoX

(T )

=
ni es interno ni T

r(ni )

=
ni es interno ni T

lg C(ni )

@TFRPA

in iert formD este potenil es reminisente l IPL(T ) en el sentido de que ponder un equilirdo est T F v difereni onsiste en que (T ) est otdo por O(n lg(n))D mientrs que el IPL(T ) por O(n2 )F r un rol ompletoD el rngo es pequeoD por ejemploD prX
T =

mientrs que on un rol ms desequilirdoD el rngo es myorY por ejemploD prX


T =

(T ) = lg (9) + lg (5) + 2 lg (3) + 5 lg (1) 8, 66 ,

gunto ms equilirdo est un rolD menor es su potenilY nlogmenteD unto menos equilirdoD myor ste esF @vem de eso un rol sply E letor y rjn IWVS ITHA e T un rol sply y k T un lveF en Ci1 (k) y Ci (k) ls rdinliddes del suErol uy rz es k ntes y despus de un pso de un sply de un totl de m psosF en ri1 (k) y ri (k) los rngos de k ntes y despus de un pso del sply de un totl de m psosF intonesD el oste mortizdo en el iEsimo psoD de(nido omo ci D est otdo omoX 3ri (k) 3ri1 (k) si i < m ci @TFRQA 3ri (k) 3ri1 (k) + O(1) si i = m
Proposicin 6.10

(T ) = lg (9) + lg (8) + lg (7) + lg (4) + 2 lg (2) + 3 lg (1) 17, 62

6.6. rboles splay

515

v demostrin onsiste en lulr el oste mortizdo pr d tipo de operin que ourre durnte un pso del sply entre los m requeridos pr suir k hst l rzF he este modoX
Demostracin

ci = ti +(Ti ) i1 (Ti1 )

@TFRRA

honde Ti1 y Ti son los roles ntes y despus de un pso en el sply entre los tres posiles tipos de(nidosF e k el nodo que suir de nivel en uno de los psos del splyD entonesD efetos de est demostrinD plnteremos un presentin menos preis del lem de eso ci 3ri (k) 3ri1 (k) + O(1) , 1 i m @TFRSA in lo que sigue trtremos los tres posiles psos que ourren en un splyX IF zigX
b Ti1 = k Ti = k b

in este soD l durin onstnte equivle un rotinD rzn por l ul sumiE mos ti = 1F il zig no lter ls rdinliddes de ls rms D y D por lo que sus rngos se neln en l difereni de potenilF or lo tntoD l difereni de potenil slo ontiene los rngos de los nodos k y bF he este modoX ci = 1 + ri (k) + ri (b) ri1 (k) ri1 (b) @TFRTA

xotemosD por oservin de l (gur del zigD que Ci1 (b) = Ci (k)D por lo que ri (k) ri1 (b) = 0D lo que nos dejX ci = 1 + ri (b) ri1 (k) @TFRUA

hel mismo modoD ri1 (b) ri (k)D por lo que podemos plnter l desiguldd siguienteX ci 1 + ri (k) ri1 (k) PF zig-zigX
c Ti1 = k b Ti = k b c

@TFRVA

3ri (k) 3ri1 (k) + O(1)

in este so tmpoo min ls rdinliddes de D D y D por lo que los rngos permneen igules entre Ti1 y Ti y se neln mutumente en el lulo del diferE enil potenilF or otr prteD el zigEzig es ms ostoso en durin que el zigF in omplejidd de tiempo se puede deir que el zigEzig efet un rotin msD l ul

516

6. rboles de bsqueda equilibrados

es proporionl 2D o seD el dole del zigF or lo tntoD el oste mortizdo se de(ne omoX ci = 2 + ri (k) + ri (b) + ri (c) ri1 (k) ri1 (b) ri1 (c) in este soD Ci1 (c) = Ci (k)D lo que he que ri1 (c) ri (k) = 0D por lo que l expresin nterior deviene enX ci = 2 + ri (b) + ri (c) ri1 (k) ri1 (b) @TFRWA

sgul que pr el zigD ri1 (b) ri1 (k) y ri (k) ri (b)F ustituimos en l euin nterior y l hemos un desigulddX ci 2 + ri (k) + ri (c) 2ri1 (k) enX Ci (c) Ci1 (k) , y= Ci (k) Ci (k) @TFSHA

x=

@TFSIA

uesto que Ci1 (k) > 0, Ci1 (k) > 0 y Ci (k) > 0D entones x > 0 e y > 0F ws nD puesto que Ci (k) > Ci1 (k) y Ci (k) > Ci (c)D entones x < 1 e y < 1F or didurD x + y < 1D lo ul se evideni expresndo ls rdinliddes en funin de sus suErolesX
x+y= 2 + C() + C() + C() + C() 1 + C() + C()1 + C() + C() = 3 + C() + C() + C() + C() 3 + C() + C() + C() + C()

@TFSPA

gmo se otr lg(x) + lg(y)c oD diho de otro modoD ul ser el mximo vlor que tomr lg(x) + lg(y)c v respuest se trt en el siguiente lemX
Lema 6.8

en x, y R | x > 0, y > 0, x + y 1D entonesD lg(x) + lg(y) 2F

or un propiedd y onoidD lg(x) + lg(y) = lg(xy)F v urv del logritmo es montonmente reiente yD dentro del dominio de nuestro intersD exhie l form de l (gur TFQHF il vlor de lg(xy) es mximo undo el produto xy es mximoF hds ls ondiiones de x e yD xy es mximo undo x = y = 1/2 = lg(xy) = 2
Demostracin
1 lg (n) 0.5 0 -0.5 -1 -1.5 -2 -2.5 -3 0 0.25 0.5 0.75 1 n 1.25 1.5 1.75 2

pigur TFQHX gurv lg n pr vlores menores que 1

6.6. rboles splay

517

ehor expndimos lg(x) + lg(y)X lg(x) + lg(y) = lg Ci1 (k) Ci (c) + lg Ci (k) Ci (k) = lg Ci1 (k) lg Ci (k) + lg Ci (c) lg Ci (k)

= lg Ci1 (k) + lg Ci (c) 2 lg Ci (k) = ri1 (k) + ri (c) 2ri1 (k)


in funin del lem TFV plntemos l siguiente desigulddX @TFSQA

2ri (k) ri (c) ri1 (k) 2 0

ri1 (k) + ri (c) 2ri (k) 2 =

@TFSRA

gomo el resultdo es positivo lo podemos sumr l desiguldd @TFSHAX ci 2 + ri (k) + ri (c) 2ri1 (k) + 2ri (k) ri (c) ri1 (k) 2

3ri (k) 3ri1 (k) + O(1)


QF zig-zagX
c Ti1 = a k Ti = a k c

3ri (k) 3ri1 (k)

@TFSSA

il rzonmiento en este so es ompletmente similr l nterior hst @TFRWAF yservndo que ri1 (a) ri1 (k)D y que ri (k) ri (c)D plntemos l siguiente deE sigulddX ci 2 + ri (a) + ri (c) 2ri1 (k) @TFSTA enX

x=

Ci (a) Ci (c) , y= Ci (k) Ci (k)

@TFSUA

in este momento dee ser lro que x + y < 1D rzn por l ulD plindo el lem TFV tenemos queX lg x + lg y 2 = Ci (a) Ci (c) lg + lg 2 = Ci (k) Ci (k) 2ri (k) ri (a) ri (c) 2 0 pinlmenteD sumndo el ldo izquierdo de @TFSVA l dereho de @TFSTAD tenemosX ci 2ri (k) 2ri1 (k) @TFSWA

@TFSVA

3ri (k) 3ri1 (k) + O(1)

518

6. rboles de bsqueda equilibrados

vos tres sos posiles de un pso del sply estn otdos por 3ri (k) 3ri1 (k) + O(1) il lem de eso es l se demostrtiv de unos untos teorems sore los rE oles splyD entre ellos el siguienteX
Proposicin 6.11

il oste mortizdo cs de un operinsplay() sore un nodo k perteneiente un rol sply es O(lg n)F
Demostracin

v operin sply puede imginrse omo un seueni de psos zig segn l orientin del nodo uyo osto mortizdo totl puede de(nirse omoX
m

cs =
i =1

ci .

ist seueni de operiones puede pitorizrse del siguiente modoX


m

. . .
i+1

. . .
1

il nodo k sue hi l rz medinte m 1 operiones zigEzig o zigEzg y un mEsim operin que podr ser ulquier de ls tres posilesF ws preismente semosD por el lem de esoD que los m 1 primeros psos estn otdos por 3ri (k) 3ri1 (k)D pues este vlor ot tnto l zigEzig omo l zigEzgY mientrs que l ltim operin podr ser ulquier de ls tresD rzn por l ul es neesrio otrl l mximoD es deirD 3rm (k) 3rm1 (k) + 1F in se lo nterior podemos de(nirX

cs

m1

=
i=1

3ri (k) 3ri1 (k) + 3rm (k) 3rm1 (k) + 1


m1 m1

=
i=1

3ri (k)

i=1

3ri1 (k)

+ 3rm (k) 3rm1 (k) + 1

= =

3rm (k) 3rm1 (k) + 1 3rm (k) 3r0 (k) + 1

3r1 (k) + 3r2 (k) + + 3rm1 (k) 3r0 (k) + 3r1 (k) + + 3rm2 (k) +

3rm (k) + 1 = 1 + lg n = O(lg n)

gomo orolrio l proposiin TFII podemos enunir que p operiones sore un rE ol sply tienen oste mortizdo de O(p lg n)F in efetoD omo y expresmos nteriE ormenteD l funin potenil onsider l lidd de equilirio del rolD l ul uent pr el tiempo de squed que efet un operin de un rol splyF

6.7. Conclusin

519

pigur TFQIX n rol sply de 512 nodos

6.7 Conclusin
iste ptulo trt el equilirio de roles inrios de squedF v ide suyente es minimizr l ntidd de nodos inspeionr en un squedF e tenor de lo nterior estudimos vris lses de equilirio junto on sus roles orrespondientesF in primer lugr onsidermos el equilirio fuerte de irth y desE rrollmos un lgoritmo O(n lg n) que equilir un eff ulquierF il desrrollo de este lgoritmo nos permiti pertrnos de ls viisitudes y di(ultdes inherentes l equilirioF il resto del ptulo se onsgr estudir ino lses de roles equilirdosX leE torizdosD trepsD evD rojoEnegro y splyF gd uno on sus ventjs y desventjs onsiderr segn l pliinF il susriptor del presente texto h llevdo un estudio emprio sore los diferentes tipos de rolesF vos resultdosD sin rigor estdstioD muho menos sin expresr intervlos de on(nzD se muestrn en ls (gurs TFQQD TFQRD TFQS y TFQT respetivmente6 F vs gr(s en uestin orresponden medids sore el siguiente experimentoX IF e gener un seueni letori de lves de inserinF PF r d tipo de rol se he Q vees l inserin de l seueni nterior yD d poteni ext de PD se efetn ls medidsF v menor durin medid entre ls tres repetiiones se onsider omo el tiempo de durinF vo nterior se repiti S veesD es deirD se generron S seuenis letoris de inserinF vs gr(s orresponden los promediosF v (gur TFQQ ilustr ls lturs de los seis tipos de eff estudidos pr seuenis de inserin letorisF ist medid es til porque nos d un ide del osto mximo involurdo en l squedF in este sentidoD l (gur TFQQ evideni y on(rm l teor er de que los roles rojoEnegro y ev son los que tienen menos lturF v sorpres de est gr( es queD l menos pr entrds letorisD los roles rojoEnegro distn de lnzr su ot teri 2 lg (n + 1) 2F
6
Las medidas en las cuales se expresa tiempo corresponden a los valores ms cercanos al centro del intervalo de conanza y fueron efectuados sobre una Intel Pentium III a 800 Mhz. Medidas sobre arquitecturas diferentes -Sparc y MIPS-, estudios sobre sesgos para vericar bondades del splay, otras mtricas -nmero de rotaciones, por ejemplo- y anlisis ms exhaustivos an estn pendientes y es un campo frtil para trabajo.

520

6. rboles de bsqueda equilibrados

(a) Treap

(b) Aleatorio

(c) Splay

(d) AVL

(e) Rojo-negro

pigur TFQPX hiferentes modelos de equilirio y sus roles resultntes pr l mism seueni de 512 lves letoris

6.7. Conclusin

521

70 50 40 30 + + + + + + 20 + + + + + + + + + 10 + + + + + + + + 0 0 5 10 15 20 60 n = 2k AVL Rojo-negro Aleatorizado Treap Splay Binario Altura mnima +

A l t u r a

pigur TFQQX eltur de diferentes eff v longitud del mino interno nos indi un equilirdo est el rolF in este sentidoD l (gur TFQR evideni que l lidd de todos los roles es equivlenteD siendo ligermente fvorle hi los roles ev y rojoEnegroF
1.07374e+09 AVL Rojonegro Aleatorizado Treap Binario Splay IPL mnimo

3.35544e+07

1.04858e+06

32768

IPL

1024

32

0.03125 0 5 10 2**k 15 20

pigur TFQRX sv pr diferentes eff @en esl logrtmiA vs (gurs TFQQ y TFQR esonden el osto de l operin sply pr los roles del mismo nomreD pues el experimento no onsider ni emul l lolidd de refereniF in este sentidoD pree que si ulquier de ls lves tiene l mism proilidd de usrseD entones el rol sply es el de ms pore desempeoF ero esto puede ser fliosoD pues l lolidd de refereni umple un rol fundmentl en l myor de ls pliionesF in los roles de ltur otdD los proilstios y los inrios lsiosD ls lves ms reientes tienden enontrrse hi ls hojsX mientrs unto joven es un lveD myor es el tiempo esperdo de squedF isto no suede on un rol splyX ls lves reientemente edids se enuentrn erns l rzD por lo que el desempeo deer de ser onsiderlemente mejor pr pliiones on lolidd de refereniF vs duriones de inserin y eliminin pr los roles sply no se muestrn porque son tn notlemente superiores l resto que su visulizin ostulizr preir ls diferenis entre ls dems urvsF i ien los ino enfoques de equilirio ofreen desempeos O(lg n) pr ls tres opeE riones fundmentlesD es ruil oservr que pr l inserin y eliminin todos estos

522

6. rboles de bsqueda equilibrados

16 14 12 10 secs 8 6 4 2 + 0 0 AVL Rojo-negro Aleatorizado Treap Binario +

+ + + + + + + + + + + + + + + + + + + + + + 5 10 n = 2k 15 20

pigur TFQSX iempo de inserin pr diferentes eff enfoques de equilirio rren ostes onstntes severmente myores que los de un eff lsioF vs (gurs TFQS y TFQT evidenin drmtimente este spetoX el eff lsio es el ms rpido hst 219 nodos pr l inserin y 214 nodos pr l elimininF e prtir de estos vloresD el eff lsio es ligermente inferior pero si tn ueno omo el rojoEnegro y el evF r est ltim oservin no se dee olvidr que los ordenes de inserin son letoriosF in l selein de un rol no se dee despreir el uso de un eff lsioF in tl sentidoD un eff dee onsiderrse ntes que ulesquier de los mtodos de equilirio desrrolldos en este ptuloF v selein de un eff dee onsiderr los siguientes spetosX IF v esl en funin del nmero de nodos es peque o medinF PF vs seuenis de inserin no deen estr onsiderlemente sesgdsD pues un eff es O(lg n) pr inseriones letorisF i ls seuenis de inserin son letorisD entones se puede onsiderr un eff pr grndes eslsF QF uesto que ls eliminiones degrdn un effD el nmero de eliminiones dee ser muho menor que el de inserionesF RF il desempeo O(lg n) es proilstioF eun on inseriones letoris y useni de eliminionesD un eff puede exhiir un so desfortundoF or lo tntoD un eff no dee utilizrse si existen requerimiento solutos de desempeoF v ide suyente de los enfoques letorizdos es eliminr ulquier sesgo en l inserin o eliminin medinte deisiones letoris que letorizn el rol hindolo equivlente un eff onstruido prtir de un seueni l zrF gonseuentementeD se puede empler un rol letorizdo o un trep undo se tem sesgo en l entrdF uesto que el desempeo es proilstioD se dee grntizr l lidd del generdor de nmeros pseudoletoriosF eun on un uen generdor de nmeros letoriosD el desempeo de un enfoque letorizdo es suseptile l infortunioF es puesD los equilirios proilstios no deen usrse si se presentn restriiones fuertes de desempeoF vs (gurs TFQS y TFQT evidenin l rol letorizdo omo uno de los ms osE tososF he hehoD pr l inserinD se prei un degrdin preile segn ument

6.8. Notas bibliogrcas

523

8 7 6 5 secs 4 3 2 + 1 0 + + + + + + + + + + + + + 5 10 n = 2k AVL Rojo-negro Aleatorizado Treap Binario +

+ + + + + + + + +

15

20

pigur TFQTX iempo de eliminin pr diferentes eff el nmero de nodosD degrdin que no ourre on l otr lterntiv letorizdX el trepF in opinin del utorD esto es explile por ls siguientes rzonesX IF vos roles letorios son ms sensiles l lidd del generdor de nmeros letoE rios que los trepsF vos effe requieren nmeros l zr entre ero y l rdinlidd del rolY mientrs que ls prioriddes de los treps utilizn todo el espetro del geE nerdor de nmeros letoriosF iste heho es importnte de onsiderr porque el rngo restringido de los roles letorios lo he ms sensile fllsD sesgos y dems imperfeiones del generdor de nmeros letoriosF ytro speto onsiderr es que el trep efet muhs menos llmds l generdor de nmeros letorios que el effeF il trep gener un letorio un sol vez por inserinY mientrs que el effe efet sorteos en l inserin y en l elimininF edemsD el effe puede efetur vrios sorteos en d operinF v ntidd esperd de sorteos depende de l rdinlidd del rolX myor ntidd de nodosD myor el nmero esperdo de sorteosF ist onsiderin es esenilD pues muhos generdores sufren de ftig en el sentido de que su letoriedd disminuye segn ument el nmero de llmdsF PF vos lgoritmos del trep son ms simples y tienen menos ostes onstntes que los del effeF v disusin nterior evideni lrmente que si existen restriiones inslvles de desempeo y si no hy espio pr l ml suerteD entones l esogeni de fto es un rol on ltur otdX un ev o un rojoEnegroF i se dese un implementin senill y que exhi uen tiempoD entonesD en opinin del utorD los treps son l mejor lterntivF pinlmenteD si se tiene onoimiento de un uen lolidd de refereniD entones el desempeo los roles sply puede ser espetulrF

6.8 Notas bibliogrcas


v histori de los enfoques de equilirio de un rol omienz por los roles inrios de squed lsiosF e prinipio de IWTHD los investigdores y sn que ls promess

524

6. rboles de bsqueda equilibrados

de desempeo de un eff slo ern vigentes ondiin de tener seuenis de inserin letoris y de no ourrir exesivs eliminionesF in IWTP se puliron los roles ev por edelson elsky y vndis TF rst reienteE menteD estos roles permneieron l esogeni de fto en l implntin de tls de smolos en memori priniplF en hoy en dD est lse de rol se us freuentemente y onform el estndr de muhs pliionesF il nmero es muy importnte en muhos lugres de ls mtemtisF is prole que su uso proveng del mundo rtstioD pues desde tiempos inmemoriles h sido onsiderd l ms ell proporin entre dos diferentes tmosF idsger F hijkstr expone los nmeros de pioni y l sein ure orientd hi ls ienis omputE ionles QU7 F e (nles de IWTHD investigiones en reuperin de lves en lmenmiento seunE drio ondujeron un nuev y populr lse de rolX el fD desuierto por fyer ISF ist lse de rol gener un orriente de investigin que ondujo diverss estruturs de squed en memori priniplD notlemente el rol PEQD desuierto por roproft y desrito por ehoD roproft y llmn WD y el rol inrio f simtrioD que es un so prE tiulr del rol f desuierto por fyer IRF vos roles rojoEnegro son un equivlente inrio de un tipo de rol uternrio denomindo por fyer PEQERF smplntr roles PEQER en memori es omplido porque en un nodo deen mntenerse lves ordends y punteros los hijosF ist lrtori es importnte porque ls demostriones er l grnt de lne pueden efeturse diretmente on los roles PEQERF in IWUVD quis y edgewik TU provehron un isomor(smo entre los roles PE QER y los roles inrios de squed y enuniron el rol ojeto de est seinX el rol rojoEnegroF eprte de que es ms fil implntr un rol rojoEnegro que un rol PEQERD l de(niin TFU estlee un enfoque omintorioD nturlD pr ver por qu los roles rojoEnegro son lnedosF ood IVR ofree un exelentsim perspetiv de los roles rojoEnegro sd en sus propieddes romtisD jo l ul se onstituy el disurso de este textoF vos treps fueron desuiertos por uillemin en IWUV IUT y estudidos en profundidd por eidel y ergon ISVF or su desempeo y senillezD est lse de rol es l selein fvorit de muhs pliionesF wuhs grndes ides son simples y nturles ondiin de que y hyn sido reveE ldsF n notle ejemplo lo onstituyen los roles letorizdos desuiertos por wrE
7
Esta proporcin est onminiscentemente presente a lo largo de toda la naturaleza, la anatoma humana inclusive. Como ejemplos vanidosos, el ombligo es considerado por los escultores como la divisin natural de todo el cuerpo. Pues bien, la distancia desde el suelo al ombligo, dividida entre la distancia desde el ombligo hasta la cabeza, es cabeza y la quijada, donde respetan esta proporcin. La proporcin en cuestin es que al dividir un segmento en dos partes, digamos x e y, se satisfaga y x x la siguiente ecuacin x+y = x . Si se efecta la transformacin = y se tiene la ecuacin divina: 2 1 = 0. Puesto que la mayora somos creyentes, en honor a Dios, creador del Universo -y del Hombre inclusive-,

. Del est

mismo modo, exactamente la misma proporcin es preservada entre la ubicado en la punta de la nariz. Todas las partes del cuerpo humano

es llamado el nmero divino, el nmero de Dios, el radio de oro o, artsticamente, la seccin urea, pues El nombre

parece que fue la proporcin que Dios utiliz para crear nuestro mundo.

es en honor a Fidias, considerado el ms grande escultor de la antigua Grecia, autor de

la estatua de Zeus en el monte Olimpo, elaborada de marl y oro aproximadamente en el ao 450 A.C. Esta obra fue incluida por el poeta Antipater de Sidon en su clebre lista de las siete maravillas del mundo antiguo.

6.9. Ejercicios

525

tinez y our IIUF hurnte ddsD los terios usron un estrutur letori nturl que resolviese l simetr de l eliminin de un effF e pesr del trep de uillemin IUT y de que eidel y ergon hyn demostrdo su letoriedd y equivleni on el eff ISVD el rol letorizdo es un estrutur nturl que ponder proilsE timente segn el equilirio fuerte de irth IVPF hesde prinipios de l omputinD los disedores de sistems hn utilizdo felizE mente heurstis utojustntes que mueven elementos reientemente edidos posiE iones de rpido esoF hesde el desurimiento de l inserin por l rz ITPD muhos progrmdores usron este speto pr provehr l lolidd de refereniF ero no fue sino hst IWVSD undo letor y rjn puliron los roles sply ITHD que se dispuso de un rol logrtmio en el sentido mortizdoF or didurD este fue uno de los primeros estudios onvinentes sore el nlisis mortizdoF

6.9 Ejercicios
IF guntos nodos tiene el rol de l (gur TFI@Ac PF hisee l rutin select_gotoup_root() presentd en TFI @gF RSPA en funin del proedimiento insert_by_pos_xt(()) explido en RFIIFU @gF QRIAF QF ijeute ls siguientes seuenis de inserin en un rol letorioF
@A IPU IWQ QH UI ISV IVS RH IP QS WR IIT IIH IQW SU VI WS IVI IIR IIP IUI @A IRQ IIV QR III IPS TI IHI RS IPT QV IP RI IWW SR PI ITT IQT ISR IVV IUR @A IRV IUT IVP IHV IRI RR IUQ IPV IHP TS IQW IWP QU IVV IIT VV ITS ITP W WI @dA IHV TU IHW UT VQ IUS IRH IQT QS ITV TP IVI IHH IIP IWU WP I IUQ IVH QQ @eA IPQ IWQ IQ IS SH IIS ITH PS RS IQT UW Q I IR IUV IHV TP SU IHI US

r tods ls seuenisD sum l siguiente seueni de nmeros letorios entre I y IHHX


RQ IW RT RQ T PV II S IH QS R QV PQ RV Q IU QH QI RI IP QS QP RR RU RH RT Q RR QP IW W QW IW PV IP IQ IV QT II SH W QQ RR T V PW T RV IQ QH PI IT RV Q IR QW W I QI PQ RV RH RT QR QH Q RH R IS QT RH RI QH PT RR PQ QR SH QQ IH RW PP W QU QP RU PT IW RH QW IP IH S IH PT QT RW PI PV I RV PR U IR QW QV RP RS PH S RH S QI PH W SH U QS IQ U IQ IW SH QS RS W QW Q QR QP IU IW RI RH QP V PR W IU RV IP RR PR U QQ PS QV RQ PR RS

RF r los siguientes roles letoriosD de(nidos por sus reorridos pre(josD ejeute ls seuenis de eliminin ddsX

Secuencia de eliminacin: IPS IRV IV II UW IPR IRH IVI IHP IUQ @A Prejo: IWS IWQ IHS RH QQ S QI PP SH TI TV TP UT ISW ISI IRT IIP IQU ITS IWW Secuencia de eliminacin: QI TV ITS PP ISW IHS IIP TI IWW ISI @A Prejo: IQP RV QU PV IP W WS UT SS UH VP IHT IHP WU ISQ IQS IWS IUI ITS IUU Secuencia de eliminacin: ITS IUU IUI W UT PV IWS RV SS QU @dA Prejo: WT VW SW PV PI IQ RT QH VQ VU IUR IRU IQP IHW IHI WW ITP ISH ISU IW

@A Prejo: RT II IV ISI IHP VQ SS UH TI TQ UW IHQ IPS IPR IRH IRV IUQ ITP ITH IVI

526

6. rboles de bsqueda equilibrados

Secuencia de eliminacin: PV IQP IQ WW IHI ISH VU IUR ISU WT @eA Prejo: IWH TQ RQ QU IQ Q PV QV SS SI IVR IUU WH IPR IPP ITV IQV ITP IVU IWT Secuencia de eliminacin: WH QU IPR IWH SI PV IPP ITV Q IQ
r todos los ejeriios sum l siguiente seueni de nmeros letorios entre I y IHHX
I VQ W VR TR RT IHH TS U RQ PH TQ PT TI IHH WS WS TH US SH IW SI PI PW WH TW VH WQ UI SP QR RH QR PW TU TQ QW SU WQ UH QI VP TU WQ RU IP WW TU R SW US RI WQ WQ PI WQ SP RW SH WQ IHH QW SV T WS TV RS TQ IH IQ R IHH VS I Q UH UU RQ WR QS V ST UI TW WT VH QH QH VS SW TV QS PW QR WU IS PW RR UW UI PT RU IP TU WR PU QH VH QW UW QP Q RW TS TT VW RS TT WQ TV TW VI VS WW VT RR IV VH SH IW TW WH WT QS IP I UP PI PT PU PW SS SP TP SH IW SH RT TV UI

SF hdo un nodo p eliminr de un rol letorizdoD onsidere el siguiente lgoritmo de elimininX @A e r = nmero letorio entre [1 , |L(p)| + |R(p)|]F @A i r |L(p)| = E v rz del surol resultnte es el predeesor de pF he lo ontrrio = E v rz del surol resultnte es el suesor de pF ruee o despruee que el rol resultnte es letorioF @CA TF snstrumente el lgoritmo nteriorF UF enlie uiddosmente el lgoritmo de inserin en un rol letorizdo y estime l ntidd esperd de sorteos junto on su vrinzF VF enlie uiddosmente el lgoritmo de eliminin en un rol letorizdo y estime l ntidd esperd de sorteos junto on su vrinzF WF gomo se h meniondoD uno de los prolems de los roles letorizdos es que se efetn muhos sorteos que hen que el generdor de nmeros letorios lne su punto de ftig ms rpidmenteF ropong un esquem que minimie ls posiiliddes de ftig del generdor de nmeros letoriosF IHF hisee un lgoritmo que genere un rol de squed letorioD es deirD que orresE pond l de(niin de rol letorio dd en TFP @gF RSSAF IIF gonsidere el siguiente prototipo de funinX
template <class Node> luka_to_tree(char *& cod)

il ul retorn el rol inrio orrespondiente l plr de vuksiewiz lmend en cod @ver RFU @gF QHPAAF esum que l plr es orretF isri l funin en uestinF

6.9. Ejercicios

527

IPF rg ls prues estdstis pertinentes pr veri(r si el sorteo de inserin en l 1 rz se distriuye on proilidd p = n+ 1F IQF rg ls prues estdstis pertinentes pr veri(r si el sorteo pr l selein de 1 l rz del lgoritmo de ontenin letori se distriuye on proilidd p = m D donde m es l ntidd de nodos del rol izquierdoF IRF hisee un lgoritmo de unin de dos roles letorios T1 y T2 tl que lves perteneientes T1 pueden ser myores que lguns lves perteneientes T2 F il lgoritmo dee ser O(n lg(n))F ISF hisee un lgoritmo de unin de dos roles letorios T1 y T2 tl que lves perteneientes T1 pueden ser myores que lguns lves perteneientes T2 F il lgoritmo dee ser O(n lg(n))F ITF hisee un lgoritmo que efete l inserin por posiin en un rol letorizdoF il rol resultnte dee ser letorioF hemuestre su respuestF @CA IUF hisee un lgoritmo que efete l eliminin por posiin en un rol letorizdoF il rol resultnte dee ser letorioF hemuestre su respuestF @CA IVF hisee un eh equivlente Gen_Rand_Tree<Key> en el ul tods ls operiones no sen reursivsF IWF ijeute ls siguientes seuenis de inserin en un trepX
@A RW WU VP IRP IVU VS IR IPQ IWR IPW IWH IIR ISP IHW TT QQ WW QU VT UQ @A II PR IPT IH IU VS IHH IWR PW WU ITU IV RV VH IP IVT T Q VR UR @A IR IUI RI IPH IUP II IPQ IS UI UR IUT IRV IRW QI IHR IVR VQ IVP VI RU @dA IQH IUT V IRP IVP IPW IPS ISQ H IPP IQ IWH IRV IVR QH VR IT I SV QW @eA R ITI Q IPH UI IRS TV IRH IWI IQR PW IIT IIV PI IHR IHV IWH ISW ISV IRV

r todos los ejeriiosD use l siguiente seueni de nmeros letoriosX


QQ VI PQ IT US TH IR VW WQ WW WU TT QV QR RU RW SP RU PI RH

PHF r los siguientes trepsD de(nidos por sus reorridos pre(josD ejeute ls seuenis de eliminin ddsX @A Prejo: IRV PP IT V WR SI RI PS QH TT TQ IPV IPR IIT IIQ III IWH IUQ IVT IUS @A @A @dA @eA

Secuencia de eliminacin: ISU PQ VS ITS IIV III UH IVR IVT IW Prejo: VT SV IS PW QP RI RU VQ ITR IPW WH VU IHP IPT IIR IHT IQT IWT IUR IWP Secuencia de eliminacin: IHH QI IWH ISV VR IHS IRW IH SP QP Prejo: SR VW QR IQU IVH RR IQQ IIP UI SI U QW RI VR ITI IS TW IIQ WQ SW Secuencia de eliminacin: IQQ S SI ISS UU IUV T ITT IVT IIS Prejo: IRH TT QV V PS IS RT UT IIH UW IHP VQ IPW ITI IRS ISI IST ISS ITR IWR Secuencia de eliminacin: PP QT UQ TQ IIS IRH IPQ RS IPQ PT Prejo: IPP IIQ RP PP U PT TP RW WU IUP IQQ IPU ISQ IQU ISI ITU IST ISV ITV IWV Secuencia de eliminacin: IWW RW UH TP ISH U PT IIV ISV US

528

6. rboles de bsqueda equilibrados

PIF hisee un lgoritmo que onstruy un trep ddos sendos rreglos on lves y prioriE ddesF il lgoritmo no puede usr ls primitivs del trepF PPF hisee un eh equivlente Gen_Treap<Key> en el ul tods ls operiones no sen reursivsF PQF hisee un lgoritmo O(n lg(n)) que efete l unin de dos trepsF PRF hisee un lgoritmo O(n lg(n)) que efete l intersein de dos trepsF PSF hisee un lgoritmo O(n lg(n)) que efete l prtiin @splitA de un trepF PTF gonsidere un trep en el ul l prioridd est dd por el nmero de esosF e myor nmero de esosD menor es l prioriddF he este modoD el trep devendr uto justnte en el sentido de que ls lves reientemente edids se enontrrn en l rzF istudie y ompre este mtodo on l selein letori de prioriddesF PUF gonsidere l inserin por l rz de un trepX

Node * insert_root(Node * r, Node * p)


v ul insert el nodo pD on lve K(p) y prioridd esogid letorimente P(p)D como raz del trep rF @A snstrumente el lgoritmo que implnt insert_root()F @A esumiendo que el vlor de P(p) es nio en el trep resultnteD demuestre que el lgoritmo de l pregunt nterior gener un trepF PVF ijeute ls siguientes seuenis de inserin en un rol evX
@A PQS PHT IVS IST IWR IHV IQU PHU IRI WQ IRV PQI US IRR T PQW P IQV QH IVU SV PRR H VQ SS @A PHU UT R PPT PIT VQ IPW PPI PQH VI PW RT PHI PHV PIP ST ITV QV UV VU IQV PIS TT IPP ISR @A PRU ITV IIQ IRI I IUT SP IUW PPQ IHT IPP IVI IHH IIV VI PI PU RI PPV IWU P IPQ PP PRR PIP @dA IRR UU PRT IWQ PIQ PQH VP RR IIR IWS IRV VV PQI H ITQ IHW PPV TT PV IP IQP IV IQS UW UR @eA QW PQR I PRP IUP IST IHV QH IUH PRI PQP Q IRH S IVH IHH IQQ TH PR IQW IPW IW PQS IIV PQT

PWF r los siguientes roles evD de(nidos por sus reorridos pre(josD ejeute ls seE uenis de eliminin ddsX @A Prejo: IQT IHQ TP PP IW IP SS RS VT UH WW IPQ IPI IPT IQR IVI ISP IRP IRU ISV IWQ IVW
PHS IWW PQS

Secuencia de eliminacin: WW IPQ IPI IVI IQR IWQ IP PP RS PHS TP IVW @A Prejo: IPV RI PV PI V PR PW WQ SR RW VR IIU WR PHU ISV IRT IRQ ISU IVP IWH PPS PII Secuencia de eliminacin: RI SR PW PII PV PQS IPV VR PR IVP IRT V @A Prejo: IIH RW PW II I PI QW WI VH UU IHP WU IWI IUQ IST ISI IUP IVR IVI PIW PIH PHW Secuencia de eliminacin:
PPU PPT PQH VH PI RW PPT IVI QW II WI PW IUP IVR WU PIQ PRR PQS

6.9. Ejercicios

529

@dA Prejo: ISI RU RR U I QS RT IIS WQ UI WR IRH IPT PIV PHQ IVR IVQ PHI IWP PIQ PHU PQP

Secuencia de eliminacin: IVR PPU PIQ PHU RT RU ISI RR PQI IIS WR U @eA Prejo: IUP IQI VW TW PU IIH IHT IIT ISS IRI IQU ISP ISV IWR IVS IUT IWQ IWH PPP PHI Secuencia de eliminacin:
PIU PRR PQT PQI PRS IVS IQI PHI IUT TW IWR IWH IUP PIU PQT ISP ISV

PQI PPU PRQ

QHF i d nodo de un rol ev lmen su lturD untos its se requierenc QIF glule l omplejidd de tiempo de l funin is_avl()F QPF smplnte entermente un eh que modele roles ev en el ul d nodo gurde su lturF @CA QQF hisee un lgoritmo O(n lg(n)) que efete l unin de dos roles evF QRF hisee un lgoritmo O(n lg(n)) que efete l prtiin @splitA de dos roles evF QSF hisee un lgoritmo O(n lg(n)) que efete l intersein de dos roles evF QTF isri un lgoritmo que determine si un rol inrio es de pioniF glule su omplejidd de tiempoF QUF isri un lgoritmo que genere el rol de pioni de orden kF QVF @he woivre E IUIVA hemuestre que

1+ 5 Fib(n + 1) = . lim n Fib(n) 2


honde Fib(i) es el iEsimo nmero de pioniF QWF hemuestre queX
n

Fi = Fn+2 1
i=0

honde Fi es el iEsimo nmero de pioniF RHF yteng un expresin que denote el nmero de hojs de un rol de pioniF RIF hemuestre que el rol de pioni Tk ontiene Fk+2 nodos externosF RPF glule l longitud del mino interno del rol de pioni de orden 8F RQF heduz un expresin generl pr l longitud del mino interno del rol de piE oni de orden Tk F @CCA RRF gonsidere Fibl omo el onjunto de todos los roles de pioni liresF n rol de pioni lire Tk de orden k se de(ne omoX @A gso se k = 0X

T0 = Fibl

@TFTHA

530

6. rboles de bsqueda equilibrados

@A gso se k = 1X

T1 = Fibl
@A gso generl pr k > 1X

@TFTIA @TFTPA

Tk =< Ti , , Tj >

tl que i = jD i < kD j < kD ((i = k 1 j = k 2) (i = k 2 j = k 1))D L(Tk ) Fibl y R(Tk ) Fibl or ejemploD y pr selr un difereni on los roles de pioni trdiionlesD pr k = 2 tenemos los siguientes dos roles posilesX hel mismo modoD pr k F

3 tenemos los siguientes roles posilesX

@A gonsidere el siguiente prototipo de funinX

template <class Node> bool is_free_fib_tree(Node * r)


v ul retorn true si el rol uy rz es r es un rol de pioni lireF smplemente l funin en uestinF @A hetermine l ntidd de roles de pioni lires distintos de orden kF @CCA @A gonsidere el siguiente prototipo de funinX

template <class Node> Node random_free_fib_tree(int k)


v ul retorn un rol de pioni lire de orden k letorioF @CCA RSF hemuestre que l inserin en un rol ev us lo ms un rotin doleF RTF ixplique y desrrolle un mtodo pr reonstruir un rol ev ddo el reorrido in(jo de ls lves y los vlores de difereni de ltur de d nodoF RUF hemuestre que pr todo rol ev existe un olorin rojoEnegroF @CA RVF hiuje el rol rojoEnegro orrespondiente l siguiente seueni de inserinX PRU IVR PRH PQV PUS PV IHV QR PHI IRU RI IIQ WQ IIH WV IHI ITR PSQ IVT UH IWV IRS PSH ISV PWP PUQ PSU PRQ PSS IUI RWF hisee un lgoritmo que exmine un rol inrio ulquier y determine si es oloreE leF SHF hisee un lgoritmo que oloree de rojoEnegro un rol ulquier que hy psdo el test del ejeriio nteriorF SIF ijeute ls siguientes seuenis de inserin en un rol rojoEnegroX
@A IR SP IHU ITW TT RR IS IIT TV IWT SI IUU UW IUI PIV SW W IWU IPS VR VW I PIQ IWS ITQ @A IIH IWW IRU IVH UW IH IPU PRH H QV IHR IWS PHU RW VW W ISQ IWI IHI SR PHT IVI

6.9. Ejercicios

531

@A ISP IS QT QI IPR PQW SU WH VT PT IPW ITW WI IQQ IQU RP WW QP QS IHP PHH PPH WS VH @dA PPV PPT WU IUS IVS ITI PI PRH PPU PQU IWR UR VR WH IWQ PU UP SI IWP IRP SS PPW ITU @eA IWU PS IHU H TP IIR IPR PPI IPP IUW IHS IPV UV PW SV RI PHV PIU RT ISV PIQ QP TT PRT ISP

SPF r los siguientes roles evD de(nidos por sus reorridos pre(josD ejeute ls seE uenis de eliminin ddsX @A Prejo: IWS IRQ WH V H I VQ SV IPS IHU IST IRV ISQ IVV IVU IVT IWQ PTR PIV PIU PII PQP
PPS PQV PTU PTS PUU PUH PUV Secuencia de eliminacin: V PTS IWQ IRV PPS IHU IWS SV H PIV IVT IPS PUH PIU PUU PVW PVS PWU PWR PWW

@A Prejo: ITH VW QS PH I PT QP UU IQQ WS IRW IQS ISW PVP PIQ IUS ITU IUV IWH PTP PRH PTW

Secuencia de eliminacin: PTP PVS ITH PTW ISW QP PRH PVP IQQ PWW PIQ PWR PT IUV ITU @A Prejo: IPW TP QV IP T QI RP VR UQ IHU WQ IPV PRI ISU IRV IRH IRQ ISH IWS IUQ PPU PPW Secuencia de eliminacin: IWS PWI VR RP QI IP PVI IUQ ISU IPW PRI IRH PUT IHU @dA Prejo: IST TU PQ IQ IH PP SQ QH TR IIS UQ VW IQV IQT ISI PUP IVS IUU ITW IUV PPW IWP Secuencia de eliminacin: PRU PPW PUP PUV PWR IQ PWP IUU IQT IWP UQ ISI IQV TR VW @eA Prejo: IHT RT QW PI Q QU RH RI TW SS SQ WH UH WQ WP PPW ITS IPV IPS IIH IQH ISW IVQ
IUR PPR IWT PWQ PQV PTH PWU Secuencia de eliminacin: ISW IPS IQH SS QU IVQ PWU PWQ ITS RI Q RT IWT WP PI PRU PWP PUV PWI PWR PWW PUT PRR PRU PWI PVI PWT

SQF @omdo y trduido de rerry IQWA hiuje un rol ev pr el ul l eliminin de un nodo requier dos rotiones dolesF hiuje el rolD identi(que el nodo eliminr y explique por qu dos rotiones son neesris y su(ientesF @CA SRF gonsidere el siguiente prototipo de squedX
template <typename T> int search(T a[], const T & x, int n)

a es un rreglo ordendo de n elementos en el ul se us l lve xF


il (n de este prolem es implntr un esquem de squed denomindo de piE oniD el ul estrutur ls oserviones sore el rreglo de l siguiente mner generlX
0 Base 1 2 3 4 5 6 7 8 9 10

T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10

Fk es el kEsimo nmero de pioniF i es l posiion de inspein tulD mientrs que p y q son los nmeros de pioni de orden inmeditmente inferior iF v ide del esquem de squed es omprr x on a[i] yD si x != a[i]D entonesD segn x se menor o myor a[i]D desplzr los intervlos de squed hi un intervlo menor o myor que iF
@A esumiendo que n + 1 = Fk+1 D esri un lgoritmo que implnte l squed de pioniF

532

6. rboles de bsqueda equilibrados

eyud IX los ndies q y p siempre son nmeros onseutivos de pioniD mientrs que ese no siempre es el so pr el ndie iF eyud PX il vlor iniil de i es Fk F eyud QX v ondiin de prd es que x != a[i] y q == 0 or p == 1F is deirD el elemento no se enuentr y no es posile desplzr el intervlo sin que se slg del rregloF @A enlie el tiempo de ejeuin de l squed de pioniF @A gmo puede herse si n + 1 = Fk+1 SSF @omdo y trduido de rerry IQWA hemuestre que n N existe un rol ev pr el ul l eliminin de un nodo requiere extmente n rotionesF sndique mo se onstruye tl rolD indique de mner generl el nodo eliminr y explique por qu n rotiones son neesrisF STF hisee un lgoritmo O(n lg(n)) que efete l unin de dos roles rojoEnegroF SUF hisee un lgoritmo O(n lg(n)) que efete l prtiin @splitA de dos roles rojoE negroF SVF hisee un lgoritmo O(n lg(n)) que efete l intersein de dos roles rojoEnegroF SWF ijeute ls siguientes seuenis de inserin en un rol splyX
@A IUQ PPH PHR WS IQV PHV PRU PTR ISR U PRR ITU PVQ IVV IVU WU IP ITV PQV IWU ITT PSQ PUH PWI IVT ITH SW TH PSH IIU @A T QU IRR PVS IHS PSW VH TS IHT PHS QP IRI PR ISH Q QH TR U SU IT IVU IHI PWQ PH UQ IR IRU WQ UW ISQ @A IQW PHH WI IRI QU PQU PPI TQ QQ PIR PPR PWU PI PUR IWS PUV PRQ IHH IWT PST IRV PSP ITQ PHT Q UU V PUT WW PVI @dA IIP IPW WT UI PQU VT UW RS PSS PPT QT TR PPS PRH ITU PUT U PQW QU PQP IIS IUS PTR IQV PP QQ PWW PPW ITI III @eA PUI IVI PHR PVV IPI IPV IHS PSR VI ITP PRU QS ST IIU IIS IUR PSQ PSS PHV TI PQW PQT TT ITI IRS UH IQU PSV IRV IHU

THF r los siguientes roles evD de(nidos por sus reorridos pre(josD ejeute ls seE uenis de eliminin ddsX
@A

Prejo: Prejo:

UU UR IV T TR PI QV UP PVT VP VQ VV PPU PHS WV IQH IWT IRU PVR PUS PUI PQT PQH PTS PRH PSW PUH PWI PWS PWV Secuencia de eliminacin: PVT PWV PWS IWT VQ PPU UU TR IRU PQT QV VV PHS T PI PUU PUS IH Q ISU IST SW RH RU WQ TR UV VU ISH PQR ITH PQI IWH ITP ITS IVT PHW PPS PII PIV PSS PUH PWH PWI PWQ Secuencia de eliminacin: IH RH RU PSS IVT ITP VU ISH WQ ISU ITH PQI PUU PWH PWQ

@A

@A

Prejo: Prejo:

PIT PIR IVV IVT IUI IQH IPP PQ IT IH U TU WV WP US WH VQ IIQ ITT ISW ITS PHP PHH PIQ PQR PTP PSI PTT PTW PWP Secuencia de eliminacin: PTT PIQ ITS IPP US U VQ ITT PQ PTW PWP IVT IT TU PIT TR TH SS IH T IS PT IW QH TU UP PRU PRS ITT WQ WH ISW IRQ IQI IIU IUQ PQV IWS IVI PRV PSP PTI PSQ PST PVR

@dA

6.9. Ejercicios

533

20

33

12

25

41

15

22

28

36

46

10

13

17

21

23

26

30

34

38

43

49

11

14

16

18

24

27

29

31

35

37

39

42

44

47

51

19

32

40

45

48

50

52

53

pigur TFQUX rol ev eliminr el nodo 0

@eA

Secuencia de eliminacin: IS IH WH PT TH ITT PQV TU PRV TR IUQ PST IIU UP T Prejo: TH PU PH IS IP S PTT IVP UQ IQT VW IQR WU WH IHS IIS ITV PRI PPP PIQ IWH IVV
IVR IWV IWW PII PSW PSI PVT PWQ Secuencia de eliminacin: IWV PU TH PTT IS PWQ VW PH PRI IIS PIQ S UQ IQT IHS

TIF hdo el rol ev de l (gur TFQUD hiuje el rol resultnte de eliminr el nodo 0 @eroAF TPF hiuje el rol ev resultnte de eliminr el nodo 53 del rol de l (gur TFIQF TQF hisee un lgoritmo que efete l prtiin de un rol splyF hemuestre que l ltur del rol resultnte es logrtmiF TRF hiuje el rol sply orrespondiente l siguiente seueni de inserinX IPU PHW PPT TS PSW WS IPH PI PRH PUP PIH IPP VR QQ PWU IHS ITH RH PPP IIS PRV IU PTP IWR IQS WI ISP IWW ITW PIW

Grafos
intre nuestros sentidos sensorilesD pree que l vist es el que oup l myor prte de nuestr perepinF xuestr memori y reuerdo estn impregndos en grn medid de imgenes visulesF in muhs osiones preferimos trtr on imgenes porque nos son ms onrets nuestr perepin y entendimiento que los oneptos strtosF gundo lidimos on lo purmente strtoD es muy posile que soiemos un imgen visulF gundo esuhmos tresD por ejemploD es posile que se nos prez un imgen reliond un tripliidd o l dgito  3F in l onstruin del onoimiento humno suelen utilizrse imgenes rti(iles pr expresr mejor ides y oneptosD o pr sintetizrls en un imgen que engloe y resum los suntos de intersF vs imgenes de este tipo son llmds omnmente gr(osF vos gr(os rtesinosD es deirD ls urvs mtemtis diujds en el eje rtesino de oordendsD permiten mirr mplimente el omportmiento de un funinD omporE tmiento ste que puede estr oulto en l mer frmulF ist lse de gr(o es rti(il en el sentido de que no se enuentr nturlmenteY o seD no se orresponde on un imgen periid en el mundo nturlF ixiste un mpli vriedd de prolems en l ul se deen expresr reliones entre oss de lgn tipoF uiz un uen ejemplo pr este tiempo lo onstituy un mp vil que represente un red de rreters entre iuddesF in l jerg omputionlD este tipo de gr(o se le llm formlmente grafo F il trmino grfo proviene del griego @grfosAD el ul signi( esriturF v esritur es expresin sensoril1 de eso tn mrvilloso y misterioso omo el lengujeF gundo leemosD no requerimos l preseni del esritor2 D sino lgn sentido de perepin y entrenmiento omo letorF vos gr(os onstituyen un de ls primers forms humns de representr onoimiento y l omputin y progrmin no espn l riquez expresiv de lo gr(oF in trminos mtemtiosD un relin es un suonjunto @R A BA de lE gn produto rtesino entre dos onjuntos A y BF in est sein nos interesn reliones entre oss de un mismo tipoD por lo que los onjuntos origen y destino son los mismos y l relinD li(d de inriD se re(ere l produto rteE sino A AF ry vrios esquems gr(os pr expresr un relin inriF in mtemti es freuente utilizr los digrms sgitlesD pero stos son engorrosos pr
1 2
Bien sea visual, tctil o de alguna otra clase. Aunque pueden perderse algunas emociones e interpretaciones involucradas cuando se escucha direc-

tamente al lector.

SQS

536

7. Grafos

ls reliones inrisF in lo que onierne este estudio existe un representin gr( que permite mirr y entender mejor un relinF v (gur UFI ilustr l relin R = {(a, b), (a, c), (a, d), (b, a), (b, c), (b, d), (b, f), (b, e), (c, a), (c, b), (c, g), (c, f), (c, h), (d, a), (d, b), (d, e), (g, c), (g, h), (f, c), (f, b), (f, h)} A A, A = {a, b, c, d, e, f, g, h}D de un mner diferente yD en generl ms simpleD que un diE grm sgitlF
a

pigur UFIX ijemplo de relin expresd on un gr(o pigurs omo l UFIE se llmn grfosF in el ejemplo en uestin se preE in visulmente ls onexiones entre los elementos del onjunto AF vos elemenE tos se diujn enerrdos entre rulosD mientrs que ls reliones entre ellos se inE din medinte lnes que onetn los rulosF is muy posile que l letor le se ms senillo preir l relin medinte l (gur UFI que en su representin mtemti R = {(a, b), (a, c), (a, d), (b, a), (b, c), (b, d), (b, f), (b, e), (c, a), (c, b), (c, g), (c, f), (c, h), (d, a), (d, b), (d, e), (g, c), (g, h), (f, c), (f, b), (f, h)}, A = {a, b, c, d, e, f, g, h}F in l jerg de grfosD los elementos de relin se llmn vrties o nodosD mientrs que ls reliones se llmn rists o rosF in el ejemplo de l (gur UFIE los vrties se diujn on rulos etiquetdos on los elementos del onjunto A = {a, b, c, d, e, f, g, h}D pero no existe ningun restriin sore l form visul que de tener un nodoY podr herse diujdo on udrdosD tringulos o ulquier otr (gurF or lo generlD en mtemtiD l migedd no es ien vistF ero vees es jusE tmente en l pidd de expresr forms gr(s diferentes pr un mism relin donde reside el poder de strin y representin de un grfoF n grfo esD puesD un estrutur de dtos orientd hi l representin gr( de ls reliones enE tre elementos de un mismo tipoF v rzn que motiv los progrmdoresD ingenierosD mtemtios y dems prtintes utilizr grfosD es l omodidd que onllev pr el entendimiento el mnejr striones gr(sF emos de presentr el pr qu es l ide de grfoX un strin generl que pretende rr un vst gm de prolems en los ules se puedn expresr reliones entre elementos de un mismo tipo y nos se ms modo visulizrls en un gr(oF i ien l ide de grfo es visul en su sentido sensorilD su trtmiento tiene dos perspetivs de estudio que no lo sonX l mtemti omintori y l progrminF il onepto de grfo y sus prolems soidos existen desde muho ntes que l proE grminF uesto que l myor de los prolems que modelizn los grfos requieren muE ho mputoD durnte muho tiempo su inters y estudio estuvo reservdo los mtemtiE

7.1. Fundamentos

537

osF v perspetiv mtemti tiende investigr el grfo omo un relinD es deirD omintorilmenteF v otr perspetiv del nlisis l onstituye l progrmin de lgoritmos sore grfosF hihos lgoritmos plnten desfos de lor de un esl y omplejidd que n no h sido ordd hst el presenteF vos lgoritmos sore grfos onjugn el uso de diverss estruturs de dtos y lgoritmosF or delntr un ejemploD el lulo de minos ptimos puede requerir lgoritmos de ordenmiento y heps inriosF

7.1 Fundamentos
gomo intuitivmente y se h meniondoD un grfo G se de(ne formlmente medinte un dupl G =< V, A > ompuest de dos onjuntosX V es el onjunto de vrties o nodos y A es el onjunto de rists o ros3 F in el ejemplo de l (gur UFPD V se ompone por ls letrs desde l A hst l MD mientrs que A lo omponen ls onexiones enumerds desde el 1 hst el 29F
29

B 1

J 9 14 15

M 5

28

8 17

16

7 L 6 N 24 25 23 27 26

A 11

10

D 12 13 18

E 18 21

22

I K

20

pigur UFPX n grfo v numerin de los ros de ls (gurs UFP y UFQ no represent mgnitudes o tiposF egn ls rterstis de l pliinD los nodos y ros pueden soirseles tipos de dtosF or ejemploD un grfo vil de rreters gurdr en sus nodos los nomres de ls iuddes junto on informin tursti y de serviios sios @estiones de gsolinD hotelesD etterAF vos ros representrn ls rreters y lmenrn ls distnis entre ls iuddes junto on un li(dor que indise su lidd @utopistD rreterD trohD etterAF e menudoD est lse de grfoD en prtiulr quel uyos ros gurdn ntiddesD se le llm grfo on pesos porque ls ntiddes se pondern y se utilizn en lgoritmosD por ejemploD pr lulr l distni ms ort entre dos iuddesF in el grfo de l (gur UFPD ulquier ro relion sus nodos en los dos sentidosF or ejemploD el ro 1 represent ls reliones A B y B A respetivmenteF in trminos mtemtiosD el ro 1 represent (A, B), (B, A) A AF in plrs mtemtisD l relin representd por el grfo de l (gur UFP es simtriF
3
Por lo general, los programadores usan el trmino nodo, mientras que los matemticos preeren Del mismo modo, los programadores utilizan el vocablo arco mientras que los el trmino vrtice.

matemticos se inclinan por usar arista. Puesto que este texto es ms para programadores, se usarn en preferencia los trminos

nodo y arco respectivamente.

538

7. Grafos

gundo l relin no es simtriD entones el grfo es dirigido y los ros se les ponen )ehs que indin el sentido de l relin entre dos nodosF n grafo dirigido tmin se denomin digrafo F v (gur UFQ muestr un ejemploF xtese que el ro 1 dirigido desde el nodo A hi el nodo B represent (A, B) RF hel mismo modoD ntese que (B, A) / R se expres por l useni del ro dirigido desde B hi AF
B 1 3 A 9 C 8 D 4 5 6 7 F 2 E

pigur UFQX n digrfo o grfo dirigido il nmero de ros onetdos un nodo es llmdo el grado del nodoF il grdo del grfo es el myor grdo entre todos sus nodosF hdo un nodo vD los nodos diretmente onetdos desde v trvs de sus ros se llmn nodos dyentesF or ejemploD en el grfo de l (gur UFQD los nodos dyentes B son {C, D, E}F vos nodos desde los ules se lleg diretmente un nodo v se denominn nodos incidentesF r el ejemplo nteriorD A es el nio nodo inidente BF n ro es incidente sore el@losA nodo@sA que l onetF ist jerg es plile un grfo no dirigidoD pero puede ompleE mentrse si los nmeros de ros entrntes y slientes se les llmn grado de entrada y grado de salida respetivmenteF hdo un ro dirigidoD su nodo de origen se le denomin dyente y l destino inidenteF n camino P G de un grfo G se de(ne omo un seueni interld de nodos y ros de GF ry vris forms de expresr un minoD ls ules dependen del tipo de grfo y de l pliinF in el so del grfo de l (gur UFPD l seueni P = A B J H N L I indi un mino desde el nodo A hst el nodo IF ytr mner puede ser diretmente A, B, J, H, N, L, ID o medinte ls etiquets de los rosX 1, 2, 3, 16, 6, 25Y est ltim form est supeditd que los ros estn etiquetdosY requisito que no se irunsrie en l de(niin forml de grfoF v longitud de un mino se ompone por el nmero de ros que ste ontengD o seD el nmero de nodos menos unoF n de ls pliiones ms importntes de los grfos es l squed de minos segn lgun restriin ddF uiz el prolem ms populr se l squed del mino mnimo entre un pr de nodosF n mino uyo primer y ltimo nodo sen igules se denomin ciclo o circuitoF i l longitud del ilo es unoD entones l mino se le li( de simple D de bucle o de lazo F il grfo de l (gur UFP ontiene un slo ilo simple en el nodo JY es deirD el pr (J, J)F n grfo G =< V, A > se li( de conexo si pr todos los pres ordendos de nodos (v1 , v2 ) G existe un mino desde v1 hst v2 F ixpresdo de otr mnerD un grfo es onexo si pr todo nodo del grfo existe un ilo que no se simpleF n grfo se die que es totalD completamente conexo oD simplementeD completoD

7.1. Fundamentos

539

si d nodo del grfo es dyente l restoF il grdo de un grfo ompleto es su nmero de nodosF v (gur UFR ilustr el grfo ompleto de grdo 5F
A B

pigur UFRX n grfo ompleto de grdo 5 il grafo complemento de un grfo GD que se denot GD es el grfo ompuesto por los ros que se requerirn pr que G deviniese ompletoF hiho de otro modoD el grfo ompleto de grdo |V | menos los ros de GF v (gur UFS ilustr un ejemploF v unin de un grfo y su omplemento es el grfo ompleto de grdo |V |F elgunos lgoritmos requieren lulr el grfo omplementoY otros requieren el grfo ompletoD el ul puede lulrse si se tiene el omplemento medinte l unin G GF
A B A B

pigur UFSX n grfo y su omplemento vs esls en nmero de nodos y ros son los ftores priniples que iniden en el tiempo de ejeuin de un lgoritmo sore un grfoF in ls expresiones de lulosD pr filitr el disursoD ls rdinliddes de los onjuntos V y A suelen representrse diretmente sin ls rrsF e un grfo que teng dos o ms ros que oneten los mismos nodos se le denominD en prfrsis on los onjuntosD multigrafo F v (gur UFT ilustr un ejemploF n multigrfo puede ser dirigidoD en uyo so se le llm multidigrafo o multigrafo dirigidoF n ro redundnte reie el nomre de paralelo F hdo un grfo G =< V, A >D ulquier suonjunto G =< V , A > | (V V )(A A | a = (v1 , v2 ) A = v1 , v2 V ) se llm subgrafo de GF v (gur UFU ilustr dos sugrfos del ilustrdo en l (gur UFPF gulquier sugrfo ompleto se llm cliqueF e un grfo que no es onexo se le llm inconexo F ngrfo inonexo G se ompone de grfos onexosD los ules se denominn subgrafos conexos de G F n grfo onexo sin ilos se llm rbol F wenester notr que st es un interE pretin diferente l de rol trtd en RFI @gF PPTAD pues en este so no es requisito denotr un nodo rzD unque nd impide herloF

540

7. Grafos

B 1 4

J 6 14 7

H 8

A 11

D 12 13

1 15

17 16

18

10

17

pigur UFTX n multigrfo


B 1 H 28 14 D 12 13 18 E 4 M 5 16 17 N 24 11 22 26 23 27 C 20 F G K I 7 L 6 25

10

(a)

(b)

pigur UFUX hos sugrfos del grfo en UFP n  rbol abarcador 4 de un grfo onexo G es un rol ompuesto on ros de G que ontiene todos los nodos de GF v (gur UFV ilustr un rol rdor del grfo mostrdo en l (gur UFPF
B 2 J 15 8 H 7 L 6 A 10 D 13 E 18 I 27 C 20 F 21 G K 17 N 25 M

16

pigur UFVX n rol rdor del mostrdo en l (gur UFP elgunos lgoritmos requieren veri(r si el grfo es bipartido o enontrrloF n grfo es bipartido si puede dividirse en dos onjuntos disjuntos de nodos B y C tl que los ros de un onjunto oneten nodos de B on nodos de C y que no exist onexin entre los nodos de un mismo onjuntoF v (gur UFW muestr un ejemploF hel sentido visul del onepto de grfo surge l ide de olorin si soimos olores los nodos o rosF il prolem de olorer nodos onsiste en pintr los nodos de mner tl que dos nodos dyentes no tengn el mismo olorF in el mismo sentidoD
4
En ingls:

spanning tree .

7.1. Fundamentos

541

B A B C D E

E C F G H I J

(a)

(b)

pigur UFWX n grfo iprtido olorer ros onsiste en pintrlos de form tl que dos ros que iniden sore el mismo nodo tengn olores diferentesF hos grfos G1 =< V1 , A1 > y G2 =< V2 , A2 > son isomorfos si es posile mir de ls etiquets de V1 por ls de V2 tl que A1 = A2 F v (gur UFIH muestr un ejemploF
6 A B 1

D 2 4 F G 5 3

pigur UFIHX hos grfos isomorfos n grfo es llmdo planar si es posile diujrlo en un plno sin que sus ros se ruenF n mino eulerino es uno que ps por todos los ros extmente un vezF iste tipo de mino tipi( lguns situiones de optiminX por ejemploD el reorrido de un rteroF n mino hmiltonino es uno que ps por todos los nodos extmente un vezF el igul que l lse nteriorD este tipo de mino tmin modeliz situiones de optiminY por ejemploD el mino que dee her un visitdor mdio pr urir tods ls iuddes de su responsiliddF vos grfos representn un lse de prolems ms omplej que he uso intensivo de implntiones del prolem fundmentl de estrutur de dtosF v ndole de prolems on grfos puede lsi(rse en utro tiposF il primer tipo de prolem se lsi( en de existencia F hdo un grfo y unos requerimientos sore steD existe un grfo que stisfg los requerimientosc or ejemploD es un grfo plnrc il segundo tipo se tipi( en de construccin F n vez que se onoe l existeni de un grfo espeilD entonesD mo onstruirlocF elgun vees no es neesrio deterE minr l existeni porque st se onoe de ntemnoD por ejemplosD pr lulr el rol rdor o lgn minoF ytrs vees s onviene determinr l existeni primeroD

542

7. Grafos

ntes de ordr l onstruinD por instniD el diujdo de un grfo plnrF el terer tipo se le denomin en de enumeracin o conteo F n vez que se determin l existeniD entones se dese onoer l ntidd de soluionesF or lo generlD estos prolems ten ms l inters mtemtio que plitivoF pinlmenteD el ltimo tipo de prolem se llm de optimizacin y onsiste en onstruir l mejor soluin segn lgn riterio de optiminF in lo que sigue de este texto se enontrrn muhos ejemplos vrindo desde el rol rdor mnimo hst l onstruin de un mino hmiltoninoF

7.2 Estructuras de datos para representar grafos


e onoen dos esquems pr representr grfos en l memori de un omputdorX mE tries o lists enlzdsF

pigur UFIIX n grfo ejemplo

7.2.1

Matrices de adyacencia

uesto que un grfo represent visulmente un relinD ls mtries preen ser l esE trutur nturlF he hehoD sts tienen un trdiin de uso exitos en l mtemti pr expresr y mnipulr reliones inris yD onseuentementeD grfosF n mtriz que represente un grfo se llm de adyacencia F e trt de un mE triz udrd M[V V ] uys entrds M(i, j) representn l onexin entre el nodo i y jF v mnim informin neesri en d entrd es un it que indique l existeni o no del roF il grfo de l (gur UFII se represent medinte l mtriz mostrd en l (gur UFIPF n ero indi l useni de roD mientrs que un uno su preseniF i el tipo de dto soido un nodo no es enteroD entones hy que implntr un mpeo de nodos hi ndies de l mtrizF v mner ms simple de herlo es medinte un rreglo de nodos uyos ndies se orresponden on ndies en l mtrizF i el rreglo est ordendoD entones l squed inri explid en QFIFW @gF ITSA enuentr muy e(zmente un ndie ddo un nodoF i los ros no tienen lgn tipo soidoD entones el eh BitArrayD estudido en PFIFS @gF SQAD puede utilizrse omo se de implntin de l mtriz de dE yeniF or el ontrrioD si los ros soin lgn tipoD entones d entrd de l

7.2. Estructuras de datos para representar grafos

543

A B C D E F G

A B C D E F G

0 1 1 1 0 1 1

1 0 1 0 1 1 1

1 1 0 1 1 0 0

1 0 1 0 1 0 0

0 1 1 1 0 1 0

1 1 0 0 1 0 1

1 1 0 0 0 1 0

pigur UFIPX wtriz de dyeni del grfo en l (gur UFII mtriz podr representr l instni del tipo que estr soid l roF in este soD requerimos un instni espeil del tipo pr indir l useni del roF n mtriz de dyeni oup O(V 2 ) eldsD oste lto un pr grfos de medin eslF or est rzn result interesnte el uso de estruturs de representin de mE tries esprids que no oupen espio por entrds nulsD en nuestro soD por useni de rosF n primer mner de horrr memori l onstituye onsiderr el tipo de grfoF i l mtriz no represent un digrfoD entones st on slo gurdr los elementos sore o dejo de l digonlF hel mismo modoD si el grfo no ontiene lzosD entones no es neesrio onsiderr l digonlF n mtriz trdiionl requiere un loque de memori ontiguo proporionl O(V 2 )F e medid que umente V ser ms difil pr un mnejdor de memori enontrr un loque ontiguoF n esquem funionlmente equivlente onsiste en prtr un rreE glo de rreglos uy representin pitri se muestr en l (gur UFIQF in ese soD el mnejdor de memori requiere prtr V loques ontiguos de tmo V D lo ul es ms fil que uno solo de V V F in C++ D un mtriz de dyeni de ros del tipo T se delr e inii del siguiente modoX inicializar arreglo de arreglos 543 T ** matriz = new T * [V]; for (int i = 0; i < V; ++i) matriz[i] = new T [V]; iste digo puede modi(rse pr usr el tipo BitArrayD lo ul se dej omo ejeriioF
A B C D E F G 0 1 1 1 0 1 1 1 0 1 0 1 1 1 1 1 0 1 1 0 0 1 0 1 0 1 0 0 0 1 1 1 0 1 0 1 1 0 0 1 0 1 1 1 0 0 0 1 0

543

pigur UFIQX erreglo de rreglos orrespondiente l mtriz de dyeni de l (gur UFII

544

7. Grafos

ry lgoritmos que se desempen mejor on mtries de dyeni que on su onE trprte que us lists enlzdsF elgunos lgoritmos on mtries de dyeni requieren otrs mtries pr mntener estdo de sus lulosD lo ul inrement el oste en memoE riF eprte del provehmiento del tipo de grfoD otr form de horrr espio es usr un rreglo esprido del tipo DynArray<T> estudido en PFIFR @gF QRAF n mtriz de dyeni requiere onoer priori el nmero de nodosF or est rznD est representin no es onveniente pr situiones en ls ules l grfo se le inserten y eliminen nodos o ros dinmimenteF
7.2.2 Listas de adyacencia

hdo un nodo v perteneiente un grfoD su list de dyeni se ompone por los nodos los ules v est onetdo medinte rosF he este modoD pr representr un grfo en memori se utilizn lists de dyeni pr d nodo del grfoF v (gur UFIR ilustr un ejemploF
A B C D E F G B A A E D B B C C D D C G A D G B A B A F F E F F E G E

pigur UFIRX vists de dyeni del grfo en l (gur UFII gd nodo de un list de dyeni gurd l direin de memori de un vrtie en el grfo5 orrespondiente l existeni de un roF uesto que en un grfoD los ros son idireionlesD stos se re)ejn dos vees en l representin on lists de dyeniD o seD un vez por d nodo extremo de d roF or ejemploD en el grfo de l (gur UFIID el ro A B pree en ls lists de dyeni de los nodo A y BF v dupliidd de ros en ls lists de dyeni rre un soreoste de espio undo los ros soin lgn tipo de dtoD pues se dupli informinF or otr prteD lgunos lgoritmos gurdn estdo de lulo en los rosD lo que requiereD en so de mntenerse l dupliidd meniondD que el estdo se tulie en dos direiones de memori diferentesF or est rzn es preferile strer un ro y gurdr direiones ste en ls lists de dyeniD en lugr de gurdr direiones de nodosF he est mnerD l list de dyeni deviene un list de rosF v distinin del nodo destino se he segn el nodo propietrio de l listF in el ejemplo de l (gur UFIID si nos enontrmos en l list de dyeni del nodo B y enontrmos el ro A BD entones semos que se trt del ro on sentido B AF gon el esquem nterior se puede mntener estdo en los ros sin neesidd de lidir
5
Se usa vrtice en lugar de nodo para distinguirlo de nodo en la lista de adyacencia.

7.3. Un TAD para grafos (List_Graph)

545

on ls dupliiddes de nodosF iste esquem tmin funion on digrfos expenss de un osto en memori ligermente superior que el de gurdr los nodosF vs lists de dyeni tienen vris ventjs respeto ls mtriesF v primer de ells es que el oste en espio es extmente proporionl l nmero de rosF isto se trdue en horros de memori undo el grfo es espridoF v segund ventj es que se filit operr el grfo en funin de su rter gr(oY es deirD en funin de nodos y rosF isto no suede en generl on un lgoritmo que use un mtriz de dyeniD el ul tiene prolemente sentido mtemtioD pero no el gr(o que selmos l prinipio del ptuloF v ltim ventj que preimos en l representin on lists es su )exiilidd pr el mnejo de memori y dinmismoF uesto que se prt memori en funin de nodos y rosD es ms simple pr el mnejdor de memori otener loquesD un en esenrios en que hy po memori o st est muy frgmentdF or otro ldoD por su rter de listsD est representin es muho ms dinmi pr operiones interlds de inserin y elimininD sore todo si ls lists son dolemente enlzdsF gomo desventj podemos identi(r que l veri(in de existeni de un ro es en el promedio o peor de los sos O(V )D pues es neesri un squed en un list de dyeniF gon un mtrizD en mioD est veri(in es O(1) o O(lg(n))F gon un mtriz de dyeniD los ros preen en el orden ddo por sus (ls @o olumnsAF in el ejemplo de l (gur UFIID los ros hi el nodo D siempre preen ntes que los que vn hi el nodo EF gon lists de dyeniD el orden de priin de los ros yD por tntoD de su orden de proesmientoD es reltivo su posiin dentro de l list de dyeniF e l vezD el orden de priin depende del orden de inserin en el grfoF eprte de l suerteD por lo generlD esto no pree tener impliiones de desempeoF

7.3 Un TAD para grafos (List_Graph)


in est sein presentremos el diseo e implntin del eh List_GraphD el ul pretende modelizr grfos generles que puedn usrse pr l myor de lses de pliE iones onoids sore grfosF e pesr de que en su sentido visulD un grfo pree ser muy generlD est strin de onepto se us pr resolver prolems muy distintosF gonseuentementeD enontrr un ptrn generl que permit modelizr un eh que funione pr tods ls lses de prolems sore grfosD es lgo difilF edemsD omo y dee ser ien sidoD luego de insistir en el prinipio (nEE(n @ IFRFP @gF PPAAD l generlidd tiene sus ostes en el sentido de que lguns pliiones no requieren l mquinri desplegd pr trtr on todos los sos posilesF il digo pertinente los eh fundmentles sore grfos se espei( en el rhivo tpl_graph.HF odr deirse que un de ls priniples di(ultdes pr modelizr un eh de grfos es el heho de que ste involur otrs lses de ojetoF isenilmenteD un grfo mnej nodos y rosD los ulesD en muhos sosD hy que trtrlos omo un strin sepE rdD unque reliondD del propio grfoF n speto esenil pr l ompresin es l oservni de que es en el momento en que se de(ne el grfoD es deirD undo ste se delre y se ompileD que se onoern ompletmente los tipos de nodos y rosF

546

7. Grafos

heido su lto dinmismoD List_Graph onstituye el prinipl eh pertinente los grfosF iste eh permite opirD signr y modi(r su topologY rterstis neesris pr un mpli gm de lgoritmosF elgoritmos sdos en mtries de dE yeni usrn un fmili de eh orientdos mtriesX Map_Matrix_Graph<GT>D Matrix_Graph<GT> y Ady_MatD los ules sern detlldmente desrrolldos en UFT @gF TPVAF
7.3.1 Grafos

546a

n List_Graph es un lse que modeliz un grfo implementdo on lists de dyeniF us prmetros tipo son el nodo y el roD y se de(ne del siguiente modoX Grafos 546a template <typename __Graph_Node, typename __Graph_Arc> class List_Graph { Tipos de List_Graph 546b Miembros privados de List_Graph 559e Miembros pblicos de List_Graph 547b Iteradores de List_Graph 550a };
Denes:

List_Graph,

used in chunks 547a, 550a, 555, 561, 562, 56466, 57174, 576a, and 577b.

546b

r poder usr un ojeto List_Graph es neesrio her de(nido los tipos de nodos y de rosD uestin l que nos oremos en ls prxims suseionesF List_Graph ser mplimente utilizdo pr l progrmin genriD es deirD pr progrmr lgoritmos que funionen pr lses generles de grfosF in l progrmin genri es menudo neesrio onoer los sutipos de List_GraphD los ules se de(nen ontinuin Tipos de List_Graph 546b (546a) typedef __Graph_Node Node; typedef __Graph_Arc Arc; typedef typename Node::Node_Type Node_Type; typedef typename Arc::Arc_Type Arc_Type; gonsideremos el siguiente frgmento de digoD el ul ejempli( el uso de estos tiposX
template <class GT> void fct(GT & g) { typename GT::Arc * arc; typename GT::Arc_Type dato; // ...

v funin es genri y reie un List_Graph llmdo GTF v primer lne delr un puntero un roD mientrs que l siguiente delr un vrile del mismo tipo que el triuto soido l roF xotemos que este digo es genrio en el sentido de que deer de operr sore ulquier ominin de tipos de nodos y rosF in lo que sigue de ls siguientes suseiones menionremos operiones sore List_Graph nivel de interfz y no de implntinF

7.3. Un TAD para grafos (List_Graph)

547

7.3.2

Digrafos (List_Digraph)

547a

il eh que modeliz digrfos se denomin List_DigraphF nto nivel de estruE tur de dtosD omo nivel de interfzD el List_Graph tiene si todo lo requerido pr mnejr digrfosF or es rzn de(niremos List_Digraph por hereni pli de List_Graph tl omo se present ontinuinX Digrafos 547a template <typename __Graph_Node, typename __Graph_Arc> class List_Digraph : public List_Graph<__Graph_Node, __Graph_Arc> { List_Digraph(); List_Digraph(const List_Digraph & dg); List_Digraph & operator = (List_Digraph & dg); };
Denes: Uses

List_Digraph, used in List_Graph 546a.

chunks 562d and 711b.

547b

v interfz de List_Digraph es idnti l de List_GraphY de hehoD esD por derivin de lsesD l mismF e nivel de implementinD l difereni reside en que en List_Graph se redund el roD sin fetr l ohereni de los lgoritmos y on un ligero onsumo de espioD pr representr l idireionlidd del roD mientrs que en List_Digraph slo se pone el ro en l list de dyeni de su nodo dyenteF uede her situiones en ls ules es neesrio determinr si un ojeto de tipo List_Graph es o no un digrfoF r eso se provee l primitiv siguienteX Miembros pblicos de List_Graph 547b (546a) 548c bool is_digraph() const; l ul retorn true si el ojeto es un digrfo y false de lo ontrrioF
7.3.3 Nodos

547c

r representr un nodo de un grfo se utiliz el eh Graph_NodeD uy espei(in generl es omo sigueX Denicin de nodo de grafo 547c template <typename Node_Info> class Graph_Node : public Dlink { typedef Graph_Node Node; typedef Node_Info Node_Type; Miembros de Graph_Node 548a }; he(niin de nodo de grfo 547c modeliz un nodo perteneiente un grfo implnE tdo medinte lists de dyeniF n Graph_Node es un lse plntill uyo prmetro es el tipo de ojeto soido l nodo y que se denomin Node_InfoF i se deseD por ejemploD un grfo de iuddesD entones l lne siguienteX
Graph_Node<Ciudad> * nodo;

helr un puntero nodo on triuto de tipo CiudadF iventulmenteD si no se requiere ningn triuto pr un nodo o si se pre(ere olorlo en un derivinD entones podemos espei(rlo on triutos vos de l siguiente formX
Graph_Node<Empty_Class> node;

548

7. Grafos

548a

il triuto de un nodo se gurd en el miemro dto node_infoD el ul se delr omo sigueX Miembros de Graph_Node 548a (547c) 548b Node_Info node_info; y que se oserv y modi( medinteX Miembros de Graph_Node 548a + Node_Info & get_info() { return node_info; }
(547c) 548a 557a

548b

hentro de un List_GraphD d nodo pertenee un list irulr dolemente enE lzd de nodosF il enle dentro de es list es this medinte hereni pli de DlinkF
7.3.3.1 Insercin de nodos

548c

r l omprensin de est susein y de ls susiguientes es neesrio prehender que un grfo List_Graph us ojetos de tipo List_Graph::Node y no estritmente de tipo Graph_NodeF eunque sin dud deer srse en Graph_NodeD List_Graph::Node podr ser un derivinF or est rznD efetos de l ompletitud de tipos es neesrio insistir en que en un List_Graph el nodo es de tipo List_Graph::NodeF reh l lrtori nterior podemos hlr de l inserin de un nodo en un List_GraphF ry dos operionesX Miembros pblicos de List_Graph 547b + (546a) 547b 548d inline virtual Node * insert_node(Node * node);
inline virtual Node * insert_node(const Node_Type & node_info);

v primer versin tom un nodo y redoD es deirD uy onstruin y fue efetudD y lo insert dentro del grfoF v segund prt l memori pr un ojeto de tipo List_Graph::NodeD le sign el triuto node_info y luego lo insert dentro del grfoF i no hy memori su(iente pr rer el nodoD entones se gener l exepin estndr bad_allocF e efetos de no rlentizr el desempeo dinmio de List_GraphD insert_node() no he ningun vlidin de orretitudD por ejemploD l dole inserinF
7.3.3.2 Eliminacin de nodos

548d

r eliminr un nodo de un grfo slo st tener un puntero lX Miembros pblicos de List_Graph 547b + (546a) 548c inline virtual void remove_node(Node * node);

549a

remove_node() elimin del grfo el nodo node junto todos sus ros inidentes y dyE entesF od l memori oupd por el nodo y sus ros es lierdF fjo el mismo espritu de no gstr ilos en vlidinD remove_node() no efet veri(in de orretitudY por ejemploD l eliminin de un nodo que no pertenez l grfo6 F
6
Las primeras versiones de

List_Graph

contenan invariantes que en cierto modo permitan validar su

uso. No obstante, se eliminaron porque la degradacin de desempeo para algoritmos prototpicos era tan severa que impeda una codicacin productiva.

7.3. Un TAD para grafos (List_Graph)

549

7.3.3.3

Acceso a los nodos de un grafo

549a

i ien ls operiones de inserin devuelven el puntero l nodo insertdoD lo ul permite reordrloD puede requerirse eso los nodos desde un List_GraphF v primitiv si pr otener un nodo ulquier del grfo esX Miembros pblicos de List_Graph 547b + (546a) 548d 549b inline Node * get_first_node(); v ul retorn un nodo ulquier ontenido dentro del grfoF get_first_node() es un punto ulquier de eso l grfoF xo dee herse ningun onsiderin er del nodo que retornr est primitivF il nmero de nodos que ontiene un List_Graph puede onoerse medinteX Miembros pblicos de List_Graph 547b + (546a) 549a 549c inline const size_t & get_num_nodes() const;
Bsqueda de nodos

549b

549c

hdo un grfoD puede plnterse l squed de lgn nodo que reun lguns rE terstisF List_Graph ofree tres forms de squedD seuenilesD es deir uyo oste es O(n) @|V | = nAD por lo que no se reomiend su uso si l squed es muy freuenteF is menester selr que si l pliin requiere squeds freuentesD entones es preferile indizr los nodos en lgun estrutur de dtos espeilD un tl hsh o lgun lse de rol inrio de squedF il primer tipo de squed est ddo porX Miembros pblicos de List_Graph 547b + (546a) 549b 549d template <typename T, class Equal> Node * search_node(const T & data); in este so se he un squed seuenil medinte invoin l riterio de iguldd Equal() (p, data)D donde p es un refereni l triuto soido l nodoF v lse Equal permite estleer lgn riterio seletivo sore lgun prte de los triutosF i se desen omprr entermente otrosD entones se puede usr l siguiente versin por omisinX Miembros pblicos de List_Graph 547b + (546a) 549c 549e Node * search_node(const Node_Type & node_info); l ul invo l operdor == de l lse Node_TypeF ytro tipo de squed onsiste en veri(r si lgn nodo prtiulr es o no prte del grfoX Miembros pblicos de List_Graph 547b + (546a) 549d 549f bool node_belong_to_graph(Node * node);

549d

549e

549f

node_belong_to_graph() retorn true si node es prte del grfoD y false de lo ontrrioF e vees se requiere usr un nodo on rterstis que no son prte de sus triutos tpios @lse Node::Node_Type o Node_InfoAF or ejemploD lgun informin inluid por derivin de Graph_NodeF uesto que no hy mner de onoer priori ests lses de irunstnisD l ni form que se nos ourre pr omunir informin sore l squed es on un puntero opoF es puesD nuestr ltim lse de squed se efet de l siguiente formX Miembros pblicos de List_Graph 547b + (546a) 549e 552b
template <class Equal> Node * search_node(void * ptr);

550

7. Grafos

l ulD usndo el riterio de iguldd bool Equal::operator() (Node * curr, void * ptr)D us un nodo on rterstis espei(ds en el puntdor ptrF
Iterador de nodos

550a

hdo un List_Graph hy un mner de reorrer todos sus nodosF List_Graph export l siguiente sulseX Iteradores de List_Graph 550a (546a) 550b
class Node_Iterator : public Dlink::Iterator { inline Node_Iterator() {} inline Node_Iterator(List_Graph & _g); inline Node_Iterator(const Node_Iterator & it); inline Node_Iterator & operator = (const Node_Iterator & it); inline Node * get_current_node(); Node * get_current() { return get_current_node(); }
List_Graph
546a.

r esoD

};
Uses

v operinget_current_node() retorn el nodo tul en donde se enuentr el iteE rdorF or rzones de omptiiliddD el mtodo trdiionl get_current() se sorerg pr que invoque get_current_node()F Node_Iterator reorre todos los nodos del grfo independientemente de sus reliones de onetividdF uesto que deriv de Dlink::IteratorD ls operiones de desplzE miento y uiin son ls mismsX next()D prev() y has_current()F il orden de visit de Node_Iterator dee onsiderrse indetermindoF v siguiente funin ejempli( el reorrido de todos los nodos del grfo y l impresinD pr d uno de ellosD del nmero de rosX
template <class GT> void recorrer(GT & g) { for (typename GT::Node_Iterator it(g); it.has_current(); it.next()) print("%d\n", g.get_num_arc(it.get_current_node()); }

Iterador de arcos de un nodo

550b

ixiste un lse de iterdor el ul reorre los ros dyentes de un nodoF osileE menteD este es el iterdor ms populr e importnteD pues es l se de ulquier reorrido de mputo sore un grfoF u espei(in es omo sigueX Iteradores de List_Graph 550a + (546a) 550a 555 class Node_Arc_Iterator : public Dlink::Iterator {
};

Miembros privados de iterador de Node 570b Miembros pblicos de iterador de Node 550c

550c

vs forms de delrr @onstruirA un ojeto Node_Arc_Iterator se expresn medinte los siguientes onstrutoresX Miembros pblicos de iterador de Node 550c (550b) 551a inline Node_Arc_Iterator();

7.3. Un TAD para grafos (List_Graph)

551

inline Node_Arc_Iterator(Node * _src_node); inline Node_Arc_Iterator(const Node_Arc_Iterator & it);

551a

snteresnte oservr que el ojeto soido un Node_Arc_Iterator es un nodo perteneiente un grfo y no el grfo mismoF Node_Arc_Iterator requiere el operdor de signinD de modo tl que se puedn opir estdos temporles de iterinF r eso requerimos el operdor =X Miembros pblicos de iterador de Node 550c + (550b) 550c 551b inline Node_Arc_Iterator & operator = (const Node_Arc_Iterator & it); uesto que Node_Arc_Iterator esD por derivinD del tipo Dlink::IteratorD ste ontiene todos sus mtodos soidos @next()D prev()D has_current()D etterAF il ojeto tul del iterdor se ede medinteX

551b

Miembros pblicos de iterador de Node 550c +


typedef Arc * Item_Type; typedef Node * Set_Type; inline Arc * get_current_arc(); Arc * get_current() { return get_current_arc(); } inline Node * get_tgt_node();

(550b)

551a 570c

get_current_arc() retorn el ro tul @de tipo ArcAD mientrs que get_tgt_node() retorn el nodo destino del ro tul @el nodo origen es el qul sore el ul se iterAF get_tgt_node() es muy til porque en este so s se distingue el nodo destinoD es deirD qul que est onetdo l extremo del ro tul del nodo origen sore el ul se est iterndoF imilr l iterdor sore nodosD el mtodo get_current() est sorergdo pr que invoque get_current_arc()F Node_Arc_Iterator es el prinipl menismo pr mnipulr grfos implntdos meE dinte lists enlzdsF is importnte destr que los ros de un nodo se visitn en un orden indetermindoD el ul dee onsiderrse letorio por ulquier pliin que hg uso de Node_Arc_IteratorF
7.3.4 Arcos

551c

n ro de un grfo se de(ne medinte el eh Graph_Arc omo sigueX Denicin de arco de grafo 551c template <typename Arc_Info> class Graph_Arc : public Dlink { typedef Graph_Arc Arc; typedef Arc_Info Arc_Type;

};

Atributos de Graph_Arc 557b Mtodos de Graph_Arc 552a

Graph_Arc modeliz un ro perteneiente un grfo implntdo medinte lists de dyeniF el igul que Graph_NodeD Graph_Arc es un lse prmetrizd uyo tipo soidoD Arc_InfoD onstituye l informin reliond l ro y l ul se ede

552

7. Grafos

medinteX
552a

Mtodos de Graph_Arc 552a


Arc<Carretera> * arco;

(551c) 566c

Arc_Info & get_info() { return arc_info; }

i se deseD por ejemploD un grfo de rretersD entones l siguiente lneX

552b

helr un puntdor un ro que us omo triuto un tipo CarreteraF n ro onet dos nodos llmdos origen y destino que pueden ederse de l siguiente mnerX Miembros pblicos de List_Graph 547b + (546a) 549f 552c inline Node * get_src_node(Arc * arc); inline Node * get_tgt_node(Arc * arc); is momento de lrr dos oss en relin los mtodos sore un roX IF in el so de un grfoD estos mtodos no neesrimente tienen sentido segn l direin del roY simplemente onformn un mner de onoer los nodos que ste onetF in el so de un digrfoD por supuestoD get_src_node() retorn el nodo dyente y get_tgt_node() el inidenteF PF ems primitivsD s omo l myor de ls de eso un roD son prte de l lse List_Graph y no de l lse Graph_ArcF isto impli que dee onoerse el grfo pr poder invor uno de estos mtodosF elgo que s tiene sentido es onoer ul es el nodo que onet un ro ddo un nodo origenF r eso se provee l siguiente primitivX Miembros pblicos de List_Graph 547b + (546a) 552b 552d inline Node * get_connected_node(Arc * arc, Node * node); v ul siempre retorn el nodo onetdo nodeD por el ro arcD independientemente de que se un grfo o digrfoF ysionlmente puede ser neesrio indgr si un nodo est o no reliondo on otro trvs de un roF r eso se proporion l primitiv siguienteX Miembros pblicos de List_Graph 547b + (546a) 552c 552e inline bool node_belong_to_arc(Arc * arc, Node * node) const; v ul retorn true si node est onetdo l ro arcF
7.3.4.1 Insercin de arcos

552c

552d

552e

r de(nir un ro en un grfo deen herse de(nido e insertdo en el grfo sus dos nodos medinte ls primitivs orrespondientes de(nids en UFQFQFI @gF SRVAF gon ls direiones de los nodos puede invorse l siguiente primitivX Miembros pblicos de List_Graph 547b + (546a) 552d 553a inline virtual Arc * insert_arc(Node * src_node, Node * tgt_node, const typename Arc::Arc_Type & arc_info);

7.3. Un TAD para grafos (List_Graph)

553

src_node y tgt_node son los nodos que relion el roF i se trt de un grfoD entones el orden entre los nodos no tiene importniF iD por el ontrrioD se trt de un digrfoD entones src_node es el nodo dyente y tgt_node el inidenteF arc_info es el vlor de triuto del ro on que se dese rerloF insert_arc() prt l memori requerid pr el roD onstruye el ro pr los vlores espei(dos por los prmetrosD lo insert en el grfo y retorn l direin de memori del nuevo roF i no hy su(iente memori se gener l exepin bad_allocF
7.3.4.2 Eliminacin de arcos

553a

r eliminr un ro slo se requiere onoer su direin y entones vlerse del mtodo siguienteX Miembros pblicos de List_Graph 547b + (546a) 552e 553b inline virtual void remove_arc(Arc * arc); el ul elimin del grfo el ro arc y lier l memoriF il mtodo no efet ningun veri(in de orretitudY por ejemploD l eliminin de un ro que no existe en el grfoF vos mtodos que ltern l topologD entindseD insert_node()D remove_node()D insert_arc() y remove_arc() son virtulesF isto es desele pr su reuso funionl por prte de extensiones o espeiliziones derivdsF n uso de ello es presentdo en UFIHFR @gF UISAF elgunos lgoritmos sore grfos requieren eliminr onjuntos de rosD her un lulo pril y luego resturrlosF in ests situiones es desele que l eliminin de ro se topolgiD de rter temporlD y no omplet omo se plnte on remove_arc()F r eso se provee l siguiente primitivX Miembros pblicos de List_Graph 547b + (546a) 553a 553c inline virtual void disconnect_arc(Arc * arc); n ro desonetdo medinte disconnect_arc() puede onetrse de nuevo trvs deX

553b

553c

Miembros pblicos de List_Graph 547b +

(546a)

553b 553d

inline virtual Arc * connect_arc(Arc * arc);


Acceso a los arcos de un grafo

7.3.4.3

553d

n mner primigeni de otener un ro ulquier de un grfo l onform el mtodoX Miembros pblicos de List_Graph 547b + (546a) 553c 553e inline Arc * get_first_arc(); el ul retorn un ro ulquier del grfoF xo deen herse suposiiones er de ul ro ser retorndoF in emrgoD los ros dentro del grfo pueden ordenrse medinteX Miembros pblicos de List_Graph 547b + (546a) 553d 554a template <class Compare> inline void sort_arcs();

553e

sort_arcs<Compare>() orden los ros segn el riterio de omprin CompareD el ul invo l operdor bool Compare::operator () (Arc * a1, Arc * 2)F il progrmdor es responsle de implntr el eso l triuto del ro por el ul se ompr y de l omprin mismF il ordenmiento se efet en O(n lg(n)) on onsumo de espio O(1)F

554

7. Grafos

554a

il nmero de ros de un grfo puede onoerse medinteX Miembros pblicos de List_Graph 547b + (546a) inline const size_t & get_num_arcs() const; el nmero de ros que tiene un nodoD medinte Miembros pblicos de List_Graph 547b + (546a) inline const size_t & get_num_arcs(Node * node) const;
Bsqueda de arcos

553e 554b

554b

554a 554c

r los ros existen utro tipos de squedD los ules se enunin ontinuinX IF fsqued por triuto Arc::Arc_Type o Arc_Info7 X en este so podemos usrX
554c

Miembros pblicos de List_Graph 547b +

(546a)

554b 554d

template <typename T, class Equal> Arc * search_Arc(const T & data);

v primer versin us el riterio de omprin EqualD lo ul permite disernir lgun prte de los triutos en l squedF v segund versin invo diretmente l operdor bool Node_Type::operator == (const Node_Type & info)F PF rue de perteneni relizd porX
554d

Miembros pblicos de List_Graph 547b +


bool arc_belong_to_graph(Arc * arc);

(546a)

554c 554f

e retorn true si un ro on direin arc pertenee l grfoD y false de lo ontrrioF QF ixisteni de un ro entre dos nodosX pr ello se us l siguiente funinX
554e

Funciones de List_Graph 554e

560b

template <class GT, class SA> typename GT::Arc * search_arc(GT & g, typename GT::Node * src_node, typename GT::Node * tgt_node);

il ul retorn l direin de un ro en so de existir lguno entre los nodos src_node y tgt_nodeF e difereni de sus rutins predeesorsD que son mtodos de List_GraphD est verE sin es un funin extern l lseF isto permite espeilizr versiones prtiulres de search_arc() que disiernn los ros segn lgn riterioF v primitiv funion pr digrfosF in so de trtrse de un multigrfo @o multidigrfoA y her ms de un ro entre los nodos involurdosD se retorn ulquier entre los redundntes sin onsiderin de lgn riterio espe(oF RF fsqued espeilizdX este es el so undo en l squed se dese distinguir lgn dto que no es prte de los triutos del ro @Arc_TypeAF
554f

Miembros pblicos de List_Graph 547b +


7
Recordemos que son sinnimos.

(546a)

554d 557c

template <class Equal> Arc * search_arc(void * ptr);

7.3. Un TAD para grafos (List_Graph)

555

v rutin retorn l direin del ro que stisfe iguldd dd por bool Equal::operator () (Arc * arc, void *ptr)D o NULL en so de que se hyn reorrido todos los ros sin stisfer el riterio de igulddF ods ls squeds son O(E) pr el peor so @squed fllidAF
Iterador sobre los arcos de un grafo
555

vos ros de un grfo pueden oservrse medinte el siguiente iterdorX Iteradores de List_Graph 550a + (546a) 550b class Arc_Iterator : public Dlink::Iterator { Arc_Iterator() {} Arc_Iterator(List_Graph & _g); Arc_Iterator(const Arc_Iterator & it); Arc_Iterator & operator = (const Arc_Iterator & it);
Arc * get_current_arc(); Arc * get_current() { return get_current_arc(); } Node * get_src_node() { return (Node*) get_current_arc()->src_node; } Node * get_tgt_node() { return (Node*) get_current_arc()->tgt_node; }
List_Graph
546a.

};
Uses

el igul que on los iterdores de este textoD Arc_Iterator ontiene ls funiones tpiE s next()D prev() y has_current() @por derivin de Dlink::IteratorAF v otenin del ro de visit tul se llev o medinte get_current_arc()F i los ros no hn sido ordendosD entones el orden de visit es indetermindoY de lo ontrrioD el iterdor visitr los ros segn el orden estleido en l ltim invoin sort_arcs()F
7.3.5 Atributos de control de nodos y arcos

in muhos sosD los lgoritmos sore grfos requieren mntener un estdo de lulo en sus nodos y rosF uiz el so ms omn se mrr o pintr omo visitdo un nodo o un roF in este diseo ontemplmos tres mners de llevr estdoD tnto en los nodos omo en los rosX its de ontrolD ontdores y ookiesF gd lse de estdo se gurd diretmente en el nodo o en el roF
7.3.5.1 Bits de control

e efetos de pintr nodos y ros slo se requiere de un itF odrmos mntener un it por d nodo y ro en un vlor ero yD l proesrlo segn el inters del lgoritmoD pintrlo on unoF il prolem de est tni es que los lgoritmos que usen el it devienen noEreentrntesF or ejemploD un prue de onetividd puede inspeionr los nodos trvs de los ros y pintrlos medid que los visitF il grfo ser onexo si se visitn todos los nodosD es deirD si l (nl de l iterin estn todos los nodos pintdosF ehor ienD otro lgoritmo que invoque prues de onetividd no puede usr el mismo

556

7. Grafos

556a

it usdo por l prue de onetividd pr pintr sus nodosD pues omprometer l onsisteni del test de onetividdF r trtr on l situin nterior usremos vrios its lsi(dos segn el lgoritmo que los utilieF stos se espei(n omo sigueX Denicin de Bits de control 556a
class Bit_Fields { unsigned int depth_first : 1; // .. declaacin de los siguientes bits };

Nmero de bit 556d

Mtodos bits control 556b


used in chunk 557.

Denes:

Bit_Fields,

556b

Bit_Fields es un triuto que mnej omo mnimo 16 its destindos llevr estdo de visitF gulquier it de ontrol puede onsultrse medinteX Mtodos bits control 556b (556a) 556c
bool get_bit(const int & bit) const { switch (bit) { case Aleph::Depth_First: return depth_first; // ... } }

556c

es omo tminD eventulmenteD puede modi(rse trvs deX Mtodos bits control 556b + (556a) void set_bit(const int & bit, const int & value) { switch (bit) { case Aleph::Depth_First: depth_first = value; break; // ... } }

556b

556d

vos its de ontrol estn enumerdos mgimente 8 segn su (n pretendido por otros lgoritmosX Nmero de bit 556d (556a) enum Graph_Bits { Depth_First, Breadth_First, // ... };
8
En la jerga de programacin, un nmero mgico es uno que es nombrado con un identicador.

7.3. Un TAD para grafos (List_Graph)

557

or ejemploD el lgoritmo de prue de ilo invorX


control_bits.set_bit(Test_Cycle, 1);

557a

efetos de pintr un visitF gd nodo y ro de un grfo ontiene its de ontrol espei(dos omo sigueX Miembros de Graph_Node 548a + (547c) 548b 558a Bit_Fields control_bits;
Uses

Bit_Fields

556a. (551c) 558b

557b

Atributos de Graph_Arc 557b


Bit_Fields control_bits;
Bit_Fields
556a. Uses

557c

in un nodo los its de ontrol pueden ederse medinteX Miembros pblicos de List_Graph 547b + (546a) inline Bit_Fields & get_control_bits(Node * node);
Uses

554f 557d

Bit_Fields

556a.

557d

min pueden olorse todos los its en ero medinteX Miembros pblicos de List_Graph 547b + (546a) inline void reset_bit(Node * node, const int & bit);

557c 557e

557e

y signrse un it en prtiulr trvs deX Miembros pblicos de List_Graph 547b + (546a) 557d 557f inline void set_bit(Node * node, const int & bit, const int & value); enlogmenteD existen ls misms operiones pr un roX Miembros pblicos de List_Graph 547b + (546a) inline Bit_Fields & get_control_bits(Arc * arc);
inline void reset_bit(Arc * arc, const int & bit); inline void set_bit(Arc * arc, const int & bit, const int & value);
Uses 557e 557g

557f

Bit_Fields

556a.

557g

e pueden reiniir los its de ontrol de todos los nodos o ros de un grfo medinteX Miembros pblicos de List_Graph 547b + (546a) 557f 558c void reset_bit_nodes(const int & bit) { for (Node_Iterator itor(*this); itor.has_current(); itor.next()) reset_bit(itor.get_current_node(), bit); } void reset_bit_arcs(const int & bit) { for (Arc_Iterator itor(*this); itor.has_current(); itor.next()) reset_bit(itor.get_current_arc(), bit); } vos ules olon en eroD se pr los nodos o rosD l itEsimo bit de ontrolF

558

7. Grafos

7.3.5.2

Contadores

558a

il segundo nivel en mnejo de estdo pr un nodo o ro es un ontdor enteroF or lo generlD ste se us pr determinr l ntidd de visits o pr mrr oloresF u de(niin pr un nodo es omo sigueX Miembros de Graph_Node 548a + (547c) 557a 559a long counter; y pr un roX Atributos de Graph_Arc long counter;
557b

558b

(551c)

557b 559b

558c

il ontdor puede ederse o reiniirse @olorse en eroA pr los nodosX Miembros pblicos de List_Graph 547b + (546a) 557g 558d inline long & get_counter(Node * node); inline void reset_counter(Node * node); y pr los rosX

558d

Miembros pblicos de List_Graph 547b +

(546a)

558c 558e

inline long & get_counter(Arc * arc); inline void reset_counter(Arc * arc);

558e

sgulmente podemos reiniir los ontdores @olorlos en eroA de todos los nodos o rosX Miembros pblicos de List_Graph 547b + (546a) 558d 559c void reset_counter_nodes() { for (Node_Iterator itor(*this); itor.has_current(); itor.next()) reset_counter(itor.get_current_node()); } void reset_counter_arcs() { for (Arc_Iterator itor(*this); itor.has_current(); itor.next()) reset_counter(itor.get_current_arc()); }
7.3.5.3 Cookies

ixisten muhos lgoritmos que requieren soir estdo de lulo de un mner muy prtiulr l tipo de lgoritmo y pr los ules los its de ontrol y ontdores no son suE (ientesF v squed del mino ms orto segn hijkstrD por ejemploD neesit gurdr iert informin temporl en los rosF v form y uso de este estdo es prtiulr l lgoritmo de hijkstr y posilemente no sirve pr otros lgoritmosF equerimos entones de un form ms mpli de soir estdo genrioF uesto que en muhs osionesD el estdo es temporlD es deirD slo se requiere durnte l ejeuin del lgoritmoD no es onveniente prmetrizrlo en un plntill que se le pse l nodo o ro undo stos se instnienF n form genriD pero delidD pr soir genrimente dtos los nodos es trvs de un cookie F il trmino ookie proviene de l progrmin de sistems y onnot un prmetro opo que se le trsmite un funinF in nuestro soD un ookie es un puntero opo que se soi un nodo o un roF

7.3. Un TAD para grafos (List_Graph)

559

559a

es puesD los nodos y los ros poseen un triuto cookieD uy espei(in es l siguienteX Miembros de Graph_Node 548a + (547c) 558a 567b void * cookie;

559b

Atributos de Graph_Arc 557b +


void * cookie;

(551c)

558b 566a

559c

vos ookies pueden ederse medinte ls siguientes primitivsX Miembros pblicos de List_Graph 547b + (546a) 558e inline void *& get_cookie(Node * node); inline void *& get_cookie(Arc * arc);

559d

559d

get_cookie() retorn un refereni on privilegios ompletosF vos ookies de todos los nodos o ros pueden reiniirse medinteX Miembros pblicos de List_Graph 547b + (546a) 559c 559f

void reset_cookie_nodes() { for (Node_Iterator itor(*this); itor.has_current(); itor.next()) itor.get_current_node()->cookie = NULL; } void reset_cookie_arcs() { for (Arc_Iterator itor(*this); itor.has_current(); itor.next()) itor.get_current_arc()->cookie = NULL; }

upongmos por ejemplo que neesitmos gurdr en d nodo un list dinmi de vlores relesF i tenemos un puntdor un nodoD llmdo nodeD entonesD un form de herlo es omo sigueX
node->get_cookie() = new DynDlist<float>;

gundo el usurio requier eder l listD puede herlo medinte un stingX


static_cast<DynDlist<float>*>(node->get_cookie()) ...

or supuestoD no dee olvidrse de entregr memori l sistem undo st y no se requierF l in se efet omo sigueX
delete static_cast<DynDlist<float>*>(node->get_cookie())

559e

i el usurio requiere un estdo estruturdoD entones ste utiliz un estruturD struct o classD segn se el soF e vees es neesrio gurdr lgun informin soid l grfoD no los nodos o rosY por ejemploD lgn nodo o ro entinel de vlor temporlF r estos sos disponemos de un ookie en el grfoX Miembros privados de List_Graph 559e (546a) 561b void * cookie;

559f

Miembros pblicos de List_Graph 547b +

(546a)

559d 560a

void *& get_cookie() { return cookie; }

560

7. Grafos

Mapeo entre nodos y arcos

560a

n uso importnte del cookie es implntr el mpeo entre grfos homomorfos o isoE morfosF in iertos lgoritmosD por ejemploD el lulo del rol rdorD se dee lE ulr un grfo diionl orrespondiente l rol rdorF r identi(r dentro del rol rdor ul es su nodo en el grfo originlD el cookie lmen l imgen del nodo dentro del rol y vieversF e este tipo de lgoritmos les puede ser muy til ls siguientes primitivs Miembros pblicos de List_Graph 547b + (546a) 559f 561a template <class N1, class N2> static void map_nodes(N1 * p, N2 * q);
template <class A1, class A2> static void map_arcs(A1 * p, A2 * q);

map_nodes() mpe entre s los nodos p y q respetivmenteF i y existe un mpeo previoD o seD si p->get_cookie() ontiene un direinD entones map_nodes() he un mpeo ompuestoF or ejemploD supongmos que p y q estn mpedos entre s y que relizmos l siguiente llmdX
map_nodes(q, t);

560b

intonesD el mpeo resultnte se puede interpretr omo p q t pF il mpeo entre ros efetudo medinte map_arcs() tiene semnti similr l de los nodosF uesto que los ookies no tienen tipoD undo se mnejn mpeos trvs de ellos hy que her onversiones engorrossF r filitr tles onversiones se plnten dos primitivs que sumen que sore el ookie existe un mpeoX Funciones de List_Graph 554e + 554e 562e template <class GT> typename GT::Node * mapped_node(typename GT::Node * p) { return (typename GT::Node *) NODE_COOKIE(p); } template <class GT> typename GT::Arc * mapped_arc(typename GT::Arc * a) { return (typename GT::Arc *) ARC_COOKIE(a); }
Denes:

mapped_node,
and 791.

used in chunks 605, 607, 612, 626b, 628, 638b, 646c, 663, 683b, 701, 704, 781b, 787, 790,

vs primitivs de mpeo permiten mntener dens de mpeos y son un mner de simpli(r muhos lgoritmosF v situin ms omn te ls lses de lgoritmos que modi(n el grfo pr efetur sus lulosD lo ul rre prdid del grfo originlF r evitr eso hemos un opi on mpeo y opermos sore l opiF vos ookies del grfo opi mntienen l imgen del grfo originlF or supuestoD esto tmin requiere que se mpeen los rosD lo ul se he de mner similr los nodosF il uso de los ookiesD unque stnte )exileD es muy delido porque no estn sometidos l sistem de tipos del ompildorF or es rzn es ltmente reomendle segurrse de que los ookies se edn medinte funiones que efeten l onversin de tipoF

7.3. Un TAD para grafos (List_Graph)

561

7.3.5.4

Reinicio de nodos y arcos

561a

odos los triutos de ontrol de un nodo o de un roD es deirD los itsD el ontdor y el ookie pueden reiniirse ompletmente medinteX Miembros pblicos de List_Graph 547b + (546a) 560a 561c inline void reset_node(Node * node); inline void reset_arc(Arc * arc); min pueden reiniirse todos los triutos de ontrol de todos los nodos o ros del grfoF in este sentido podemos ilustrr un uso onreto de ls lses Operate_On_Nodes()() y Operate_On_Arcs()()F fsimenteD lo que desemos es reorrer d nodo e invor reset() pr d triuto de ontrolF ist tividd se puede espei(r medinte l siguiente lse operE inX Miembros privados de List_Graph 559e + (546a) 559e 564a struct Reset_Node { void operator () (List_Graph&, Node * node) const { node->control_bits.reset(); node->counter = 0; node->cookie = NULL; } };
Uses

561b

List_Graph

546a.

561c

ehor esriimos simplemente l reiniiin de los nodos medinte invoin operate_on_nodes() on Reset_Node omo operinX Miembros pblicos de List_Graph 547b + (546a) 561a 562a void reset_nodes() { Operate_On_Nodes <Graph_Class, Reset_Node> () (*this); } enlogmenteD l mism tni se pli pr reiniir los rosF is tpioD ntes de her un lulo que involure los triutos de ontrolD tnto de noE dos omo de rosD invor reset_nodes() y reset_arcs() pr limpirlos de vlores utilizdos por lulos previosF
7.3.6 Macros de acceso a nodos y arcos

561d

e efetos de filitr l legiilidd de digoD unque en detrimento del dignstio sinE ttio del ompildorD l implntin de List_Graph y lgunos lgoritmos usn los siguientes mrosX Macros para grafos 561d # define NODE_BITS(p) ((p)->control_bits) # define NODE_COUNTER(p) ((p)->counter) # define IS_NODE_VISITED(p, bit) (NODE_BITS(p).get_bit(bit)) # define NODE_COOKIE(p) ((p)->cookie) # define ARC_COUNTER(p) ((p)->counter) # define ARC_BITS(p) ((p)->control_bits)

562

7. Grafos

# define IS_ARC_VISITED(p, bit) (ARC_BITS(p).get_bit(bit)) # define ARC_COOKIE(p) ((p)->cookie)


7.3.7 Construccin y destruccin de

List_Graph

562a

fsimenteD un grfo puede onstruirse por omisin o por opi desde otro grfoX Miembros pblicos de List_Graph 547b + (546a) 561c 562b inline List_Graph(); inline List_Graph(const List_Graph & g);
Uses

List_Graph

546a.

562b

il primer onstrutor re un grfo vo @sin nodos y rosAD el segundo un opi de grfo gF is posile signr un grfo otro grfoX Miembros pblicos de List_Graph 547b + (546a) 562a 562c inline List_Graph& operator = (List_Graph & g);
Uses

List_Graph

546a.

562c

in este soD el grfo destino se destruye ompletmente y se opi el fuente gF il destrutorX Miembros pblicos de List_Graph 547b + (546a) 562b 562d inline virtual ~List_Graph();
Uses

List_Graph

546a.

562d

elimin del grfo todos los nodos y ros que ste ontieneF od l memori es lierdF e puede onstruir un grfo prtir de un digrfoD s omo tmin signr un grfo un digrfoF in ese soD los ros dirigidos son sustituidos por ros idireionlesX Miembros pblicos de List_Graph 547b + (546a) 562c inline List_Graph(List_Digraph<Node, Arc> & g);
inline List_Graph & operator = (List_Digraph<Node, Arc> & g);
Uses

List_Digraph

547a and

List_Graph

546a.

562e

in osiones no tn exepionles se requiereD dems de l opi del grfoD un mpeo isomorfo entre ls opisF in est situin espeil puede usrse l siguiente funinX Funciones de List_Graph 554e + 560b 563a template <class GT> void copy_graph(GT & gtgt, GT & gsrc, const bool cookie_map = false); el ulD en so de que el prmetro cookie_map se iertoD he un mpeo iyetivo entre los dos grfos trvs de los ookies de sus nodos y rosF el (nl de l opiD el puntero cookie de d nodo ontendr l imgen en el grfo opiY igul se pli pr los rosF v opi mped es un funin extern l lseD es deirD no es un mtodo de List_GraphF v rzn es que es imposile onoer el tipo (nl de los nodos y ros de un lse sd en List_GraphF el herl extern l lse se est en posiin de onoer los tipos en uestin y de her ls opis deudsF gonsiguientementeD no es reomendle que l opi de grfos suyz en el onstrutor opi o el operdor de signinF v opi mped es muy til pr llevr efeto muhos lgoritmosF or ejemploD pr lulr el omplemento de un grfo podemosD en primer lugrD opir el grfoD luegoD insertmos sore l opi los ros neesrios pr volverlo ompletmente onexo yD (nlmenteD eliminmos de l opi quellos ros que hyn sido mpedosF

7.3. Un TAD para grafos (List_Graph)

563

563a

xo tods ls vees es onveniente mper ls opis medinte los ookiesF v generliE dd del so l represent tod situin en l ul el grfo opir y onteng dtos en los ookiesF ist es l rzn por l ul el mpeo entre los ookies es opionl l opiF is posile orrr explitmente un grfoD es deirD eliminr todos sus nodos @y rosAF r ello se us el siguiente mtodoX Funciones de List_Graph 554e + 562e 563b template <class GT> inline void clear_graph(GT & g); ist primitiv es muy vlios undo se usn grfos temporles orrespondientes lulos intermediosF
7.3.8 Operaciones genricas sobre nodos

563b

in osiones se requiere her un operin espe( sore todos los nodosY por ejemploD poner lgn vlor iniil de triutoF r tles efetos se proveen ls siguientes rutinsD ls ulesD por su senillezD se implntn diretmenteX Funciones de List_Graph 554e + 563a 563c template <class GT, class Operation, class SN = Default_Show_Node<GT> > class Operate_On_Nodes { void operator () (GT & g, Operation op = Operation()) const { for (Node_Iterator<GT,SN> it(g); it.has_current(); it.next()) op (g, it.get_current_node()); } void operator () (GT & g, void * ptr, Operation op = Operation()) const { for (Node_Iterator<GT,SN> it(g); it.has_current(); it.next()) op (g, it.get_current_node(), ptr); } }; gomo se veD sends lses reorren d nodo del grfo g de tipo genrio GT y efetn l operin Operation() () sore d nodoF v segund versin permite psr prmetros trvs del puntero ptrF
7.3.9 Operaciones genricas sobre arcos

563c

el igul que pr los nodosD es posile efetur operiones genris sore todos los nodos del grfoF r eso se proveeD por ejemploD l siguiente operinX Funciones de List_Graph 554e + 563b template <class GT, class Operation, class SA = Default_Show_Arc<GT> > class Operate_On_Arcs { void operator () (GT & g, Operation op = Operation()) const { for (Arc_Iterator<GT,SA> it(g); it.has_current(); it.next()) op (g, it.get_current_arc()); } void operator () (GT & g, typename GT::Node * p,

564

7. Grafos

{ }

Operation op = Operation()) const for (Node_Arc_Iterator<GT,SA> it(p); it.has_current(); it.next()) op (g, it.get_current_arc());

};

v semnti es similr l de los nodos @ver UFQFV @gF STQAAF v segund operin slo se irunsrie los ros dyentes un nodoF
7.3.10 Implantacin de

List_Graph

564a

List_Graph mnej dos lists irulres dolemente enlzdsX un de sus nodos y otr de sus rosF gd list soi un ontdor de sus elementosX Miembros privados de List_Graph 559e + (546a) 561b 564b
Dlink size_t Dlink size_t node_list; num_nodes; arc_list; num_arcs; // // // // lista de cantidad lista de cantidad nodos de nodos arcos de arcos

564b

num_nodes y num_arcs ontilizn ls ntiddes totles de nodos y ros del grfoF istos triutos se tulizn en l primitivs de inserin y elimininF node_list y arc_list son ls eersD de tipo DlinkD de ls lists de nodos y rosD respetivmenteD que ontiene el grfoF eordemos que ls lses Graph_Node y Graph_Arc derivn de DlinkF v se DlinkD puesD onform en d lse el enle dole de l lists node_list y arc_listF gomo node_list y arc_list sonD por derivinD de tipo DlinkD plntemos ls siE guientes funiones de onversin de Dlink Graph_Node y Graph_ArcX Miembros privados de List_Graph 559e + (546a) 564a 564c
static Node * dlink_to_node(Dlink * p) { return (Node*) p; } static Arc * dlink_to_arc(Dlink * p) { return (Arc*) p; }
Acceso a nodos y arcos

7.3.10.1

564c 564d

gon ests onversiones y podemos odi(r legilemente los mtodos sios de eso nodos y rosX Miembros privados de List_Graph 559e + (546a) 564b 568a

Implantacin de List_Graph 564d

565a

template <typename Node, typename Arc> Node * List_Graph<Node, Arc>::get_first_node() { return dlink_to_node(node_list.get_next()); } template <typename Node, typename Arc> Arc * List_Graph<Node, Arc>::get_first_arc() { return dlink_to_arc(arc_list.get_next()); }
List_Graph
546a.

Uses

7.3. Un TAD para grafos (List_Graph)

565

nto l squed de nodos omo l de ros requieren iterr sore l orrespondiente list @node_list o arc_listD segn se el soAF or es rzn nos onviene implementr estos iterdores efetos de que ls squeds se efeten medinte ellosF
Iterador de nodos

v lse Node_Iterador se implnt diretmente por derivin pli de Dlink::IteratorF


Iterador de arcos

v mism onsiderin que pr el iterdor sore los nodos pli sore el iterdor sore los rosD pues stos tmin se fundmentn en DlinkF
Bsqueda de nodos

565a

vos diferentes estilos de squed de nodos y ros se instrumentn trvs de lgunos de los dos iterdores presentdos en ls seiones previsF v implementin de un de ls primitivs ilustr el esquem generlX Implantacin de List_Graph 564d + 564d 565b template <typename Node, typename Arc> template <typename T, class Equal> Node * List_Graph<Node, Arc>::search_node(const T & data) { for (Node_Iterator it(*this); it.has_current(); it.next()) { Node * p = it.get_current_node(); if (Equal () (p->get_info(), data)) return p; } return NULL; }
Uses

List_Graph

546a.

e l exepin de l espeilizin por omisinD d rutin se fundment en el iterdor sore nodos del grfo Node_IteratorF
Bsqueda de arcos

565b

v squed de un ro dentro del grfo es reminisente l de un nodoX reorrer medinte el iterdor de ros hst stisfer l squed o herlos reorrido entermenteD en uyo soD l squed es fllidF v implementin es omo sigueX Implantacin de List_Graph 564d + 565a 566b template <typename Node, typename Arc> template <typename T, class Equal> Arc * List_Graph<Node, Arc>::search_Arc(const T & data) { for (Arc_Iterator it(*this); it.has_current(); it.next()) { Arc * a = it.get_current_arc(); if (Equal () (a->get_info(), data)) return a; }

566

7. Grafos

}
Uses

return NULL;
List_Graph
546a.

ws delnteD undo de(nmos el iterdor de ros sore un nodo implementremos l squed de un ro que onete dos nodosF
7.3.10.2 Arcos

566a

n ro onet dos nodos llmdos origen y destinoD delrdos de l siguiente mnerX Atributos de Graph_Arc 557b + (551c) 559b 569 void * src_node; // nodo origen void * tgt_node; // nodo destino istos triutos son de tipo void* porque desde un Graph_Arc no se puede onoer el tipo exto de Graph_NodeY ste se onoer undo se instnie el grfoF v implntin del eso estos triutos se he desde l lse List_Graph de l siguiente mnerX Implantacin de List_Graph 564d + 565b 566d template <typename Node, typename Arc> Node * List_Graph<Node, Arc>::get_src_node(Arc * arc) { return (Node*) arc->src_node; } template <typename Node, typename Arc> Node * List_Graph<Node, Arc>::get_tgt_node(Arc * arc) { return (Node*) arc->tgt_node; }
Uses

566b

List_Graph

546a.

566c

r l implntin de get_connected_node() disemos un rutin homnimD prte de Graph_ArcD que nos sirv de intermediriX Mtodos de Graph_Arc 552a + (551c) 552a void * get_connected_node(void * node) { return src_node == node ? tgt_node : src_node; } D medinte ellD llevr o el mtodo de List_GraphX Implantacin de List_Graph 564d + 566b 571b template <typename Node, typename Arc> Node * List_Graph<Node, Arc>::get_connected_node(Arc * arc, Node * node) { return (Node*) arc->get_connected_node(node); }
Uses

566d

List_Graph

546a.

Listas de adyacencia

gomo y h sido deidido y es sidoD l representin en memori de List_Graph se s en lists de dyeniF eprte de un myor onsumo de espio pr grfos muy densosD un prolem de este enfoque es l redundni de nodos en l lists de dyeniF

7.3. Un TAD para grafos (List_Graph)

567

567a

isto esD por d ro u v se requiere un nodo en l list de dyeni de uD y de otro en l list de vF ist redundni exige eder ls dos lists de dyeni d vez que de lgun form se requier modi(r un roF r evdir el prolem de ohereni nteriorD y por myor e(ieni en rpiE dezD diseremos un estrutur de dtos espeilizd uy de(niin omienz por el tipo Arc_NodeX Denicin de Arco-Nodo 567a struct Arc_Node : public Dlink { void * arc; Arc_Node() : arc(NULL) {} Arc_Node(void * __arc) : arc(__arc) {} };
Denes:

Arc_Node,

used in chunks 56870 and 57274.

Arc_Node deriv de DlinkD por lo que ste es prte de un list dolemente enlzdF il mpo arc es un puntero un Graph_Arc @o fmilir de l por derivinAF itrimenteD un Arc_Node se represent en memori de l mner ilustrd en l (gur UFISF
Dlink void* enlace del Arc_Node en la lista arc_list de un nodo Puntero hacia el arco

pigur UFISX epresentin en memori de un ojeto Arc_Node

counter num_arcs=2 counter control_bits cookie

counter num_arcs=2 counter control_bits cookie

B
counter num_arcs=2 counter control_bits cookie

Nodos

(a) Grafo de tres nodos sin arcos

(b)

Representacin

en

memoria

pigur UFITX n grfo simple y el estdo de su estrutur de dtos vos ojetos del tipo Arc_Node son los omponentes de l list de dyeni de d nodoF he este modoD l list de dyeni de un nodo se de(ne omo sigueX Miembros de Graph_Node 548a + (547c) 559a Dlink arc_list;

567b

568

7. Grafos

esD un nodo se represent en memori del modo ilustrdo en l (gur UFIUF


Dlink arc_list (contiene Arc_Node) num_arcs counter Dlink control_bits Node_Info cookie Enlace del nodo en la lista de nodos del grafo counter

pigur UFIUX epresentin en memori de un nodo r un grfo de tres nodosD sin rosD el estdo de l estrutur de dtos es el orresE pondiente l de l (gur UFITD es deirDtres nodos enlzdos trvs de node_list en l lse List_GraphF uesto que no hy rosD ls lists de dyeni de d nodo estn vsF in sntesisD mnejmos tres tipos de lists irulres dolemente enlzdsX @IA l list de todos los nodos del grfoD @PA l list de todos los ros del grfoD y @QA l list por nodo de sus rosF les lists son edids medinte l lse DlinkF or es rzn plnteremos funiones de onversin desde enles de tipo Dlink hi el nodoF gomenemos on l list de dyeni de un nodoD l ul es de tipo DlinkD pero sus nodos9 de tipo Arc_NodeX Miembros privados de List_Graph 559e + (546a) 564c 568b static Arc_Node * dlink_to_arc_node(Dlink * p) { return (Arc_Node*) p; }
Uses

568a

Arc_Node

567a.

i tenemosD por ejemploD un puntero un ojeto NodeD podemos eder l primero de sus ros en su list de Arc_NodeX
Arc_Node * p = dlink_to_arc_node(node->arc_list.get_next());

il ul dee trnsformrse un ojeto de tipo Arc medinteX


Arc * arc = static_cast<Arc*>(p->arc);

568b

pues p->arc es de tipo void*F r endulzr un poo est onversin esriimos l siguiente primitivX Miembros privados de List_Graph 559e + (546a) 568a 570a static Arc * void_to_arc(Arc_Node * arc_node) { return (Arc*) arc_node->arc; }
Uses

Arc_Node

567a.

eordemos que un nodo tiene un list arc_list de elementos de tipo Arc_Node enlzdos medintes punteros doles DlinkF e su vezD un Arc_Node tiene un puntero un ro de tipo Graph_ArcF ist on(gurin nos permitir un inserin O(1) l vez que no se redundr el roF eroD s ls ossD l eliminin de un ro todv requiere reorrer l list de ros del nodo destino pr enontrr su Arc_Node y eliminrloF or est rzn uiremos en Graph_Arc dos punteros l Arc_NodeD uno l del nodo origen y otro l del nodo destinoF il Graph_Arc tendr entones l representin en memori mostrd en l (gur UFIVF
9
Tngase cuidado con la ambigedad. En esta frase nos referimos a los nodos de una lista enlazada y no a los de un grafo.

7.3. Un TAD para grafos (List_Graph)

569

src_arc_node counter control_bits cookie

Dlink enlace en la lista de arcos del grafo

Arc_Info

tgt_arc_node

pigur UFIVX epresentin en memori de un ro vo que ondue ls siguientes delriones pr un roX Atributos de Graph_Arc 557b + (551c) 566a Arc_Node * src_arc_node; // puntero al Arc_Node del nodo fuente Arc_Node * tgt_arc_node; // puntero al Arc_Node del nodo destino
Uses

569

Arc_Node

567a.

y uy on(gurin nos permite resolver dos prolemsX IF el momento de eliminr un ro en un grfoD requerimos eliminr el Arc_Node de ls lists del nodo origen y destino respetivmenteF isto se logr en O(1) medinte el eso los mpos src_arc_node y tgt_arc_nodeF PF gundo se trte de un digrfoD el nodo destino del ro no ontiene un Arc_Node que punte l roF hel mismo modoD el mpo tgt_arc_node se mntiene en NULLF

counter num_arcs=2 counter

A
counter control_bits cookie

control_bits cookie

1
counter num_arcs=2 counter control_bits cookie

B
counter num_arcs=2 counter control_bits cookie

C
Nodos

(a) Grafo de tres nodos con un arco

(b) Representacin en memoria

pigur UFIWX n grfo simple y el estdo de su estrutur de dtos i l grfo de l (gur UFIWE le insertmos un ro desde el nodo A hi el BD entones el estdo de l estrutur de dtos depr en el de l (gur UFIWEF gomo se veD unque hy un solo roD existen dos ojetos de tipo Arc_Node reliondo on lF in este estdo es simple preir el sentido de l estrutur de dtosD sore todo l momento de eliminr un roF upongmos que desemos eliminr el nio ro del grfo UFIWEF e trvs de su direin tenemos eso direto los ojetos Arc_Node de ls lists de dyeni de A y BF uesto que d ojeto Arc_Node est dolemente enlzdoD l eliminin de l list de dyeni de d nodo es diretF

570

7. Grafos

counter num_arcs=2 counter control_bits cookie

A
counter control_bits cookie

counter num_arcs=2 counter

B
Arc_Nodes
counter control_bits cookie

control_bits cookie

B
counter num_arcs=2 counter control_bits cookie

counter control_bits cookie

2
C

3
Arcos Nodos

pigur UFPHX n grfo simple y el estdo de su estrutur de dtos v list de ros de todo el grfoD mnejd trvs del triuto arc_list de List_GraphD se muestr mejor en l (gur UFPHF equ tmin se evideni l ompleE jidd de l estrutur de dtosF List_Digraph hered tod l interfz de List_Graph y si tod su implntinF in lguns operiones requeriremos determinr si se trt de un grfo o un digrfoF r eso utilizremos un nder lgiX Miembros privados de List_Graph 559e + (546a) 568b bool digraph; il vlor de digraph es true si se trt de un digrfoY false de lo ontrrioF
Iterador de arcos sobre un nodo

570a

gomo y se dijoD un iterdor de ros prtir de un nodo se implement prtir de Dlink::IteratorD pues Arc_Node es por derivin de tipo DlinkF eprte de gurdr el grfo y el nodo desde el ul se iterD Node_Arc_Iterator mntiene l funin que determin ul ro mostrrX
570b

Miembros privados de iterador de Node 570b


Node * src_node;

(550b)

uesto que Node_Arc_Iterator es por derivin de tipo Dlink::IteratorD ste tiene todos los mtodos soidos @next()D prev()D has_current()D etterAF il mtodo Dlink::Iterator::get_current() no puede usrse diretmente porque ste retorn un Dlink y neesitmos onoer en prinipio el Arc_NodeF or tntoD disemos est onverE sinX
570c

Miembros pblicos de iterador de Node 550c +

(550b)

551b

Arc_Node * get_current_arc_node() { return dlink_to_arc_node(Dlink::Iterator::get_current()); }


Arc_Node
567a.

Uses

7.3. Un TAD para grafos (List_Graph)

571

Bsqueda de un arco dados dos nodos

gon el iterdor de ros sore un nodo podemos implntr filmente l squed de un ro que onete dos nodosF v ide es tomr uno de los nodosD preferilemente el que onteng menos rosD y desde ll reorrer sus ros hst enontrr el otro nodo o hst que no hyn ms ros que reorrerD en uyo soD l squed es fllidF
571a

Implantacin de funciones de List_Graph 571a

575

template <class GT, class SA> typename GT::Arc * search_arc(GT & g, typename GT::Node * src_node, typename GT::Node * tgt_node) { Node_Arc_Iterator<GT, SA> itor; typename GT::Node * searched_node; // escoger nodo con menos arcos if (g.is_digraph() or src_node->num_arcs < tgt_node->num_arcs) { searched_node = tgt_node; itor = Node_Arc_Iterator<GT, SA>(src_node); } else { searched_node = src_node; itor = Node_Arc_Iterator<GT, SA>(tgt_node); } for (/* nada */; itor.has_current(); itor.next()) if (itor.get_tgt_node() == searched_node) return itor.get_current_arc(); } return NULL;

7.3.10.3

Insercin de nodos

571b

il primer tipo de inserin sume que l memori pr el nodo y h sido prtd y se instrument de l siguiente mnerX Implantacin de List_Graph 564d + 566d 571c template <typename Node, typename Arc> Node * List_Graph<Node, Arc>::insert_node(Node * node) { ++num_nodes; node_list.append(node); return node; }
Uses

List_Graph

546a.

571c

il segundo tipo extiende el trjo nterior pr prtr l memori pr el nodo y olorle l informin dd de l form siguienteX Implantacin de List_Graph 564d + 571b 572 template <typename Node, typename Arc> Node * List_Graph<Node, Arc>::insert_node(const typename Node::Node_Type & node_info) {

572

7. Grafos

}
Uses

return List_Graph<Node, Arc>::insert_node( new Node (node_info) );


List_Graph
546a.

7.3.10.4

Insercin de arcos

r insertr un ro deen onoerse los nodos que ste relionD los ules deen herse insertdo previmente en el grfoF v inserin de un ro se resume en los siguientes psosX IF eprtr memori pr el ro @de tipo ArcA y signrle sus dtosF PF i l inserin ourre en un grfo @no un digrfoAD prtr entones memori pr un ojeto de tipo Arc_Node orrespondiente l nodo destino tgt_nodeD ponerlo puntr hi el ro redo en @IA e insertrlo en l list de dyeni de tgt_nodeF in este punto deemos estr pendientes de que el ro insertr no represente un lzoD y sD de ese modoD no duplir el Arc_NodeF QF eprtr memori pr un ojeto de tipo Arc_Node orrespondiente l nodo origen src_nodeD ponerlo puntr hi el ro redo en @IA e insertrlo en l list de dyeni de src_node RF snsertr el ro en l list de ros del grfoF il lgoritmo nterior se odi( omo sigueX Implantacin de List_Graph 564d + 571c 573 template <typename Node, typename Arc> Arc * List_Graph<Node, Arc>::insert_arc(Node * src_node, Node * tgt_node) { // paso 1: apartar memoria para Arc e iniciar unique_ptr<Arc> arc ( new Arc ); // apartar memoria para arco arc->src_node = src_node; // Iniciar sus campos arc->tgt_node = tgt_node;
// paso 3: (parcial): apartar Arc_Node de src_node unique_ptr<Arc_Node> src_arc_node (new Arc_Node (arc.get())); // paso 2: si es grafo ==> apartar Arc_Node de tgt_node if (not digraph) // si es digrafo ==> no insertar en otro nodo { // insercin en nodo destino if (src_node == tgt_node) // es un lazo? arc->tgt_arc_node = src_arc_node.get(); else { // apartar arco nodo para tgt_node unique_ptr<Arc_Node> tgt_arc_node(new Arc_Node(arc.get())); // insercin en lista de adyacencia de tgt_node arc->tgt_arc_node = tgt_arc_node.get(); tgt_node->arc_list.append(tgt_arc_node.get()); tgt_node->num_arcs++; tgt_arc_node.release(); } }

572

7.3. Un TAD para grafos (List_Graph)

573

// paso 3 (resto): insercin en lista adyacencia src_node arc->src_arc_node = src_arc_node.get(); src_node->arc_list.append(src_arc_node.get()); src_node->num_arcs++; arc_list.append(arc.get());//paso 4:insertar en lista arcos grafo ++num_arcs; src_arc_node.release(); }
Uses

return arc.release();
Arc_Node
567a and

List_Graph

546a.

v odi(in es ligermente diferente l lgoritmo en stellno porque en ell se onsider l posiilidd de que ourr un fll de memoriF r mntener el digo lo ms preido l lgoritmo en stellno usmos utopunteros10 F or eso l estrtegi es prtr los tres loques de memori que requerimos @el del Arc y los dos Arc_NodeAD y si no h ourrido exepinD entones podemos insertr en tods ls lists sin riesgo de fllF
7.3.10.5 Eliminacin de arcos

v eliminin de un ro es ms senill porque no hy puntos eventules de exepin11 F il proedimiento se resume en los siguientes psosX IF iliminr de ls list de dyeni del nodo origen el Arc_Node y lierr su memoriF il eso este Arc_Node se d por el triuto arc->src_arc_nodeF PF i se trt de un grfo @no un digrfoAD eliminr entones de l list de dyeni del nodo destino el Arc_Node y lierr su memoriF il eso este Arc_Node se d por el triuto arc->tgt_arc_nodeF in este pso hy que prestr tenin que el ro se un iloD en uyo so no hy que ni eliminr de l list de dyeni ni lierr l memoriY ms iones y fueron hehs en el pso nteriorF QF pinlmenteD eliminr el ro de l list de ros del grfo y lierr su memoriF vos psos nteriores se re)ejn en el siguiente digoX Implantacin de List_Graph 564d + template <typename Node, typename Arc> void List_Graph<Node, Arc>::remove_arc(Arc * arc) { // paso 1: eliminar Arc_node de src_node Node * src_node = get_src_node(arc); Arc_Node * src_arc_node = arc->src_arc_node;

573

572 574

src_arc_node->del(); // desenlaza src_node de la lista de nodos src_node->num_arcs; // decrementa contador de arcos de src_node
10
Un autopuntero es una clase de objeto apuntador que maneja la liberacin automtica de memoria De este modo se ahorra la inclusin de un manejador de excepciones en este caso, el destructor no efectuar el cuando se invoca al destructor. cuando se ejecuta el mtodo

que prevea una falla de memoria y que requiera limpiar estado intermedio. Los autopunteros se liberan

11

release();

delete.

Salvo que se trate de un error del usuario, por ejemplo, eliminacin doble o un bug en la implantacin.

574

7. Grafos

}
Uses

delete src_arc_node; // entrega memoria if (not digraph) { // eliminacin arco en nodo destino Node * tgt_node = get_tgt_node(arc); if (src_node != tgt_node) // verificar eliminacin de ciclo { // paso 2: eliminar Arc_node de tgt_node Arc_Node * tgt_arc_node = arc->tgt_arc_node; tgt_arc_node->del(); tgt_node->num_arcs; delete tgt_arc_node; } } // eliminacin de arco del grafo arc->del(); // desenlazar arc de lista de arcos de grafo num_arcs; delete arc;
Arc_Node
567a and

List_Graph

546a.

7.3.10.6

Eliminacin de nodos

574

v eliminin de un nodo puede preer omplid nte el requerimiento de que deen eliminrse todos sus ros inidentes y dyentesF e pesr de todoD si no se trt de un digrfoD result senill si nos smos en l eliminin del ro implntd en l susein nteriorX Implantacin de List_Graph 564d + 573 576a template <typename Node, typename Arc> void List_Graph<Node, Arc>::remove_node(Node * node) { if (not digraph) // Eliminar arcos adyacentes a node while (not node->arc_list.is_empty()) // mientras queden arcos { // obtener Arc_Node Arc_Node * arc_node = dlink_to_arc_node(node->arc_list.get_next()); Arc * arc = void_to_arc(arc_node); // obtener el arco remove_arc(arc); // eliminarlo del grafo } else for (Arc_Iterator it(*this); it.has_current();) { Arc * arc = it.get_current(); if (get_src_node(arc) == node or get_tgt_node(arc) == node) { it.next(); remove_arc(arc); } else it.next(); } // en este punto el nodo ya no tiene arcos

7.3. Un TAD para grafos (List_Graph)

575

}
Uses

node->del(); // desenlazar nodo de lista de nodos del grafo num_nodes; delete node;
Arc_Node
567a and

List_Graph

546a.

i se trt de un digrfoD entones l uestin es ms difil e ine(ienteD pues on l estrutur de dtos dised no qued otr lterntiv que mirr todos los ros y eliminr quellos que punten nodeF isto puede ser extremdmente ine(iente y hy que estr onsiente de este oste l hor de lterr l topolog de un digrfoF
7.3.10.7 Limpieza de grafos

575

remove_node() nos he l myor prte del trjo neesrio pr limpir un grfo @opeE rinclear_graph()AD pues st se remite eliminr todos los nodos del grfoX Implantacin de funciones de List_Graph 571a + 571a 577a
template <class GT> void clear_graph(GT & g) { for (Arc_Iterator<GT> it(g); it.has_current(); ) // eliminar arcos { typename GT::Arc * arc = it.get_current(); it.next(); g.remove_arc(arc); } for (Node_Iterator<GT> it(g); it.has_current(); ) // eliminar nodos { typename GT::Node * p = it.get_current(); it.next(); // avanzar antes de borrar (consistencia iterador) g.remove_node(p); // eliminarlo del grafo } }

uesto que remove_arc() y remove_node() son virtulesD puede her tod un den de derivinF or eso es ms seguro eliminr los ros y luego los nodosD en lugr de eliminr diretmente los nodos @que tmin eliminn intrnsemente los rosAF
7.3.10.8 Mapeo de nodos y arcos

eordemos que estipulmos el mpeo de nodos y de ros trvs de los ookiesF gonenE trmosnos en map_node()D el ul mpe los ookies de dos nodos y preserv l omposiin de mpeos en el sentido de que si los ookies son distintos de NULLD entones el mpeo se propg omo si los ookies fuesen un list enlzd irulrF sniilmenteD si no hy mpeoD entones node_map(p, q) onstruye l siguiente on(gurin de enlesX
p q

vuegoD si ourre otr llmd node_map(q,r)D entones los enles devienen enX
p q r

576

7. Grafos

576a

glrmenteD los mpeos deen omportrse omo si trtse de un inserin en un list irulrD simplemente enlzdD sin nodo eerD lo que nos ondue X Implantacin de List_Graph 564d + 574 577b template <typename Node, typename Arc> template <class N1, class N2> void List_Graph<Node, Arc>::map_nodes(N1 * p, N2 * q) { if (NODE_COOKIE(p) == NULL) { NODE_COOKIE(p) = q; NODE_COOKIE(q) = p; return; } NODE_COOKIE(q) = NODE_COOKIE(p); NODE_COOKIE(p) = q; } template <typename Node, typename Arc> template <class A1, class A2> void List_Graph<Node, Arc>::map_arcs(A1 * p, A2 * q) { if (ARC_COOKIE(p) == NULL) { ARC_COOKIE(p) = q; ARC_COOKIE(q) = p; return; } ARC_COOKIE(q) = ARC_COOKIE(p); ARC_COOKIE(p) = q; }
Uses

List_Graph

546a.

7.3.10.9

Copia de grafos

576b

he mner generlD l opi puede seprrse en dos fsesX @IA opi de nodosD y @PA opi de rosF gopir nodos es reltivmente filX por d nodo del grfo origen se re un opi y se insert en el grfo destinoF v opi de ros es similrX por d ro del grfo origen se re un opi y se insert en el grfo destinoF eordemos que pr insertr un ro hy que espei(r sus nodosF gundo inspeionmos un ro del grfo origenD los nodos que exminmos re(eren l grfo origenD pero el ro insertr en el grfo destino requiere nodos respeto l grfo destino y no respeto l origenF e nos present entones el siguiente prolemX ddo un nodo del grfo origenD mo onoer su equivlente en el grfo opi destinoc n mner de herlo ser medinte un mpeo de nodos entre los dos grfos trvs de sus ookiesD pero l semnti de l interfz copy_graph() puede impedir este tipo de mpeo @undo el prmetro cookie_map == falseAF or es rzn hremos el mpeo medinte un tl instrumentd on un rol evX Declaracin de tabla mapeo 576b (577a) DynMapAvlTree<typename GT::Node*, typename GT::Node*> map;

map mpe nodos del grfo origen src_graph nodos del grfo destino thisF

7.3. Un TAD para grafos (List_Graph)

577

577a

il mtodo de opi se espei( omo sigueX Implantacin de funciones de List_Graph 571a + 575 template <class GT> void copy_graph(GT & gtgt, GT & gsrc, const bool cookie_map) { clear_graph(gtgt); // limpiar this antes de copiar

Declaracin de tabla mapeo 576b

// fase 1: recorrer nodos de src_graph e insertar copia en this for (typename GT::Node_Iterator it(gsrc); it.has_current(); it.next()) { typename GT::Node * src_node = it.get_current_node(); unique_ptr<typename GT::Node> tgt_node(new typename GT::Node(src_node)); map.insert(src_node, tgt_node.get()); typename GT::Node * tgt = tgt_node.release(); gtgt.insert_node(tgt); // insertar en grafo destino if (cookie_map) GT::map_nodes(src_node, tgt);

} // fase 2: por cada arco de src_graph, crear en this un // arco que conecte a los nodos mapeados de map for (typename GT::Arc_Iterator it(gsrc); it.has_current(); it.next()) { typename GT::Arc * src_arc = it.get_current_arc(); // obtener imgenes de nodos en el grafo destino y crear arco typename GT::Node * src_node = map[gsrc.get_src_node(src_arc)]; typename GT::Node * tgt_node = map[gsrc.get_tgt_node(src_arc)]; typename GT::Arc * tgt_arc = gtgt.insert_arc(src_node, tgt_node); *tgt_arc = *src_arc; if (cookie_map) GT::map_arcs(src_arc, tgt_arc);

eprte de su utilizin pli en el ontexto de un pliinD copy_graph() es usdo por el onstrutor opi y el operdor de signinF
7.3.10.10 Ordenamiento de arcos

577b

vos ros estn ontenidos en l list dolemente enlzd arc_listF r ordenrlos nos vldremos del mergesort implementdo en QFPFIFS @gF IUPAF epelmos l mergesort por vris rzonesF in primer lugrD difereniD por instniD del quiksortD el desempeo O(n lg(n)) del mergesort est grntizdo y no supeditdo l permutinF in segundo lugrD el onsumo de espio del mergesort es lo sumo O(lg(n))D difereni del O(n)D que es el peor so de onsumo pr el quiksort on lists enlzdsF es puesD el ordenmiento de los ros se remite X Implantacin de List_Graph 564d + 576a template <typename Node, typename Arc> template <class Compare>

578

7. Grafos

void List_Graph<Node, Arc>::sort_arcs() { mergesort<Cmp_Arc<Compare> >(arc_list); }


Uses

List_Graph

546a and

mergesort

173a.

sort_arcs() reie l lse de omprin Compare sore punteros ros de tipo ArcY est lseD que l dee proveer el usurio interesdo en ordenr los rosD he l omE prin bool operator () (Arc *, Arc *)F ero el mergesort sore lists enlzds invo bool operator () (Dlink *, Dlink *) @ QFPFIFS @gF IUPAAD pr omprrF heemosD puesD esriir l lse de omprin pr mergesort()D l ul se denomin Cmp_ArcF u funin es onvertir los punteros de tipo Dlink Arc* e invor l omE prin CompareF

7.4 TAD camino sobre un grafo (Path<GT>)


v squed de minos es un de ls tividdes ms omunes en l mnipulin sore un grfoF or eso vle l pen un eh que modelie minos y filite su onstruinF il eh Path<GT> modeliz un mino sore un List_GraphD su estrutur generl se de(ne omo sigueX Camino de grafo 578a 597b template <class GT> class Path {

578a

};

Tipos de path 578d Miembros privados de path 578b Miembros pblicos de path 578c

Denes:

Path,

used in chunks 579c, 597602, 650, 682, 683, 687, 692, 7046, 726, 727a, 770, 771, 798, and 801.

578b

il prmetro tipo GT dee ser de tipo List_GraphD List_Digraph o de lgun lse desendienteF Path<GT> gurd l instni del grfo en un triutoX Miembros privados de path 578b (578a) 578e GT * g; el ul es onsultle medinteX

578c

Miembros pblicos de path 578c

(578a) 579c

GT & get_graph() { return *g; }

578d

v lse Path<GT> lee los tipos onernientes los nodos y ros del grfo de l siguiente mnerX Tipos de path 578d (578a) typedef typename GT::Node_Type Node_Type; typedef typename GT::Arc_Type Arc_Type; vo mismo se pli pr los punteros nodos y rosD on l exepin de que stos se mnejn de mner privdX Miembros privados de path 578b + (578a) 578b 579a typedef typename GT::Node Node; typedef typename GT::Arc Arc;

578e

7.4. TAD camino sobre un grafo (Path<GT>)

579

579a

xuestr mner de representr un mino es medinte los ros que lo omponenF ist form es independiente de idiosinrsis tles omo que se trte un multigrfoD un digrfoD etterF uesto que en List_Graph y en su derivdo List_DigraphD un ro no expres l direinD es neesrio indir ul es el nodo origenF he este modoD el otro nodo del ro ser el suesor en el minoF v oservin nterior sugiere l siguiente representin de estrutur de dtos de d punto del minoX Miembros privados de path 578b + (578a) 578e 579b struct Path_Desc { Node * node; // nodo origen Arc * arc; // arco adyacente Path_Desc(Node * _node = NULL, Arc * _arc = NULL) : node(_node), arc(_arc) {} };
Denes:

Path_Desc,

used in chunks 57981.

579b

he este modoD un mino se represent omo un list de Path_DescX Miembros privados de path 578b + (578a) DynDlist<Path_Desc> list;
Uses

579a

DynDlist

85a and

Path_Desc
12

579a.

v form trdiionl ndo grfoX


579c

de delrr un mino es uno vo que re(ere un determiE


(578a) 578c 579d

Miembros pblicos de path 578c +


Path
578a.

Path(GT & _g, void * __cookie = NULL) : g(&_g), cookie(__cookie) {}

Uses

579d

il onstrutor inii un mino vo sore el grfo gF r omenzr operr sore un mino vo hy que indir ul es su nodo iniilF isto se he medinte l siguiente primitivX Miembros pblicos de path 578c + (578a) 579c 579e void init(Node * start_node) { list.append(Path_Desc(start_node)); }
Uses

Path_Desc

579a.

579e

donde start_node es nodo iniio del minoF e puede her lo mismo en tiempo de onstruinF v longitud de un mino es el nmero de ros que lo omponenF in nuestr estruE tur de dtosD est informin est dd por el nmero de elementos del triuto listX Miembros pblicos de path 578c + (578a) 579d 579f const size_t & size() const { return list.size(); } v limpiez de un mino onsiste en orrr todos sus nodos y rosD lo ul se efet on l operin siguienteX Miembros pblicos de path 578c + (578a) 579e 580a void clear_path() { while (not list.is_empty()) list.remove_first(); }
12
En realidad, la tradicin an no est instituida.

579f

580

7. Grafos

580a

v ul v l list de Path_DescF vuego de tener un mino iniidoD es deirD on su primer nodoD l onstruin del mino se remite dirle los rosF r eso se dispone de l siguiente operinX Miembros pblicos de path 578c + (578a) 579f 580b void append(Arc * arc) { Path_Desc & last_path_desc = list.get_last(); last_path_desc.arc = arc; list.append(Path_Desc(g->get_connected_node(arc, last_path_desc.node))); }
Uses

Path_Desc

579a.

580b

ytr form de dir un omponente l mino es espei(r el siguiente nodo en lugr del roF r eso se provee el append() por nodoX Miembros pblicos de path 578c + (578a) 580a 580c void append(Node * node) { if (list.is_empty()) { init(node); return; } Node * last_node = get_last_node(); Arc * arc = search_arc(*g, last_node, node); append(arc); } v rutin es delid porque puede rrer migeddes sore multigrfos y multidiE grfosF vo omn en l onstruin de minos es por el extremo denomindo ltimo nodoF in emrgoD osionlmente es posile extender el mino por el primer nodoD es deirD dir un nuevo nodo o ro tl que ste deveng el primeroF isto se he medinte ls ontrprtes insert()F vos extremos de un mino se onsultn medinte ls primitivs siguientesX Miembros pblicos de path 578c + (578a) 580b 581a Node * get_first_node() { return list.get_first().node; }
Node * get_last_node() { return list.get_last().node; } Arc * get_first_arc() { return list.get_first().arc; } Arc * get_last_arc() { typename DynDlist<Path_Desc>::Iterator it(list); it.reset_last(); it.prev(); return it.get_current().arc; }
Uses

580c

DynDlist

85a and

Path_Desc

579a.

he ests rutinsD quiz l que meree un expliinD es get_last_arc()F eordemos primero que un DynDlist<T> slo puede ederse por sus extremosF i se dese un

7.5. Recorridos sobre grafos

581

581a

elemento diferenteD entones es neesrio reorrer l seueni trvs de un iterdorF ehor ienD get_last_arc() dee retornr el ltimo ro del minoD pero ste no se enuentr en el ltimo Path_Desc de listD sino en el penltimoF isto es lo que motiv que el iterdor se posiione en el ltimo Path_Desc y luego retroed un posiinF he est formD desde el penltimo Path_Desc se ede l ltimo roF wuhos lgoritmosD sore todo los que efetn retroeso @ktrkingAD onstruyen minos uyos extremos (nles deen ser orrdosF or est rzn es indispensle l siguiente primitivX Miembros pblicos de path 578c + (578a) 580c 581b void remove_last_node() { list.remove_last(); list.get_last().arc = NULL; } l ul orr el ltimo ro @junto on su nodoA del minoF vuego de onstruido un minoD puede requerirse reorrerloF r eso se provee un iterdorX Miembros pblicos de path 578c + (578a) 581a class Iterator : public DynDlist<Path_Desc>::Iterator { // ... Path_Desc & get_curr_path_desc() { return this->DynDlist<Path_Desc>::Iterator::get_current(); } Node * get_current_node() { return this->get_curr_path_desc().node; }
Arc * get_current_arc() { return this->get_curr_path_desc().arc; } bool has_current_arc() const { return this->has_current() and not this->is_in_last(); } bool has_current_node() const { return this->has_current(); }
DynDlist
85a and

581b

};
Uses

Path_Desc

579a.

7.5 Recorridos sobre grafos


e hn identi(do dos ptrones rquetpios de explorinD llmdos squed en proE fundidd y en mplitud respetivmenteF v myor de los lgoritmos sore grfos exhie un u otr o ms mners de explorrloF v ide de los reorridos es similr los de los roles estudidos en el ptulo RD es deirD un ptrn de proesmiento presente en muhos lgoritmosF vos reorridos y otrs primitivs sds en ellos se de(nen en el rhivo tpl_graph_utils.HF

582

7. Grafos

7.5.1

Iteradores ltro

582a

is prole que l ide de iterdor se enuentre entre los ms tiles y verstiles ptrones de diseo SUF rst el presenteD ulquier de los iterdores que hemos presentdo omprende l totlidd del onjunto l que re(erenF rontmente onsttremos que muhos prolems modelizdos sore grfos requieren so(stids estruturs de dtosD s omo el empleo de distintos lgoritmosF e us de estoD por lo omnD diser e instrumentr lgoritmos sore grfos no es un tre senillD mxime undo pretendemos l generlidd y generiiddF or didurD los grfos requieren stnte espio de memoriD por lo que su horre puede ser rtio en muhs situionesF e vees es importnte proesr lguns lses de nodo o ro de un grfo y desrtr otrosF n mner genri de (ltrr l seueni presentd por un iterdor onsiste en usr un iterador ltro D el ul en interfz es muy similr un iterdor trdiionlF r un iterdor (ltro dee espei(rseX el onjunto sore el ul se iterD un iterE dor sore quel onjunto y un funin que deide si un elemento devuelto por el iterE dor dee o no ser mostrdo por el iterdor (ltroF u espei(in reside en el rhivo filter_iterator.HD el ul se de(ne omo sigueX lter_iterator.H 582a template <class Container, class It, class Show_Item> class Filter_Iterator : public It {
};

Miembros privados de iterador ltro 582b Miembros pblicos de iterador ltro 583b
used in chunks 58385.

Denes:

Filter_Iterator,

gundo se instni un iterdor (ltro @Filter_IteratorAD se espei(n tres lses prmetrizds segn lo y meniondoX IF ContainerX el tipo de onjunto sore el ul se iterF PF ItX un iterdor sore el onjunto ContainerF snternmenteD el iterdor (ltro instni un iterdor de tipo Container::ItD on el ul se reorren los elementos de ContainerF QF Show_ItemX un lse que determin si un elemento del onjunto dee o no ser mostrdo por el iterdorF isto se efet medinte l llmd lgi bool Show_Item::operator()(Container&, Container::Item_Type&)D l ul dee reE tornr true si el elemento dee mostrrse o false de lo ontrrioF v implntin es reltivmente senill y est fundmentd en l derivin pli de Container::ItF r instrumentr l llmd onvenid Show_Item()() requerimos gurdr el onjunto en puntero omo triuto de l lseX Miembros privados de iterador ltro 582b (582a) 583a Container * cont; Show_Item show_item;

582b

7.5. Recorridos sobre grafos

583

583a

edemsD empleremos dos tipo de rutinsD un pr poner el iterdor en uno de los extremos de l seueni y otr pr vnzrloY sts se relizn de l siguiente mnerX Miembros privados de iterador ltro 582b + (582a) 582b void goto_first_valid_item() { try { // colocarse en el primer elemento que acepte show_item for (It::reset_first(); true; It::next()) if (not It::has_current() or show_item (*cont, It::get_current())) return; } catch (std::overflow_error) { /* seguir overflow; no propagar */ } } void forward() { It::next(); try { // avanzar hasta el siguiente item que acepte show_item for (;true; It::next()) if (not It::has_current() or show_item (*cont, It::get_current())) return; } catch (std::overflow_error) { /* seguir overflow; no propagar */ } }

583b

goto_first_valid_item() pone el iterdor (ltro en el primer elemento vlido que deE termine show_item(*cont,It::get_current())AF forward() lo vnz hst l primer posiin vlid segn el mismo riterioF in ms operiones existe l posiilidd de que no hy ms elementos que mostrrF in este soD el iterdor dee dejrse en el estdo de desorde std::overflow_error sin propgr l exepin @ menos que se ejeute un next() sore un iterdor desorddoD y est es l rzn por l ul el primer next() sore forward() no trp l exepinAF ry dos rutins nlogs pr poner el iterdor en el ltimo elemento y vnzr hi trsX goto_last_valid_item() y backward()F vs rutins de vne de(nids oultn el enmsrmiento de elementos trvs de show_itemF wedinte ellsD l instrumentin dee ser filmente omprensileX Miembros pblicos de iterador ltro 583b (582a)
typedef typename It::Item_Type Item_Type; Filter_Iterator(Show_Item si = Show_Item()) : cont(NULL), show_item(si) {} Filter_Iterator(Container & cont, Show_Item si = Show_Item()) : It(cont), cont(&cont), show_item(si) { goto_first_valid_item(); } void next() { forward(); }

584

7. Grafos

void prev() { backward(); } void reset_first() { goto_first_valid_item(); } void reset_last() { goto_last_valid_item(); }


Uses

Filter_Iterator

582a.

wedinte est primitiv un iterdor (ltro ofree l ilusin de ser un iterdor de ALEPH @ofree extmente su mism interfzAF vos iterdores de ALEPH fueron disedos pensndo en el rendimiento y legiiliddF riniplmente por es rznD stos no exportn un interfz reminisente l de l iliote stdc++D pues st ltim onsume tiempos en opis temporles13 F
7.5.1.1 Iterador ltro de arcos de un nodo

584a

il iterdor (ltro que mos de de(nir es plile prtimente ulquier ontenedor de ALEPHD los reliondos los grfos inlusiveF gonseuentementeD segn ls irunsE tnis lgortmisD lguns vees neesitremos iterr de mner que los lgoritmos no ven lguns lses de rosY los usdos pr lulo prilesD por ejemploF or est rzn de(niremos un iterdor externo l lse List_Graph que oper sore los ros de un nodoF l lse se espei( del modo siguienteX Iteradores ltros de List_Graph 584a 584b template <class GT, class Show_Arc = Default_Show_Arc<GT> > class Node_Arc_Iterator : public Filter_Iterator<typename GT::Node*, typename GT::Node_Arc_Iterator, Show_Arc>
Uses

Filter_Iterator

582a.

iendo derivd de Filter_Iterator on el iterdor de nodos del grfoD l interfz de Node_Arc_Iterator es idnti List_GraphXXNode_Arc_IteratorF v lse glol Node_Arc_Iterator tiene un espeilizin por omisin que no efeE t ningn (ltrdo y que es implntdo por l lse Default_Show_ArcF is deirD si no se espei( un lse (ltro de rosD entones Node_Arc_Iterator muestr todos los rosF iste iterdor ser mplimente utilizdo por los lgoritmos de grfosF u versin por omisin es en desempeo equivlente l iterdor List_GraphXXNode_Arc_IteratorD pues el rter inline de los mtodos permite l ompildor relizr diretmente l llmdF
7.5.1.2 Iterador ltro de arcos

584b

imilr l iterdor nteriorD pero pr todos los ros de grfoD de(nimos un iterdor (ltroX Iteradores ltros de List_Graph 584a + 584a 585a template <class GT, class Show_Arc = Default_Show_Arc<GT> > class Arc_Iterator : public Filter_Iterator<GT, typename GT::Arc_Iterator, Show_Arc>
Uses

Filter_Iterator

582a.

il uso de este iterdor es menos freuente que Node_Arc_IteratorF


13
Un ejemplo tpico:

for (typename set<T>::iterator = s.begin(); it < s.end(); it++)

7.5. Recorridos sobre grafos

585

7.5.1.3

Iterador ltro de nodos

585a

wuho menos freuente de usoD pero plusileD de(nimos un iterdor (ltro sore los nodosX Iteradores ltros de List_Graph 584a + 584b template <class GT, class Show_Node = Default_Show_Node<GT> > class Node_Iterator : public Filter_Iterator<GT, typename GT::Node_Iterator, Show_Node>
Uses

Filter_Iterator

582a.

7.5.2

Recorrido en profundidad

in un reorrido en profundiddD el grfo se visit trtndo de onformr el mino ms lrgo posile ntes de retornr un nodo y visitdoF is un reorrido de ndole reursivF i __dft(p) fuese l primitiv de reorrido sore el nodo pD entones el lgoritmo generl ser omo sigueF
Algoritmo 7.1 (Recorrido en profundidad desde el nodo p) il lgoritmo es reurE sivo on prototipo __dft(p)D donde p es el nodo tul de visitF e us un vrile glolD num_nodesD uyo vlor iniil es eroD pr selr l nE tidd de nodos visitdosF

IF i p est pintdoD es deirD y fue mrdo omo visitdo = retorneF PF intr pF QF snrementr num_nodes en unoF RF i num_nodes == |V | = todos los nodos del grfo hn sido reorridos y el lgoritmo terminF SF r todo ro a dyente pX @A e q el nodo inidente desde p trvs del ro aF @A vlmr __dft(q); e le die en profundidd porqueD ddo el nodo pD el reorrido no revis un nuevo ro p r hst no her reorrido ompletmente en profundidd el nodo q desde el ro tul p qF wuhs veesD un prolem sore grfos onsiste en usr un nodo on lguns rE terstis que representn l soluinF or est rznD los reorridos sore grfos tmin se les llmD indistintmenteD squedsF impleremos omo sinnimoD entonesD l exE presin squed en profundidd pr referir l reorrido homnimoF emos hor mo odi(r el reorrido en profundiddF r eso exminemos el prototipo de l funin reursiv que nos implntr el lgoritmo UFIX Recorrido en profundidad 585b 586 template <class GT, class SA> inline static bool __depth_first_traversal(GT & g, typename GT::Node * node, typename GT::Arc * arc, bool (*visit)(GT & g, typename GT::Node *, typename GT::Arc *), size_t & count);

585b

586

7. Grafos

ist es l rutin reursiv que implnt el lgoritmo UFIF __depth_first_traversal<GT,SA>() oper sore un ojeto derivdo de List_GraphD el ul est expresdo por el prmetro tipo GTF il prmetro tipo SA represent el riterio de mird de los rosY internmenteD __depth_first_traversal() utiliz un iterdor (ltro sore los rosF he este modo se puede on(gurr el reorrido pr onsiderr o no ros del grfo segn lgn riterioF vos prmetros de l funin se desrien sX IF gX el grfo sore el ul se he el reorridoF PF nodeX el nodo que se est visitndoF QF arcX el ro desde el ul se lleg l nodo nodeF RF (*visit)()X puntero l funin de visitF i este puntero es distinto de nuloD entones l funin de visit se invo l primer vez que se ve un nodoF v funin de visit tiene los siguientes prmetrosX @A gX el grfo que se est visitndoF @A _nX puntero l nodo visitdoF @A _aX puntero l ro que ondue l nodo visitdo _nF

(*visit)() retorn un vlor lgioF i es trueD entones se sume que l squed h termindoY de lo ontrrioD l squed prosigue hst que (*visit)() retorne true o hst que se hyn visitdo todos los ros y nodos del grfo segn su onetividdF
SF node_counterX prmetro por refereni que ontiliz l ntidd de nodos visiE tdosF

586

__depth_first_traversal() reorre reursivmente el grfo prtir del nodo nodeF il vlor de retorno de (*visit)() permite detener l squed segn lgn riterio espe(o emeido en l funinF il reorrido en profundidd se invo por primer vez desde l siguiente rutin de uso plioX Recorrido en profundidad 585b + 585b 587
template <class GT, class SA = Default_Show_Arc<GT> > inline size_t depth_first_traversal(GT & g, typename GT::Node * start_node, bool (*visit)(GT & g, typename GT::Node *, typename GT::Arc *), SA sa = SA()) { g.reset_bit_nodes(Depth_First); // reiniciar Depth_First de nodos g.reset_bit_arcs(Depth_First); // reiniciar Depth_First de arcos size_t counter = 0; // inicialmente no se ha visitado ningn nodo

__depth_first_traversal<GT,SA>(g, start_node, NULL, visit, counter, sa); } return counter;

7.5. Recorridos sobre grafos

587

587

l ul explor en profundidd el grfo g prtir del nodo start_node y retorn l ntidd de nodos visitdosF i se espei( un funin de visitD entones st se invo d vez que durnte l explorin se desur un nodoF ry otr versinD que no requiere espei(r el nodo de iniio y que rrn l visit sore un nodo ulquier del grfo @el que rroj get_first_node()AF entes de implntr __depth_first_traversal() es onveniente her lguns lrE toris que nos yudrn omprender el digo de ste y otros lgoritmos sore grfosF in primer lugr ordemos l mner de mrr los nodosD l ul ser medinte un it de ontrolD en nuestro soD el it Depth_FirstF in segundo lugrD efetos de elerr el reorridoD vmos mrr tmin los ros vistosF isto nos horr llmds reursivs que vn er sore nodos previmente visitdos desde otro minoF rehs ls lrtoris pertinentes podemos presentr l rutin reursivX Recorrido en profundidad 585b + 586 template <class GT, class SA> inline static bool __depth_first_traversal(GT & g, typename GT::Node * node, typename GT::Arc * arc, bool (*visit)(GT & g, typename GT::Node *, typename GT::Arc *), size_t & count, SA sa = SA()) { if (IS_NODE_VISITED(node, Depth_First)) return false;
NODE_BITS(node).set_bit(Depth_First, true); // marca nodo visitado count++; /* Aqu se visita el nodo si se desea que el orden sea prefijo */ if (count == g.get_num_nodes()) // se visitaron todos lo nodos? return true; // recorrer recursivamente arcos de node for (Node_Arc_Iterator<GT, SA> it(node, sa); it.has_current(); it.next()) { typename GT::Arc * arc = it.get_current_arc(); if (IS_ARC_VISITED(arc, Depth_First)) continue; ARC_BITS(arc).set_bit(Depth_First, true); // visitado if (__depth_first_traversal<GT, SA>(g, it.get_tgt_node(), arc, visit, count, sa)) return true; // ya se explor cabalmente it.get_tgt_node()

} /* Aqu se visita si se desea que el orden sea sufijo */ } return false; // retorne y siga explorando

v rutin est on(gurd pr detenerse undo se hyn visitdo todos los nodosF i ls irunstnis del lulo lo meritnD puede ser neesrio reorrer todos los rosF

588

7. Grafos

L A D E N

I C F G K

pigur UFPIX n grfo ejemplo in este so st on eliminr el if (count == g.get_num_nodes()) pr segurr que se ven todos los nodos y ros onexosF v (gur UFPP ilustr dos interpretiones de reorrido pr el grfo de l (gur UFPID un reorrido que omienz en el nodo A y otro en NF n vez estleido el nodo de iniioD el orden de visit depende de l topolog del grfo y del orden en que se presenten los ros en ls lists de dyeni de d nodoF il reorrido en profundidd puede plnterse omo pre(jo o su(joF i el proesmiento o visit del nodo se efet ntes del forD entones el reorrido es pre(joF iD por el ontrrioD se he despus del forD entones es su(joF in mos tiposD el orden de visit es el mismo que si se hiiese sore el rol rdor que rteriz el reorridoF
A B J D C F E G H M N L I K F C N E D A B J H M L G K I

(a) Inicio en A

(b) Inicio en N

pigur UFPPX roles rdores de profundidd del grfo de l (gur UFPI il reorrido en profundidd se us undo se estim que el nodo soluin est lejno del iniioF xotemos que los roles de profundidd de l (gur UFPP son lrgos y delgdosD on pos rmsF il primero es ompletmente seuenil porque prtir de A es posile

7.5. Recorridos sobre grafos

589

visitr entermente el grfo sin neesidd de regresr un nodo y visitdoF in el segundo rol vemos un regreso l nodo GF i el grfo es onexoD entones l squed en profundidd requiere lo sumo O(V ) + O(E) = O(max(V, E)) psos pr iniilizr los its de los nodos y rosF osteriormenteD l rutin omienz en el primer nodo del grfo y lo sumo llm reursivmente V vees __depth_first_traversal()F hurnte d llmd reursiv se reorre entermente l list de dyeni del nodo de visitD lo ul impli queD en el peor de los sosD se visitrn todos los rosF or tntoD l squed en profundidd on lists enlzds esD pr el peor soD O(V ) + O(E)F il peor oste en espio de l explorin en profundidd ourre si el grfo es fuerteE mente onexoF n indiin de esto se muestr mirndo el rol rdor en profunE didd de l (gur UFPPE@AF yservemos que tiene un sol rmD lo que es equivlente un list enlzdF in este soD l profundidd reursiv es proporionl O(V )F i el grfo no es onexoD entones el reorrido ulmin sin her visitdo todos los nodosY qullos que sen visitdos dependern del nodo por el ul se iniie l squedF il reorrido que hemos presentdo us nodosD por eso podemos detenerlo undo se hn visitdo todos los nodosF in osionesD l squed se plnte en funin de rosD en uyo soD el reorrido tiende ser ms ostosoD pues l detenin dee herse undo se hyn visitdo todos lo rosF
7.5.3 Conectividad entre grafos

589

n de ls pliiones ms simples de l squed en profundidd es l prue de oneE tividdF v ide si es reorrer el grfo y veri(r si se visitn todos los nodosD en uyo so podemos onluir on ertitud que el grfo es onexoF ry un onsiderin diionl que he nuestro lgoritmoD y que onsiste en revisr l ntidd de rosD l ulD si es menor l nmero de nodos menos unoD entones podemos onluir que el grfo es inonexo y horrrnos el reorridoF v rutin resultnte se implnt entones de l siguiente mnerX Prueba de conectividad 589 template <class GT, class SA = Default_Show_Arc<GT> > inline bool test_connectivity(GT & g) { if (g.get_num_arcs() < g.get_num_nodes() - 1) return false;
} return depth_first_traversal<GT, SA>(g, NULL) == g.get_num_nodes();

test_connectivity() retorn true si el grfo es onexoD false de lo ontrrioF v prue sore el nmero de ros tom tiempo O(1) y puede horrr tiempo de ejeuinF imperoD est no es orret si trtmos on un multigrfoF test_connectivity() no oper sore digrfosF ist lse de onetividd se estudi en UFUFI @gF TQVAF
7.5.4 Recorrido en amplitud

ytr form de proesr el reorrido sore un grfo que privilegi los nodos ms ernos sore los ms lejnos y queD segn l ndole del grfoD puede ser ms onvenienteD es el reorrido en mplitudF in est lse de squed no se proes un nodo de un nivel i

590

7. Grafos

hst que no se hyn proesdo todos los nodos del nivel nterior i 1D es deirD un espeie de reorrido por nivelesF il medio pr gurdr los nodos por niveles es el mismo que pr los rolesX un olF in nuestro so usmos un ol de punteros rosF
A B J M C H N I D E L F G K A D B E J C H F G N M L I K

(a) Inicio en A

(b) Inicio en N

pigur UFPQX roles rdores de mplitud del grfo de l (gur UFPI v difereni esenil entre l squed en mplitud y l de profundidd es que l de mplitud explor los minos ms ortos primeroD mientrs que l de profundidd tiende ir por los ms lrgosF iste heho se indii perfetmente ontrstndo los roles de reorridosD los ules son ms frondosos pr el reorrido en mplitud @ver (gurs UFPP @gF SVVA y UFPQ @gF SWHAAF v primitiv no es reursivF iene los mismos prmetros que su ontrprte en profundidd y se instrument del siguiente modoX Recorrido en amplitud 590 600d template <class GT, class SA = Default_Show_Arc<GT> > inline size_t breadth_first_traversal(GT & g, typename GT::Node * start, bool (*visit)(GT &, typename GT::Node *, typename GT::Arc *) ) { g.reset_bit_nodes(Breadth_First); g.reset_bit_arcs(Breadth_First); DynListQueue<typename GT::Arc*> q; // cola de arcos pendientes
// ingresar a la cola los arcos de nodo start for (Node_Arc_Iterator<GT, SA> it(start); it.has_current(); it.next()) q.put(it.get_current_arc()); NODE_BITS(start).set_bit(Breadth_First, true); size_t node_counter = 1; // contador de nodos visitados // mientras queden arcos en cola y resten todos por visitar while (not q.is_empty() and node_counter < g.get_num_nodes()) { typename GT::Arc * arc = q.get();// saque de cola ms cercano ARC_BITS(arc).set_bit(Breadth_First, true); typename GT::Node * src = g.get_src_node(arc); typename GT::Node * tgt = g.get_tgt_node(arc); if (IS_NODE_VISITED(src, Breadth_First) and IS_NODE_VISITED(tgt, Breadth_First)) continue;

590

7.5. Recorridos sobre grafos

591

typename GT::Node * visit_node = // prximo a visitar IS_NODE_VISITED(src, Breadth_First) ? tgt : src; /* Aqu se visita el nodo mediante la funcin de visita */ NODE_BITS(visit_node).set_bit(Breadth_First, true); node_counter++; // insertar en cola arcos del nodo recin visitado for (Node_Arc_Iterator<GT, SA> it(visit_node); it.has_current(); it.next()) { typename GT::Arc * curr_arc = it.get_current_arc(); if (IS_ARC_VISITED(curr_arc, Breadth_First)) continue; // revise nodos del arcos para ver si han sido visitados if (IS_NODE_VISITED(g.get_src_node(curr_arc), Breadth_First) and IS_NODE_VISITED(g.get_tgt_node(curr_arc), Breadth_First)) continue; // nodos ya visitados } q.put(curr_arc);

} return node_counter;

v squed en mplitud puede ser ms ostos en tiempo y en espio que l de profundiddD pues el enolmiento mntiene ros que no hn sido visitdosD lo que no suede on el empilmiento de l squed en profundidd que lmen ros visitdosF il peor so de ejeuin de l squed en mplitud ourre undo es neesrio visitr todos los ros ntes de her visto todos los nodosD o seD O(E)D ul es el mismo de l squed en profundiddF r nlizr el oste en espio es onveniente oservr l dinmi de inserin y eliminin de ros en l olF gundo se s de l ol un ro perteneiente l nivel i @respeto l nodo de iniioAD st puede ontener ros del nivel i y del superior i + 1F i interpretmos el reorrido omo el reorrido por niveles de un rolD entones podemos pertrnos de que lo sumo se tendrn E/2 ros en l olD lo ul equivle un oste O(E)D ul puede ser stnte myor que el oste en espio O(V ) del reorrido en profundiddF gundo reorrer en profundidd o en mplitudc v respuest depende de vrios ftoresD de los ules el prinipl es l presunin de ern que se teng er del nodo soluin onsiderndo que l riterio de ern inide l topolog del grfo y su densiddF i el nodo soluin se presume ernoD entones el riterio de mplitud tiende enontrrlo ms rpido que el de profundiddF v squed en mplitud de un nodo prtiulr enuentr el mino ms orto en ntidd de rosF or ostumreD no generliddD se tiende her primero un squed en profundidd pr enontrr un soluin o un proximin yD posteriormenteD pr (nrlD se he un en mplitudF

592

7. Grafos

7.5.5

Prueba de ciclos

592a

lnteemos el prolem de determinr si existe o no un ilo prtir de un nodo prtiulr src_nodeF in este soD un riterio en profundidd pree preferile l de mplitud porque no gst tiempo ni espio en los ros priles que n no son proesdosF n squed en profundidd prilD es deirD que no neesrimente pretend visitr todos los nodosD sirve pr detetr si existe un ilo prtir de un nodoF v ide es explorr reursivmente hst enontrr el nodo de prtidD en uyo so l prue es positivD o ulminr l squedD en uyo so es negtivF xuestr prue de ilo se poy sore l siguiente rutin reursivX Bsqueda de ciclo 592a 592b template <class GT, class SA> inline static bool __test_cycle(GT & g, typename GT::Node * src_node, typename GT::Node * curr_node);

__test_cycle() es de uso privdoD efet l explorin reursiv en profundidd por el nodo curr_node en squed del nodo src_node y mnej tres prmetrosX
IF gX el grfo sore el ul se reliz l prueF PF src_nodeX el nodo pr el ul se veri( si existe un iloF QF curr_nodeX es el nodo de visit de l llmd reursivF v rutin retorn true si desde curr_node se lnz el nodo iniil src_nodeY en este so existe un iloF i se reorre enter y reursivmente el omponente onetdo curr_nodeD entones podemos onluir que psndo por curr_node no es posile lnzr src_node y queD por lo tntoD por est v no hy iloF in este so retornmos falseF v interfz pli se plnte y se instrument de l siguiente formX Bsqueda de ciclo 592a + 592a 593 template <class GT, class SA = Default_Show_Arc<GT> > inline bool test_for_cycle(GT & g, typename GT::Node * src_node) { g.reset_bit_nodes(Test_Cycle); // reiniciar Test_Cycle para nodos g.reset_bit_arcs(Test_Cycle); // reiniciar Test_Cycle para arcos
// explorar recursivamente por arcos adyacentes a src_node for (Node_Arc_Iterator<GT, SA> it(src_node); it.has_current(); it.next()) { typename GT::Arc * arc = it.get_current_arc(); if (IS_ARC_VISITED(arc, Test_Cycle)) continue; ARC_BITS(arc).set_bit(Test_Cycle, true); // pintar arco if (__test_cycle<GT,SA>(g, src_node, it.get_tgt_node())) return true; // ciclo detectado

592b

// Se han explorado todos los caminos desde src_node // sin encontrar de nuevo a src_node ==> no hay ciclo return false;

7.5. Recorridos sobre grafos

593

593

test_for_cycle() retorn true si existe un ilo desde src_nodeY false de lo onE trrioF n punto esenil en este lgoritmo es queD difereni de lo que plntemos en ls suseiones nteriores onernientes ls squedsD no deemos detenernos undo hymos visitdo todos los nodosD pues lgn ilo podr enontrrse por lgn ro que no hy sido visitdoF xo tenemos en este so otr lterntiv que explorr todos los rosD rzn por l ul el lgoritmo es O(E) pr el peor so en que no exist iloF hiho lo nteriorD estmos listos pr implntr l explorin reursivX Bsqueda de ciclo 592a + 592b template <class GT, class SA> inline static bool __test_cycle(GT & g, typename GT::Node * src_node, typename GT::Node * curr_node) { if (src_node == curr_node) return true; // ciclo detectado!
if (IS_NODE_VISITED(curr_node, Test_Cycle)) return false; NODE_BITS(curr_node).set_bit(Test_Cycle, true); // marque nodo // buscar caminos desde current_node a ver si llega a src_node for (Node_Arc_Iterator<GT, SA> it(curr_node); it.has_current(); it.next()) { typename GT::Arc * arc = it.get_current_arc(); if (IS_ARC_VISITED(arc, Test_Cycle)) continue; ARC_BITS(arc).set_bit(Test_Cycle, true); // marque arco if (__test_cycle<GT,SA>(g, src_node, it.get_tgt_node())) return true; // ciclo encontrado desde el arco actual

// En este punto se han explorado caminos desde curr_node // sin encontrar src_node ==> no existe ciclo por curr_node return false;

7.5.6

Prueba de aciclicidad

n grfo es lio si ste no ontiene ilosF gomo muhos lgoritmos requieren veri(r est ondiin sore lulos de grfos prilesD es importnte que est prue se hg e(ientementeF n vrinte del lgoritmo nterior de prue de ilos puede utilizrse pr veri(r iliidd sore un grfo inonexoF odemos invor test_for_cycle() pr d nodo del grfoD y si tods ls ejeuiones rrojn omo resultdo flsoD entones el grfo es lioF il prinipio de l prue de iliidd es que si durnte l explorin del grfoD psndo por un ro no visitdoD vemos un nodo y visitdoD entones el grfo tiene un

594

7. Grafos

594a

ilo @el que permite regresr l nodo visitdo por un mino diferenteAF in virtud de est oservin podemos plnter l siguiente rutinD privdD reursivD de explorin en profundiddX Prueba de aciclicidad 594a 594b template <class GT, class SA> inline static bool __is_graph_acyclique(GT & g, typename GT::Node * curr_node) { if (IS_NODE_VISITED(curr_node, Is_Acyclique)) return false;
NODE_BITS(curr_node).set_bit(Is_Acyclique, true); // marcar nodo for (Node_Arc_Iterator<GT, SA> i(curr_node); i.has_current(); i.next()) { typename GT::Arc * arc = i.get_current_arc(); if (IS_ARC_VISITED(arc, Is_Acyclique)) continue; ARC_BITS(arc).set_bit(Is_Acyclique, true); if (not __is_graph_acyclique<GT,SA>(g, i.get_tgt_node())) return false;

// todos los arcos recorridos sin encontrar ciclo ==> // el grafo es acclico pasando por curr_node return true;

594b

__is_graph_acyclique() reliz un prue de iliidd prtir del nodo curr_nodeF e retorn true si hy iliiddY false de lo ontrrioF v detenin se efet undo se detet un iloY en este so __is_graph_acyclique() retorn falseF il que no se enuentre ilo por lgn ro dyente de curr_node no impli que no exist lguno por otro de sus rosF lo undo se hyn explordo todos los ros de curr_node sin enontrr ilo podemos onluir que el grfo es lioF i un sugrfo de un grfo onexo es lioD entonesD sin importr desde ul nodo se iniieD un squed en profundidd dee detetr un ilo por enuentro de un nodo y mrdoF i eso no ourreD es deirD si no podemos regresr l nodo origen de l squedD entonesD on tod ertitudD el sugrfo es lioF i eso suede pr todos los nodos onexosD entones el grfo es lioF ry un oservin ruil en el so de un grfo onexo @no un digrfoD multigrfo o multidigrfoAX si l ntidd de ros es menor que l de nodosD entones el grfo no puede ontener ningn iloF iste heho nos ot l prue de iliidd O(V )F v prue puede iniirse desde ulquier nodo y l siguiente versin pli es perfetmente plileX Prueba de aciclicidad 594a + 594a 595
template <class GT, class SA = Default_Show_Arc<GT> > inline bool is_graph_acyclique(GT & g, typename GT::Node * start_node) {

7.5. Recorridos sobre grafos

595

if (g.get_num_arcs() >= g.get_num_nodes()) return false; g.reset_bit_arcs(Is_Acyclique); g.reset_bit_nodes(Is_Acyclique); } return __is_graph_acyclique<GT,SA>(g, start_node);

595

__is_graph_acyclique() reliz l explorin reursiv en profundiddY start_node es el nodo de iniio de l prueD el ul dee perteneer un omponente de grfo sospehoso de tener un iloF v utilidd de l interfz nterior es undo start_node hy sido dido en lgn lulo y se requier veri(r si l diin us o no un iloF ist rutin funion pr ulquier grfo onexo @sin importr el nodo de iniioA o pr veri(r iliidd desde un nodo prtiulr start_nodeF i no se tiene onoimiento er de l onetividd del grfoD entones es neesrio inspeionr los eventules omponentes onexos del grfoD uestin que se puede efetur del siguiente modoX Prueba de aciclicidad 594a + 594b template <class GT, class SA = Default_Show_Arc<GT> > inline bool is_graph_acyclique(GT & g) { if (g.get_num_arcs() >= g.get_num_nodes()) return false;
g.reset_bit_arcs(Is_Acyclique); g.reset_bit_nodes(Is_Acyclique); for (Node_Iterator<GT> it(g); it.has_current(); it.next()) { typename GT::Node * current_node = it.get_current_node(); if (IS_NODE_VISITED(current_node, Is_Acyclique)) continue; if (not __is_graph_acyclique<GT,SA>(g, current_node)) return false;

} return true;

hespus de l primer llmd __is_graph_acyclique(g, curr_node)D lgunos nodos y quedn mrdos on el vlor Is_AcycliqueY sore stos no se dee repetir l prue de iliiddF uesto que is_graph_acyclique() detet ilo veri(ndo si un nodo h sido o no visitdoD st no oper pr digrfosF i tenemos un digrfoD entones podemos llmr test_for_cycle() pr d nodo del grfoF i enontrmos un ilo nos detenemos y semos que el digrfo no es lioF i promos pr todos los nodosD entones podemos onluir que el grfo es lioF ist tni rre un oste de O(V E)F in UFUFR @gF TRVA desrrollremos un tni que determin l iliidd en O(V + E)F

596

7. Grafos

7.5.7

Bsqueda de caminos por profundidad

v squed de minos es un prolem omn y rtio de los grfosF in est susein slo desrrollremos prue de existeni y determinin de minosF in l sein UFW @gF TURA estudiremos vrios lgoritmos pr determinr el mino de oste mnimoF
7.5.7.1 Prueba de existencia

596a

hdo un pr de nodosD mo determinr si existe un mino entre ellosc vlmemos __test_for_path() l rutin reursivD que explor en profundidd el grfoD en squed de un nodo destino end_node y uyo prototipo se enuni ontinuinX Prueba de camino 596a 596b template <class GT, class SA> inline static bool __test_for_path(GT & g, typename GT::Node * curr_node, typename GT::Node * end_node);

596b

g es el grfoF curr_node es el nodo tul que se est visitndo y end_node es el nodo destino del minoF i se enuentr end_nodeD entones existe el mino psndo por curr_node y l rutin retorn trueF i se explorn tods ls vs por curr_node sin enontrr end_nodeD entones se onluye que psndo por curr_node no existe mino end_node y l rutin retorn falseF r este prolemD el onoimiento que tengmos sore l onetividd del grfo nos yud un pooF il grfo puede ser inonexo y un s existir mino entre los nodos onsiderdosF es ls ossD en est situin no tenemos ms lterntiv que explorr el grfoF ero si el grfo es onexo y no es dirigidoD entones on ertitud existe un mino entre ulquier de sus nodos y no requerimos explorrloF emos hor mo se pli l rutin nterior pr l prue de existeni de mino entre un nodo iniil start_node y otro (nl end_nodeX Prueba de camino 596a + 596a 597a
template <class GT, class SA = Default_Show_Arc<GT> > inline bool test_for_path(GT& g, typename GT::Node * start_node, typename GT::Node * end_node) { // si el grafo es conexo ==> existe camino if (not g.is_digraph() and g.get_num_arcs() >= g.get_num_nodes()) return true; g.reset_bit_nodes(Test_Path); g.reset_bit_arcs(Test_Path); // buscar recursivamente por arcos adyacentes a start_node for (Node_Arc_Iterator<GT, SA> i(start_node); i.has_current(); i.next()) { typename GT::Arc * arc = i.get_current_arc(); ARC_BITS(arc).set_bit(Test_Path, true); // marcar arco if (__test_for_path<GT, SA>(g, i.get_tgt_node(), end_node)) return true; } // todos los arcos de start_node han sido explorados sin // encontrar camino hasta end_node ==> no existe camino return false;

7.5. Recorridos sobre grafos

597

597a

test_for_path() retorn true si existe un mino entre start_node y end_nodeY false de lo ontrrioF v prue de mino prilD es deirD determinr si hy un mino desde un nodo inE termedio curr_node hst uno (nl end_node se implement segn el ptrn de squed en profundiddX Prueba de camino 596a + 596b
template <class GT, class SA> inline static bool __test_for_path(GT & g, typename GT::Node * curr_node, typename GT::Node * end_node) { if (curr_node == end_node) return true; // se alcanz a end_node

if (IS_NODE_VISITED(curr_node, Test_Path)) // se visit curr_node? return false; // s, no explore NODE_BITS(curr_node).set_bit(Test_Path, true); // pintar curr_node // buscar recursivamente a travs de arcos de curr_node for (Node_Arc_Iterator<GT, SA> i(curr_node); i.has_current(); i.next()) { typename GT::Arc * arc = i.get_current_arc(); if (IS_ARC_VISITED(arc, Test_Path)) continue; ARC_BITS(arc).set_bit(Test_Path, true); // pintar arco if (__test_for_path<GT, SA>(g, i.get_tgt_node(), end_node)) return true;

// todos los arcos adyacentes de curr_node explorados sin // encontrar a end_node ==> no existe camino por curr_node return false;

yservemos queD en detrimento de l e(ieniD trvs de __test_for_path() podeE mos enontrr ilos o lzosF il tiempo de ejeuin de test_for_path() esD en el peor soD proporionl l ntidd de rosD pues ste no iterr ms de E veesD o seD O(E)F gon l representin mtriil hy un mner de lulr ls reliones de oneE tividd entre todos los nodos de un grfoF l relin se llm lusur trnsitiv y se lulmedinte un lgoritmo llmdo de rshllD que ser presentdo en UFTFQ @gF TQSAF
7.5.7.2 Bsqueda de camino entre dos nodos

597b

in osionesD lo que se dese es enontrr y onstruir un mino ulquier entre dos nodosF r eso diseremos un primitivD muy similr l de l susein nteriorD uyo (n se otener un ojeto de tipo Path ontentivo de un mino entre dos nodos y on l interfz siguienteX Camino de grafo 578a + 578a 598a

598

7. Grafos

template <class GT, class SA = Default_Show_Arc<GT> > inline bool find_path_depth_first(GT & g, typename GT::Node * start_node, typename GT::Node * end_node, Path<GT> & path);
Uses

Path

578a.

find_path_depth_first() enuentr y onstruyeD medinte un squed en profundiE ddD un mino entre start_node y end_node del grfo gF il mino resultnte se gurd en el prmetro pathF v rutin retorn true si se logr enontrr un minoY false de lo ontrrioD en uyo soD el vlor de path dee onsiderrse indetermindoF v funin ontempl los siguientes prmetros tipoX
IF GTX el tipo de grfoF PF SAX el (ltro del iterdor de rosF wuhos lgoritmos requieren usr minos entre pres de nodosF or eso puede ser til prmetrizr el mtodo find_path_depth_first()D o seD que ste se psdo omo prmetro un mtodoF hesde el lenguje CD el medio trdiionl pr esto es un punE tero funinD pero el estndr C++ no permite punteros funiones plntillsF r ontorner est situinD y l vez dr un estilo ms hi los ojetosD exportremos find_path_depth_first() jo el nomre de un lseX Camino de grafo 578a + 597b 598b template <class GT, class SA = Default_Show_Arc<GT> > class Find_Path_Depth_First { bool operator () (GT & g, typename GT::Node * start_node, typename GT::Node * end_node, Path<GT> & path) const { return find_path_depth_first<GT,SA>(g, start_node, end_node, path); } };
Uses

598a

Path

578a.

598b

find_path_depth_first() es l interfz pliD l ul se poy sore l rutin siE guienteD que es l que efet l explorin reursiv en profundiddX Camino de grafo 578a + 598a 599

template <class GT, class SA> inline bool __find_path_depth_first(GT& g, typename GT::Node * curr_node, typename GT::Arc * curr_arc, typename GT::Node * end_node, Path<GT> & curr_path) { if (curr_node == end_node) // se alcanz nodo final? { // s, terminar aadir el arco y terminar curr_path.append(curr_arc); return true; } if (IS_NODE_VISITED(curr_node, Find_Path)) // ha sido visitado? return false; // s ==> desde l no hay camino curr_path.append(curr_arc); // aadir curr_arc al camino NODE_BITS(curr_node).set_bit(Find_Path, true);

7.5. Recorridos sobre grafos

599

// buscar recursivamente a travs de arcos de curr_node for (Node_Arc_Iterator<GT, SA> i(curr_node); i.has_current(); i.next()) { typename GT::Arc * next_arc = i.get_current_arc(); if (IS_ARC_VISITED(next_arc, Find_Path)) continue; ARC_BITS(next_arc).set_bit(Find_Path, true); typename GT::Node * next_node = i.get_tgt_node(); if (__find_path_depth_first<GT, SA> (g, next_node, next_arc, end_node, curr_path)) return true; // se encontr camino

} curr_path.remove_last_node(); }
Uses

return false;
Path
578a.

599

v estrutur es l mism que l de ls diferentes exploriones en profundidd que hemos presentdoF v difereni estri en que ntes de visitr reursivmente los ros de curr_nodeD lo dimos l minoF i reorremos todos los ros de curr_node sin enontrr un mino hi end_nodeD entones smos curr_node del minoF hd l ndole reursiv del lgoritmoD path funge omo pilF or tntoD el mximo tmo de path podr lnzr O(E)F __find_path_depth_first() retorn true si se logr onstruir un mino hE i end_node proviniendo desde current_nodeF ry dos prmetros diionles respeto __test_for_path()X el ro tul current_arc y el mino pathF path es un prmeE tro de slid que ontiene el vlor del mino enontrdoF current_arc es un ro uyo nodo origen es current_node que se requiere porque en l lse Path se insert por ros y no por nodosF xos flt implntr l primitiv pliX Camino de grafo 578a + 598b template <class GT, class SA = Default_Show_Arc<GT> > inline bool find_path_depth_first(GT & g, typename GT::Node * start_node, typename GT::Node * end_node, Path<GT> & path) { path.clear_path(); path.init(start_node); g.reset_bit_nodes(Find_Path); g.reset_bit_arcs(Find_Path); NODE_BITS(start_node).set_bit(Find_Path, true);
// explorar recursivamente cada arco de start_node for (Node_Arc_Iterator<GT, SA> i(start_node); i.has_current(); i.next()) { typename GT::Arc * arc = i.get_current_arc(); ARC_BITS(arc).set_bit(Find_Path, true); typename GT::Node * next_node = i.get_tgt_node(); if (IS_NODE_VISITED(next_node, Find_Path))

600

7. Grafos

continue; if (__find_path_depth_first<GT, SA>(g, next_node, arc, end_node, path)) return true;

}
Uses

} return false;
Path
578a.

gundo se dese onstruir @o determinr existeni deA un mino ulquier entre dos nodos es preferile vlerseD en un primer instniD de un explorin en profundiddF vuegoD si se requiere uno ms orto en rosD o que onsum menos memoriD entones puede herse por mplitudF ytr situin en l ul es preferile l explorin en profundidd es undo se usque un mino sore un grfo lio o un rolF
7.5.8 Bsqueda de caminos por amplitud

600a

il (n de est susein es onstruir un mino por mplitud entre dos nodos start y endF el omenzr por start explormos y enolmos todos sus ros en squed de endF i no hemos hlldo endD entones ontinumos por todos los minos de longitud dosF iste proeso ontin hst enontrr el mino en uestinF r llevr o l estrtegi nteriorD l ol dee gurdr minos priles desde el nodo de iniio hst el del ltimo nivel que se hy explordoD lo ul se espei( del siguiente modoX Declaracin de cola de caminos 600a (601) DynListQueue<Path<GT>*> q; // cola de caminos parciales
Uses

Path

578a.

600b

xtese que es un ol de punteros minosD lo ul impli que l memori de stos dee prtrse yD sore todoD undo se ve l olD lierrseF gomo se trt de punteros Path*D el destrutor de l ol no lierr l memori oupd por los minosD lo ul requiere l siguiente in explit pr lierr l olX vaciar cola y liberar caminos 600b (601) while (not q.is_empty()) delete q.get(); ist in dee herse l (nl del proedimiento de l squedD se hy enontrdo o no un minoD o si ourre un exepinF r mnejr el mino tul de explorinD mnejremos l siguiente vrileX Declaracin de camino actual 600c (601) Path<GT> * path_ptr = NULL;
Uses

600c

Path

578a.

600d

v inserin en l ol requiere @IA prtr memori pr el mino y @PA l propi in de insertr en l olF uesto que hy mnejo de memori en ms operionesD usremos un rutin on utoEpunterosX Recorrido en amplitud 590 + 590 601 template <class GT> inline static void __insert_in_queue(GT & g, DynListQueue<Path<GT> *> & q, typename GT::Node * node, typename GT::Arc * arc, Path<GT> * path_ptr = NULL)

7.5. Recorridos sobre grafos

601

unique_ptr<Path<GT> > path_auto; if (path_ptr == NULL) // iniciar o copiar* path_auto = unique_ptr<Path<GT> >(new Path<GT>(g, node)); // iniciar else path_auto = unique_ptr<Path<GT> >(new Path<GT>(*path_ptr));// copiar path_auto->append(arc); q.put(path_auto.get()); path_auto.release();
Path
578a.

// aadir el nuevo arco // insertar el nuevo camino en cola

}
Uses

__insert_in_queue() re un nuevo mino on el ro dido arc y lo enol en l ol qF v rutin mnej un vrile Path llmd path_autoD l ulD segn el vlor de path_ptrD se proes de dos posiles formsX
IF i path_ptr == NULLD entones path_auto es un nuevo mino on nodo de iniio nodeF PF i path_ptr != NULLD entones el mino ontenido en *path_ptr se opi path_autoF in ulquier de los dos sosD el ro arc se le de path_auto y ste se insert en l olF gon lo nterior podemos diser l siguiente squed de mino en mplitudX Recorrido en amplitud 590 + 600d 602 template <class GT, class SA = Default_Show_Arc<GT> > inline bool find_path_breadth_first(GT& g, typename GT::Node * start, typename GT::Node * end, Path<GT> & path) { path.clear_path(); // limpiamos cualquier cosa que est en path g.reset_bit_nodes(Find_Path); g.reset_bit_arcs(Find_Path);

601

Declaracin de cola de caminos 600a Declaracin de camino actual 600c


// insertar los caminos parciales con nodo inicio start for (Node_Arc_Iterator<GT, SA> i(start); i.has_current(); i.next()) __insert_in_queue<GT>(g, q, start, i.get_current_arc()); NODE_BITS(start).set_bit(Find_Path, true); // mrquelo visitado while (not q.is_empty()) // mientras queden arcos por visitar { path_ptr = q.get(); // extraiga camino actual typename GT::Arc * arc = path_ptr->get_last_arc(); ARC_BITS(arc).set_bit(Find_Path, true); // marcar arco typename GT::Node * tgt = path_ptr->get_last_node(); if (IS_NODE_VISITED(tgt, Find_Path)) // visit ltimo nodo?

602

7. Grafos

{ // s ==> camino no conduce a end ==> borrar camino delete path_ptr; continue; } if (tgt == end) // se encontr un camino? { // s ==> path_ptr contiene camino buscado path.swap(*path_ptr); // copiar resultado al parmetro path return true; } NODE_BITS(tgt).set_bit(Find_Path, true); // marcar ltimo nodo // insertar en cola arcos del nodo recin visitado for (Node_Arc_Iterator<GT,SA> i(tgt); i.has_current(); i.next()) { typename GT::Arc * curr_arc = i.get_current_arc(); if (IS_ARC_VISITED(curr_arc, Find_Path)) // arco visitado? continue; // s ==> avanzar al siguiente // revise nodos del arco para ver si han sido visitados if (IS_NODE_VISITED(g.get_src_node(curr_arc), Find_Path) and IS_NODE_VISITED(g.get_tgt_node(curr_arc), Find_Path)) continue; // nodos ya visitados ==> no meter arco __insert_in_queue<GT>(g, q, NULL, curr_arc, path_ptr); } delete path_ptr; // borrar camino extrado de la cola } // fin while (not q.is_empty())

vaciar cola y liberar caminos 600b

vaciar cola y liberar caminos 600b


}
Uses

return false;
Path
578a.

e dee prestr muh tenin lierr los minos que sen vistos y desehdosD ien se porque el nodo y hy sido visitdo o porque path_ptr y hy sido opidoF gomo se dee preirD find_path_breadth_first() onsume ms memori que su ontrprte en profundiddF eprte de que l ol tiende reer ms que un pilD ul es el so en el reorrido en profundiddD l ol gurd minos enteros desde el nodo de iniioF el igul que pr find_path_depth_first()D find_path_breadth_first() tmin puede invorse medinte un instni espeil de lseX
602

Recorrido en amplitud 590 +

601

template <class GT, class SA = Default_Show_Arc<GT> > class Find_Path_Breadth_First { bool operator () (GT & g, typename GT::Node * start, typename GT::Node * end, Path<GT> & path) const { return find_path_breadth_first <GT, SA> (g, start, end, path); }

7.5. Recorridos sobre grafos

603

};
Uses

Path

578a.

7.5.9

rboles abarcadores de profundidad

603a

il ojeto de est susein es desrrollr un lgoritmo queD prtir de un nodo de iniioD explore en profundidd un grfo y onstruy otro grfo orrespondiente un rol rE dorF l rutin tiene l siguiente form generlX rboles abarcadores 603a 604 template <class GT, class SA = Default_Show_Arc<GT> > inline bool find_depth_first_spanning_tree(GT & g, typename GT::Node * gnode, GT & tree) {
return true;

Inicializar construccin rbol abarcador 603b Recorrer en profundidad nodos adyacentes a gnode 603c

find_depth_first_spanning_tree() mnej tres prmetrosX


IF gX un grfo onexo sore el ul se requiere onstruir un rol rdorF PF gnodeX el nodo iniil desde el ul se dese omenzr l onstruin del rol rE dorF QF treeX un grfo de slid donde se olor el rol rdor resultnteF il vlor de retorno es true si existe un rol rdorY false de lo ontrrioF or didurD find_depth_first_spanning_tree() mpe los nodos y ros trvs de los ookiesF he este modoD el usurio puede onoerD dentro del grfoD ules nodos o ros perteneen l rol rdorF entes de omenzr l explorin reursiv de gD es neesrio limpir sus its de ontrol y segurrse de que tree est voX Inicializar construccin rbol abarcador 603b (603a) g.reset_nodes(); g.reset_arcs(); clear_graph(tree); // asegurar que rbol destino est vaco NODE_BITS(gnode).set_bit(Spanning_Tree, true); // marcar gnode typename GT::Node * tnode = tree.insert_node(gnode->get_info()); GT::map_nodes(gnode, tnode); smos el it Spanning_Tree pr pintr un nodo o ro que hy sido visitdoF gon lo nterior en mente podemos plnter el reorrido en profundidd prtir de gnodeX Recorrer en profundidad nodos adyacentes a gnode 603c (603a 604) for (Node_Arc_Iterator<GT, SA> i(gnode); i.has_current(); i.next()) { typename GT::Arc * arc = i.get_current_arc(); if (IS_ARC_VISITED(arc, Spanning_Tree)) continue;
typename GT::Node * arc_tgt_node = i.get_tgt_node();

603b

603c

604

7. Grafos

if (IS_NODE_VISITED(arc_tgt_node, Spanning_Tree)) continue; // destino ya visitado desde otro arco if (__find_depth_first_spanning_tree<GT,SA>(g, arc_tgt_node, arc, tree, tnode)) return false; // ya el rbol est calculado

v estrutur es similr l de otros lgoritmos sdos en el reorrido en profundiddF v rutin reursiv es __find_depth_first_spanning_tree()D l ul ept los siguientes prmetros en el orden presentdoX IF gX el grfo reorrerF PF arc_tgt_nodeX un nodo dentro de g que n no h sido visitdo y que no tiene imgen en treeF QF garcX el ro tul de g uyo nodo origen es gnodeF xotemos que el ro n no tiene imgen en treeY ste ser insertdo l omienzo de __find_depth_first_spanning_tree()F RF gnodeX un nodo de gD y visitdoD que tiene imgen en treeF SF treeX el rol rdor que se est onstruyendoF TF tnodeX l imgen de gnode en treeF xotemos que en este so funge de nodo destinoF v rutin reursiv resultnte tiene entones l siguiente implntinX rboles abarcadores 603a + 603a 605 template <class GT, class SA> inline static bool __find_depth_first_spanning_tree(GT & g, typename GT::Node * gnode, typename GT::Arc * garc, GT & tree, typename GT::Node * tnode) { NODE_BITS(gnode).set_bit(Spanning_Tree, true); // marcar nodo ARC_BITS(garc).set_bit(Spanning_Tree, true); // marcar arco
typename GT::Node * tree_tgt_node = tree.insert_node(gnode->get_info()); GT::map_nodes(gnode, tree_tgt_node); typename GT::Arc * tarc = tree.insert_arc(tnode, tree_tgt_node, garc->get_info()); GT::map_arcs(garc, tarc); tnode = tree_tgt_node; if (tree.get_num_nodes() == g.get_num_nodes()) // grafo abarcado? return true; // tree ya contiene el rbol abarcador

604

Recorrer en profundidad nodos adyacentes a gnode 603c


} return false;

7.5. Recorridos sobre grafos

605

he este lgoritmo es fundmentl entender su ondiin de prdD ul se lnz undo se hn rdo todos los nodos de gD es deirD undo l ntidd de nodos de tree se l mism que l de gF min es importnte notr que l evitr l didur de un ro o nodo y visitdo en treeD es imposile usr un iloD rzn que grntiz que tree seD en efetoD un rolF
7.5.10 rboles abarcadores de amplitud

605

in el mismo sentido que pr un rol rdor en profundidd podemos plnter un rutin que nos extrig del grfo el rol rdor orrespondiente l reorrido en mE plitud desde un nodo ddoF l rutin se efet de l siguiente mnerX rboles abarcadores 603a + 604 607 template <class GT, class SA = Default_Show_Arc<GT> > inline void find_breadth_first_spanning_tree(GT & g, typename GT::Node * gp, GT & tree) { g.reset_bit_nodes(Spanning_Tree); g.reset_bit_arcs(Spanning_Tree); clear_graph(tree); unique_ptr<typename GT::Node> tp_auto(new typename GT::Node(gp)); tree.insert_node(tp_auto.get()); GT::map_nodes(gp, tp_auto.release());
DynListQueue<typename GT::Arc*> q; // insertar en cola arcos gp for (Node_Arc_Iterator<GT, SA> i(gp); i.has_current(); i.next()) q.put(i.get_current_arc()); NODE_BITS(gp).set_bit(Spanning_Tree, true); while (not q.is_empty()) { typename GT::Arc * garc = q.get(); ARC_BITS(garc).set_bit(Spanning_Tree, true); typename GT::Node * gsrc = g.get_src_node(garc); typename GT::Node * gtgt = g.get_tgt_node(garc); if (IS_NODE_VISITED(gsrc, Spanning_Tree) and IS_NODE_VISITED(gtgt, Spanning_Tree)) continue; // los dos nodos de garc ya fueron visitados if (IS_NODE_VISITED(gtgt, Spanning_Tree)) // gtgt visitado? std::swap(gsrc, gtgt); // s, intercmbielo con gsrc typename GT::Node * tsrc = mapped_node<GT>(gsrc); NODE_BITS(gtgt).set_bit(Spanning_Tree, true); // gtgt visitado // crear copia de gtgt, insertarlo en tree y mapearlo unique_ptr<typename GT::Node> ttgt_auto(new typename GT::Node(gtgt)); tree.insert_node(ttgt_auto.get()); typename GT::Node * ttgt = ttgt_auto.release();

606

7. Grafos

GT::map_nodes(gtgt, ttgt); // insertar nuevo arco en tree y mapearlo typename GT::Arc * tarc = tree.insert_arc(tsrc, ttgt, garc->get_info()); GT::map_arcs(garc, tarc); if (tree.get_num_nodes() == g.get_num_nodes()) // abarca a g? break; // insertar en cola arcos de gtgt for (Node_Arc_Iterator<GT, SA> i(gtgt); i.has_current(); i.next()) { typename GT::Arc * current_arc = i.get_current_arc(); if (IS_ARC_VISITED(current_arc, Spanning_Tree)) continue; // revise nodos de arcos para ver si han sido visitados if (IS_NODE_VISITED(g.get_src_node(current_arc),Spanning_Tree) and IS_NODE_VISITED(g.get_tgt_node(current_arc),Spanning_Tree)) continue; // nodos ya visitados ==> no meter arco q.put(current_arc);

}
Uses

mapped_node

560b.

uesto que de l ol se otienen ros de los ules un solo nodo est ontenido en tree yD demsD tree es permnentemente onexoD entones es imposile que l inlusin de un nuevo ro use un iloF tree esD por tntoD un rol rdorF
7.5.11 rboles abarcadores en arreglos

n mner muy simple de representr un rolD que no explimos en el ptulo RD onsiste en mntener un rreglo de pdres d nodo del rolF gd entrd i del rreglo ontiene el pdre del nodo uyo ndie o nmero es iF v ide es pitorizd medinte los ejemplos de l (gur UFPRF
6

0 6

1 2

2 0

3 6

4 3

5 3

6 -

0 5

1 6

2 6

3 -

4 3

5 3

6 3

(a)

(b)

pigur UFPRX hos ejemplos de roles representdos on rreglos r el so de un rol rdor de un grfoD y en generl pr roles de ulquier ndoleD l representin pitorizd sume que los nodos estn enumerdosD lo ul nos restringe l representinF r evitr esto emplemos un rreglo de punteros nodosD en el ul l entrd ontentiv de NULL represent l rzF gomo el eh List_Graph permite representr multigrfosD el mero rreglo de pdres no es su(iente pr distinguir multirosF ist migedd puede resolverse medinte un

7.5. Recorridos sobre grafos

607

607

rreglo de ros en lugr del de nodosD pero esto slo es vlido si el rol rdor re(ere un digrfoF es queD en rs de l generliddD empleremos dos rreglos de punterosD uno nodos y otro rosF i g es un grfo y de lgun mner tenemos un rol rdor representdo en los rreglos de punteros nodos pred[] y ros arcs[] respetivmenteD entones podemos otener un grfo tree ontentivo del rol rdor medinte l siguiente rutinX rboles abarcadores 603a + 605 template <class GT> void build_spanning_tree(GT & g, GT & tree, DynArray<typename GT::Node> * pred, DynArray<typename GT::Arc> * arcs, const bool with_map = false) { tree.clear(); for (int i = 0; i < g.get_num_nodes(); ++i) { typename GT::Arc * garc = arcs[i]; if (garc == NULL) continue;
typename GT::Node * gsrc = g.get_src_node(garc); typename GT::Node * tsrc = NULL; if (IS_NODE_VISITED(gsrc, Spanning_Tree)) tsrc = mapped_node <GT> (gsrc); else { NODE_BITS(gsrc).set_bit(Spanning_Tree, true); tsrc = tree.insert_node(gsrc->get_info()); } typename GT::Node * gtgt = g.get_tgt_node(garc); typename GT::Node * ttgt = NULL; if (IS_NODE_VISITED(gtgt, Spanning_Tree)) ttgt = mapped_node <GT> (gtgt); else { NODE_BITS(gtgt).set_bit(Spanning_Tree, true); ttgt = tree.insert_node(gtgt->get_info()); } typename GT::Arc * tarc = tree.insert_arc(tsrc, ttgt, garc->get_info()); ARC_BITS(garc).set_bit(Min, true); if (with_map) { GT::map_nodes(gsrc, tsrc); GT::map_nodes(gtgt, ttgt); GT::map_arcs(garc, tarc); }

}
Uses

DynArray

34 and

mapped_node

560b.

608

7. Grafos

il prmetro with_map indi si el rol rdor dee o no mperse on el grfo gF eprte de l eonom de espioD representr roles rdores de grfos medinte rreglos es prtiulrmente til pr lgoritmos de squed de minos mnimosD espeE (mente los lgoritmos de ployd y fellmnEpordD los ules estudiremos en UFWFP @gF TVSA y UFWFQ @gF TWPA respetivmenteF
7.5.12 Conversin de un rbol abarcador a un

Tree_Node

in RFS @gF PTRA desrrollmos el eh Tree_Node D el ul modeliz un rol mErioD mientrs que en ls suseiones preedentes mos de desrrollr lgoritmos pr
Paraguiapos 55 Maracaibo 254 109 252 Maracay 49 130 251 222 Machiques San Felipe 295 252 San Antonio 36 69 48 22 San Cristobal 113 Mrida Sacramento Rubio 150 200 Caparo 38 El Cantn 180 Barinas Guanare 547 San Fernando La Fra 86 El Viga 79 173 526 94 167 Santa Barbara 59 Valera 86 Carora 102 Barquisimeto San Carlos 261 241 220 100 107 120 Ciudad Bolivar San Juan 130 Pto Ordaz 315 Valencia 435 El Tigre 171 139 166 Maturn Coro Caracas 310 Barcelona 199 10 Pto La Cruz 82 Cuman

pigur UFPSX n grfo vil de iuddes y distnis lulr roles rdores orrespondiente los reorridos en profundidd y mplitud de un grfoF in est susein desrrollremos un lgoritmo que nos onvierte un rE ol rdor de tipo List_Graph un rol de tipo Tree_Node F eprte de su vlor didtioD est rutin nos permitir pelr l diujdo utomtio de roles mErios y s esquemtizrD lo lrgo de este textoD diferentes roles que se desuren en muhos de los lgoritmos que existen sore grfosF xuestro lgoritmo de onversin reside en el rhivo graph_to_tree.HF v onversin se invo trvs de l siguiente interfzX Conversin de List_Graph a Tree_Node 608 609a template <class GT, typename Key, class Convert> static Tree_Node<Key> * graph_to_tree_node(GT & g, typename GT::Node * groot); v ul retorn un rol de tipo Tree_Node<Key>* orrespondiente l rol rdor g on rz en groot14 F graph_to_tree_node() tiene tres prmetros tipoX IF GTX il tipo de List_GraphD que ontiene un rol rdor y que se dese onvertir Tree_Node F PF KeyX v lve que se lmenr en el Tree_Node F QF ConvertX n lse de trnsformin desde typename GT::Node* hi Tree_Node<Key>*F in el operdor () de est lse se deleg l onversin trvs de l siguiente llmdX
14
Los rboles dibujados en este texto son procesados con una rutina llamada en el archivo

608

generate_tree.H,

la cual genera un rbol de entrada al programa de dibujado

generate_tree() residente nt.

7.5. Recorridos sobre grafos

609

Merida El Vigia La Fria Machiques Maracaibo Coro Valencia Barquisimeto Carora Valera Caparo Rubio Sn Cristobal Sn Antonio Smento El Canton Barcelona Pto La Cruz Cumana Maturin Pto Ordaz Cd Bolivar El Tigre Guanare Barinas Sn Fernando Sn Juan Caracas Maracay Sn Felipe Sn Carlos Paraguaipos Sta Barbara

pigur UFPTX rol rdor en profundidd del grfo de l (gur UFPS @gF THVA on nodo de iniio wrid
void operator () (typename GT::Node * groot, Tree_Node<Key>* troot)

gd vez que se re y se mpe un nodo de tipo groot de tipo typename GT::Node *D se invo X
Convert () (groot, troot);

v ul extre lgun informin de grootD l onvierte l tipo Key y sign este resultdo troot->get_key()F RF SAX el (ltro de rosF

609a

graph_to_tree_node() se poy sore l siguiente rutin privdX Conversin de List_Graph a Tree_Node 608 + 608 609b
template <class GT, typename Key, class Convert> static void __graph_to_tree_node(GT & g, typename GT::Node * groot, Tree_Node<Key> * troot);

609b

l ul se enrg de reorrer reursivmente el rol rdorg prtir del nodo groot y mntiene en troot el equivlente de tipo Tree_Node<Key>F wedinte __graph_to_tree_node() podemos implntr l rutin prinipl de l siE guiente mnerX Conversin de List_Graph a Tree_Node 608 + 609a 610a template <class GT, typename Key, class Convert, class SA = Default_Show_Arc<GT> > inline Tree_Node<Key> * graph_to_tree_node(GT & g, typename GT::Node * groot)

610

7. Grafos

Tree_Node<Key> * troot = new Tree_Node<Key>; // apartar memoria raz Convert () (groot, troot); //convertir de groot y copiar a troot __graph_to_tree_node <GT, Key, Convert, SA> (g, groot, troot);

return troot;

610a

graph_to_tree() iniiliz l rz Tree_Node<Key>F il resto del trjo lo efet l explorin reursiv de groot implntd por __graph_to_tree()X Conversin de List_Graph a Tree_Node 608 + 609b
template <class GT, typename Key, typename Convert, class SA> static inline void __graph_to_tree_node(GT & g, typename GT::Node * groot, Tree_Node<Key> * troot) { typedef typename GT::Node Node; typedef typename GT::Arc Arc; // recorrer arcos de groot y construir recursivamente for (Node_Arc_Iterator<GT, SA> it(groot); it.has_current(); it.next()) { Arc * arc = it.get_current_arc(); if (IS_ARC_VISITED(arc, Convert_Tree)) continue; ARC_BITS(arc).set_bit(Convert_Tree, true); // arc visitado Node * gtgt = it.get_tgt_node(); Tree_Node<Key> * ttgt = new Tree_Node<Key>; Convert () (gtgt, ttgt); // asignarle la clave troot->insert_rightmost_child(ttgt); // insertarlo como hijo } __graph_to_tree_node <GT, Key, Convert, SA> (g, gtgt, ttgt);

is su(iente on slo mrr los ros que y se hn visitdoD puesD omo g es un rolD no hy posiilidd de visitr l nodo desde otro roF il it de mr se denoE min Convert_TreeF
7.5.13 Componentes inconexos de un grafo

610b

hdo un grfoD se dese determinr l ntidd de sugrfos inonexos que lo onformnF e tles efetosD onsideremos l siguiente primitivX Componentes inconexos 610b 611a template <class GT, class SA = Default_Show_Arc<GT> > inline void inconnected_components(GT & g, DynDlist<GT> & list);
Uses

DynDlist

85a and

inconnected_components

611b.

7.5. Recorridos sobre grafos

611

Merida El Vigia La Fria Sta Barbara Carora Barquisimeto Valencia Maracay Sn Felipe Valera Maracaibo Coro Paraguaipos Caparo Rubio Barinas Guanare Sn Carlos Sn Fernando Sn Juan El Tigre Cd Bolivar Pto Ordaz Maturin

Machiques Sn Cristobal Sn Antonio Smento El Canton

Caracas Barcelona Pto La Cruz Cumana

pigur UFPUX rol rdor en mplitud del grfo de l (gur UFPS @gF THVA on nodo de iniio wrid

611a

inconnected_components() reie un grfo g y un list de grfos v listF vuego de l ejeuin de l primitivD list ontiene los sugrfos mpeos de g orrespondientes sus omponentes inonexosF i g es onexoD entones list ontiene un solo grfoF ry vris mners de provehr el reorrido en profundidd pr resolver este proE lemD lguns ms e(ientes y otrs ms simples de implntrF in todos los sosD l ide si es reorrer los nodos del grfo segn el nodo exmindo se hy visitdo o noF n lgoritmo simple onsiste en efetur dos psdsF v primer reorre los ros por profundidd y pint los nodos segn l onetividdF el (nl de est psdD los nodos y ros quedn pintdos segn el olor del omponente inonexo desde el ul se inii su reorrido en profundiddF hurnte est psd se insertn los nodosD ms no los rosD en los sugrfos resultdosF osteriormenteD en un segund psdD se reorren los ros y stosD segn su olorD se insertn en su orrespondiente sugrfo resultdoF v primer psd del lgoritmo tom O(E)D mientrs que l segund O(E)F or tntoD el lgoritmo es O(E)F e puede logrr un lgoritmo ms e(iente que horre l segund psd si se onstruye diretmente el sugrfo durnte el reorrido en profundidd en lugr de postergrlo pr l segund psdF iste es el enfoque que empleremosF gonsideremos l primitiv siguienteX Componentes inconexos 610b + 610b 611b
template <class GT, class SA = Default_Show_Arc<GT> > inline void build_subgraph(GT & g, GT & sg, typename GT::Node * g_src, size_t & node_count);

611b

build_subgraph() reorre en profundidd el grfo g y onstruye un omponente sg segn l onetividd del nodo que se est visitndoF g_src es el nodo tul de g que se intent visitrF node_count es un ontdor sore el nmero de nodos visitdos que permite detetr undo se h inspeiondo todo el grfoF build_subgraph() es invodo por inconnected_components()D el ul reorre todos los nodos del grfo yD pr d nodo curr_node que no hy sido visitdoD he un llmd build_subgraph()D l ul onstruir el omponente inonexo orrespondiente l reorrido en profundidd desde curr_nodeF r poder mper todo el omponente inonexoD l detenin dee herse undo se hyn reorrido todos los rosF fjo ls reiente premiss podemos enunir el lgoritmo de(nitivoX Componentes inconexos 610b + 611a 612
template <class GT, class SA = Default_Show_Arc<GT> > inline void inconnected_components(GT & g, DynDlist <GT> & list) {

612

7. Grafos

g.reset_nodes(); g.reset_arcs(); size_t count = 0; // contador de nodos visitados for (typename GT::Node_Iterator i(g); // recorrer nodos de g count < g.get_num_nodes() and i.has_current(); i.next()) { typename GT::Node * curr = i.get_current_node(); if (IS_NODE_VISITED(curr, Build_Subtree)) continue; // crear subgrafo componente inconexo conectado por curr_node list.append(GT()); // crea subgrafo y lo inserta en lista GT & subgraph = list.get_last(); // grafo insertado en list } build_subgraph <GT, SA> (g, subgraph, curr, count);

Denes: Uses

inconnected_components, DynDlist 85a.

used in chunk 610b.

612

ehor podemos implntr build_subgraph()D l ul se remite explorr en profunE didd desde un nodo g_src l squed de todos los ros y nodos sequiles desde g_srcD y que onformrn un omponente onexo del grfoX Componentes inconexos 610b + 611b template <class GT, class SA = Default_Show_Arc<GT> > inline void build_subgraph(GT & g, GT & sg, typename GT::Node * g_src, size_t & node_count) { if (IS_NODE_VISITED(g_src, Build_Subtree)) return;
NODE_BITS(g_src).set_bit(Build_Subtree, true); // g_src visitado ++node_count; typename GT::Node * sg_src = mapped_node <GT> (g_src); if (sg_src == NULL) // est mapeado g_src? { // No, cree imagen de g_src en el subgrafo sg y mapee sg_src = sg.insert_node(g_src->get_info()); GT::map_nodes(g_src, sg_src); } for (Node_Arc_Iterator<GT, SA> i(g_src); // explore desde g_src node_count < g.get_num_nodes() and i.has_current(); i.next()) { typename GT::Arc * arc = i.get_current_arc(); if (IS_ARC_VISITED(arc, Build_Subtree)) continue; // avance prximo arco ARC_BITS(arc).set_bit(Build_Subtree, true); // arc visitado typename GT::Node * g_tgt = i.get_tgt_node(); // destino de arc typename GT::Node * sg_tgt = mapped_node <GT> (g_tgt);

7.5. Recorridos sobre grafos

613

if (sg_tgt == NULL) // est mapeado en sg? { // no, hay que mapearlo e insertarlo en el subgrafo sg sg_tgt = sg.insert_node(g_tgt->get_info()); GT::map_nodes(g_tgt, sg_tgt); } // tenemos nodos en subgrafo, insertamos arco y mapeamos typename GT::Arc * sg_arc = sg.insert_arc(sg_src, sg_tgt, arc->get_info()); GT::map_arcs(arc, sg_arc); } build_subgraph<GT,SA>(g, sg, g_tgt, node_count);

}
Uses

mapped_node

560b.

7.5.14

Puntos de articulacin de un grafo

hdo un grfo onexoD un punto de articulacin, o de corteD es un nodo tl que l eliminrse divide l grfo en l menos dos sugrfos disjuntosF v (gur UFPV muestr un ejemplo en el ul sus puntos de rtiulin estn resltdosF
M K B E G

L D C

pigur UFPVX n grfo y sus puntos de rtiulin vos sugrfos disjuntos resultntes de l eliminin de los puntos de orte de un grfo se denominn loques o omponentes onexosF e un grfo sin puntos de rtiulin se le li( de grfo ionexoF vos omponentes onexos de un grfo son ionexosF v determinin de los puntos de rtiulin es fundmentl pr l prue de plnridd y pr lgunos lgoritmos de diujdoD l vez que onstituye otr pliin ms de l squed en profundiddF min revel en ierto modo los puntos rtios de un grfoF or ejemploD en un red eltriD los puntos de rtiulin indin los puntos que l fllr pueden omprometer l redY lo mismo pli l myor de lses de redesX de trnsporteD de pquetes de redD etterF in est susein presentremos un lgoritmo linel sdo en l squed en proE fundiddD el ul permite enontrr e(ientemente los puntos de orte de un grfoF df ) X e un grfo onexo G =< V, E > sore el ul se efet un reorrido en profundiddF e v V un nodoF intonesD df (v) se de(ne omo el ordinl de visit de un reorrido en profundiddF in otrs plrsD df (v) denot el orden de visit en un reorrido en profundiddF
Denicin 7.1 (Nmero

il vlor de df (v) pr ulquier nodo es diretmente lulle por el reorrido en profundidd pre(joF

614

7. Grafos

(a) Grafo con un punto de corte


..... ...... . .... ..... ... ..... ... .... .... ..... .. .... .... .... .... .... .... .. ... B,1,0 ..... . . . . . ... .... . ... . ..... ....... ... . . .. .... . .. ..... . .. . .. ... .... . . . .... . . ...... .... ... .... . ... .. .... . . A,2,0 . . . . ... .. .... . .. . . .. ... .. .. ... . . . ... .... .. .... . .... ... ..... .. . ..... ..... . ... ........... . . .C,3,0 . ... .... ... .. .... . ..... ... .. ..... ... ... . . . ..... . .. G,4,0 ........ .. .. .. . . .. ..... ... . ... .. ........ ..... .... .... ... ... ...... .. ... ... . . . F,5,0 .. ... ... ... .. . . . . ...... .. .... . . H,6,4 . . ...... ....... ...... .... .. ... ... .. . I,7,6 ........ .. .. ..... ... ..... ... ..... .... .... ..... ... ...... .. ....... . . . .....L,8,6 .. ... .. . . . . .. ...... ... ... . .. . . .. .. ..... .. . . . . . . .. .. . .. ...... . J,9,7 . .. ... .. .... ..... ...... ....... K,10,8

D,0,-

J,0,- . I,1,0 H,2,0 . .. .. . .. ...


... . .. ..... . ... .. . .. . ... .. ... . . ... .. ... ... ... ... .. .. ... . . ... .. .... . ... . . .. .. ... .. .. .. ....... .. ..L,9,0 . ... ... .. .. K,10,0

F,3,2 .. ...... . ... .. ..... .... .. .... .... .. .... .... .. .... .... . . B,4,2 . . . . . . .... . . .. ..... ..... ....... ... .. .. ..... ... ..... .. ... .... . ... .. . ... .. . ...... .. ..... .. .... .. .... .. . A,5,2 . . . ... .. ... . .. ... . ...... . . ... .... .... ... ... ..... ... . . . ... .. ... . ... ..... C,6,2 ... . .. .... ........ ... . . . . . . . . . . . . ......... . .. .. . ... ..... . . . .. . . . . .. . ..... .. . . ... .. ..... .. .. . . .. .... ... . G,7,2 .. . .. ... ... .. ... .... .. .... .. .... .. .. ..... ...... ....... .. ....... D,8,3 .........

F,1,0 .. ...... .. ... .. ..... .... .. .... .. .... .. .... .... ... .... ... . . B,2,0 . . . . . . . . . ... . . . .... ..... ....... ... .. .. . .... ..... .. .. ... .... . ... .. . ... .. . ...... .. ..... .. .... .. .... .. . A,3,0 . . . ... .. ... . .. ...... ... . . ... .... .... ... . ... ..... ... . . . ... . .. . ... ...... ... . . .. .... .......C,4,0 ... . . . . . . . . . . . . ......... . .. . .. ... ..... . . . .. . . . . .. . ..... .. . .. ... . . . . ..... . . . .. ... ... . G,5,0 . ... . .. ... .. ... . .. .. ... .. .... . ... .. .. ..... .. ...... ....... .. . ....... . . . D,6,1 ....

H,0,. ... .. .. ... . .. ... ... ...


.. .. .. ..

I,7,0 ........
.... .... ......L,8,0 ....... ..... ..... .... ... .. . . .. .. .. .. . . . .... .... . . . .. .......

....... ..... .... .. ... .. ... .. J,9,7 . . .. .. .. .... ..... ...... ....... K,10,8

(b) en D

Comienzo

(c) Comienzo en J

(d) Comienzo en H

pigur UFPWX n grfo on puntos de orte y sus roles rdores on sus nmeros df D low y ros noErdores puntedos gundo se efet un reorrido en profundiddD los ros por los ules se desuren nuevos nodos son llmdos ros rdoresD pues stos son prte del rol rdor que rteriz el reorridoF enlogmenteD el resto de los rosD es deirD quellos que no son prte del rol rdorD son tilddos de noErdoresF low) X e G =< V, E > ungrfo onexo sore el ul se he un reorrido en profundiddF e v V un nodoF intonesX
Denicin 7.2 (Nmero

low(v) = mnimo de df (x) | x nodo onetdo v por ro noErdor low(w) | w un hijo de v

df (v)

@UFIA

614a

il vlor low(v) puede lulrse progresivmente durnte un reorrido en profundiddF r un nodo p ulquier usremos el ontdor de d nodo pr lmenr df (p)D y el puntero ookie pr el de low(p)X Puntos de corte 614a 615a template <class GT> inline static long & df(typename GT::Node * p) template <class GT> inline static long & low(typename GT::Node * p) ist rutins retornn los vlores de df (p) y low(p)D respetivmenteF istos vlores son iniilizdos l prinipio de l rutin que nos lule los puntos de orteX Inicializar nodos y arcos 614b (616a) Operate_On_Nodes <GT, Init_Low <GT> > () (g); g.reset_arcs();

614b

7.5. Recorridos sobre grafos

615

(a) Grafo sin puntos de corte


..... ...... . .... ..... ... ..... ... .... .... ..... .. .... .... .... .... .... .... .. ... B,1,0 ..... . . . . . ... .... . ... . ..... ....... ... . . .. .... . .. ..... . .. . .. ... .... . . . .... . . ...... .... ... .... . ... .. .... . . A,2,0 . . . . ... .. .... . .. . . .. ... .. .. ... . . . ... .... .. .... . .... ... ..... .. . ..... ..... . ... ........... . . .C,3,0 . ... .... ... .. .... . ..... ... .. ..... ... ... . . . ..... . .. G,4,0 ........ .. .. .. . ..... . .. ..... ... . ... .. ..... ........ ..... .... .. .... .... .... ... ... ...... .. ... ... .. . . . . . F,5,0 ........ .. .... .. ..... .. ..... ... ..... .. ... ... . .. .. . .... ... . . . . . ...... .. .. . .... . . . . . H,6,4 . . ...... . .. . .. ....... ... ...... .. ... .... ... .. .. .... . ..... ..... ...... .. .. ... . I,7,4 ................ .... .. ..... ... ..... ... .... . ..... .. .... .... ..... .. .... ... ...... . .. .. ... ....... . . . .....L,8,4 .. ... .. . . . . .. ...... ... ... . .. . . .. .. ..... .. . . . . . . .. .. . .. ...... . J,9,7 . .. ... .. .... ..... ...... ....... K,10,8

D,0,-

. ..... . . .. . . . . .. ... . . . .. .. ..... . . . .. .. .. . .. .. . . . ... . .. ... ... .. . .. . F,2,0 . . . . . . . ... .. ... .. ... . .. ..... .. . .. .. . ..... . . ..... .. . . .. .. . .. . . .... .. .. .. .. .. .... ... . .. ... . .. . B,3,0 . .. . ... ....... . . . . . . . . . . .. ... . . . . . .. . . . ..... ... .. . .. .. ... ... . ... .. . . . . .. .. .. .. .. .. .. .. .... . . ... . .. . . . . . . ... .. . . .. .. .. . .. .. ... . .. .. .. A,4,0 .. .. .. . . . ... ... . .. .. . .. . . .. .. . .. ... . ... . ... . .. . .. . .. ... .. .. .. . ... . ... . . ... ... . ...... . ... . . . . . . ... . ....... C,5,0 ... .. ... . . .... .. ... .. .. . . . ... . .. . .. ... ....... .... . .. .. . . ... .. . .. ..... ... .. .. . . . . .. . . . ..... .. . .. .... . .. .. .. .. .. G,6,0 . . . . . . . . . .. . .. ... ..... .. . .. .. .. . . . . . . . . . . . . . . .. . . .. ...... ... .. .... . .. . . . . . . . . . . . . . .. .. . .... .. ... . . . .. ... . . . . . . . .. .. .. .. .. D,7,2..... ... . L,8,0 . . ... .. ... ... . . . . ... . .. .... ..... . ..... .. .... ...... .. ... . ....... . . .. H,9,1 .. K,10,0

J,0,- .... I,1,0

. . . .. . . . .. . F,1,0 .. ..... .... . . .. . ... . ..... .. ... . . . . . . .. . . .. .. .. . .. . ... . ... . ... . ... .... ... . .. .. . B,2,0 . .. ... ...... . . ... ...... . .. . . . . ... . . . . .. . .. . ..... .. .. . ... .. . .. ... . . . . . . . .... . .. . .. .. .... . . .. ... . . .. . . . . . . .. . .. .. ... . A,3,0 . . . .. .. . . . . . . .. ... . .... .. ... .. .. .. . .. ... . . . . .. ... .. .. .... .. .. .. .. .. . . ... ... ... .... . .. . . . .... ..... . .. ... .... . .. C,4,0 . . .. .. . .. . .... ... .. .. .. . . .. . .. ... .......... . .. . .. .. ... ... . ... .. . . . . . ... . . ....... . . . . . . . . .... . ... . ... .......... G,5,0 . .. .. ... ... . . . . ..... . .. . .... . . . ... ... .... . ... . . . . ... ..... .. .. . D,6,1 ... . L,7,0 . ....... .. ....... ...... .. .. ...... .. ..... . . . . . . . .... . .... ... . . . . .. ... .. .. . . . I,8,0 . . . ... .. .. .. . . .. . . . . . ..... .. ... . . ... ... J,9,7 ........ .... ... .... .... ..... ...... ...... K,10,7 .... .... ...

. .... ....

H,0,- ...

(b) en D

Comienzo

(c) Comienzo en J

(d) Comienzo en H

pigur UFQHX n grfo sin puntos de orte y sus roles rdores on sus nmeros df D low y ros noErdores puntedos

615a

honde l iniilizin de un nodo est instrumentd por llse Init_LowD uy espeiE (in es omo sigueX Puntos de corte 614a + 614a 615b template <class GT> struct Init_Low { void operator () (GT & g, typename GT::Node * node) { g.reset_counter(node); // inicializa df low <GT> (node) = -1; // inicializa low } }; v interfz de lulo de los puntos de orte se denomin compute_cut_nodes()Y sus prmetros son el grfoD el nodo iniio de squed y un list sore l ul se lmenn sus puntos de rtiulinX

615b

Puntos de corte 614a +

615a 623

template <class GT, class SA = Default_Show_Arc<GT> > void compute_cut_nodes(GT & g, typename GT::Node * start, DynDlist<typename GT::Node *> & list) {

}
Uses

Inicializar deteccin de nodos de corte 616a Explorar recursivamente las ramas de start 616b Vericar si start es un nodo de corte 617a
85a.

DynDlist

616

7. Grafos

7.5.14.1

Deteccin de los puntos de corte

il lgoritmo de lulo de puntos de orte efet un reorrido en profundiddD lul progresivmente los vlores df (v) y low(v) pr d nodo v y determin si v es o no un punto de orte segnX IF i v es rz y tiene dos o ms rmsD entones v es un nodo de orteF isto ser demostrdo en l proposiin UFI @g TPHAF PF v no es rz y v tiene un hijo w tl que low(w) df (v)D entones v es un punto de orte isto ser demostrdo en l proposiin UFP @g TPHAF in el nterin puede veri(rse l pliilidd exminndo ls (gurs UFPW y UFQHF
7.5.14.2 Desarrollo del algoritmo

616a

compute_cut_nodes tiene tres fses uys funiones estn lrmente enunidsF eprte de reiniir los ros y nodos requerimos el ontdor glol de visits que determinr el df de d nodoD el nodo iniil por donde omenzr usr y un ontdor de llmds l explorin reursivD l ul ser implntd por __compute_cut_nodes()X Inicializar deteccin de nodos de corte 616a (615b)
long current_df = 0; // contador global de visitas NODE_BITS(start).set_bit(Depth_First, true); // marcar start df <GT> (start) = current_df++; int call_counter = 0; // contador llamadas recursivas

Inicializar nodos y arcos 614b

616b

call_counter uent l ntidd de llmds efetuds __compute_cut_node()D lo ul permitir luegoD segn el onoimiento ddo en UFSFIRFI @gF TITAD determinr si start es o no un nodo de orteF v siguiente fse es l explorin reursiv todos los nodos onetdos por startX Explorar recursivamente las ramas de start 616b (615b) // Recorra los arcos de start mientras g no haya sido abarcado for (Node_Arc_Iterator<GT, SA> i(start); i.has_current() and current_df < g.get_num_nodes(); i.next()) { typename GT::Node * tgt = i.get_tgt_node(); if (IS_NODE_VISITED(tgt, Depth_First)) continue;
typename GT::Arc * arc = i.get_current_arc(); if (IS_ARC_VISITED(arc, Depth_First)) continue; ARC_BITS(arc).set_bit(Depth_First, true); __compute_cut_nodes <GT, SA> (g, list, tgt, arc, current_df); ++call_counter;

7.5. Recorridos sobre grafos

617

617a

egn el orolrioD start es un nodo de orte si el rol rdor de profundidd on rz start tiene ms de un hijoF in lo trminos de este lgoritmoD esto est determindo por l ntidd de vees que se explore reursivmente un nodo onetdo startY diho de otro modoD l ntidd de vees que se llme __compute_cut_nodes()F i se llm un sol vezD start no es un nodo de orteF he lo ontrrioD sin importr el vlor exto de call_counterD start es de orteF vo nterior se expres entones del siguiente modoX Vericar si start es un nodo de corte 617a (615b) if (call_counter > 1) // es la raz un punto de articulacin? { NODE_BITS(start).set_bit(Cut, true); list.append(start); } gd vez que se detete un nodo de orteD ste se mrr on el it CutD el ul nos servir luego pr mrr los omponentes onexos soidos los puntos de orteF v interfz de l explorin reursivD __compute_cut_nodes()D se expres sX Denicin del recorrido recursivo para los puntos de corte 617b template <class GT, class SA> inline static void __compute_cut_nodes(GT & g, DynDlist<typename GT::Node *> & list, typename GT::Node * p, typename GT::Arc * a, long & curr_df);
Uses

617b

DynDlist

85a.

uyos prmetros se de(nen omo sigueX IF gX el grfoF PF listX l list de nodos de orteF __compute_cut_nodes() de d punto de orte enontrdo est listF QF pX el nodo tulmente siendo visitdoF RF aX el ro desde el ul se lnz pF iste esD en el rol rdor de profundiddD el ro que onet su nodo pdreF SF curr_dfX el vlor tul del ontdor de visits que ser signdo l nodo siendo visitdo omo su vlor df F v implntin de __compute_cut_nodes() de l reursinD el lulo de los vE lores low de d nodo y l distinin de que el nodo visitdo se o no un hoj dentro del eventul rol rdor de profundiddX Implantacin del recorrido recursivo para los puntos de corte 617c template <class GT, class SA> inline static void __compute_cut_nodes(GT & g, DynDlist<typename GT::Node *> & list, typename GT::Node * p, typename GT::Arc * a, long & curr_df)
{ NODE_BITS(p).set_bit(Depth_First, true); // pinte p visitado low <GT> (p) = df <GT> (p) = curr_df++; // asgnele df // recorrer arcos de p mientras no se abarque a g

617c

618

7. Grafos

bool p_is_cut_node = false; for (Node_Arc_Iterator <GT, SA> i(p); i.has_current(); i.next()) { typename GT::Arc * arc = i.get_current_arc(); if (arc == a) continue; // a es el padre de arc ==> ignorarlo typename GT::Node * tgt = i.get_tgt_node(); if (IS_NODE_VISITED(tgt, Depth_First)) { if (not IS_ARC_VISITED(arc, Depth_First)) // no abarcador? if (df<GT>(tgt) < low<GT>(p)) // s, verificar valor low low<GT>(p) = df<GT>(tgt); // actualizar low(p) continue; } if (IS_ARC_VISITED(arc, Depth_First)) continue; ARC_BITS(arc).set_bit(Depth_First, true); // marque arco __compute_cut_nodes<GT, SA>(g, list, tgt, arc, curr_df); if (low<GT>(tgt) < low<GT>(p)) low<GT>(p) = low<GT>(tgt); // actualizar low(p) if (low<GT>(tgt) >= df<GT>(p) and df<GT>(tgt) != 0) // de corte? p_is_cut_node = true;

}
Uses

// aqu, p ya fue explorado recursivamente if (p_is_cut_node) { NODE_BITS(p).set_bit(Cut, true); list.append(p); }


DynDlist
85a.

v rutin proveh el propio reorrido sore los ros pr lulr low(p) extE mente segn l frmul @UFIAF sniilmenteD low(p) = df (p)D luegoD durnte l inspein de los ros de pD se determin si se trt del ro pdreD de un ro noErdor o de un hijoF gd mird sore un ro hijo o uno noErdor veri( si hy un vlor menor pr olorle low(p)F vos ros noErdores se identi(n porque no son mrdos on el it Depth_FirstF il ro pdre se distingue medinte el prmetro aF pinlmenteD los ros del rol rE dor s son mrdos justo ntes de l llmd reursivF uesto que pr determinr si p es un nodo de orte es neesrio inspeionr todos sus ros @rdores y noErdoresAD l detenin del reorrido dee herse undo se hyn mirdo todos los ros y no todos los nodosF hespus de un llmd reursiv se se que tgt es un hijo de pF or es rzn se ompr low(tgt) df (p) pr detetr si p es un nodo de orteF il lgoritmo propg el menor vlor de low desde ls hojs hst sus nestrosD pues l ide es memorizr si existe un ro dentro de un desendeni que rue o no hi un sendeniF

7.5. Recorridos sobre grafos

619

19

18 20

16 15

17

14 21 28 27

13

10

23 7 1

26

22 11 12 2 3

24

25

(a) Un grafo con varios puntos de corte


... . ..1,0,.. ... ... ... ... ... .... ..... ..... ... . 21,20,0 . . . .... . ... . .... . . . .... . .. . .... . . .. . .... . . . .... . . . . .... . . . . . .... . 23,21,0 . . 15,14,13 . ..... . . . . . . . . . ..... . . . . . . . . . . . . . .. . . . . . . .... .. . . . . . . . . . . ..... . . .. . . . . . . ..... . . .... . . . . . . . .... . 16,15,13 22,22,0 28,23,21 . . ... .. . . . . . .. ... . . . . .. . .. . . . . . . . . . .. . . . . . . . .. . . . . . . . . . . . . . . .. . . . . 19,16,13 24,24,21 ... . . . . . .. ... . . . . . . . . . .. . . . . . . . .. .. . . . . . . ... . . . . . . . ... . . . . 20,17,13 18,19,14 27,25,23 . . . . . . . .. . . . . . . . . .. . . . . . . .. . . . . . . . . . . . .. . . . 17,18,13 25,26,24 . . . . .. ... ... 26,27,25 .. .. . .. . 14,13,13 . .. ... .

2,1,0 . ..
...

7,6,6 ... . .
...

... ...

... . . . ... . .. . . ... .. . . .. . ... . . ... .. .. . . . . . . . . . . ... 5,2,0 ... . . . . .8,7,6 . . . ... ... . . . .. . . . .. .. . . ... ... . . . ... .. .. .. .. .. . ... . ... . ... .. . ... .... ... . ... . 4,3,0 ... . .. .. 10,8,6 . . . . .. .. ... ... .. . . .. . . . . . . .... . .. . . . .. . .. .. .. .. .. . .. .. .. .. . .. . . . . .... .. . .. ... . . . . . . .... . .. . .. ... .. . 6,4,0 9,9,6 . . . . . . .. .. . .. . . . . . . . . . . ... .. . .. . . . . . . .. .. . .. . . . . . .. . . . . . . . . . . . ... . .. . . . ... . .. . .. 3,5,0 .. . . . .. . 13,10,6 . . . .. .. . .. . .. . .. . .. . .. . .. . .. . .. . .. .11,11,6 . .. . . .. . . .. . .... .. ..

12,12,6

(b) rbol abarcador

pigur UFQIX n grfo y su rol rdor de profundidd junto on sus df y low


7.5.14.3 Anlisis Anlisis y correctitud del algoritmo

uesto que compute_cut_nodes() es esenilmente un squed en profundidd que exmin todos los rosD el oste del lgoritmo es O(E) + O(V )F
Correctitud

xuestr prue se orientr demostrr que los dos riterios enunidos en UFSFIRFI @gF TITA efetivmente detetn puntos de orteF il primer pso pr nlizr l orretitud es rterizr un propiedd fundmentl de un punto de orteD l ul est expresd por el siguiente lemF
Lema 7.1 i v es un punto de orte de un grfo G tl que l eliminr v de G este se divide en l menos dos sugrfos G1 y G2 D entones todo mino desde ulquier nodo en G1 hi ulquier otro nodo en G2 ontiene vF

uesto que v es un punto de orteD el grfo puede verse s de mner generl omo en l (gur UFQPF
Demostracin (Por contradiccin)

620

7. Grafos

G2

G1

pigur UFQPX isquem generl de divisin de un grfo en torno punto de orte i existiese un mino G de u hi w que no pse por vD entones v no ser un punto de orteD lo que es un ontrdiin r el so en el que un nodo se rz de un rol rdor de profundiddD l detein del punto de orteD tl omo se expres en UFSFIRFIE se veri( medinte l siguiente proposiinF
Proposicin 7.1

e T el rol rdor de profundidd de un grfo G =< V, E > generdo prtir de un nodo vF i v tiene ms de un hijoD entones v es un nodo de orteF

Demostracin upongmos un nodo v que no es de orte y es rz de un rol rdor en profundiddF en u y w dos hijos de v tl omo en l (gur UFQQF
v u w

pigur UFQQX gso genrio negdo de l proposiin UFI eordemos que el reorrido en profundidd @y __compute_cut_nodes()A mr los nodos visitdos en pre(jo @justo en l primer lneAF esD el primer nodo visitdo es vD despus u y seguidmente todos los nodos que sen lnzles desde u sin psr por vD pues ste ltimo est mrdo omo visitdoF hespus de her visitdo uD el reorrido regres v @se regres compute_cut_nodes()15 A y prosigue hi los nodos dyentes v que n no hn sido visitdosY en nuestro so hi wF or tntoD no existe ningn ro que onete un nodo en l rm uy rz es u on un nodo en l rm uy rz es wD pues si no huiese sido visto desde u o desde uno de sus desendientesF gonseuentementeD todo mino x y tl que x es igul o desendiente de u e y es igul o desendiente de w ps por el nodo vD lo ul impliD segn el lem UFID que v es un nodo de orte r ompror l orretitud de l segund ondiin de detein @UFIA enunid en UFSFIRFI @gF TITA nos vldremos de l siguiente proposiinF e G =< V, E > un grfoF e T =< V, E >, E E un rol rdor de profundidd de G y v un nodo ulquier de T distinto l rzF i v tiene un hijo w tl que low(w) df (v)D entones v es un nodo de orteF
Proposicin 7.2
15
Note que se trata de

compute_cut_nodes()

y no del recorrido recursivo

__compute_cut_nodes().

7.5. Recorridos sobre grafos

621

Demostracin (Por contradiccin) vo primero que deemos her es reordr l de(niin de low(w) segn l frmul UFIX

low(w) = mnimo de df (x) | x nodo onetdo v por ro noErdor low(y) | y un hijo de w

df (w)

@UFPA

ehor deemos mirr el lgoritmoD espe(mente l rutin __compute_cut_nodes()D y estudir mo st efetivmente stisfe el lulo segn @UFPAF il vlor iniil de low(w) se sign en l segund lne de __compute_cut_nodes()X
low <GT> (p) = df <GT> (p) = curr_df++; // asgnele df

he qu se desprende que iniilmente low(w) > df (v)F or tntoD de no fetrse low(w) durnte el resto de l ejeuin de __compute_cut_nodes()D w ser detetdo omo un punto de orteF r el siguiente nlisis es onveniente mntener en uent que un omponente onexo no ontiene puntos de orteF in orden seuenilD ls prtes de __compute_cut_nodes() on prmetro w en ls ules se puede fetr low(w) sonX IF if (IS_NODE_VISITED(tgt, Depth_First)) { if (not IS_ARC_VISITED(arc, Depth_First)) // no abarcador? if (df<GT>(tgt) < low<GT>(w)) // s, verificar valor low low<GT>(w) = df<GT>(tgt); // actualizar low(p) // ... e deen reunir vris ondiiones pr que ourr est fetinF in primer lugrD los nodos w y tgt y deen estr visitdosF in segundo lugr el ro w tgt no h sido visto por el reorridoD o seD el ro w tgt es no rdorF pinlmenteD l fetin slo ourre si df(tgt) < low(w)F glrmente existe un mino tgt v wY pero el que exist un ro direto w tgt y low(tgt) < low(w) impli que existe un ilo tgt v w tgtD pues df (tgt) < df (w)F or tntoD tgt, v y w perteneen l mismo omponente onexoD lo ul impli que v no es un nodo de orteF PF if (low<GT>(tgt) < low<GT>(w)) low<GT>(w) = low<GT>(tgt); // actualizar low(p) ist fetin slo puede ourrir despus de her visitdo entermente tgtF r que low(tgt) < low(w) se iertoD un desendiente de tgt dee estr onetdo un nestro de vF v situin es genrimente pitorizd en l (gur UFQRF vlmemos x tl desendienteF il vlor low(x) es fetdo durnte l ejeuin de l lne nterior y disutidF vuegoD los nestros entre w y x vn heredndo el vlor low(x) durnte el regreso reursivoF iste so es un extensin del nterior en el ul existe un ilo tgt v w x tgtF or tntoD jo el mismo rzonmientoD tgt, v, w y x perteneen l mismo omponente onexoD lo ul impli que v no es un nodo de orteF

622

7. Grafos

tgt

pigur UFQRX egundo so de modi(in del vlor low(w) in sntesisD iniilmente low(w) df (v) y v se sume omo de orteF vuego se trnsE form low(w) < df (v) si v no es de orteF ehor neguemos l proposiin y supongmos que v tiene un hijo w tl que low(w) df (v) pero v no es de orteD lo ul no es posile segn lo que mos de nlizr del lgoritmoF v proposiin es pues iert rst el presenteD hemos demostrdo que los dos riterios de detein de puntos de orte mostrdos en UFSFIRFI @gF TITA son orretosF ero nuestr demostrin no prue que compute_cut_nodes() detet todos los puntos de orteF r herloD deemos ompror que ulquier punto de orte enj en un de ls dos ondiionesF il mino lgio pr herlo es demostrr l su(ieni de d un de ls proposiiones UFI y UFP respetivmenteD lo ul es delegdo en ejeriioF
7.5.15 Componentes conexos de los puntos de corte

n vez luldos los puntos de orte puede ser desele onoer ules son sus compooD tminD bloques D es deirD los sugrfos resultntes de suprimir los puntos de orteF n primer y muy simple lgoritmo pr determinr los omponentes onexos onsiste en tomr un opi mped del grfo y sore ste eliminr sus nodos de orteF vos sugrfos resultntes son diretmente los omponentes onexos del grfoF n prolem on este lgoritmo es su oste en espioF uede ser interesnte no slo tener los omponentes onexos sino el resto del grfo originlD de modo tl que pudirmos reonstruirlo prtir de sus omponentes onexosD puntos de orte y ros que ontengn l menos un punto de orteF is momento de introduir dos nuevs de(niionesF
nentes conexos Denicin 7.3 (Arco de corte) e un grfo G =< V, E > y dos nodos de orte u, v tles que stos onformn un ro a = (u, v) EF intones el ro (u, v) es denomindo de orteF hiho de otro modoD un ro de orte es quel onformdo por dos nodos de orteF itrimenteD un ro de orte se generliz del siguiente modoX
G1 u v G2

or ejemploD los ros (1, 7) y (1, 14) del grfo de l (gur UFQI son de orteF

7.5. Recorridos sobre grafos

623

Denicin 7.4 (Arco de cruce)

e un grfo G =< V, E > y un ro a E tl que a = (u, v) est ompuesto por un nodo de orte u y por un nodo v perteneiente lgn omponente onexoF intonesD el ro a = (u, v) es llmdo de rueF itrimenteD un ro de rue se generliz del siguiente modoX
u v G2

or ejemploD los ros (1, 2), (1, 21) y (1, 22) del grfo de l (gur UFQI sonD entre otros msD de rueF ytendremos los omponentes onexos en dos fsesF v primer se enrg de pintr los omponentes onexosD los nodos y ros de orte y los ros de rue on diferentes olores de modo tl que en l fse siguiente se les distingF r est fse empleremos l rutin paint_subgraphs()F hd un list de nodos de orte luld medinte compute_cut_nodes()D paint_subgraphs() pint los omponentes onexos del grfo segn los ortesF ist tE niD ms omplej pero on menor onsumo de espioD onsiste en pintr el grfo prtir de un punto de orte e ir mindo los olores segn se regrese l punto de prE tid o se lne otro punto de orteF isto presume que ls mrs dids @el it CutA por compute_cut_nodes() n siguen presentesF vlmremos nuestr primitiv si paint_subgraphs()D l ul tiene l siguiente interfzX
template <class GT, class SA> long paint_subgraphs(GT & g, const DynDlist<typename GT::Node*> & cut_node_list);

g es un grfo on sus nodos de orte luldos y gurddos en l list cut_node_listD mientrs que cut_arc_list es un prmetro de slid que retorn los ros de orte del grfoF il vlor de retorno es l ntidd de olores enontrdD o seD l ntidd de omponentes onexos o loquesF paint_subgraphs() sume que previmente se ejeut sore el grfo l rutin compute_cut_nodes()F vuego de un llmd paint_subgraphs()D el grfo g deviene oloredo de l siE guiente formX
IF gomponentes onexos lrededor de un nodo de orte son oloredos on un olor entre 1 y nD donde n es l ntidd totl de omponentes onexos que tiene el grfoF or oloredosD insistimosD queremos deir que todos los nodos y ros perteneientes un olor i tienen su vlor de ontdor en iF PF vos nodos de orte tienen olor 0F QF vos ros de orte tienen olor 0 y el it Cut en trueF RF vos ros de rue son oloredos on el olor espeil Cross_ArcF xotemos que est lse de ro no es de orte ni pertenee un omponente onexoF il olor de un ro de rue se de(ne omoX
623

Puntos de corte 614a +


Denes:

615b 624

const long Cross_Arc = -1;


Cross_Arc,
used in chunks 624 and 625b.

624

7. Grafos

r veri(r si un ro es de rueD empleremos l primitiv siguienteX


624

Puntos de corte 614a +

623 625a

template <class GT> inline static bool is_a_cross_arc(typename GT::Arc * a) { return ARC_COUNTER(a) == Cross_Arc; }
Cross_Arc
623.

Uses

v segund fse onsiste en mper el grfo previmente pintdo segn lguno de los olores empledos en l primer fseF r est fse se emplen dos primitivsX IF
template <class GT, class SA> void map_subgraph(GT & g, GT & sg, const long & color);

e utiliz pr otener los omponentes onexos del grfo segn sus puntos de rtiE ulinF

g es un grfo on sus nodos de orte previmente luldos y mrdo meE dinte compute_cut_nodes()F sg es el grfo en donde se dese otener un opi mped del omponente onexo de olor color previmente pintdo meE dinte paint_subgraphs()F
xotemos que deemos her tnts llmds sore sugrfos sg distintos omo omE ponentes onexos teng gF y seD l ntidd de oloresD ul es el vlor de retorno de paint_subgraphs()F PF
template <class GT, class SA> void map_cut_graph(GT & g, DynDlist<typename GT::Node*> & cut_node_list, GT & cut_graph, DynDlist<typename GT::Arc*> & cross_arc_list);

ytiene el grfo de orteD es deirD el grfo ompuesto por todos los nodos y ros de orteF

g es un grfo on sus nodos de orte previmente luldos y mrdo meE dinte compute_cut_nodes()F cut_node_list es l list de nodos de orte tmin otenid luego de llmr compute_cut_nodes()F cut_graph es el grfo donde se dese un opi mped del grfo de orteF pinlmenteD cross_arc_list es l list de ros de rue en gD los ules no perteneen ni los omponentes onexosD ni l grfo de orteF
7.5.15.1 Pintado de componentes conexos

qrosso modoD l tni de pintdo onsiste en iniir un reorrido en profundidd desde un nodo onetdo punto de orteF gundo el reorrido reursivo lne un nodo de orteD que puede ser el mismo de prtidD entones se he un mio @inrementoA de olorF hurnte el reorrido de un omponenteD tnto los nodos omo los ros son oloredos on el olor tulF n vez que todos los ros hyn sido reorridos sin ruzr un punto de orteD entones el grfo estr oloredo segn los omponentes soidos sus puntos de rtiulinF

7.5. Recorridos sobre grafos

625

625a

iendo que un loque se ede desde un ro de rueD su pintdo se origin en el nodo perteneiente l ro de rueX Puntos de corte 614a + 624 625b template <class GT, class SA> inline static void __paint_subgraph(GT & g, typename GT::Node * p, const long & current_color) { if (is_node_painted <GT> (p)) return;
paint_node <GT> (p, current_color); for (Node_Arc_Iterator<GT, SA> it(p); it.has_current(); it.next()) { typename GT::Arc * arc = it.get_current_arc(); if (is_arc_painted <GT> (arc)) continue; typename GT::Node * tgt = it.get_tgt_node(); if (is_a_cut_node <GT> (tgt)) continue; paint_arc <GT> (arc, current_color); } __paint_subgraph <GT, SA> (g, tgt, current_color);

625b

v llmd iniil __paint_subgraph() se ejeut desde un ro de rue por l siguiente rutin que revis un punto de orteX Puntos de corte 614a + 625a 626a template <class GT, class SA> inline static void __paint_from_cut_node(GT & g, typename GT::Node * p, long & current_color) { // pintar recursivamente con dif colores bloques conectados a p for (Node_Arc_Iterator<GT, SA> it(p); it.has_current(); it.next()) { typename GT::Arc * arc = it.get_current_arc(); typename GT::Node * tgt_node = it.get_tgt_node(); if (is_a_cut_node <GT> (tgt_node)) // es un arco de corte? { ARC_BITS(arc).set_bit(Cut, true); // marque como de corte continue; // avance a prximo arco } else { paint_arc <GT> (arc, Cross_Arc); // marque como de cruce if (is_node_painted <GT> (tgt_node)) continue; } // pintar recursivamente nodo conectado a arc

626

7. Grafos

__paint_subgraph <GT, SA> (g, tgt_node, current_color); } current_color++; // cambiar color (sig arco en otro bloque)

}
Uses

Cross_Arc

623.

626a

gomo se veD __paint_from_cut_node() tom un nodo de orte y se enrg de invor __paint_subgraph() sore el ro tul o pintr el ro de orteF pinlmente no flt implementr l rutin priniplX Puntos de corte 614a + 625b 626b template <class GT, class SA = Default_Show_Arc<GT> > inline long paint_subgraphs(GT & g, const DynDlist<typename GT::Node*> & cut_node_list) { g.reset_counter_nodes(); g.reset_counter_arcs(); long current_color = 1;
// Recorrer cada nodo de corte y pintar sus bloques for (typename DynDlist<typename GT::Node*>::Iterator i(cut_node_list); i.has_current(); i.next()) __paint_from_cut_node<GT,SA>(g, i.get_current(), current_color); }
Uses

return current_color;
DynDlist
85a.

hespus de lulr los puntos de orte y tenerlos en cut_node_listD el usurio invo paint_subgraphs() pr pintr on distintos olores los loques del grfoF gd loque puede distinguirse medinte su olorF vos ros de rue se distinguen trvs del olor espeil Cross_ArcF vos nodos y ros de orte se distinguen medinte el it CutF rst el presente no se h heho un opi diionl del grfoF
7.5.15.2 Copia mapeada de componentes conexos

626b

in lguns irunstnis es onveniente opir los distintos loques de un grfoF or ejemploD los lgoritmos de diujdo o de detein de plnridd simpli(n sus lulos trjndo sore los loquesF uesto que menudo es neesrio modi(r los loquesD es preferile herlo sore opis que sore el grfo originlF il proeso de identi(inD opi y mpeo un sugrfoD ddo un olor es simple un vez que se tienen pintdos los omponentes onexosX usr y enontrr el primer nodo on el olor de inters yD prtir de lD her un explorin en profundidd que visiteD opie y mpee los nodos y ros on el mismo olorF ore un nodo del grfo gsrcD on el olor de inters  colorD y opido y mpedo un sugrfo sgD el resto del mpeo se omplet reursivmente de l siguiente mnerX Puntos de corte 614a + 626a 627 template <class GT, class SA> inline static void __map_subgraph(GT & g, GT & sg, typename GT::Node * gsrc, const long & color) { typename GT::Node * tsrc = mapped_node<GT>(gsrc); // gsrc en sg

7.5. Recorridos sobre grafos

627

// recorrer arcos de gsrc y aadir a sg los del color de inters for (Node_Arc_Iterator <GT, SA> i(gsrc); i.has_current(); i.next()) { typename GT::Arc * garc = i.get_current_arc(); if (get_color <GT> (garc) != color or IS_ARC_VISITED(garc, Build_Subtree)) continue; // arco es de otro color o ya est visitado ARC_BITS(garc).set_bit(Build_Subtree, true); typename GT::Node * gtgt = i.get_tgt_node(); typename GT::Node * ttgt = NULL; // imagen gtgt en sg if (IS_NODE_VISITED(gtgt, Build_Subtree)) // gtgt en sg? ttgt = mapped_node<GT> (gtgt); else { // gtgt no est en sg ==> copiarlo y mapearlo unique_ptr<typename GT::Node> ttgt_auto(new typename GT::Node(gtgt)); sg.insert_node(ttgt_auto.get()); GT::map_nodes(gtgt, ttgt_auto.get()); NODE_BITS(gtgt).set_bit(Build_Subtree, true); ttgt = ttgt_auto.release(); } typename GT::Arc * tarc = sg.insert_arc(tsrc, ttgt, garc->get_info()); GT::map_arcs(garc, tarc); } __map_subgraph<GT, SA> (g, sg, gtgt, color);

}
Uses

mapped_node

560b.

627

__map_subgraph() mr los nodos y ros visitdos on el it Build_SubtreeY de este modo se distingue que un nodo o ro on el olor de inters hy sido o no mpedoF v rutin de interfz map_subgraph() us sore el grfo g el primer nodo on olor  color y mpe el omponente onexo l sugrfo sgF e espei( omo sigueX Puntos de corte 614a + 626b 628 template <class GT, class SA = Default_Show_Arc<GT> > void map_subgraph(GT & g, GT & sg, const long & color) { clear_graph(sg); typename GT::Node * first = NULL; // busque primer nodo con color for (typename GT::Node_Iterator it(g); it.has_current(); it.next()) if (get_color <GT> (it.get_current_node()) == color) first = it.get_current_node();
// cree first, insrtelo en sg y mapelo unique_ptr<typename GT::Node> auto_tsrc(new typename GT::Node(first)); sg.insert_node(auto_tsrc.get()); GT::map_nodes(first, auto_tsrc.release()); NODE_BITS(first).set_bit(Build_Subtree, true); } __map_subgraph <GT, SA> (g, sg, first, color); // mapee first

628

7. Grafos

xos flt por onstruir el grfo de orte y gurdr los ros de rueF r eso on un psd sore l list de nodos de orte remos y mpemos sus imgenes en el grfo de orte cut_graphF hespusD efetumos un rrido sore todos los rosF vos que estn pintdos los ignormosD pues perteneen los omponentes onexosF vos ros de orte los opimos e insertmos en cut_graphD mientrs que los de rue los insertmos en l list cross_arc_listF n detlle esenil es pertrse de queD on exepin de los omponentes onexos y del grfo de orteD los ros de rue no son opidosF
628

Puntos de corte 614a +

627

template <class GT, class SA = Default_Show_Arc<GT> > void map_cut_graph(GT & g, DynDlist<typename GT::Node*> & cut_node_list, GT & cut_graph, DynDlist<typename GT::Arc*> & cross_arc_list) { clear_graph(cut_graph); // recorra lista de nodos de corte e insrtelos en cut_graph for (typename DynDlist<typename GT::Node*>::Iterator it(cut_node_list); it.has_current(); it.next()) { typename GT::Node * gp = it.get_current(); unique_ptr<typename GT::Node> tp_auto(new typename GT::Node(gp)); cut_graph.insert_node(tp_auto.get()); GT::map_nodes(gp, tp_auto.release()); } // recorra arcos de g ==> cut_graph = {arcos no corte} U // cross_arc_list = {arcos de cruce} for (Arc_Iterator <GT, SA> it(g); it.has_current(); it.next()) { typename GT::Arc * garc = it.get_current_arc(); if (is_a_cross_arc <GT> (garc)) { cross_arc_list.append(garc); continue; } if (not is_an_cut_arc <GT> (garc)) continue; typename GT::Node * src = mapped_node<GT>(g.get_src_node(garc)); typename GT::Node * tgt = mapped_node<GT>(g.get_tgt_node(garc)); typename GT::Arc * arc = cut_graph.insert_arc(src, tgt, garc->get_info()); GT::map_arcs(garc, arc);

}
Uses

DynDlist

85a and

mapped_node

560b.

il grfo cut_graph es inonexo y sus omponentes pueden hllrse medinte build_subgraph() implntd en gomponentes inonexos 610b @ UFSFIQ @gF TIHAA

7.6 Matrices de adyacencia


ixiste un mplio orpus de l teor de grfosD s omo un extens vriedd de irunsE tnis de desempeoD en ls ules puede ser preferile usr l mtriz de dyeni omo

7.6. Matrices de adyacencia

629

representin de un grfoF ALEPH export los siguientes eh vinuldos ls mtries de dyeniX IF Map_Matrix_Graph<GT>X modeliz un mtriz de dyeni mpeo de un grfo de tipo GT sdo sore List_GraphF iste eh emple omo ojetos ls lses Graph_Node y Graph_Arc utilizds pr List_GraphF il eso un entrd de l mtriz retorn punteros ros de un grfo implemenE tdo medinte un vrinte de List_GraphF ueden espei(rse punteros nodos o sus ndies en l mtriz de dyeniF

Map_Matrix_Graph<GT> no est destind en s lulosD simplemente onstituye el primer pso pr otener un mtriz de dyeniF in emrgoD desde este eh es posile modi(r los ontenidos de los nodos y de los rosF
PF Matrix_Graph<GT>X modeliz un mtriz de dyeni prtir de un List_Graph uys entrds ontienen el tipo Graph_Arc::ArcF v ide de este eh es otener un opi de un grfo sdo sore List_Graph que pued modi(rse sin fetr el grfo originlF QF Ady_MatX modeliz un mtriz de dyeni en l ul el usurio espei( el tipo de dto que se dese omo entrd de l mtrizF RF Bit_Mat_Graph<GT>X el ul modeliz un mtriz de dyeni de itsF vs utro lses nteriores se de(nen en el rhivo tpl_matgraph.HD de ls ules presentremos on ierto detlle Ady_Mat @ UFTFI @gF TPWAA y Bit_Mat_Graph<GT> @ UFTFP @gF TQQAAF
7.6.1 El TAD

Ady_Mat

629

in muhs irunstnis se requiere un mtriz homomorf un de dyeni que onE teng vlores distintos yD muy prolementeD de tipos diferentes los del grfoF or ejemE ploD podr neesitrse un mtriz ontentiv de duriones de tryetos entre rosF r l situin nterior se tiene el tipo Ady_MatD el ul modeliz un mtriz eleE mentos de tipo Entry_Type y espei(d de l siguiente formX Ady_Mat 629 template <class GT, typename __Entry_Type, class SA = Default_Show_Arc<GT> > class Ady_Mat { Miembros privados de Ady_Mat 630a Miembros pblicos de Ady_Mat 630b }; Implantacin de mtodos de Ady_Mat 632b

Ady_Mat dee estr estritmente ligdo un ojeto List_GraphF il punto esenil en l lse Ady_Mat est ddo por el heho de que el usurio puede deidir el tipo de dtos que lergrn ls entrds de l mtrizF gonseuentementeD Ady_Mat no neesrimente represent un mtriz de dyeniF

630

7. Grafos

630a

vos triutos de Ady_Mat son muy similres los de ls mtries nterioresX Miembros privados de Ady_Mat 630a (629) GT * lgraph; DynArray<Node*> nodes; DynArray<Entry_Type> mat; mutable size_t num_nodes; mutable Entry_Type Null_Value;
Uses

DynArray

34 and

Null_Value.

630b

vos esos un ojeto Ady_Mat son similres los de Map_Matrix_Graph<GT>F vos nodos pueden referirse por punteros nodos en un List_Graph o por sus ndies enteros respeto l mtrizF il onsumo de memori de l mtriz es proporionl l ntidd de entrds que hyn sido esritsF n entrd (i, j) que no hy sido esrit puede retornr false undo se invoque mat.exist(index)F or este medio se detet si l entrd es nulF il resto de los triutos son oservlesX Miembros pblicos de Ady_Mat 630b (629) 630c GT & get_list_graph() { return *lgraph; }
const Entry_Type & null_value() const { return Null_Value; } const size_t & get_num_nodes() const { return num_nodes; }
Uses

Null_Value.

630c

il uso de Null_Value es el mismo que el de l lse Matrix_Graph<GT>X de(nir el ero en l mtriz y permitir un horro de espio por los ros usentesF uesto que el tipo de dto que ontiene l mtriz es independiente del ojeto List_GraphD no hy neesidd de oupr espio priori pr el ontenido de l mtrizF or eso tiene sentido el siguiente onstrutorX Miembros pblicos de Ady_Mat 630b + (629) 630b 630d Ady_Mat(GT & g) : lgraph(&g), num_nodes(lgraph->get_num_nodes()) { copy_nodes(g); } in este soD l mtriz no oup memori iniilmenteY st se prtr medid que ls entrds se vyn esriiendoF in emrgoD si se opt por onstruir de est form un ojeto Ady_MatD entones el usurio dee enrgrse l mismo de esriir tods ls entrds de l mtriz @ trvs del operdor (i, j)AD pues el vlor Null_Value no se h de(nidoD o de(nir Null_Value ntes de efetur ulquier esriturF il eh no veri( este ordenF ry dos mners de horrr memori por useni de ros o porque l pliin mneje lgn elemento nuloD l primer onsiste en de(nir Null_Value en tiempo de onstruin medinteX Miembros pblicos de Ady_Mat 630b + (629) 630c 631a Ady_Mat(GT & g, const Entry_Type & null) : lgraph(&g), num_nodes(lgraph->get_num_nodes()), Null_Value(null) { copy_nodes(*lgraph); }
Uses

630d

Null_Value.

7.6. Matrices de adyacencia

631

631a

in este soD Entry_Type dee ser el mismo tipo que GT::Arc_TypeF n error de ompiE lin dee generrse si no es sF v segund mner es medinte l siguiente primitivX Miembros pblicos de Ady_Mat 630b + (629) 630d 631b void set_null_value(const Entry_Type & null) { Null_Value = null; }
Uses

Null_Value.

il tipo Ady_Mat est destindo pr gurdr dtos de ulquier tipoD sore todo pr lulos temporles requeridos por lgoritmos de grfos disedos pr mtries de dyE eniF gomo tlD es muy omn iniilizr mtries de tipo Ady_MatF r est tre se proveen dos lses de interfesX IF
631b

Miembros pblicos de Ady_Mat 630b +

(629)

631a 631c

template <class Operation> void operate_all_arcs_list_graph();

ist primitiv ejeut l operin Operation() sore d entrd de l mtriz que onteng un ro en List_GraphF xotemos que l operin no se invo pr ros usentesF il formto de l lse Operation() es Operation()(mat, arc, i, j, entry)D uyos pE rmetros se desrien sX @A matX es un refereni l ojeto Ady_Mat sore el ul se est relizndo l operinF @A arcX es un puntdor l ro dentro del List_Graph soido l mtrizF @A iX es el ndie del nodo origen en l mtrizF @dA jX es el ndie del nodo destino en l mtrizF @eA entryX es un refereni l ontenido de l entrd (i, j) en l mtrizF iventulmenteD si se requiere trnsmitir lgn prmetro diionl l operinD entones puede usrse l siguiente versinX
631c

Miembros pblicos de Ady_Mat 630b +

(629)

631b 632a

template <class Operation> void operate_all_arcs_list_graph(void * ptr);

v ul invo Operation()(mat, arc, i, j, entry, ptr)F gomo ejemploD onsideremos iniilizr un mtriz on los vlores de distnis gurddos en d roF uponiendo que l distni de un ro es esile medinte un mtodo del ro llmdo get_distance()D l iniilizin de un ro en l mtriz puede espei(rse de este modoX
struct Init_Arc { void operator () (AdyMat<Grafo) & mat, Grafo::Arc * arc, int & i, int & j, Entry & entry) { entry = arc->get_distance(); } };

632

7. Grafos

he este modo pueden iniirse tods ls entrds medinteX


mat.operate_all_arcs_list_graph <Init_Arc> ();

uesto que slo se iniilizn entrds pr ros dentro del List_Graph soidoD quells entrds en donde no hy ro ontienen el vlor Null_ValueF PF v segund interfz est sd en ndies de Ady_MatX
632a

Miembros pblicos de Ady_Mat 630b +

(629)

631c

template <class Operation> void operate_all_arcs_matrix(); template <class Operation> void operate_all_arcs_matrix(void * ptr);

il esquem es similr l nteriorD slvo que en este so se reorren tods ls entrds yD por tntoD se prt l memori pr todsF gonseuentementeD el onsumo de espio es O(n2 )F il esquem de prmetros de l lse Operation() es el siguienteX @A matX refereni l mtrizF @A src_nodeX puntero l nodo origen dentro del List_Graph soidoF @A tgt_nodeX puntero l nodo destino dentro del List_Graph soidoF @dA sX ndie del nodo origenF @eA tX ndie del nodo destinoF @fA entryX refereni entrd dentro de l mtrizF @gA ptr @opionl segn l interfzAX puntero opoF glri(d l interfzD podemos mostrr lguns de ls implementiones de los mtoE dos nterioresX Implantacin de mtodos de Ady_Mat 632b (629) template <class GT, typename __Entry_Type, class SA> template <class Operation> void Ady_Mat<GT, __Entry_Type, SA>::operate_all_arcs_list_graph() { // recorrer todos los nodos del grafo for (typename GT::Node_Iterator nit(*lgraph); nit.has_current(); nit.next()) { Node * src = nit.get_current_node(); const long src_idx = node_index<List_Graph_Type>(nodes, num_nodes, src);
// recorrer todos los arcos del nodo origen for (Node_Arc_Iterator<GT, SA> at(src); at.has_current(); at.next()) { Arc * arc = at.get_current_arc(); const long tgt_idx = node_index<List_Graph_Type>(nodes, num_nodes, arc->get_tgt_node()); Entry_Type & entry = mat.touch(index_array(src_idx, tgt_idx, num_nodes));

632b

7.6. Matrices de adyacencia

633

Operation () (*this, arc, src_idx, tgt_idx, entry);

template <class GT, typename __Entry_Type, class SA> template <class Operation> void Ady_Mat<GT, __Entry_Type, SA>::operate_all_arcs_matrix() { const long & n = num_nodes; for (int s = 0; s < n; ++s) { Node * src_node = get_node<GT>(nodes, s); for (int t = 0; t < n; ++t) { Node * tgt_node = get_node<GT>(nodes, t); Entry_Type & entry = mat.touch(index_array(s, t, num_nodes)); } Operation () (*this, src_node, tgt_node, s, t, entry);

}
7.6.2

El TAD

Bit_Mat_Graph<GT>

633a

v ltim lse de mtriz se llm Bit_Mat_Graph<GT> y represent un muy simple mtriz de dyeni de itsF n vlor uno indi preseni de roY uno nuloD useniF or supuestoD el tipo en uestin est sdo en el eh BitArray desrrolldo en PFIFS @gF SQA y se de(ne de l siguiente mnerX Mtodos privados de Bit_Mat_Graph<GT> 633a (633b) 633c BitArray bit_array;
Uses

BitArray

54a.

633b

wientrs que el Bit_Mat_Graph<GT> se espei( medinte l siguiente lseX Bit_Mat_Graph<GT> 633b template <class GT, class SA = Default_Show_Arc<GT> > class Bit_Mat_Graph { Mtodos privados de Bit_Mat_Graph<GT> 633a Mtodos pblicos de Bit_Mat_Graph<GT> 634a }; n Bit_Mat_Graph<GT> represent un mtriz de dyeni uyos its slo expreE sn preseni o useni de ro dentro de un grfo representndo on un List_GraphF Bit_Mat_Graph<GT> no sirve pr mnejr multigrfos o multidigrfosF Bit_Mat_Graph<GT> mntiene un puntdor l List_Graph soidoD un rreglo dinmio de nodos que permitir lulr rpidmente el ndie medinte l squed inri y l ntidd de nodosX Mtodos privados de Bit_Mat_Graph<GT> 633a + (633b) 633a GT * lgraph; DynArray<typename GT::Node*> nodes;

633c

634

7. Grafos

mutable size_t
Uses

n;

DynArray

34.

634a

ry vris mners de onstruir un Bit_Mat_Graph<GT>X Mtodos pblicos de Bit_Mat_Graph<GT> 634a Bit_Mat_Graph() : lgraph(NULL) {}

(633b) 634b

Bit_Mat_Graph(GT & g) : bit_array(g.get_num_nodes()*g.get_num_nodes()), lgraph(&g) { copy_list_graph(g); } Bit_Mat_Graph(const Bit_Mat_Graph & bitmat) : bit_array(bitmat.bit_array), lgraph(bitmat.lgraph), nodes(bitmat.nodes), n(bitmat.n) {} Bit_Mat_Graph(const size_t & dim) : bit_array(dim*dim), lgraph(NULL), nodes(dim), n(dim) {}
Uses

copy_list_graph.

634b

il urto onstrutor no requiere un List_Graph porque est destindo delrr mtries de its usrse pr lulos prilesF istoD por supuestoD impide el eso por direiones de nodos en un List_GraphF iventulmente se puede espei(r el List_Graph por seprdoD s omo tmin onsultrloX Mtodos pblicos de Bit_Mat_Graph<GT> 634a + (633b) 634a 634c void set_list_graph(GT & g) { const size_t & n = g.get_num_nodes(); bit_array.set_size(n*n); lgraph = &g; copy_list_graph(g); } GT * get_list_graph() { return lgraph; }
Uses

copy_list_graph.

634c

pinlmenteD deemos implntr ls utro forms de esoD dos de ls ules pueden instrumentrse diretmente de form similr ls lses mtries que y hemos trtdoX Mtodos pblicos de Bit_Mat_Graph<GT> 634a + (633b) 634b Node * operator () (const long & i) { return Aleph::get_node<GT>(nodes, i); } long operator () (Node * node) const { return node_index<GT>(nodes, n, node); } v implntin del eso un entrd mtriil (i, j) es ms omplej que ls nterioresD pues el ompildor y l myor de hrdwre no mnejn its omo un uniddF il ompildor mnej plrs ompuests por itsF xo podemosD puesD implntr el operdor (i, j) pr que retorne un itF mpoo nos sirve que el operdor (i, j) nos

7.6. Matrices de adyacencia

635

retorne un plr de tipo intD pues el eso podr ser de esriturF heemos entones distinguir los esos de esritur de los de letur y pr eso se us un lse Proxy en el mismo estilo que otros tipos y estudidosF
7.6.3 Algoritmo de Warshall

slustrremos nuestr primer utilizin de un mtriz de dyeni pr implntr un lere lgoritmo que lul tods ls reliones de onetividd de un grfo trvs de los distintos minosF il lgoritmo en uestin tiene ms sentido sore grfos dirigidos y es onoido omo de rshll IUV en honor su desuridorF
02 04 06 10 13

03

07

09

11

01

05

08

12

14

pigur UFQSX n grfo dirigido gomo enunimos l prinipioD un grfo es un mner de representr un relin mtemtiF in este sentidoD un relin inri E sore un onjunto V @lo ul onform el grfo < V, E >A es transitiva si x, y, z V = (x, y), (y, z) EF n grafo transitivo es todo quel que represent un relin trnsitivF v lusur trnsitiv de un relin R es l relin R de(nid por todo pr (x, y) R tl que existe un mino entre x e yF v lusur trnsitiv R de un relin R es l mnim relin que ontiene RF
Denicin 7.5 (Clausura transitiva)

i un relin R se represent mtriilmenteD entones l mtriz orrespondiente l relin R represent tods ls reliones posiles de onetividd entre d pr de nodosF n entrd R (i,j) = 0 indi que existe un mino entre los nodos i y jF glulr R nos permiteD puesD implementr un prue de existeni de mino entre ulquier pr de nodosF il lgoritmo de rshll pr lulr l lusur trnsitiv se sirve de l onstruin de reliones entre minos de longitud i + 1F v ide es onstruir un seueni de reliones intermedis @o digrfosA R0 , R1 , R2 , . . . , Rn F in d iterin que lul Rk D se exminn todos los tros (vk , vi , vj ) de nodos de Rk1 F i l trnsitoriedd vi vj vk existe en Rk1 D entones se de el ro vi vk Rk
k k i j i j

=
(b)

(a)

k1

Rk

pigur UFQTX edidur de ro en Rk

636

7. Grafos

or supuestoD si dentro de un trio (vk , vi , vj ) en Rk1 y existe un ro vi vk D entones l entrd Rk i,j = 1F v frmul resultnte es entonesX
k 1 1 k 1 Rk ( Rk i,j = Ri,j i,k Rk,j )

@UFQA

il proeso se ejeut n vees hst llegr los minos de longitud nF vo que nos rroj
n

R = Rn =
v operin

k =1

R k 1 R k

@UFRA

R k 1

Rk

se efet segn @UFQAF


1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0 0 0 1 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 1 0 0 0 0 1 0 0 0 0 0 0 0 5 0 0 1 0 0 0 0 0 0 0 0 0 0 0 6 0 0 1 1 0 0 0 0 0 0 0 0 0 0 7 0 0 0 0 1 0 0 0 0 0 0 0 0 0 8 0 0 0 0 0 0 1 0 0 0 0 0 0 0 9 0 0 0 0 0 0 1 0 0 0 0 0 0 0 10 11 12 13 14 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0

R0 =

pigur UFQUX wtriz de dyeni de its del grfo de l (gur UFQS il lulo de l lusur trnsitiv de un grfo representdo medinte un ojeto de tipo List_Graph se instrument en el rhivo wrshllFr 636a espei(do de l siguiente formX warshall.H 636a template <class GT, class SA = Default_Show_Arc<GT> > void warshall_compute_transitive_clausure(GT & g, Bit_Mat_Graph<GT, SA> & mat) {
}

636a

Calcular clausura transitiva 636b

636b

g es un List_Graph sore el ul se dese lulr l lusur trnsitivD mientrs que mat es el resultdo de l lusur en uestin segn el lgoritmo de rshllF e efetos de horro de espio diseremos un lgoritmo que slo use dos mtries de mner tl de no redundr el espio de ls n mtriesF r eso denominmos mat omo l mtriz de its Rk en l iterin k y mat_prev omo Rk1 D el ul hy que iniir R0 X Calcular clausura transitiva 636b (636a) 637
Bit_Mat_Graph<GT, SA> mat_prev(g);

7.7. Grafos dirigidos

637

637

lo nos qued implntr el lgoritmo en si segn @UFRAX Calcular clausura transitiva 636b + (636a) const size_t & n = mat.get_num_nodes(); for (int k = 0; k < n; k++) { for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) mat(i, j) = mat_prev(i, j) or (mat_prev(i, k) and mat_prev(k, j));
} mat_prev = mat;

636b

1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 1 1 1 1 0 1 0 0 0 0 0 0 0

2 0 0 0 0 0 0 0 0 0 0 0 0 0 0

3 1 1 1 1 1 0 1 0 0 0 0 0 0 0

4 1 1 1 1 1 0 1 0 0 0 0 0 0 0

5 1 1 1 1 1 0 1 0 0 0 0 0 0 0

6 1 1 1 1 1 0 1 0 0 0 0 0 0 0

7 1 1 1 1 1 0 1 0 0 0 0 0 0 0

8 1 1 1 1 1 0 1 0 0 0 0 0 0 0

9 1 1 1 1 1 0 1 0 0 0 0 0 0 0

10 11 12 13 14 1 1 1 1 1 1 1 0 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0

R =

pigur UFQVX glusur trnsitiv del grfo del l (gur UFQS @pgF TQSAF

7.7 Grafos dirigidos


el iniio de este ptulo introduimos l noin de grfo dirigido o digrfoF in UFQFP @gF SRUA presentmos el eh que lo representD List_DigraphD uy implntin es fundmentlmente idnti l de List_GraphD pues st ltim es su se por hereniF gsi todos los lgoritmos que hst el presente hemos disedo opern on digrfosF wuhos lgoritmos mtriilesD en l ourreni el de rshll pr l lusur trnsitivD y el de ploydErshll pr el lulo de minos mnimos @ver UFWFP @gF TVSAAD fueron oneidos pr digrfosF ypern perfetmente sore grfos porque un grfo es tmin un digrfo16 F
Aqu puede revelrsenos una inconsistencia expresada por el hecho de que List_Digraph hereda de List_Graph y no al revs, como pudiera sugerir la lnea de razonamiento que estamos tomando. La inversin se debe a la estructura de datos y la reutilizacin. En lo que concierne a la implantacin, la nica diferencia entre los dos tipos se encuentra en la implantacin del mtodo

16

insert_arc()

( 7.3.10.4 (Pg. 572)). Si

observamos bien este mtodo podemos percatarnos de que podramos implantar a los digrafos como base de los grafos. La decisin obedeci a que los algoritmos sobre grafos son ms generales que los de digrafos y, sobre todo, ms simples. Parece, pues, con ms sentido comn que los grafos sean base objetiva (tienen los mismos mtodos) y subjetiva de los digrafos y no al contrario.

638

7. Grafos

7.7.1

Conectividad entre digrafos

638a

in digrfosD l ide de onetividd puede ser onfusF hos nodos son onexos o estn diretmente onetdos si entre ellos existe un roF hel mismo modoD son onexos o estn indiretmente onetdos si entre ellos existe un mino que los oneteF imiE lrmenteD un digrfo es onexo si todos sus nodos son onexosF in un digrfoD emperoD el que un nodo p est onetdo q no impli que q est onetdo pF iste heho tiene onseuenis en los lgoritmosF in l ourreni de est suseinD nos revel que l rutin test_connectivity() estudid en UFSFQ @gF SVWA no nos sirve pr digrfosF r digrfos es preferile menudo empler l noin de lnzilidd entre dos nodosX un nodo q es lnzle desde otro p si existe un mino p qF es ls ossD podemos her un prue de onetividd sndonos en el reorrido en profundidd que veri(que si desde d nodo se pueden lnzr los restntesD l ul y fue previmente instrumentdX Algoritmos para digrafos 638a 638b template <class GT, class SA = Default_Show_Arc<GT> > bool is_reachable(GT & g, typename GT::Node * src, typename GT::Node * tgt) { return test_for_path <GT, SA> (g, src, tgt); } v mism rutin sd en l squed en profundidd puede usrse sin prolem lguno pr digrfos representdos on listsF
7.7.2 Inversin de un digrafo

638b

in osiones puede ser til otener el digrfo inverso G =< V, E >D es deirD un digrfo on los mismos nodos pero sus ros invertidosF isto se logr muy filmente reorriendo el digrfo e insertndo ros invertidos en el digrfo destinoX Algoritmos para digrafos 638a + 638a template <class GT, class SA = Default_Show_Arc<GT> > void invert_digraph(GT & g, GT & gi) { // recorrer todos los arcos del digrafo g for (Arc_Iterator<GT, SA> it(g); it.has_current(); it.next()) { typename GT::Arc * arc = it.get_current();
// procesar nodo origen typename GT::Node * ssrc = g.get_src_node(arc); typename GT::Node * rsrc = mapped_node<GT> (ssrc); if (rsrc == NULL) // ya est creado ssrc en gi? { // no == crearlo, insertarlo y mapearlo unique_ptr<typename GT::Node> rsrc_auto(new typename GT::Node(ssrc)); gi.insert_node(rsrc_auto.get()); GT::map_nodes(ssrc, rsrc_auto.get()); rsrc = rsrc_auto.release(); } // procesar nodo origen typename GT::Node * stgt = g.get_tgt_node(arc);

7.7. Grafos dirigidos

639

}
Uses

typename GT::Node * rtgt = mapped_node<GT> (stgt); if (rtgt == NULL) // ya est creado ssrc en gi? { // no == crearlo, insertarlo y mapearlo unique_ptr<typename GT::Node> rtgt_auto(new typename GT::Node(stgt)); gi.insert_node(rtgt_auto.get()); GT::map_nodes(stgt, rtgt_auto.get()); rtgt = rtgt_auto.release(); } typename GT::Arc * ai = gi.insert_arc(rtgt, rsrc, arc->get_info()); GT::map_arcs(arc, ai);

mapped_node

560b.

invert_digraph() es un rutin muy simpleF glrmenteD su desempeo es O(E) y menudo se us omo etp iniil de otros lgoritmosF n pliin es onoer el grdo de entrd de un nodoF hdo un nodo pD g.get_num_arcs(p) nos proporion el grdo de slidD mientrs que gi.get_num_arcs(p) el de entrdD siendo gi el grfo inverso de gF in expresiones formles suele designrse l grdo de entrd omo gin (v) y gout (v) omo el de slidF in l jerg de digrfos suelen usrse los trminos grdo de dyeni pr referir l grdo de slid y grdo de inideni pr el de entrdF in ese sentido se distinguen dos lses de nodos espeilesF e uno l ul slo le lleguen ros y desde el ul no slg ningunoD es deirD uno uyo grdo de dyeni se eroD se le tild de terminl o sumideroF in el sentido simtrimente inversoD uno desde el ul slo slgn ros y no le llegue ningunoD o seD uno on grdo de inideni eroD se le llm fuente u origenF
7.7.3 Componentes fuertemente conexos de un digrafo

n ide similr l onetividd en digrfos es l de conectividad fuerte F heimos que dos nodos u y v estn fuertemente onetdos si existen los minos u vyv uF in funin de su lnzilidd deimos que un digrfo es  fuertemente onexo si todos sus nodos son lnzles entre siF gontrrimenteD deimos que es dilmente onexo si no es fuertemente onexoF n indiin de l fuerz de onetividd de un grfo puede onoerse medinte el lgoritmo de rshll @ UFTFQ @gF TQSAAF i el grfo es fuertemente onexoD entones su lusur trnsitiv no ontiene erosF inontrmos pues en este lgoritmo un tni O(V 3 ) pr verigur por l onetividd fuerteD s omo tmin indgr sore l lnE zilidd entre ulquier pr de nodosF hisponiendo de l lusur trnsitivD l prue de lnzilidd tom lo sumo O(lg V )D si se requiere indizr los nodosF r grfos enormes y densosD el lgoritmo de rshll puede ser inplile en espE ioY en estos sos podemos doptr un estrtegi sd en l rutin is_reachable()Y invorl pr d pr de nodos nos he el mismo trjo en O(V 2 ) O(V E) = O(V 3 E) psosY ms ostoso en tiempo pero menos en espioF in funin de l onetividd fuerteD en un digrfo pueden identi(rse sus componentes fuertemente conexos Y es deirD loques o sugrfos dilmente

640

7. Grafos

(a)

(b)

pigur UFQWX n digrfo y sus dos omponentes fuertemente onexos onexos entre siD pero fuertemente onexos en sus nodos internosF ry vrios y leres lgoritmos pr lulr los omponentes fuertemente onexosF
7.7.3.1 Algoritmo de Kosaraju

el ms ntiguo lgoritmo onoido pr determinr los omponentes fuertemente onexos de un digrfoD y prolemente el ms simple de omprenderD se le onoe omo el de uosrjuF
Algoritmo 7.2 (Algoritmo de Kosaraju)

v entrd es un digrfo G =< V, E >F v slid es un list l de omponentes fuertemente onexosF IF l = PF rg un squed en profundidd en G en l ul los nodos se enumern en su(jo segn su orden de termininF e df (v) este nmeroF QF gonstruy el grfo invertido G =< V, E > mpedo on GD es deirD los mpos df (v) en G son los mismos luldos en el pso PF RF e S l seueni de nodos ordend desendentemente por df F e i = |V |F SF v S = @los nodos preen ordendos por df (v) desde el myor hst el menorA @A i v no est mrdo = iF e T =

iiF T = grfo lnzle por el reorrido en profundidd desde v en G sore todo nodo que no est visitdoF
el (nl de iloD T es un omponente fuertemente onexo de GF TF wrque todos los nodos y ros de T F UF l = l T F odemos identi(r tres fses priniplesD tods O(V ) + O(E)X el reorrido en proE fundidd que enumer los nodos por su orden de terminin reursivD l onstruin de G y el reorrido (nl ordendo desendentemente en el que se desuren los ompoE nentes fuertemente onexosF hdo un loque fuertemente onexoD l enumerin invers de los nodos re)ej el orden de visit del reorrido en profundiddF in el ejemplo de l (gur UFRHE identi(mos los nodos i @IHAD q @SAD r @WA e s @VA omo los ltimos nodos

7.7. Grafos dirigidos

641

en mrrse en su(jo de los loques identi(dos en el grfo inverso de l (gur UFRHE omo D D y respetivmenteF in el so del primer nodo i @IHAD ste desure el omponente sin posiilidd de mirr lgunos de los loques restntesF vuegoD desde r @WAD puede lnzrse el loque D pero ste y est mrdo omo visitdoD lo que he que slo se ve el nodo r @WAF imilrmenteD desde el nodo s @VA se pueden lnzr los loques y D pero un vez msD esto se evit l y estr visitdosF
1 A B 3 5 G F 4 A 1 B 3 5 G F 4

b d

8 E 10 C 2 D 0 H 9 K 6 I J

7 E 10 C 2 D 0 H 9 I

8 J

g a

K 6

(a) El digrafo luego del primer recorrido

(b) El grafo invertido

pigur UFRHX vs dos fses del lgoritmo de uosrjuF vos nodos estn etiquetdos segn su orden de terminin reursiv en profundiddF e sume que l llmd iniil ourre en el nodo i il lulo de df (v) se efet en profundiddD pero l signin del ontdor de visit se he el su(joD o seD l trmino de l llmd reursivD tl omo se indi en l siguiente rutinX Asignacin de df en sujo 641 template <class GT, class SA> inline static void __dfp(GT & g, typename GT::Node * p, DynArray<typename GT::Node*> & df) { if (IS_NODE_VISITED(p, Depth_First)) return;
NODE_BITS(p).set_bit(Depth_First, true); // recorre en profundidad los arcos de p for (Node_Arc_Iterator<GT,SA> it(p); it.has_current(); it.next()) { typename GT::Arc * a = it.get_current_arc(); if (IS_ARC_VISITED(a, Depth_First)) continue; ARC_BITS(a).set_bit(Depth_First, true); __dfp<GT,SA>(g, it.get_tgt_node(), df); } df.append(p); // asignacin de df(p) en sufijo NODE_COUNTER(p) = df.size();
DynArray
34.

641

}
Uses

in lugr de psr un ontdorD l rutin reie un rreglo dinmio de punteros nodosF v ide es gurdr en el rreglo l seueni de signin del df (v) pr un nodo ddo vF il elemento df[0] represent el primer nodo l ul se sign su df D el ul es el ms profundo en l llmd reursivF enlogmenteD df[1] es el segundo nodo y s suesivmente hst

642

7. Grafos

terminr on el nodo iniio de l llmd reursivF il uso del rreglo df[] evit ordenr explitmente los nodos por su enumerin o utilizr un hep pr onoer el myorF v instrumentin (nl del lgoritmo de uosrjuD s omo su veri(in de orreE titudD se delegn en ejeriioF
7.7.3.2 Algoritmo de Tarjan

il lgoritmo de rjn UVD ITT tiene l virtud de identi(r los loques de un digrfo en un solo reorrido en profundidd y sin neesidd de opir el grfoF r eso l rutin emple un vrinte de los nmeros df y low de(nidos en UFSFIR @gF TIQAD @UFIA @pgF TIRA er del lulo de los puntos de orte o rtiulinF in quel entones de(nimos df (v) omo el orden en que es visitdo el nodo v por un reorrido en profundidd y low(v) omo el mnimo df entre todos los nodos onetdos v por minos onformdos por ros rdores y noErdoresF uesto que se trt de un digrfoD no requerimos pensr en ros noErdoresD sino ms ien en nodos lnzlesF he este modoD low(v) puede de(nirse ms simple omoX

low(v) = mnimo df
B1

del omponente fuertemente onexo donde se enuentr v

@UFSA

B2 B
4

F J B
5

E B3 C D

pigur UFRIX n digrfo on sus loques gonsideremos un nodo ulquier v y un rutin reursiv en profundidd __scc(v,...)D l ul siempreD su iniioD (j df (v) = low(v) = ontdor de visit tulF or l propi de(niin de onetividd fuerte @ UFUFI @gF TQVAAD es lro que ulquier llmd reursivD sin importr ul se el nodoD desurir todos los nodos perteneientes l loque en el ul se enuentr vF ehor oservemos el digrfo de l (gur UFRI y ejempli(quemos vris llmdsF i l llmd ourre sore el nodo MD entones st slo se desure un solo loqueD el B5 F i l llmd ourre sore HD entones se desuren los loques B3 D B4 y B5 F i l llmd ourre sore hD entones se desuren todos los loquesF urge pues l pregunt existe lgun mner de delimitr el loquecD es deirD undo inspeionmos un ro w xD mo podemos disernir si w y x estn o no en el mismo loquec sndependientemente del nodo por donde iniiemos un reorrido en profundiddD el vlor low(v)D pr ulquier nodo vD dee orresponderse on el vlor df (v) del primer nodo visitdo dentro del loqueF etomndo el ejemplo de l (gur UFRID un eventul orden de visit puede exminrse en l (gur UFRPF il orden de primers llmds __scc(v,...) se muestr en l (gur UFRQF gd rol orresponde un llmd desde el for de tarjan_connected_components()D mientrs que d rol muestr los loques que se desuren reursivmente en profundiddF

7.7. Grafos dirigidos

643

B1 11,5 A 10,5 B 8,8 G

B2 9,8 F J 7,5 E H 12,12 2,1 I 4,1 3,1 1,1 K 14,13 M B


4

15,13 N

5,5 C D 6,5

B3

13,13

pigur UFRPX n reorrido en profundidd del digrfo de l (gur UFRIF gd nodo est etiquetdo on el pr df , lowF
K-(1,1) C-(5,5) O-(13,13)

I-(2,1)

D-(6,5)

M-(14,13)

J-(3,1)

E-(7,5)

N-(15-13)

L-(4,1)

G-(8,8)

B-(10,5)

H-(12,12)

F-(9,8)

A-(11,5)

pigur UFRQX roles de reorrido en profundidd pr el digrfo de l (gur UFRPF gd nodo muestr l etiquet del nodo y sus nmeros df y lowF he l (gur UFRQ podemos her lguns oserviones en pos de disernir si un pr de nodos estn o no dentro del mismo loqueX IF i el rol tiene un sol rmD entones ste ontiene un solo loqueF iste es el so de los loques B4 y B5 F PF i el rol ontiene vris rmsD entones hy tnts rms omo loquesF iste es el so del segundo rolD uy rz es gD el ul ontiene los loques B1 D B2 y B3 F in este soD mo distinguimos un loque del otroc n oservin ms detlld nos permite identi(r que los loques B2 y B3 se enuentrn en rms hijs del nodo iF he qu nos pree l pregunt mo identi(mos el iniio de un rmcF v respuest est dd por el pr < df (v), low(v) >F gd iniio de rmD que se orresE ponde l iniio de un loqueD se identi( por el heho de que df (v) = low(v)F isto es independiente de l form de l rmF il vlor df (v) es lulle medinte un ontdor de visitsD mientrs que el vlor low(v) es lulle por retorno de reursin @ktrkA y por inspein de ros noE rdoresF gonformmosnos por los momentos on sumir que se lul el vlor de low(v) y estudiemos un primer y simple lemF e un digrfo G =< V, E > y T un rol rdor en profundidd ulquierF e v V un nodo ulquier de G tl que df (v) = low(v)F e B el omponente fuerteE mente onexo l que pertenee vF intonesD
Lema 7.2

w V | low(w) = low(v) w B

@UFTA

644

7. Grafos

hiho de otr formD todo nodo w perteneiente l loque de vD y slo ellosD tienen vlor low(w) = low(v)F
Demostracin Necesidad

= X por l propi de(niin de low @UFSA pgF TRPD low(w) = low(v)D pues si no ontrdir l de(niinF = X supongmos un nodo x B | low(x) = low(v)F ist suposiin onE trdie l de(niin @UFSA pgF TRP

Suciencia

i tenemos un digrfo on sus vlores df y low luldosD entones podemos distinguir sus loques del siguiente modoX IF gd nodo v on df (v) = low(v) se enuentr en un loque distintoF ixisten tntos loques omo nodos que stisfgn df (v) = low(v)F PF or d loque identi(do medinte un nodo v on df (v) = low(v)D los nodos w on low(w) = low(v) perteneen l mismo loque de v il prximo lem indii que el reorrido en profundidd desure los loquesF e un digrfo G =< V, E > y T un rol rdor en profundidd ulquierF e v V un nodo ulquier en G tl que df (v) = low(v)D entones el loque l que pertenee v se r entermente desde T F
Lema 7.3 Demostracin

or l de(niin @UFSA pgF TRPD v es el primer nodo visitdo en el reorrido en profundiddF esD en su rol rdorD v tiene que ser el nestro de todos los nodos del loque l que pertenee vF gonseuentementeD el resto de los nodos del loque se r desde v ehor onsideremos el lgoritmo de rjnF v rutin que funge de interfz del lgoE ritmoD y que invo l reorrido reursivo en sD esX Componentes fuertemente conexos 644 647a template <class GT, class SA> inline void tarjan_connected_components(GT & g, DynDlist <GT> & blk_list, DynDlist<typename GT::Arc*> & arc_list) {
for (typename GT::Node_Iterator it(g); curr_df < n; it.next()) { typename GT::Node * v = it.get_current(); if (not IS_NODE_VISITED(v, Aleph::Depth_First)) __scc<GT, SA>(g, blk_list, stack, v, curr_df); } }
Uses

644

Inicializar Tarjan 645a

Construir y mapear los bloques 646c


85a.

DynDlist

7.7. Grafos dirigidos

645

645a

g es el digrfo sore el ul se dese lulr los loquesF blk_list es un list de digrfos mpedos orrespondiente los distintos loques de gF pinlmenteD los ros de g que ruzn entre los loques se gurdn en l list arc_listF v rutin emple lguns vriles internsD de ls ules hor es menester lri(r ls siguientesX Inicializar Tarjan 645a (644 647a 653)
long curr_df = 0; // contador de visitas const long & n = g.get_num_nodes();

645b

curr_df es el ontdor de nodos visitdosD el ul slo se inrement l desurir un nodo no visitdo y se emple pr signr el vlor de df (v) y el iniil de low(v) lo lrgo de ls llmds reursivs de __scc()F il for revis los nodosD invo __scc() pr d nodo no visitdo y se detiene undo se hn visitdo todos los nodosD lo ul se detet undo curr_df == nF __scc() se de(ne del siguiente modoX Rutinas estticas de Tarjan 645b 647b
template <class GT, class SA> inline void __scc(GT & g, DynDlist <GT> & list, DynListStack<typename GT::Node*> & stack, typename GT::Node * v, long & df_count) { Inicio de recorrido sobre v 645c Recorrer en profundidad bloque conexo a v 646b Vericar si df (v) = low(v) y calcular bloque 645d }
DynDlist
85a and

Uses

DynListStack

105c.

645c

ist rutin reorre en profundidd el nodo v del grfo g y gurd en l list list sus loquesY stack es un pil de nodos visitdos uyo sentido expliremos ms delnteD v es el nodo tul que se reorre en profundidd y df_count es el ontdor de visitsF il primer pso l entrr __scc(v,...) es empilr v en l pil stackX Inicio de recorrido sobre v 645c (645b 647b) 646a push_in_stack<GT>(stack, v); n vez reorridos en profundidd los nodos dyentes vD se pregunt por df (v) = low(v)F i es iertoD entones l pil ontiene l seueni z, y, . . . , w, v @invertidAD por lo que podemosD desempilr on seguridd el loque hst que squemos vX Vericar si df (v) = low(v) y calcular bloque 645d (645b) if (low <GT> (v) == df <GT> (v)) // primer nodo visitado del bloque? { // s ==> saque los nodos del bloque que estn en pila const size_t & blk_idx = list.size(); GT & blk = list.append(GT()); while (true) // sacar el bloque de la pila hasta sacar a v { typename GT::Node * p = pop_from_stack<GT>(stack); typename GT::Node * q = blk.insert_node(p->get_info()); GT::map_nodes(p, q); NODE_COUNTER(p) = NODE_COUNTER(q) = blk_idx; if (p == v) break; }

645d

646

7. Grafos

646a

il vlor blk_idx es el nmero de loqueF iste ndie permiteD luego de her reorrido entermente el digrfoD reonoer los distintos loquesF il onoimiento que nos proporion el lem UFQ nos segur que el loque est enter y seuenilmente ontenido en l pilD pues v es rz del loque en el rol rdor en profundiddF v determinin de low(v) se he por retroeso @ktrkingAF gundo visitmos un nodo vD el vlor de low(v) se inii en df (v)X Inicio de recorrido sobre v 645c + (645b 647b) 645c NODE_BITS(v).set_bit(Aleph::Depth_First, true); df<GT>(v) = low<GT>(v) = df_count++; vuegoD se revisn los ros de v y se invo reursivmente __scc(w,...) por d nodo w que se onexo v y que no hy sido visitdoX Recorrer en profundidad bloque conexo a v 646b (645b 647b) // recorrer en profundidad todos los nodos conectados a v for (Node_Arc_Iterator<GT, SA> it(v); it.has_current(); it.next()) { typename GT::Node * w = it.get_tgt_node(); if (not IS_NODE_VISITED(w, Aleph::Depth_First)) { __scc <GT, SA> (g, list, stack, w, df_count);
} else if (is_node_in_stack<GT>(w)) // si est en pila ==> v fue visitado antes que p low <GT> (v) = std::min(low <GT> (v), df <GT> (w)); low <GT> (v) = std::min(low <GT> (v), low <GT> (w));

646b

646c

el slir de __scc(g, list, stack, w, df_count)D w y tiene luldo su low(w)D por lo que ste se otej on low(v) pr veri(r si se enuentr un vlor menor que el tulF i w y h sido visitdo desde otr iterin de tarjan_connected_components()D entones deemos veri(r su low(w) slo si w pertenee l loque de vD lo ul veri(mos por l preseni de w en l pilF r lmenr los vlores df y low empleremos el ontdor y el ookieD extmente de l mism mnerD y on ls misms rutins que emplemos en UFI @gF TIRAF r ulminrD l ltim prte del lgoritmo de rjn onsiste en onstruir los suE digrfos mpedos de los loquesX Construir y mapear los bloques 646c (644) // recorrer cada uno de subgrafos parciales y aadir sus arcos for (typename DynDlist<GT>::Iterator i(blk_list); i.has_current(); i.next()) { // recorrer todos los nodos del bloque GT & blk = i.get_current(); for (typename GT::Node_Iterator j(blk); j.has_current(); j.next()) { typename GT::Node * gsrc = j.get_current(); // recorrer arcos de gsrc for (Node_Arc_Iterator<GT, SA> k(gsrc); k.has_current(); k.next()) {

7.7. Grafos dirigidos

647

}
Uses

typename GT::Node * gtgt = k.get_tgt_node(); typename GT::Arc * ga = k.get_current_arc(); if (NODE_COUNTER(gsrc) != NODE_COUNTER(gtgt)) { // arco inter-bloque ==> adalo a arc_list arc_list.append(ga); continue; } // insertar y mapear el arco en el sub-bloque typename GT::Node * bsrc = mapped_node<GT>(gsrc); typename GT::Node * btgt = mapped_node<GT>(gtgt); typename GT::Arc * ba = blk.insert_arc(bsrc, btgt, ga->get_info()); GT::map_arcs(ga, ba);

DynDlist

85a and

mapped_node

560b.

647a

tarjan_connected_components() he un trjo loriosoD pero grntiz l otenE in de omponentes fuertemente onexos omo sugrfosF in emrgoD vees slo es preferile identi(r los omponentes sin neesidd de mntenerlos omo grfosF in ese so podemos plnter l siguiente versinX Componentes fuertemente conexos 644 + 644 649a
template <class GT, class SA> inline void tarjan_connected_components(GT & g, DynDlist<DynDlist<typename GT::Node*> > & blks) { for (typename GT::Node_Iterator it(g); curr_df < n; it.next()) { typename GT::Node * v = it.get_current(); if (not IS_NODE_VISITED(v, Aleph::Depth_First)) __scc <GT, SA> (g, blks, stack, v, curr_df); }
DynDlist
85a.

Inicializar Tarjan 645a

}
Uses

647b

v difereni respeto l versin nterior estri en que en lugr de lulr y retornr un list de sugrfosD trjmos on un list de list de nodosY d list ontiene los nodos perteneientes un omponenteF ist versin sorergd tmin requiere sorergr __scc() pr que rei l list de listsX Rutinas estticas de Tarjan 645b + 645b template <class GT, class SA> inline void __scc(GT & g, DynDlist<DynDlist<typename GT::Node*> > & list, DynListStack<typename GT::Node*> & stack, typename GT::Node * v, long & df_count) {

}
Uses

Inicio de recorrido sobre v 645c Recorrer en profundidad bloque conexo a v 646b Vericar si df (v) = low(v) y eventualmente llenar lista 648
85a and

DynDlist

DynListStack

105c.

648

7. Grafos

648

v estrutur es esenilmente idnti l nteriormente desrrolldD slvo por el ltimo loque eri(r si df (v) = low(v) y eventulmente llenr list 648 D el ul se desrie del siguiente modoX Vericar si df (v) = low(v) y eventualmente llenar lista 648 (647b) if (low<GT>(v) == df<GT>(v)) // primer nodo visitado del bloque? { // s ==> saque los nodos del bloque que estn en pila list.append(DynDlist<typename GT::Node*>()); DynDlist<typename GT::Node*> & l = list.get_last(); while (true) // sacar bloque de pila hasta llegar a v { typename GT::Node * p = pop_from_stack<GT>(stack); l.append(p); if (p == v) break; } }
Uses

DynDlist

85a.

gomo no se requiere onstruir sugrfos mpedos de los loquesD est versin es ms e(iente en tiempo y espioF edemsD el mero heho de seprr los nodos del digrfo en onjuntos segn su perteneni l omponente fuertemente onexoD rroj stnte informin sore l onetividdF in l ourreniD todo el trjo que y hiimos de mper los loques en sugrfos puede herse on l list de listsF il punto qu es que on tn solo tener un nodo del omponente fuertemente onexo y se tiene posiilidd de proesrlo sin fetr los dems omponentesF
7.7.4 Prueba de aciclicidad

in UFSFT @gF SWQA disemos l primitiv is_graph_acyclique()D destind veri(r por l existeni de ilo en un grfoF gomo quell rutin se s en el pintdo de los nodosD no funion pr digrfosF gundo se enuentr un nodo que y h sido pintdoD no hy mner de ser si lo fue por un ilo o por proedeni desde un nodo perteneiente otro loqueF ytr primitiv que desrrollmos en UFSFS @gF SWPA fue test_for_cycle()F odeE mos veri(r por l iliidd llmndo test_for_cycle() por d nodo del grfo hst urir todos los nodos o enontrr un iloF iste enfoque tomr O(V E)F il lgoritmo de rjnD que es O(V ) + O(E)D puede emplerse pr determinr e(ienE temente si un digrfo tiene o no ilosF i prtimos del heho de que un loque dee tener forzdmente ilosD el lgoritmo de rjn responde por su existeniF in otrs plrsD si l ntidd de loques de un digrfo es menor que l de nodosD entones existe l menos un iloD pues un omponente fuertemente onexo ontiene un iloF snterpretdo de otro modoX st on enontrr un loque de dos o ms nodos pr onluir que el grfo tiene un iloF in trminos del lgoritmoD esto equivle detetr si un seueni de pops en el loque eri(r si df (v) = low(v) y lulr loque 645d ontiene ms de un nodoF i el lzo extre l menos dos nodosD entones tenemos un omponente fuertemente onexo de dos o ms nodosD el ulD por de(niinD ontiene un iloF egn ls onsideriones hehsD l rutin reursiv deviene enX

7.7. Grafos dirigidos

649

649a

Componentes fuertemente conexos 644 +

647a 649b

template <class GT, class SA> inline static bool __ida(GT & g, DynListStack<typename GT::Node*> & stack, typename GT::Node * v, long & df_count) { push_in_stack <GT> (stack, v); NODE_BITS(v).set_bit(Aleph::Depth_First, true); df<GT>(v) = low<GT>(v) = df_count++; // recorrer en profundidad todos los nodos conectados a v for (Node_Arc_Iterator <GT, SA> it(v); it.has_current(); it.next()) { typename GT::Node * w = it.get_tgt_node(); if (not IS_NODE_VISITED(w, Aleph::Depth_First)) { if (__ida <GT, SA> (g, stack, w, df_count)) return true; low<GT>(v) = std::min(low<GT>(v), low<GT>(w)); } else if (is_node_in_stack<GT>(w)) // si est en pila ==> v fue visitado antes que p low<GT>(v) = std::min(low<GT>(v), df<GT>(w));

}
Uses

} if (low<GT>(v) == df<GT>(v)) // primer nodo visitado de bloque? { // s ==> verifique si tiene dos o ms nodos int i = 0; for (; true; ++i) // sacar bloque de la pila hasta sacar a v { typename GT::Node * p = pop_from_stack <GT> (stack); if (p == v) break; } return i > 1; // si sacamos dos o ms nodos entonces hay ciclo } return false;
DynListStack
105c.

649b

__ida() es un rutin esttiF v de uso plio se de(ne omoX Componentes fuertemente conexos 644 + 649a

650

template <class GT, class SA> inline bool is_digraph_acyclique(GT & g) { long curr_df = 0; // contador de visitas const long & n = g.get_num_nodes(); DynListStack<typename GT::Node*> stack; // pila que define rama for (Node_Iterator <GT, SA> it(g); curr_df < n; it.next()) { typename GT::Node * v = it.get_current(); if (not IS_NODE_VISITED(v, Aleph::Depth_First)) if (__ida<GT, SA>(g, stack, v, curr_df)) // visitar v return true;

650

7. Grafos

}
Uses

} return false;
DynListStack
105c.

v ul tiene l mism estrutur que tarjan_connected_components()F iste lgoritmo determin l existeni de ilos en un digrfo en tiempo O(V ) + O(E) y on un mximo onsumo de espio de O(V )F
7.7.5 Clculo de ciclos en un digrafo

650

in el mismo sentido de l vrinte de l susein preedente podemos empler el lgoE ritmo de rjn pr lulr efetiv y e(ientemente un ilo en un digrfoF gundo smos de l pil en el loque eri(r si df (v) = low(v) y lulr loque 645d D onstruimos un digrfo uxilir que mpe l omponente onexoF ore este omponente usmos un ilo medinte un squed en profundiddF pinlmenteD medinte el mpeoD onstruimos el mino orrespondiente l iloX Componentes fuertemente conexos 644 + 649b 652b template <class GT, class SA> inline static bool __cc(GT & g, DynListStack<typename GT::Node*> & stack, typename GT::Node * v, long & df_count, Path<GT> & path) { push_in_stack <GT> (stack, v); NODE_BITS(v).set_bit(Aleph::Depth_First, true); df<GT>(v) = low<GT>(v) = df_count++;
// recorrer en profundidad todos los nodos conectados a v for (Node_Arc_Iterator <GT, SA> it(v); it.has_current(); it.next()) { typename GT::Node * w = it.get_tgt_node(); if (not IS_NODE_VISITED(w, Aleph::Depth_First)) { if (__cc<GT, SA> (g, stack, w, df_count, path)) return true; } else if (is_node_in_stack<GT> (w)) // si est en pila ==> v fue visitado antes que p low<GT>(v) = std::min(low<GT>(v), df<GT>(w)); low<GT>(v) = std::min(low<GT>(v), low<GT>(w));

if (low<GT>(v) == df<GT>(v)) // primer nodo visitado del bloque? { // saque nodos de pila e insertelos en bloque auxiliar GT blk; // grafo auxiliar DynMapAvlTree<typename GT::Node*, typename GT::Node*> table; while (true) // saca el componente y lo inserta en blk { typename GT::Node * p = pop_from_stack<GT>(stack); typename GT::Node * q = blk.insert_node(p->get_info()); table.insert(q, p);

7.7. Grafos dirigidos

651

} if (blk.get_num_nodes() == 1) return false; // si blk slo tiene un nodo no hay ciclo // terminanos de construir el bloque con los arcos for (typename GT::Node_Iterator j(blk); j.has_current(); j.next()) { typename GT::Node * bsrc = j.get_current(); typename GT::Node * gsrc = table[bsrc]; // recorrer los arcos de gsrc for (Node_Arc_Iterator<GT, SA> k(gsrc); k.has_current(); k.next()) { typename GT::Node * gtgt = k.get_tgt_node(); typename GT::Node ** btgt_ptr = table.test(gtgt); if (btgt_ptr == NULL) // arco del bloque? continue; typename GT::Arc * ga = k.get_current_arc(); blk.insert_arc(bsrc, *btgt_ptr, ga->get_info());

table.insert(p, q); if (p == v) break;

// buscar ciclo en blk. typename GT::Arc * a = blk.get_first_arc(); Path<GT> aux_path(blk); Find_Path_Depth_First<GT>() (blk, blk.get_tgt_node(a), blk.get_src_node(a), aux_path); path.clear_path(); for (typename Path<GT>::Iterator i(aux_path); i.has_current(); i.next()) path.append(table[i.get_current_node()]); path.append(table[blk.get_tgt_node(a)]); return true; } return false;
DynListStack
105c and

}
Uses

Path

578a.

Find_Path_Depth_First <GT> () no est dised pr enontrrilosF or elloD lo que hemos es seleionr un ro ulquier s t y enontrr un mino t sF he este modoD el ilo lo onform t s tF v rutin prinipl se llm Compute_Cycle_In_Digraph()D uy estruturD on el dido de errr el iloD es similr tarjan_connected_components()F is empled pr l squed de ilos negtivos en un digrfo @ver UFWFQFW @gF UHQAAF

652

7. Grafos

7.7.6

Prueba de conectividad

652a

v motivin iniil de est sein jo l ul desrrollmos todo este orpus fue l de onetividd de un digrfo @ UFUFI @gF TQVAAF in este sentidoD tnto el lgoritmo de uosrju omo el de rjn nos permiten on ertitud determinr si un digrfo es o no fuertemente onexoF v ide es simpleX si el lulo de los omponentes fuertemente onexos rroj un solo loqueD entones el digrfo es entermente onexoF ero pgr estos ostesD espeilmente el onsumo de memoriD slo pr un prolem de existeni es inneesrioD pues podemos dptr el lgoritmo de rjn pr responder por l prue de onetividdF eordemos que el lgoritmo de rjn detet un nuevo omponente en el loque eri(r si df (v) = low(v) y eventulmente llenr list 648 F esD lo nio que estruE turlmente deemos her pr veri(r l onetividd es modi(r este loque de l siguiente mnerX Vericar si hay ms de un bloque 652a (652b) if (low<GT>(v) == df<GT>(v)) // primer nodo visitado de bloque? { // saque nodos de pila hasta encontrar a v while (pop_from_stack<GT>(stack) != v);
} return stack.is_empty();

652b

xotemos que si el digrfo es entermente onexoD entones l pil dee quedr v l ulminr el whileF i eso no ourreD entones hy l menos dos omponentesD lo que signi( que el digrfo no es onexoF gon el loque eri(r si hy ms de un loque 652a D el reorrido en profundidd rterstio del lgoritmo de rjn es el mismoX Componentes fuertemente conexos 644 + 650 653 template <class GT, class SA> inline bool __ttc(GT & g, DynListStack<typename GT::Node*> & stack, typename GT::Node * v, long & df_count) { push_in_stack<GT>(stack, v); NODE_BITS(v).set_bit(Aleph::Depth_First, true); df<GT>(v) = low<GT>(v) = df_count++;
// recorrer en profundidad todos los nodos conectados a v for (Node_Arc_Iterator<GT, SA> it(v); it.has_current(); it.next()) { typename GT::Node * w = it.get_tgt_node(); if (not IS_NODE_VISITED(w, Aleph::Depth_First)) { if (not __ttc <GT, SA> (g, stack, w, df_count)) return false; low <GT> (v) = std::min(low <GT> (v), low <GT> (w)); } else if (is_node_in_stack<GT>(w)) low <GT> (v) = std::min(low <GT> (v), df <GT> (w)); }

Vericar si hay ms de un bloque 652a

7.7. Grafos dirigidos

653

}
Uses

return true;
DynListStack
105c.

653

pinlmenteD l prue de onetividd se instrument del siguiente modoX Componentes fuertemente conexos 644 + 652b template <class GT, class SA> inline bool tarjan_test_connectivity(GT & g) {
for (typename GT::Node_Iterator it(g); curr_df < n; it.next()) { typename GT::Node * v = it.get_current(); if (not IS_NODE_VISITED(v, Aleph::Depth_First)) if (not __ttc <GT, SA> (g, stack, v, curr_df)) return false; } return true;

Inicializar Tarjan 645a

7.7.7

Digrafos acclicos (DAG)

Denicin 7.6 (Digrafo acclico -DAG-)

n digrfo lio o heq17 D es un digrfo

sin ilosF il empleo ms populr de los digrfos lios es pr modelizr plni(iones u horriosF in este soD los nodos representn tres o tividdes que instrumentn un or y los ros ls preedenis posiles de ls tividdesF gonsideremos l tre generl de vestirseD l ul onsiste en ponerse ls prends en un orden espe(o que puede relionrse segn el digrfo de l (gur UFRRF enemos nueve psosD resumidos en el
Medias Interiores Camisa

Zapatos

Pantalon

Corbata

Correa

Chaleco

Palt

pigur UFRRX qrfo dirigido lio que de(ne en los psos pr vestirse digrfo jo los nomres de ls prendsD que no pueden efeturse en un orden ritrrioD sino en el expresdo por ls reliones del digrfoF r vestirnos deudmente no podemosD por ejemploD ponernos l orre ntes que el pntlnF in un digrfo lio siempre se distinguenD undo menosD un nodo fuente y uno sumideroF in el vestirse tenemos los interioresD medis y mis omo fuentesD mientrs que los zptos y l plt omo sumiderosF
17
Del ingls Directed Acyclique Graph.

654

7. Grafos

7.7.8

Planicacin de tareas

il vestirse nos est tn rrigdo que quiz no preiemos ien l omplejidd que tiene el herlo en el orden orreto18 F egn ument l ntidd de tres y sus prelionesD ument l di(ultdF in ors grndesD es neesrioD en muhs osiones ruilD enontrr el orden seuenil orreto en que deen ejeutrse tods ls tres o tividdesF l orden es denomindo ordenmiento topolgioF il vestirse puede ordenrse topolgimenteD desde nodos fuentes hst nodos sumiE derosF n ejemplo es mostrdo en l (gur UFRSF is deirD desde ls tividdes iniiles

Interiores

Pantalon

Medias

Camisa

Correa

Corbata

Chaleco

Zapatos

Palt

pigur UFRSX eueni topolgi ordend pr vestirse o primigenisD psndo por ls intermedis segn ls dependenisD hst ls (nlesF in l instrumentin de un or hy situiones en que es posile llevr o tividdes en prleloD vees simultnementeF in l ourreni on el vestirse poE drmos ponernos los interiores mientrs otrs dos persons migs nos ponen l mis y ls medisF i onsidermos un durin onstnte pr l puest de un prend de vestirD entonesD en lugr de empler nueve psos pr vestirnos solos podrmos empler ino si nos yudn dos persons msF r prehenderlo vse l (gur UFRTF
Medias Interiores Camisa

Paso 1

Pantalon

Corbata

Paso 2

Zapatos

Correa

Paso 3

Chaleco

Paso 4

Palt

Paso 5

pigur UFRTX yrdenmiento topolgio prlelo del vestirseF sos que pueden ejeutrse simultnemente se enuentrn en el mismo nivel gundo se or en prlelo hy que sinronizr los orntes pr que no emprendn tres sin que previmente se hyn ulmindo tividdes dependientes efetuds por otros orntesF or ejemploD l tre que pong ls medis dee esperr que el pntln est puesto ntes de poner los zptosF il prolem nterior puede ojetizrse de mner generl omo l plni(in de n tresD uys dependenis estn de(nid por un digrfo lioD en m orntesF
18
Considere un individuo que no conozca la cultura occidental y se le proponga vestirse. Considere tambin caminar por la selva amaznica con vestimentas occidentales.

7.7. Grafos dirigidos

655

e ls tres se les puede soir un durin o osteF in este so se trt de enontrr l mnim plni(inD es deirD de enontrr m > 1 seuenis de tresD pr drle m orntes de mner tl que l durin o oste totl se mnimoF vos digrfos de tres pueden simpli(rse segn irunstnis de l situin rel modelizdD del medio de ejeuin y del (n de l plni(inF odemosD por ejemploD sumir que olorse l mis y l ort son un sol tre on un durin myorF e est in se le denomin reduin porque redue l ntidd de nodos del digrfoD simpli( l omprensin del modelo yD por lo generlD redue el tiempo de ejeuinF gdens seuenilesD es deirD minos simples de nodos on un solo ro de entrd y otro de slidD pueden omprimirse un solo nodo onsistente de su sum de tresF v reduin nterior se efetu sore un den seuenilD pero puede perfetE mente herse sore un sudigrfo enteroF gomo ejemplo ulminnte onsideremos l orgnizin del vestirse mostrd en l (gur UFRUF
Medias, interiores Pantalon, Zapatos Camisa

Correa

Corbata Chaleco

Palt

pigur UFRUX qrfo reduido dirigido lio de los psos del vestirse vos digrfos de plni(in tienen diverss pliionesD entre ls ules e menE ionrX IF lni(in de instruiones enuzr por uno o vrios proesdoresX los ompiE ldores genern instruiones en digo de mquinF gd instruin tiene un duE rin en ilos y un preedeni sore otrs pr que no ourr ruptur del enuzE miento @pipeliningAF in este soD el ompildor onstruye un digrfo lio segn l ndole del proesdor y optimiz l seueni de instruinF PF lni(in de ors o proyetosX por ejemploD pr onstruir un omplejo de edi(ios se puede relizr un digrfo de tividdes yD en funin de los orntes @onstrutorsD mquinrisD ntidd de personsAD enontrr un plni(in de jo oste o de mnim durinF
7.7.9 Ordenamiento topolgico

ixiste un lsio y simplsimo lgoritmo pr enontrr un ordenmiento topolgio de un digrfo lioX v entrd del lgoritmo es un digrfo GF v slid es un list de nodos lD iniilmente vD orrespondiente l ordenmiento topolgio del digrfo GF
Algoritmo 7.3 (Ordenamiento topolgico)

epit mientrs G teng nodosX

656

7. Grafos

IF isoj un nodo sumidero v @uno que no teng ros de slidAF PF ilimnelo de G junto on todos sus ros de entrdF QF impile19 v l list lF iste lgoritmo enuentr el ordenmiento de mner inversX desde los sumideros hst los fuentesF gd iterin elimin un sumidero del digrfoD lo que on ertitud dejD l eliminr sus ros de entrdD l menos un nuevo sumidero dentro del grfoF il lgoritmo progres hst que no queden ms nodosF n mner diret y simple de implntr el lgoritmo UFQ es oteniendo el digrfo inverso y entones ejeutr literlmente el lgoritmoF il nio inonveniente es que se dupli el espioD lo que puede ser ostoso pr digrfos enormesF il lgoritmo UFQ puede plnterse perfetmente en funin de los fuentesY es deirD seleionr nodos fuentesD eliminrlos junto sus ros de slid y ontinur on los nuevos fuentesF en en este so es neesrio relizr un opi si se dese onservr el digrfo originlF v implntin del lgoritmo UFQ sin efetur un opi del digrfo es ms omplejD pues deemos trtr on dos prolems que el eh List_Digraph no nos resuelve direE tmenteX @IA determinr el grdo de entrd de un nodo y @PA proesr rpidmente los nodosD desde los sumideros hst los fuentesF
Ordenamiento topolgico por profundidad

656

egn el sentidoD podemos onsiderr dos lses de lgoritmosF i vmos desde los sumideros hi los fuentesD entones un reorrido en profundiddD que visite d nodo en su(joD omenzr por el primer sumidero que se enontrdoF hdo un nodo ulquier currD ste puede reorrerse reursivmenteD en profundidd y en su(joD de l siguiente formX Ordenamiento topolgico 656 657a template <class GT, class SA> static inline void __topological_sort(GT & g, typename GT::Node * curr, DynDlist<typename GT::Node*> & list) { if (IS_NODE_VISITED(curr, Depth_First)) return;
NODE_BITS(curr).set_bit(Depth_First, 1); // marcarlo como visitado // visitar recursivamente en sufijo los nodos adyacentes a curr for (Node_Arc_Iterator<GT, SA> it(curr); it.has_current() and list.size() < g.get_num_nodes(); it.next()) __topological_sort<GT, SA> (g, it.get_tgt_node(), list); }
Uses

list.insert(curr); // insercin sufija de nodo que devino sumidero


DynDlist
85a.

19

Con la operacin de tipo

push().

7.7. Grafos dirigidos

657

657a

in importr ul se el primer nodo desde el ul se invoque est rutinD st vnzr reursivmente hst enontrr un nodo y visitdo o hst un sumideroY en este ltimo so no se entr en el for y el nodo se insert en listF uesto que insertmos en list l prinipioD el primer sumidero que se oserve ser el ltimo nodo en l listD mientrs que el ltimo oservdoD o seD un fuenteD ser el primeroF snsertr en list omo en un pil nos proporion el orden topolgioF n vez que invo l ltim instruin list.insert(curr)D todos los nodos lnzE les desde curr y hn sido insertdos en listF gonseuentementeD el orden de inserin es orretoD pues curr v ntes en su orden topolgioF is importnte oservr que l ondiin de detenin del for inluye el heho de que y todos los nodos hyn sido visitdosF isto se detet undo l ntidd de nodos de l list se l mism que l rdinlidd del grfoF in so de que __topological_sort() se iniie desde un nodo que no es fuente o que existn vrios fuentesD quedrn nodos sin visitrD ergoD sin insertr en l listF isto se resuelve simplemente reorriendo todos los nodos del grfo e invondo __topological_sort()X Ordenamiento topolgico 656 + 656 657b template <class GT, class SA> inline void topological_sort(GT & g, DynDlist<typename GT::Node*> & list) { for (typename GT::Node_Iterator it(g); it.has_current() and list.size() < g.get_num_nodes(); it.next()) { typename GT::Node * curr = it.get_current_node(); if (not IS_NODE_VISITED(curr, Depth_First)) __topological_sort<GT, SA>(g, curr, list); } }
Uses

DynDlist

85a.

topological_sort() puede iterr tnts vees omo ros teng el digrfoY esto he que el desempeo tiend O(E) lo ulD en el peor de los sosD puede ser O(V 2 )F eroD por lo generlD pr un digrfo lioD E 2V F
Ordenamiento topolgico por amplitud

657b

ytro enfoque pr ordenr topolgimente se equipr on un reorrido en mplitudD lo ul onllev l ventj de ontrolr mejor el onsumo de espio l limitrlo un ol de nodos Eon el reorrido en profundiddD l reursin puede lnzr O(V )D lo que podrD en lgunos sosD rrer peligro pr l pil del sistemEX Ordenamiento topolgico 656 + 657a 659 template <class GT, class SA> inline void q_topological_sort(GT & g, DynDlist<typename GT::Node*> & list) { // recorra todos los arcos para contar grados de entrada for (Arc_Iterator<GT,SA> it(g); it.has_current(); it.next()) NODE_COUNTER(it.get_tgt_node())++;
// revisar nodos con grado de entrada 0 y meterlos en cola DynListQueue<typename GT::Node*> q; // cola de fuentes for (typename GT::Node_Iterator it(g); it.has_current(); it.next())

658

7. Grafos

typename GT::Node * p = it.get_current_node(); if (NODE_COUNTER(p) == 0) // es un nodo fuente? q.put(p); // s ==> colocarlo en la cola

}
Uses

while (not q.is_empty()) { typename GT::Node * p = q.get(); // saque ltimo fuente list.append(p); // insrtelo en el orden topolgico // decrementar grado de entrada de cada nodo adyacente a p for (Node_Arc_Iterator<GT, SA> it(p); it.has_current(); it.next()) { typename GT::Node * tgt = it.get_tgt_node(); if (NODE_COUNTER(tgt) == 0) // tgt deviene fuente? q.put(tgt); // s ==> colquelo en la cola } }
DynDlist
85a.

il desempeo de este lgoritmo es 2 O(V ) por los dos primeros lzos ms O(E) por el whileF vo que nos rroj O(E) omo desempeo generl del lgoritmoD rendimiento similr l versin sd en l squed en profundiddF
A I P

F B G C K J

M Q N R O L S

H D

hrvuygqefptxws
(b)

topological_sort()

hrvuygqefptxws
(c)

q_topological_sort()

pigur UFRVX n digrfo y sus ordenmientos topolgios

Rangos topolgicos

il rngo topolgio de un nodo es su nivel en el digrfo respeto ls tres que lo preeden y ls que los suedenF n rngo topolgio ses Esin espei(r que se trt de un nodoE es un onjunto de tres que pueden llevr o independientemente un vez que hn sido ulminds ls tividdes del rngo predeesorF or ejemploD los rngos topolgios del digrfo de l (gur UFRV sonX R1 = {A, C, D}D R2 = {B, G, H}D R3 = {F, K, L}D R4 = {I, J, O}D R5 = {M, N, S} y R6 = {P, Q, R}F isto signi( que si ls tres tomsen l mism durinD entones primero hr que ejeutr R1 D luegoD R2 D y s suesivmenteF

7.7. Grafos dirigidos

659

659

il lulo de los rngos puede herse medinte ulquier de los lgoritmos de orE denmiento topolgioF re qu un vrinte del sdo en mplitud que emple dos olsX Ordenamiento topolgico 656 + 657b template <class GT, class SA> inline void q_topological_sort(GT & g, DynDlist<DynDlist<typename GT::Node*>*> & ranks) { // recorra todos los nodos para contabilizar grado de entrada for (typename GT::Node_Iterator i(g); i.has_current(); i.next()) for (Node_Arc_Iterator <GT, SA> j(i.get_current_node()); j.has_current(); j.next()) NODE_COUNTER(j.get_tgt_node())++;
// revisar nodos con grado de entrada 0 y meterlos en cola DynListQueue<typename GT::Node*> q; // cola de fuentes for (typename GT::Node_Iterator it(g); it.has_current(); it.next()) { typename GT::Node * p = it.get_current_node(); if (NODE_COUNTER(p) == 0) // es un nodo fuente? q.put(p); // s ==> colocarlo en la cola } while (not q.is_empty()) { DynDlist<typename GT::Node*> * rank = new DynDlist<typename GT::Node*>; DynListQueue<typename GT::Node*> aq; while (not q.is_empty()) // saca todos los nodos del nivel i { typename GT::Node * p = q.get(); // saque ltimo fuente rank->append(p); // insrtelo en el rango topolgico // decrementar grado entrada de cada nodo adyacente a p for (Node_Arc_Iterator<GT, SA> it(p); it.has_current(); it.next()) { typename GT::Node * tgt = it.get_tgt_node(); if (NODE_COUNTER(tgt) == 0) // tgt deviene fuente? aq.put(tgt); // s ==> colquelo en cola auxiliar } } ranks.append(rank); q.swap(aq); }

}
Uses

DynDlist

85a.

il lgoritmo es estruturlmente similr q_topological_sort()F il prmetro ranks es un list de lists de nodosF gd list es un rngo y ontiene los nodos que lo onformnF v list est ordend por el orden del rngoD es deirD l primer list ontiene ls tres que se ejeutn de primero y s suesivmenteF il lgoritmo emple un ol uxilir aqF gundo se derement el grdo y se deterE min que hy que enolrD el nodo se mete en qaF n vez que se hn sdo todos los

660

7. Grafos

nodos de grdo eroD los ules orresponden los del rngo tulD los nodos de qa se opin @en O(1) medinte swap()A hi q y se repite el proedimientoF in osionesD ls tres no tienen l mism durinD lo que en iert form rompe on l prelinF in ests situionesD ls tres pueden dividirse en duriones determinds y s onstruir un digrfo equivlente uyos nodos representn l mism durinF ore este digrfo extendido se lul el rngoF

7.8 rboles abarcadores mnimos


hdo un grfo onexo G =< V, E > on distnis @o pesosAD un rol rdor mnimo es un rol rdor de G tl que l sum totl de sus distnis es mnimF
G H C L G H C L

(a)

(b)

pigur UFRWX n grfo y su rol rdor mnimo vos roles rdores tienen muy tiles pliionesF upongmosD por ejemploD l plni(in de un sistem ferrovirio nionl o de un red de trnsmisin eltri pr el psF emos proyetos onllevn ostes en trminos de trjoD durin y (nnimientoF in ests situiones se puede modelizr un grfo de tods ls lterntivs de ftiilidd segn los trminos meniondosF il grfo mntendr ls posiles vs en funin de l geogrfD o de l durin de onstruin o del oste de (nnimientoF in ms situionesD un rol rdor mnimo nos proporion l red mnim que en los trminos del modelo grntiz omplet onetividdF
7.8.1 Manejo de los pesos del grafo

i pretendemos elorr lgoritmos generles pr lulr roles rdores mnimosD es deirD que operen pr ulquier lse de pesosD entones deemos seprr del lgoritmo todo lo que t los pesosF in tl sentido usremos lguns lses que sern prmetros tipos de un lgoritmo pr lulr el rol rdor mnimoX IF Distance<GT>X lse de eso l peso de un roD l ul dee exportr los siguientes triutosX @A Distance<GT>::Distance_TypeX el tipo de dto que represent un peso en un roF @A typename Distance<GT>::Distance_Type operator() (typename GT::Arc *a)X retorn el vlor de peso ontenido en el ro aF

7.8. rboles abarcadores mnimos

661

@A typename Distance<GT>::Max_DistanceX onstnte estti orrespondiente l vlor mximo de distni que un lgoritmo onsiderr omo vlor in(nitoF @dA typename Distance<GT>::Zero_DistanceX onstnte estti orrespondiente l elemento neutro de l sumF in l inmens myor de sosD este ser el eroF PF Compare<GT>X lse que efet l omprin entre dos pesos y que dee exportrX
bool operator () (const typename Distance<GT>::Distance_Type & op1, const typename Distance<GT>::Distance_Type & op2) const;

pr implntr l relin menor queF QF PlusX lse de sum entre distnis implntd medinte el operdorX
typename Distance<GT>::Distance_Type Plus::operator () (const typename Distance<GT>::Distance_Type & op1, const typename Distance<GT>::Distance_Type & op2) const;

661a

vs lses Distance y Compare se onjugn jo un lse espeil de omprin de ros uy de(niin es omo sigueX Comparador de arcos 661a 661b template <class GT, class Distance, class Compare> struct Distance_Compare { bool operator () (typename GT::Arc * a1, typename GT::Arc * a2) const { return Compare () ( Distance () (a1) , Distance () (a2) ); } };
Denes:

Distance_Compare,

used in chunks 662a, 668, and 669a.

661b

n primer form de onjugr ests lses es implntndo el lulo del oste de un grfoD es deirD l sum de los pesos de todos sus rosX Comparador de arcos 661a + 661a template <class GT, class Distance, class Compare, class Plus, class SA> typename Distance::Distance_Type total_cost(GT & g) { typename Distance::Distance_Type sum = Distance::Zero_Distance; // recorrer todos los arcos y sumar su peso for (Arc_Iterator <GT, SA> it(g); it.has_current(); it.next()) sum = Plus () (sum, Distance () (it.get_current_arc()));
} return sum;

7.8.2

Algoritmo de Kruskal

il lgoritmo de uruskl seleion los ros insertr en T segn su pesoD desde del menor l myorF r eso los ros se ordenn previmenteD de mner tl queD iterndo

662

7. Grafos

662a

sore ellos @ver UFQFIHFI @gF STSAAD stos prezn ordendmenteF iste ordenmiento previo lo hemos del siguiente modoX ordenar arcos 662a (663c) g.template sort_arcs<Distance_Compare<GT, Distance, Compare> >();
Uses

Distance_Compare

661a.

662b

is deirD se invo el mtodo de ordenmiento de ros plntedo en UFQFIHFIH @gF SUUAF il proeso pr otener el rol rdor mnimoD luego de tener los ros ordendos se delineD grndes rsgosD de l siguiente mnerX calcular rbol abarcador mnimo segn Kruskal 662b (663c) // Recorrer arcos ordenados de g hasta que numero de arcos de // tree sea igual al numero de nodos de g for (Arc_Iterator<GT, SA> arc_itor(g); tree.get_num_arcs() < g.get_num_nodes() - 1; arc_itor.next()) { // obtenga siguiente menor arco typename GT::Arc * arc = arc_itor.get_current_arc();

Vericar si nodo origen existe en tree 663a Vericar si nodo destino existe en tree 663b
typename GT::Arc * arc_in_tree = tree.insert_arc(tree_src_node, tree_tgt_node, arc->get_info()); if (Has_Cycle<GT, SA>() (tree)) // arc_in_tree causa ciclo? { // hay ciclo ==> hay que remover el arco tree.remove_arc(arc_in_tree); // eliminar arco y procesar continue; // siguiente arco } GT::map_arcs(arc, arc_in_tree);

il ilo mir los ros del grfo desde el menor hst el myorF gd ro que es mirdo se insert en tree yD si ste no us un iloD entones ste es prte del rol rdorF il proeso ontin hst que l ntidd de ros del rol se extmente l ntidd de nodos del grfo menos unoD lo ul es l indiin de que el rol y r ompletmente los nodos del grfo sin perder su ondiin de rolY prtir de este momento ulquier otro ro que se inserte en tree usr un iloF n grn ondd del lgoritmo de urusklD prensile medinte inspein de sus loques priniplesD es que puede modi(rse on reltiv filidd pr que opere onE urrentementeF in primer lugrD omo suintmente explimos on el quiksort en QFPFPFW @gF IVRAD podemos elerrlo sustnilmente si lo modi(mos pr usr vrios proesdores mterilesF ws difilD pero omprodmente posileD es modi(r el loque lulr rol rdor mnimo segn uruskl 662b pr que mneje los loques internos eri(r si nodo origen existe en tree 663a y eri(r si nodo destino existe en tree 663b en proesdores diferentesF or requerimientos de interfzD pr insertr un ro en tree es neesrio que sus nodos y hyn sido previmente insertdosF iste es el rol sio de los loques eri(r si nodo origen existe en tree 663a y eri(r si nodo destino existe en tree 663b D del ul omentremos el primeroX

7.8. rboles abarcadores mnimos

663

663a

Vericar si nodo origen existe en tree 663a

(662b)

typename GT::Node * g_src_node = g.get_src_node(arc); // origen en g typename GT::Node * tree_src_node; // origen en tree if (not IS_NODE_VISITED(g_src_node, Aleph::Kruskal)) // est en tree? { // No, crearlo en tree, atarlo al cookie y marcar como visitado NODE_BITS(g_src_node).set_bit(Aleph::Kruskal, true); tree_src_node = tree.insert_node(g_src_node->get_info()); GT::map_nodes(g_src_node, tree_src_node); } else tree_src_node = mapped_node<GT>(g_src_node);
mapped_node
560b.

Uses

663b

gomo se veD el loque tiene dos )ujosX o el nodo y est insertdo y mpedo en tree @)ujo del elseAD o hy que rerloD mrrlo y mperloF il otro loque es similr pero on el otro extremo del roX Vericar si nodo destino existe en tree 663b (662b) typename GT::Node * g_tgt_node = g.get_tgt_node(arc); typename GT::Node * tree_tgt_node; // destino en rbol abarcador if (not IS_NODE_VISITED(g_tgt_node, Aleph::Kruskal)) { // No, crearlo en tree, atarlo al cookie y marcar como visitado NODE_BITS(g_tgt_node).set_bit(Aleph::Kruskal, true); tree_tgt_node = tree.insert_node(g_tgt_node->get_info()); GT::map_nodes(g_tgt_node, tree_tgt_node); } else tree_tgt_node = mapped_node<GT>(g_tgt_node);
Uses

mapped_node

560b.

663c

gon tods ls estruturs nteriores podemos espei(r l rutin de interfzX Algoritmo de Kruskal 663c template <class GT, class Distance, class Compare, class SA = Default_Show_Arc<GT> > inline void kruskal_min_spanning_tree(GT & g, GT & tree) { g.reset_bit_nodes(Aleph::Kruskal); // limpiar bits de marcado clear_graph(tree); // limpia grafo destino
}

ordenar arcos 662a calcular rbol abarcador mnimo segn Kruskal 662b

el (nl de l llmdD tree ontiene un rol rdor uyos cookiesD tnto de nodos omo de rosD estn mpedos l grfo g y vieversF vs distnis de los ros son de tipo Distance::Distance_Type y edids por est lseF vs ompriones entre distni ls efet l lse CompareF v implntin omplet reside en el rhivo Kruskal.HF
7.8.2.1 Anlisis del algoritmo de Kruskal
662a

il tiempo de ejeuin estr ddo por l sum de los loques ordenr ros lulr rol rdor mnimo segn uruskl 662b F

ms

664

7. Grafos

10

12

10

10

12

10

15

15

(a)
L 4 M 2 N 3 O 6 P L 4 M 2

(b)
N 3 O 6 P

10

12

10

10

12

10

15

15

(c)
L 4 M 2 N 3 O 6 P L 4 M 2

(d)
N 3 O 6 P

10

12

10

10

12

10

15

15

(e)

(f)

pigur UFSHX rogreso del lgoritmo de uruskl @d (gur orresponde tres iterionesA emos por nlisis previos que l mejor mner de ordenr un list es O(n lg(n))D por lo que el loque ordenr ros 662a exhie O(E lg E)D esperdo o determinist segn el mtodo de ordenmientoF r el loque lulr rol rdor mnimo segn uruskl 662b sumimosD omo peor soD que l on(gurin de ros es tl que stos deen revisrse omE pletmenteF il while requerirD puesD O(E) iterionesF hentro del while se ejeuE tn onstntemente dos operionesX l inserin del ro en tree y l prue de iE liidd has_cycle()F v inserin de un ro es O(1)D mientrs que l invoin has_cycle() @ver UFSFT @gF SWQAA es O(V )D puesD por su ondiin de rol o de grfoD prilmente inonexoD en tree E V F il loque lulr rol rdor mnimo segn uruskl 662b onllev entones O(E) O(V ) = O(E V ) en el peor de los sosF il lgoritmo de uruskl onsumeD pr el peor soD O(E lg E) + O(E V ) = O(max(E lg E, E V )D lo ul lo he trtivo pr grfos espridosF
7.8.2.2 Correctitud del algoritmo de Kruskal

r ls prues de orretitud nos es onveniente introduir l ide de orte de un grfoD lo ul no es otr os que un prtiin de G en dos sugrfos disjuntos G1 y G2 F vos ros elimindos de GD es deirD quellos que onetn nodos de G1 on nodos de G2 D se denominn ros de orteF oert edgewik IST h rterizdo dos propieddes sore los roles rdoresD ls ules fungen de instrumentos de prueF v primer de ells te un roreseni de roles rdores priles y se desrie jo el lem siguienteF

7.8. rboles abarcadores mnimos

665

G
. . . corte arcos de

G1

G2

pigur UFSIX isquem genrio de orte de un grfo G e G =< V, E > un grfo y T =< V, E >| E E un rol rdor mnimo de GF e < G1 , G2 > un orte ulquier de GF intones el ro de rue mnimo entre los posiles de rue entre G1 y G2 pertenee l rol rdor mnimoF
Lema 7.4 (Lema del corte - Sedgewick 2002 [156]) Demostracin (por contradiccin)

upongmos un orte ulquier < G1 , G2 > y l existeni de un rol rdor mnimo T =< V, E > uyo ro de rue no es el mnimoF en T1 y T2 los omponentes de T segn el orteF il sunto se pitoriz en l (gur UFSPF e a el ro de rue entre T1 y T2 D el ulD omo y hemos dihoD no es el mnimo
T
. . . T2

T1

arcos de corte

pigur UFSPX isquem generl del lem del orte de los de rue entre G1 y G2 F uesto que T1 y T2 son liosD podemos suprimir el ro de rue a y sustituirlo por el de rue mnimo amin y s rer un rol rdor T =< V, E >=< V, E {a} {amin } >F uesto que peso(amin ) < peso(a) = eE peso(e) < eE peso(e)D lo que ontrdie l premis iniil de que T es el rol rdor mnimo de GF il lem es pues ierto il segundo lem te l diin de ros que usen ilos y su onseuente supreE sinF
Lema 7.5 (Lema del ciclo - Sedgewick 2002 [156]) e G un grfo onexo ulquier y T su rol rdor mnimoF e G un grfo onstruido por E didur de un ro e GF intonesD dir e T y eliminr el ro de myor peso en el ilo result en un rol rdor T que es mnimoF Demostracin

i e es el ro on myor peso del iloD entones ste no puede ser prte de T porque sino T no ser mnimo @existir otro ro de menor pesoAF he lo ontrrioD se emax el ro on myor pesoF iliminr emax de T lo ort en dos roles disjuntos los ulesD segn el lem del ilo UFR estn onetdos en T por el mnimo ro de rueF T es por tnto mnimo e G un grfo onexo ulquierF inE tones el lgoritmo de uruskl enuentr un rol rdor mnimoF
Proposicin 7.3 (Sedgewick - 2002 [156])

666

7. Grafos

Demostracin (por induccin sobre

n = |V |)

IF n 2X l prue es inmeditF PF n > 2X sumimos que l proposiin es iert pr un grfo Gn de n nodosF esD el lgoritmo de uruskl onstruye un rol rdor mnimo Tn de n 1 rosF ehor estudiremos l vlidez del lgoritmo pr un grfo Gn+1 de n + 1 nodosF

G1

G2

pigur UFSQX isquem genrio de prtiin del grfo il lgoritmo de uruskl mntiene un roreseni de roles rdoresD los ules por l hiptesis indutiv son mnimosF ehor miremos l inserin del ro undo l roreseni tiene n 1 rosF in este momentoD podemos onsiderr un prtiin de Gn+1 en G1 G2 y dos roles rdores T1 y T2 F esD l seleionr e insertr un ro e = u vD ourre uno entre los siguientes sosX @A e re un iloD en uyo so e se eliminF uesto que los ros fueron vistos ordendmenteD e es el ro on myor peso dentro del ilo usdoF he este modoD l eliminrlo del rolD segn el lem del ilo @UFS @gF TTSAAD T1 y T2 se preservn y estos son roles rdores mnimosF @A xo se re un iloD en uyo so l diin de e une los omponentes inonexos T1 y T2 rendo un solo omponente T F ehor ienD puesto que e es visto ordeE ndmenteD e es el mnimo ro de rue entre G1 y G2 yD por el lem del orte @UFR @gF TTRAAD T es un rol rdor mnimo v proposiin es iert pr todo grfo

7.8.3

Algoritmo de Prim

il segundo lgoritmo pr onstruir un rol rdor se s en un modi(in del reorrido en mplitudD en l ul en lugr de empler un ol pspyD se us un ol de prioridd que ponder los pesos de los rosF
7.8.3.1 Algoritmo genrico

Algoritmo 7.4

@elgoritmo de rim pr lulo de rol rdor mnimoA v entrd es un un grfo onexo GF v slid es un grfo onexo T orrespondiente l rol rdor mnimo de GF

IF e q un ol de prioridd de ros ordend segn su peso y T =

7.8. rboles abarcadores mnimos

667

PF eleione un nodo v y met en q todos sus rosF wrque v omo visitdo QF while not q.is_empty() y T no rque G @A a = q.get(); @A if (los nodos de a estn visitados) =

continue;
@A e t el nodo no visitdo de a @dA snsertr a en T y mrque a y t omo visitdos @eA weter en q todos los ros dyentes t que n no hyn sido visitdosF i l ol de prioridd se instrument medinte un hepD entones este lgoritmo se ejeut en tiempo O(E lg(E)) y onsume espio O(E)F gomo se puede preirD el lgoritmo de rim es estruturlmente idntio l reorrido en mplitud @ UFSFR @gF SVWAAD on l difereni de que en lugr de empler un ol pspy se emple un de prioriddD l ulD su vezD suye sore el hepF
7.8.3.2 Interfaz del algoritmo de Prim

667

il lgoritmo de rim se invo medinte ls siguiente interfzX Algoritmo de Prim 667 template <class GT, class Distance, class Compare = Aleph::less<typename Distance::Distance_Type>, class SA = Default_Show_Arc<GT> > inline void prim_min_spanning_tree(GT & g, typename GT::Node * first, GT & tree) {

Declaracin de cola de prioridad 671a Inicializar heap 671b calcular rbol abarcador mnimo segn Prim 671c

punionlmenteD est interfz es ext l del lgoritmo de urusklF


7.8.3.3 Heap exclusivo de arcos mnimos

ixiste un tniD presentd por edgewik ISTD que redue sustnilmente el tmo del hep no ms de V entrdsF isto impli que el oste en tiempo se redue O(lg V ) y el de espio O(V )D en lugr de los respetivos O(lg E) y O(E)F n hep exlusivo de ros mE nimos es un hep que gurd ros de un grfo ordendos por su peso de mner tl que en ningn momento pueden existir dos ros on el mismo nodo destinoF
Denicin 7.7 (Heap exclusivo de arcos mnimos)

r un grfo G =< V, E >D es imposile que el hep onteng ms de V 1 rosD pues si no hr dos ros on el mismo nodo destinoF or su rter de hep se grntiz que l extrin de un ro se orresponder on el de peso mnimo entre todos los inluidos en el onjuntoF

668

7. Grafos

668a

n hep tl omo el que mos de de(nir es implntle medinte el eh BinHeap<Key> estudido en RFU @gF PVPAF ist lse de hepD que llmreE mos ArcHeapD se de(ne en el rhivo rhepFr 668a X archeap.H 668a
template <class GT, class Distance, class Compare, class Access_Heap_Node> struct ArcHeap : public BinHeap<typename GT::Arc*, Distance_Compare<GT,Distance,Compare> > {

};

Atributos pblicos de ArcHeap 668b

Denes: Uses

ArcHeap, used in chunks 670b, Distance_Compare 661a.

671a, and 679.

668b

il rhivo de(ne l lse ArcHeapD l ul implement un hep exlusivo de ros mnimos perteneientes un grfo de tipo GTD on eso los pesos de los ros medinte l lse Distance y omprin entre ls distnis trvs de l lse CompareF il sentido del prmetro tipo Access_Arc ser explido prontmenteF gomo se puede oservr de l delrinD st hered l implementin de BinHeap<Key>D pues el orden de slid es uno de los requerimientos priniples undo se extrig lgn roF he este modoD el BinHeap<Key> mnejr nodos del siguiente tipoX Atributos pblicos de ArcHeap 668b (668a) 669a typedef typename BinHeap <typename GT::Arc*, Distance_Compare<GT, Distance, Compare> >::Node Node;
Uses

Distance_Compare

661a.

in este hep l operin de inserin de un ro se resume jo el siguiente lgoritmoX


Algoritmo 7.5

@snserin genri en un hep exlusivoA v entrd es un ro a que relion dos nodos s y tD origen y destinoD respetivmenteF s es un nodo que y pertenee un rol rdor y que h sidoD por tntoD visitdoF t no h sido visitdo y no pertenee l rol rdorF IF fusque en el hep un ro a tl que su nodo destino se tF PF i a h sido enontrdo = @A i a > a = @segn lo que rroje l lse histneA iF ilimine a del hep iiF snserte a en el hep de lo ontrrio = iiiF snserte a en el hep r que est operin se lleve o en O(lg V ) es neesrio enontrr un mner rpid de reuperr a que no ompromet el desempeo del hepF odemos usr un tl de nodos destinos de ros ontenidos en el hepD l ul podr instrumentrse medinte un tl hsh o un rol rdorF in nuestr implementinD un poo en detrimento de l lriddD notremos en d nodo del grfoD trvs del ookieD un puntero hi el nodo del hep dentro del ArcHeapF

7.8. rboles abarcadores mnimos

669

r eder l ookie nos vlemos de un lse de esoD denomind Access_Heap_NodeD uyo operdor () dee orresponderse on el siguiente prototipoX
template <class GT, class Distance, class Compare> typename BinHeap<typename GT::Arc*,Distance_Compare<GT,Distance,Compare> >::Node *& Access_Heap_Node::operator () (typename GT::Node * p);

669a

il operdor retorn un puntero l nodo del hep que ontiene un ro inluido en el ArcHeap uyo nodo destino es pD o NULLD si el hep no ontiene ningn ro on p omo nodo destinoF is responsilidd del usurio de ArcHeap el que Access_Heap_Node::operator () retorne NULL l primer vez en que se inserte un ro on un nodo destinoF is muy importnte que se retorne un refereni un puntero y no un opiY de modo tl que se pued mir el vlor del puntdorF ehor podemos implntr l inserin segn el lgoritmo UFSX Atributos pblicos de ArcHeap 668b + (668a) 668b 669b void put_arc(typename GT::Arc * arc, typename GT::Node * tgt) { Node *& heap_node = Access_Heap_Node () (tgt); if (heap_node == NULL) // existe arco insertado en el heap? { // No ==> crear nuevo nodo para el heap y asignarle arco heap_node = new Node; heap_node->get_key() = arc; this->insert(heap_node);
return; } // dos arcos con igual destino ==> tomar menor; descartar mayor typename GT::Arc *& arc_in_heap = heap_node->get_key(); // arc_in_heap tiene distancia menor que arc? if (Distance_Compare <GT, Distance, Compare> () (arc_in_heap, arc)) return; // antiguo arco permanece en el heap; nuevo se ignora // arc_in_heap ser el arco recin insertado arc arc_in_heap = arc; // cambia el arco update(heap_node); // actualiza el heap con el nuevo peso de arc

Denes: Uses

put_arc, used in chunks 671, Distance_Compare 661a.

680c, and 681b.

669b

r un grfo G =< V, E >D el oste de un inserin de ros es O(lg V )D pues l sustituin de un ro ot el hep un mximo de V 1 elementosF v eliminin es tn omplej omo l inserinD pues prte del mnejo de memori hy que segurr que el ro elimindo no se relione on su nodo destinoX Atributos pblicos de ArcHeap 668b + (668a) 669a typename GT::Arc * get_min_arc() { Node * heap_node = this->getMin(); typename GT::Arc * arc = heap_node->get_key(); // seleccionar nodo que retorne la clase de acceso

670

7. Grafos

typename GT::Node * p = (typename GT::Node*) arc->src_node; if (Access_Heap_Node () (p) != heap_node) p = (typename GT::Node*) arc->tgt_node; Access_Heap_Node () (p) = NULL; delete heap_node; } return arc;

Denes:

get_min_arc,

used in chunks 671c and 681a.

uesto que el hep y est otdo un mximo de V 1 rosD l eliminin es O(lg V )F


7.8.3.4 Inicializacin del algoritmo de Prim

670a

vo primero que deemos her es de(nir l estrutur que ontendr el ookie de un nodoD de modo tl que podmos usr el hep exlusivo disedo en l susein preedenteX Deniciones de Prim 670a 670b template <class GT> struct Prim_Info { typename GT::Node * tree_node; // imagen en el rbol abarcador void * heap_node; // puntero en el heap exclusivo }; il mpo tree_node gurd l imgen del nodo dentro del rol rdorD mientrs que heap_node l direin dentro del hep exlusivo que gurd el mnimo ro l nodo en uestin omo destinoF heap_node se delr omo void* deido que tenemos diferentes rues de tipos involurdosF il onstrutor segur que undo se prte l memori los mpos se iniien utomtimente en NULLF hdo un puntero nodo pD el eso estos mpos se filit medinte los siguientes mros PRIMINFO()D TREENODE() y HEAPNODE()F ehorD segn los requerimientos del tipo ArcHeapD deemos espei(r el eso l mpo heap_nodeX Deniciones de Prim 670a + 670a template <class GT, class Distance, class Compare> struct Prim_Heap_Info { typedef typename ArcHeap<GT, Distance, Compare, Prim_Heap_Info>::Node Node; Node *& operator () (typename GT::Node * p) { return (Node*&) HEAPNODE(p); } };
Denes: Uses

670b

Prim_Heap_Info, ArcHeap 668a.

used in chunk 671a.

v iniilizin del ookie del nodo se efetn medinte Operate_On_Nodes()D inE vod l prinipio del lgoritmoY similr se he pr lierr l memori l (nl del lgoritmoF

7.8. rboles abarcadores mnimos

671

671a

vo que nos flt por de(nir en l iniilizin del lgoritmo de rim onierne l hep exlusivoF in primer lugrD su delrinX Declaracin de cola de prioridad 671a (667) typedef Prim_Heap_Info<GT, Distance, Compare> Acc_Heap; ArcHeap<GT, Distance, Compare, Acc_Heap> heap;
Uses

ArcHeap

668a and

Prim_Heap_Info

670b.

671b

in todo momentoD l operin heap.get_min_arc() nos rroj el ro on el menor peso entre todos los inluidos dentro del hepF ist esD hst los momentosD l ni difereni on l ol trdiionl empled en el reorrido en mplitud estudido en UFSFIH @gF THSAF in segundo lugrD l inserin de los ros dyentes l nodo de iniioX Inicializar heap 671b (667) NODE_BITS(first).set_bit(Aleph::Prim, true); // visitado TREENODE(first) = tree.insert_node(first->get_info()); // meter en heap arcos iniciales del primer nodo for (Node_Arc_Iterator<GT,SA> it(first); it.has_current(); it.next()) { typename GT::Arc * arc = it.get_current_arc(); ARC_BITS(arc).set_bit(Aleph::Prim, true); heap.put_arc(arc, it.get_tgt_node()); }
Uses

put_arc

669a.

7.8.3.5

El algoritmo de Prim

671c

ehor estmos listos pr onstruir itertivmente el rol rdor en el orden estleE ido por l olD lo ul se he de l siguiente mnerX calcular rbol abarcador mnimo segn Prim 671c (667) while (tree.get_num_nodes() < g.get_num_nodes()) // mientras tree no abarque g { // obtenga siguiente menor arco typename GT::Arc * min_arc = heap.get_min_arc(); typename GT::Node * src = g.get_src_node(min_arc); typename GT::Node * tgt = g.get_tgt_node(min_arc); if (IS_NODE_VISITED(src, Aleph::Prim) and IS_NODE_VISITED(tgt, Aleph::Prim)) continue; // este arco cerrara un ciclo en el rbol
typename GT::Node * tgt_node = IS_NODE_VISITED(src, Aleph::Prim) ? tgt : src; TREENODE(tgt_node) = tree.insert_node(tgt_node->get_info()); NODE_BITS(tgt_node).set_bit(Aleph::Prim, true); // insertar en heap arcos no visitados de tgt_node for (Node_Arc_Iterator<GT, SA> it(tgt_node); it.has_current(); it.next()) { typename GT::Arc * arc = it.get_current_arc(); if (IS_ARC_VISITED(arc, Aleph::Prim)) continue; ARC_BITS(arc).set_bit(Aleph::Prim, true); // marcar arco

672

7. Grafos

typename GT::Node * tgt = it.get_tgt_node(); if (IS_NODE_VISITED(tgt, Aleph::Dijkstra)) continue; // nodo visitado ==> causar ciclo } heap.put_arc(arc, tgt);

}
Uses

// insertar nuevo arco en tree y mapearlo typename GT::Arc * tree_arc = tree.insert_arc(TREENODE(src), TREENODE(tgt), min_arc->get_info()); GT::map_arcs(min_arc, tree_arc);
669b and

get_min_arc

put_arc

669a.

gomo veremos posteriormenteD el rol rdor resultnte de este proeso es mnimoF


L 4 M 2 N 3 O 6 P L 4 M 2 N 3 O 6 P

10

12

10

10

12

10

15

15

(a)
L 4 M 2 N 3 O 6 P L 4 M 2

(b)
N 3 O 6 P

10

12

10

10

12

10

15

15

(c)
L 4 M 2 N 3 O 6 P L 4 M 2

(d)
N 3 O 6 P

10

12

10

10

12

10

15

15

(e)

(f)

pigur UFSRX rogreso del lgoritmo de rim @d (gur orresponde tres iterionesA ry un difereni ruil en l mner en que el lgoritmo de rim trt on l propiedd del ilo @UFS pgF TTSA y que nos permite evdir un prue de iliiddF uesto que el rol rdor tree siempre es onexoD podemosD por simple inspein de visit de los nodos de un ro proesdoD determinr si l inlusin del nuevo ro en tree usr un iloF i mos nodos y hn sido visitdosD entones l inserin del ro usr un iloY de lo ontrrioD el ro form prte del rol rdor mnimoF gon el lgoritmo de uruskl no podemos her est onsiderin porque tree es inonexoF
7.8.3.6 Anlisis del algoritmo de Prim

v iniilizin pr prtr los ontenidos de los ookies y su lierin l (nlD requieren rrer todos los nodos del grfoF emos sonD por tntoD O(V )F il loque sniilizr hep 671b reorre los ros del nodo origenF in el muy extremo peor so en el que el nodo est onetdo l resto de los nodos sniilizr hep 671b es

7.8. rboles abarcadores mnimos

673

O(V )F vs tres fses nteriores sonD en onjuntoD O(V )F in unto l loque lulr rol rdor mnimo segn rim 671c D ste es un poo ms sutil de nlizr porque l ntidd de iteriones del while depende de lo que sued on el for internoD el ulD su vezD tmpoo tiene un ntidd de repetiiones extF i exminmos on uiddo el loqueD entones podemos pertrnos de que deemos indgr dos ntiddesX
IF il nmero de vees que se ede el hep exlusivoD el ul nos proporion l ompleE jidd del while omindo on el forF fjo el supuesto de que el grfo es onexoD es lro que todos los nodos deen ser mirdos por el lgoritmoD pues ste se inii desde el primer ro del nodo origen y ulmin hst que todos los nodos estn rdosD lo ul es l ondiin de prd del whileF gd nuevo nodo inspeiondo rre su inlusin en el rol rdor20 y l onseuente inserin de todos los ros no visitdos dyentes l nodo rein proesdoF gundo ourre l inserin del ltimo nodoD y todos los ros del grfo hn sido visitdos yD omo stos son mrdosD se sn del hep un sol vezF emos pues que se efetn lo sumo E inseriones de ro en el hepF in unto l ntidd de extriones deemos notr queD puesto que trtmos on un hep exE lusivoD ste s ros durnte l inserin en un oste O(1)F yurren entones lo sumo V extriones de rosD lo ul nos rroj un omplejidd de O(V + E) = O(E) pr l ntidd de repetiiones que relizn el while y el for omindosF i en lugr de un hep exlusivo trtsemos on un hep trdiionlD entones hrmos E extrionesD tendrmos un lgoritmo ms lento pero on l mism omplejidd itertivF PF il tmo mximo o promedio del hepD el ul nos proporion el oste de operr on lF uesto que usmos un hep exlusivoD es seguroD de lo que prehendimos en l de(niin UFU @ UFVFQFQ @gF TTUAA que su tmo no exede de V 1 elementosD lo ul nos rroj un oste de operin de O(lg V ) por d l inserin o elimininF il oste de un operin sore el hep exlusivo esD puesD O(lg V )F he ls ntiddes reientemente lulds podemos onluir que el oste del loque lulr rol rdor mnimo segn rim 671c es O(E) O(lg V ) = O(E lg V )F vos utro loques involurdos ontilizn O(V ) + O(E lg V ) = O(E lg V )D que es el desempeo de(nitivo en tiempo del lgoritmo de rimF is importntsimo destr que si ussemos un hep trdiionl pr gurdr los rosD entones el oste de un operin sore el hep estr otdo por O(lg E)D el ul otr l lgoritmo de rim un desempeo de O(E lg E)D un oste sustnilmente myor l que nos proporion el hep exlusivoF enlogmenteD tendrmos un oste en espio de O(E) versus el O(V )F il hep exlusivoD unque omplejoD no es un prihoD pues su uso se reompens on reesD tnto en tiempo omo en espioF il lgoritmo de rim es el mtodo de prefereni pr grfos densosF
20
Recordemos que en este algoritmo, el rbol abarcador siempre es conexo, lo que asegura que no se crear un ciclo cuando se inserte en el rbol un nodo no visitado.

674

7. Grafos

7.8.3.7

Correctitud del algoritmo de Prim

e G un grfo onexo ulquierF inE tones el lgoritmo de rim enuentr un rol rdor mnimoF
Proposicin 7.4 (Sedgewick - 2002 [156]) Demostracin (por induccin sobre

n = |V |)

IF n < 2X in este soD el hep retorn el menor ro del nodo iniil y onstruye un rol pril de dos nodos el ul esD on ertitudD mnimoF PF n > 2X hor sumimos que l proposiin iert pr un rol rdor mnimo pril de n nodos de un grfo Gn F e difereni del lgoritmo de urusklD el de rim siempre mnej un solo rol rE dor mnimo pril @que por supuesto es onexoAF esD lo lrgo de l ejeuinD el orte de Gn+1 puede interpretrse omo Gi {v}D donde i es l |T | @vse (gur UFSSAF or l hiptesis indutivD el lgoritmo de rim enuentr un rol rdor mnimo Ti por d Gi | i < nF

Gi+1 Ti v

Gi

pigur UFSSX isquem de orte del lgoritmo de rim gundo el rol rdor mnimo ontiene n nodosD el orte lleg ser Gn {v}F el extrer del hep un roD ste d el menor ro de entre los restntesD el ulD l insertrlo en Tn D nos d dos posiiliddesX @A ue el ro forme un iloD en uyo soD por el lem del ilo @UFS @gF TTSAAD ste es el myor entre todos los ros que onformn el iloF el eliminrlo de Tn+1 se otiene rol previo Tn que es mnimoF @A ue el ro no forme un iloD en uyo soD plntendo un orte Gn {b}D el ro es el mnimo entre los posiles de rue @fue extrdo del hepA yD omo lo semos del lem del orte @UFR @gF TTRAAD el nuevo rol Tn+1 es mnimoF v proposiin es pues iert pr todos los nodos de grfo

7.9 Caminos mnimos


in grfos ponderdosD el prolem del mino mnimo onsiste en enontrr un mino entre un pr de nodos tl que l sum totl de todos los pesos se mnimF gomo ejemplos podemos onsiderrX IF hds iuddes y distnis entre rretersD enontrr el mino de menor distni entre un pr de iuddesF

7.9. Caminos mnimos

675

PF hds iuddes y duriones en hors de vuelo en vin y en eslsD segn oferts y disponiiliddes de erolnesD onseguir el itinerrio que lleve de un iudd otr en el menor tiempo posileF i mimos duriones por ostes eonmiosD entones podemos plnter el enonE trr el itinerrio eonmimente ms rtoF QF hd un red de omputdorsD se dese enontrr el mino ms orto de nodos intermedios por donde puedn irulr los pquetes en el menor tiempo posileF enlogmenteD si se trt de un red telefniD entonesD efetos de prestr uen serviio yD l vezD de horrr ostesD se dese enontrr el mino ms orto entre onmutdores intermedirios de tl mner que se mejoren prmetros omo lteni de trnsmisin @fundmentl pr l onversinA o ntidd de llmds simultnes que pueden efeturse en l redF RF n rootD en funin de sus menismos de visinD dee plni(r un tryeto desde un punto otroF il terreno y sus ostulos se modeliz medinte un grfoF in este soD pr horrr tiempo y energ se lul el mino de mnim distni entre los puntosF ry muhs ms situiones en ls que puede preer este prolemF r que ste teng sentidoD el grfo dee ser onexo o que l menos exist un mino entre un pr de nodosD uestin ltim que podemos determinr medinte l rutin test_for_path() estudid en UFSFUFI @gF SWTAF vos tres lgoritmos de minos mnimos que estudiremos en est sein opern pr digrfosF lo el lgoritmo de hijkstr oper pr grfosF xormlmenteD por rzones de strinD es plusile tener pesos negtivos en un grfoF in este sentidoD en el estudio y lulo de minos mnimos hy un surdo mtemtio y posilemente fsioD del ul deemos tener espeil uiddoF e trt de los ilos negtivosF on surdos porque su existeni en el grfo plnte un ilo que in(nitmente reorrido ser mnimoF
7.9.1 Algoritmo de Dijkstra

in IWSWD idsger F hijkstrD posilemente uno de los ient(os de ls ienis omputE ionles ms grndiosos de todos los tiemposD hizo plio un lgoritmo pr enontrr todos los minos ms ortos entre un nodo de iniio y el resto de los del grfoF il lgoritmo de hijkstr puede emplerse pr grfos o digrfosF is stnte deudo pr grfos eulidinosF odo lo pertinente l lulo de minos mnimos segn el lgoritmo de hijkstr suE ye en el rhivo Dijkstra.HF ry un grn reminiseni entre el lgoritmo de hijkstr y el de rim expresd por el heho de que mos se sn en un explorin de grfo segn ls prioriddesF v difereni esenil suye en que el lgoritmo de hijkstr us vlores priles tnto en los nodos omo en los rosF hdo un nodo iniil v0 D ul represent el nodo origen de un mino mnimoD los vlores de los que hlmos y los ules se re(ere el lgoritmo de hijkstrD se lsi(n de l siguiente mnerX

676

7. Grafos

 Para los nodosX ddo un nodo ulquier vi D Acc(vi ) represent l mnim distni umuld desde v0 hst vi F sniilmenteD Acc(v0 ) = 0F  Para los arcosX ddo un ro ulquier e entre los dyentes un nodo vi D Pot(e) design l distni potenil umuld urir desde el nodo v0 hst el nodo destino de eF i d(e) design l distni @o pesoA del ro eD entonesD ddo un nodo vi X Pot(e) = Acc(vi ) + d(e) @UFUA

ist operin se efet pr d ro de un nodo de trnsito durnte l ejeuin del lgoritmoF sniilmenteD pr el nodo de iniio v0 D e dyente v0 , distni umuld desde v0 es nul @Acc(v0 ) = 0AF Pot(e) = d(e)D pues l

676

imilr l lgoritmo de rimD el lgoritmo de hijkstr utiliz un hep exlusivo @ UFVFQFQ @gF TTUAA segn los poteniles de rosF esD el lgoritmo de hijkstr es estruturlmente igul l de rimY ls operiones sore el hep no exeden de O(lg V ) en tiempo y de O(V ) en espioF in emrgoD se requiere un poo ms de uiddo por l informin diionl en los nodos y los los rosF il uso del hep exlusivo pr el lgoritmo de hijkstr ser presentdo en UFWFIFP @gF TUWAF il prototipo de nuestr implementin del lgoritmo de hijkstr se de(ne del siguiente modoX Prototipo del algoritmo de Dijkstra 676 682 template <class GT, class Distance, class Compare = Aleph::less<typename Distance::Distance_Type>, class Plus = Aleph::plus<typename Distance::Distance_Type>, class SA = Default_Show_Arc<GT> > inline void dijkstra_min_paths(GT & g, typename GT::Node * start_node, GT & tree) {
}

algoritmo de Dijkstra 680b

g es el grfo @o digrfoA sore el ul se dese lulr un rol rdor de distnis mnimsF start_node es el nodo iniilD el ul puede onsiderrse rz del rol rE dorF pinlmenteD tree es el rol rdor de minos mnimos on iniio @o rzA en start_nodeF vuego de l ejeuinD g y tree estn mpedos medinte sus ookiesF in unto los tipos prmetrizdosD GT es el tipo del grfo y del rol rdor de distnis mnimsF Distance es un lse que ede l distni lmend en el ro segn l ndole on que se de(n el pesoF Compare es un lse de omprin entre tipos typename Distance::Distance_TypeF Plus es un lse que efet l sum lgeri de distnisF or ltimoD SA es un (ltro de rosF
7.9.1.1 Distancia acumulada en los nodos

v distni umuld puede gurdrse medinte el ookie del nodoF heemos prtr un loque de memori en dnde lmenr el umuldo Acc(vi )F qurdremos pues por

7.9. Caminos mnimos

677

677a

d nodoD l informin de(nid por el siguiente registroX Informacin por nodo en Dijkstra 677a 679a template <class GT, class Distance> struct Dijkstra_Node_Info { typename GT::Node * tree_node; // nodo rbol abarcador typename Distance::Distance_Type dist; // distancia acumulada void * heap_node;
Dijkstra_Node_Info() : tree_node(NULL), dist(Distance::Zero_Distance), heap_node(NULL) {}

};

677b

tree_node esD omo su omentrio lo indiD l imgen del nodo en el rol rdor de minos mnimosF dist es el umuldo Acc(vi ) desde start_nodeF heap_node es un puntero un nodo dentro del hep exlusivo ordendo por poteniles @ver UFVFQFQ @gF TTUAAF v mnipulin de los mpos nteriores se reliz trvs de los siguientes mrosX Denicin de macros para algoritmo de Dijkstra 677b 679b // conversin de cookie a Node_Info # define DNI(p) ((Dijkstra_Node_Info<GT,Distance>*) NODE_COOKIE((p))) // Acceso al nodo del rbol en el grafo # define TREENODE(p) (DNI(p)->tree_node) # define ACC(p) (DNI(p)->dist) // Acceso a la distancia acumulada # define HEAPNODE(p) (DNI(p)->heap_node)
entes de ejeutr el lgoritmoD se requiere iniilizr los nodos yD omo veremos prontE menteD los rosF isto lo ejeutmos del siguiente modoX Inicializacin de nodos y arcos 677c (680a) Operate_On_Nodes<GT, Initialize_Dijkstra_Node<GT, Distance> > () (g); v lse Initialize_Dijkstra_Node se espei( sX Clase apartadora de informacin para nodo 677d template <class GT, class Distance> struct Initialize_Dijkstra_Node { void operator () (GT & g, typename GT::Node * p) { g.reset_bit(p, Aleph::Dijkstra); NODE_COOKIE(p) = new Dijkstra_Node_Info <GT, Distance>; } }; gomo vemosD l funin es iniilizr el it de ontrolD prtr l memori pr un ojeto Dijkstra_Node_Info y signrl l ookieF enlogmenteD despus de ulminr el lgoritmo tenemos que lierr los ojetos Dijkstra_Node_InfoX Desinicializar nodos y arcos 677e (680b 682) Operate_On_Nodes <GT, Destroy_Dijkstra_Node <GT, Distance> > () (g); v lse Destroy_Dijkstra_Node es un poo ms delidD pues prte de lierr l memoE ri dee mper el nodo del grfo on su orrespondiente en el rol rdor ontentivo

677c

677d

677e

678

7. Grafos

de los minos mnimosX


678a

Clase liberadora de informacin para nodo 678a

template <class GT, class Distance> struct Destroy_Dijkstra_Node { void operator () (GT &, typename GT::Node * p) { Dijkstra_Node_Info<GT,Distance> * aux = DNI(p);//bloque a liberar typename GT::Node * tp = TREENODE(p); // imagen en rbol abarcador if (tp != NULL) // est este nodo includo en el rbol abarcador? { NODE_COOKIE(p) = NODE_COOKIE(tp) = NULL; GT::map_nodes (p, tp); } else NODE_COOKIE(p) = NULL; } delete aux;

};

7.9.1.2

Potencial en los arcos

678b

v informin pr un ro es preid l del nodo y se de(ne de mner similrX Informacin por arco en Dijkstra 678b template <class GT, class Distance> struct Dijkstra_Arc_Info { typename GT::Arc * tree_arc; // imagen en rbol typename Distance::Distance_Type pot; // potencial del arco };
Denes:

Dijkstra_Arc_Info,

used in chunks 678c and 679b.

678c

il mnejo de est estrutur medinte mrosD su iniilizin y lierin se reliz de mner similr l de los nodosF v informiones diionles soids los nodos y ros es prtd e iniilizd l prinipio del lgoritmo y lierd l (nlD de l mism mner que on el lgoritmo de rimF in onsonni on l interfz de ArcHeap deemos espei(r l lse de eso l mpo heap_nodeF ero ntes de elloD deemos indirle l lse ArcHeap que dee eder l potenil del ro y no l vlor de l distni retorndo por Distance::operator () (typename GT::Arc *a)F r esoD internmente disemos un lse wrpper @envoltriA de l lse Distance proporiond por el usurio que se enrgue de retornr el potenilX Denicin de Distance en Dijkstra 678c template <class GT, class Distance> struct Dijkstra_Pot : public Distance { typename Distance::Distance_Type operator () (typename GT::Arc *a) { typedef Dijkstra_Arc_Info<GT, Distance> Arc_Info;

7.9. Caminos mnimos

679

};
Uses

Arc_Info * arc_info = (Arc_Info*) ARC_COOKIE(a); return arc_info->pot;

Dijkstra_Arc_Info

678b.

679a

ist es l lse de distni que le psremos ArcHeapF ehorD de(nido el eso l potenil de un roD espei(mos l informin que tendr el hepX Informacin por nodo en Dijkstra 677a + 677a template <class GT, class Distance, class Compare> struct Dijkstra_Heap_Info { typedef typename ArcHeap<GT, Dijkstra_Pot<GT, Distance>, Compare, Dijkstra_Heap_Info>::Node Node;
Node *& operator () (typename GT::Node * p) { return (Node*&) HEAPNODE(p); }
ArcHeap
668a.

};
Uses

679b

Denicin de macros para algoritmo de Dijkstra 677b +


# # # # define define define define

ist estrutur tmin meree lgunos mrosX

677b

DAI(p) ((Dijkstra_Arc_Info<GT, Distance>*) ARC_COOKIE(p)) ARC_DIST(p) (Distance () (p)) TREEARC(p) (DAI(p)->tree_arc) POT(p) (DAI(p)->pot)
and 681b.

Denes:

ARC_DIST, used in chunks 680c POT, used in chunks 67981. TREEARC, used in chunk 681a. Uses Dijkstra_Arc_Info 678b.

679c

entes de de(nir el hep deemos espei(r l mner en que se omprn los potenE ilesX Comparacin entre potenciales 679c template <class GT, class Compare, class Distance> struct Compare_Arc_Data { bool operator () (typename GT::Arc * a1, typename GT::Arc * a2) const { return Compare () (POT(a1), POT(a2)); } };
Uses

POT

679b.

679d

isto nos permite delrr el hepY Declaracin de heap en Dijkstra 679d (680b 682) typedef Dijkstra_Heap_Info<GT, Distance, Compare> Heap_Info; ArcHeap<GT, Dijkstra_Pot<GT, Distance>, Compare, Heap_Info> heap;
Uses

ArcHeap

668a.

680

7. Grafos

7.9.1.3

El algoritmo de Dijkstra

680a

il lgoritmo tiene dos fsesX un de iniilizin otr de luloF v iniilizin prt l memori diionl pr l distni umuld y los potenilesX Inicializar algoritmo de Dijkstra 680a (680b 682)
NODE_BITS(start_node).set_bit(Aleph::Dijkstra, true); ACC(start_node) = Distance::Zero_Distance; TREENODE(start_node) = tree.insert_node(start_node->get_info()); NODE_COOKIE(TREENODE(start_node)) = start_node;

Inicializacin de nodos y arcos 677c

680b

el (nl del lgoritmo deemos segurrnos de que el hep se lierdo ntes l inE formin soid los nodos y rosF i ourre l revsD entones el hep referenir ookies que y fueron lierdosF or es rzn remos un loque interno donde se delr el hepF he ese modoD l estrutur generl del lgoritmo de hijkstr qued omo sigueX algoritmo de Dijkstra 680b (676)
{

Inicializar algoritmo de Dijkstra 680a

} // al final de este bloque se destruye el heap

Declaracin de heap en Dijkstra 679d Meter arcos iniciales en heap 680c Calcular rbol abarcador de Dijkstra 680d

// bloque que asegura que heap se destruya antes que // los bloques almacenados en los cookies

Desinicializar nodos y arcos 677e

680c

el igul que el reorrido en mplitud y el lgoritmo de rimD deemos meter los ros de iniio en el hep ntes de iniir el luloX Meter arcos iniciales en heap 680c (680b 682) for (Node_Arc_Iterator<GT, SA> it(start_node); it.has_current(); it.next()) { typename GT::Arc * arc = it.get_current_arc(); POT(arc) = ARC_DIST(arc); ARC_BITS(arc).set_bit(Aleph::Dijkstra, true); heap.put_arc(arc, it.get_tgt_node()); }
Uses

ARC_DIST

679b,

POT

679b, and

put_arc

669a.

680d

n vez que los poteniles iniiles estn en el hep y el vlor de distni nul en start_nodeD se inii l iterin pr lulr el rol rdor de hijkstrD uys rms son minos mnimos desde l rz start_nodeX Calcular rbol abarcador de Dijkstra 680d (680b)
// mientras tree no abarque a g while (tree.get_num_nodes() < g.get_num_nodes()) { }

Obtener y procesar prximo arco con menor potencial 681a Actualizar potenciales y meterlos en heap 681b

il loque repetitivo termin undo tree r gD lo ul se detet undo tree lnz l mism ntidd de nodosF el igul que el lgoritmo de rimD el de hijkstr mntiene tree onexoD lo ul permite detetr ilos por simple mrdo de los nodos visitdos sin neesidd de un prue de iliiddF or modulriddD es muy onveniente

7.9. Caminos mnimos

681

dividir el lulo interno del lzo en dos prtes estruturlmente idntis l del reorrido en mplitud y el lgoritmo de rimX IF
681a

Obtener y procesar prximo arco con menor potencial 681a


typename GT::Arc * garc = heap.get_min_arc(); typename GT::Node * gsrc = g.get_src_node(garc); typename GT::Node * gtgt = g.get_tgt_node(garc); // Estn los dos nodos visitados? if (IS_NODE_VISITED(gsrc, Aleph::Dijkstra) and IS_NODE_VISITED(gtgt, Aleph::Dijkstra)) continue; // insertar arco causara ciclo typename GT::Node * new_node = // escoger no visitado IS_NODE_VISITED(gsrc, Aleph::Dijkstra) ? gtgt : gsrc;

(680d 683a)

typename GT::Node * ttgt = tree.insert_node(new_node->get_info()); TREENODE(new_node) = ttgt; NODE_BITS(new_node).set_bit(Aleph::Dijkstra, true); typename GT::Arc * tarc = // insertar nuevo arco en tree tree.insert_arc(TREENODE(gsrc), TREENODE(gtgt), garc->get_info()); TREEARC(garc) = tarc;
Uses

get_min_arc

669b and

TREEARC

679b.

PF
681b

Actualizar potenciales y meterlos en heap 681b

(680d 683a)

ACC(new_node) = POT(garc); // actualizar dist desde nodo inicial const typename Distance::Distance_Type & acc = ACC(new_node); // por cada arco calcular potencial e insertarlo en heap for (Node_Arc_Iterator<GT, SA> it(new_node); it.has_current(); it.next()) { typename GT::Arc * arc = it.get_current_arc(); if (IS_ARC_VISITED(arc, Aleph::Dijkstra)) continue; ARC_BITS(arc).set_bit(Aleph::Dijkstra, true); typename GT::Node * tgt = it.get_tgt_node(); if (IS_NODE_VISITED(tgt, Aleph::Dijkstra)) continue; // causara ciclo ==> no se mete en heap POT(arc) = Plus () (acc, ARC_DIST(arc)); // calcula potencial heap.put_arc(arc, tgt);
679b,

}
Uses

ARC_DIST

POT

679b, and

put_arc

669a.

682

7. Grafos

is importnte remrr l ondd que port veri(r si el nodo destino del ro y h sido visitdoF in efetoD est veri(in puede horrmos un inserin l hepD uyo oste es O(lg V )F fjo est mism lne de oservinD notemos que puede ourrir que el destino de arc y hy sido visitdoD pues y puede existir otr v insertd en el hep que lne el nodo destinoF or es rzn es neesrio que en el loque ytener y proesr prximo ro on menor potenil 681a se veri(que visit de los dos nodos del roF il lgoritmo de hijkstr puede implntrse filmente on mtries de dyeniF v estrutur es similr eD inlusiveD puede gurdrse en un mtriz que onteng todos los pres de minos mnimosF ist tni se estudir en UFWFP @gF TVSAF
L 4 M 2 N 3 O 6 P L 4 M 2 N 3 O 6 P

10

12

10

10

12

10

15

15

(a)
L 4 M 2 N 3 O 6 P L 4 M 2

(b)
N 3 O 6 P

10

12

10

10

12

10

15

15

(c)
L 4 M 2 N 3 O 6 P L 4 M 2

(d)
N 3 O 6 P

10

12

10

10

12

10

15

15

(e)

(f)

pigur UFSTX rogreso del lgoritmo de hijkstr on rz en el nodo @d (gur orresE ponde tres iterionesA

7.9.1.4

Clculo de un camino mnimo

682

il lgoritmo nterior lul un rol rdor on rz en el nodo origenF us rms representn minos mnimos desde el origen ulquier otro nodoF i lo que se pretende es onoer un mino mnimo entre dos nodosD entones podemos horrr tiempo de ejeuin si detenemos el lulo del rol rdor un vez que se lne el nodo destinoF isto lo podemos plnter de l siguiente mnerX Prototipo del algoritmo de Dijkstra 676 + 676 template <class GT, class Distance, class Compare = Aleph::less<typename Distance::Distance_Type>, class Plus = Aleph::plus<typename Distance::Distance_Type>, class SA = Default_Show_Arc<GT> > inline void dijkstra_min_path(GT & g, typename GT::Node * start_node,

7.9. Caminos mnimos

683

typename GT::Node * end_node, Path<GT> & min_path) GT tree; // rbol abarcador temporal {

Inicializar algoritmo de Dijkstra 680a

} }
Uses

Declaracin de heap en Dijkstra 679d Meter arcos iniciales en heap 680c Calcular rbol abarcador de Dijkstra parcial 683a

Desinicializar nodos y arcos 677e Buscar en tree camino entre start_node y end_node 683b
578a.

Path

683a

wenin espeil meree l posiin del loque penltimo loque hesiniilizr nodos y ros 677e D l ul dee estr ntes que fusr en tree mino entre strtnode y endnode 683b F v rzn de esto es que hesiniilizr nodos y ros 677e efet los mpeos de los nodos y ros hi el rol rdorF v primer prte del lgoritmo es muy similr l loque lgoritmo de hijkstr 680b F v ni difereni est dd por el loque glulr rol rdor de hijkstr pril 683a uy estrutur es preid l loque glulr rol rdor de hijkstr 680d D slvo que pr horrr tiempo de ejeuinD el lulo del rol rdor se detiene undo se mir el nodo destino end_nodeD o seD undo gtgt == end_nodeX Calcular rbol abarcador de Dijkstra parcial 683a (682) while (tree.get_num_nodes() < g.get_num_nodes()) // mientras tree no abarque g {
if (gtgt == end_node) // est end_node en rbol abarcador? break; // s ==> camino mnimo ya est en rbol abarcador }

Obtener y procesar prximo arco con menor potencial 681a

Actualizar potenciales y meterlos en heap 681b

683b

el trmino de este loqueD tree ontiene un rol rdorD prolemente prilD que ontiene un mino mnimo desde start_node hst end_nodeF vo primero que hemosD puesD es enontrr ese mino mnimoX Buscar en tree camino entre start_node y end_node 683b (682) 683c typename GT::Node * tstart_node = mapped_node<GT>(start_node); typename GT::Node * tend_node = mapped_node<GT>(end_node); Path<GT> tree_min_path(tree); find_path_depth_first(tree, tstart_node, tend_node, tree_min_path);
Uses

mapped_node

560b and

Path

578a.

683c

tree_min_path ontiene el mino mnimo en treeD pero lo que desemos es el mino mnimo en gF es puesD l siguiente fse onsiste en opirD siguiendo el mpeoD el mino tree_min_path l prmetro min_pathX Buscar en tree camino entre start_node y end_node 683b + (682) 683b min_path.clear_path(); min_path.init(start_node); typename Path<GT>::Iterator it(tree_min_path); for (it.next(); it.has_current(); it.next())

684

7. Grafos

min_path.append(GRAPHNODE(it.get_current_node()));
Uses

Path

578a.

7.9.1.5

Correctitud del algoritmo de Dijkstra

n sunto de esenil onoimiento es que el lgoritmo de hijkstr no oper orretmente pr ros negtivosF il lgoritmo sume que l distni totl desde el nodo origen no
2

3 2

-2

pigur UFSUX ijemplo de ro negtivo que he fllr l lgoritmo de hijkstr dereeY premis fundmentl pr djudir perteneni de un ro l rol rdor mnimo on rz en el nodo origenF gonsideremosD omo ontrejemploD el grfo de l (gur UFSU y origen en el nodo 0F il lgoritmo de hijkstr seleion omo rol rdor los ros 0 2 y 0 1D lo que heD flsmenteD el ro 0 2 omo el mino mnimo desde 0 hst 2 on oste 3D undo el mnimo es 0 1 2 on oste 021 F elrdo lo nteriorD podemos estleer l orretitud jo l siguiente proposiinX e G un grfo onexo ulquierF intones el lgoritmo de hijkstr sore un nodo de origen v enuentr un rol rdor ontentivo de todos los minos mnimos desde vF
Proposicin 7.5

n = |V |) upong un grfo onexo G =< V, E >D un nodo v V rz de un rol rdor de hijkstr y un rol rdor T =< V, E >F
Demostracin (por induccin sobre

IF n = 2X en este soD el lgoritmo s un solo ro que onform el rol rdor desde el nodo origen y que es el mnimoF PF ehor suponemos que l proposiin es iert pr todo n y onsttmos si lo es pr n + 1F e v V el nodo origen del rol rdor y w un nodo destino que en l iterin n no se enuentr en el rol rdor pril Tn F or l hiptesis indutiv Tn es un rol rdor de todos los minos mnimos desde vD es deirD d mino v u en Tn es de distni mnimF ehor exminemos l iterin que dir w Tn trvs de un ro e = x wF i se us un hep trdiionlD entones pueden otenerse ros que usen ilos y se desrtenF ero (nlmente se otendr e = x wD ul es el ro de menor distni entre un nodo x Tn y w de los que onetn Tn on w sin usr un iloF i se us un hep exlusivoD entones se otiene diretmente eF
21
Este simplsimo ejemplo es vlido tanto para el heap exclusivo como para un heap tradicional. Hacemos esta aclaratoria porque muchos contraejemplos de falla del algoritmo de Dijkstra con pesos negativos son diseados para un heap tradicional y no exclusivo. A pesar de la disminucin de probabilidad de falla ante el uso de un heap exclusivo, el algoritmo de Dijkstra sigue siendo incorrecto con pesos negativos.

7.9. Caminos mnimos

685

y e v x Tn e w

pigur UFSVX isquem genrio pr l ltim iterin del lgoritmo de hijkstr r pror que rol rdor resultnte es el de todos lo minos mnimos desde vD deemos pror que el mino v w es de distni mnimF rgmoslo por reduin l surdoF upongmos que existe un mino v y w tl que d(v y w) < d(v x w)F or l hiptesis indutivD d(v y) es mnimF ehor ienD d(x w) d(y w)D pues el hep orden por pesoF or tntoD d(v x)+ d(x w) d(v y)+ d(y w)D pero esto ontrdie l suposiin d(v y w ) < d( v x w)F or tntoD v x w es un mino mnimo y el rol rdor es el de todos los minos mnimos desde v
7.9.1.6 Anlisis del algoritmo de Dijkstra

il nlisis es prtimente similr l del lgoritmo de rimD pues ls estruturs de )ujo de mos lgoritmos son ls mismsF v fse iniilizin de nodos y ros onsume O(V ) + O(E)D lo ulD puesto que el grfo es onexoD puede onsiderrse O(E)F vo mismo ourre pr l lierin de memori l (nl del lgoritmoF es puesD el nlisis se entr en ontilizr ls iteriones del loque glulr rol rdor de hijkstr 680d D uyo nlisis es idntio l del lgoritmo de rimD pues l estrutur es l mism y el lgoritmo de hijkstr tmin us el hep exlusivoF il loque glulr rol rdor de hijkstr 680d tiene un omplejidd en tiempo de O(E lg V )D ul es el desempeo de(nitivo del lgoritmo de hijkstrF
7.9.2 Algoritmo de Floyd-Warshall

il lgoritmo de ploydErshll lul todos los minos mnimos entre pres de nodosF is un vrinte del lgoritmo de rshll pr lulr l lusur trnsitiv estudido en UFTFQ @gF TQSAF gomo tlD oper sore mtries de dyeni y posee l virtud de operr on pesos negtivosF uede dptrse pr detetr y determinr ilos negtivosF il lgoritmo fue primermente reportdo desuierto por ployd SPD peroD puesto que estruturlmente es similr l de rshllD suele llmrsele de ploydErshllF v espei(in del lgoritmo se enuentr en el rhivo Floyd.HF
7.9.2.1 Interfaces

il lgoritmo de ploydErshll mnej ls siguientes interfesX

686

7. Grafos

IF
686a

Interfaces del algoritmo de Floyd-Warshall 686a

template <class GT, typename Distance, class Compare = Aleph::less<typename Distance::Distance_Type>, class Plus = Aleph::plus<typename Distance::Distance_Type>, class SA = Default_Show_Arc<GT> > void floyd_all_shortest_paths (GT & g, Ady_Mat<GT, typename Distance::Distance_Type, SA> & dist, Ady_Mat<GT, long, SA> & path);

v rutin reie ino prmetros tipoX @A GTX el tipo de grfo @o digrfoAF @A DistanceX es l lse que mnej ls distnisF winimlmenteD ste dee exportr los triutos siguientes explidos en UFVFI @gF TTHAX iF iiF iiiF ivF

Distance_Type Max_Distance Zero_Distance operator () (typename GT::Arc *)

@A CompareX lse de omprin entre distnisF @dA PlusX lse de sum entre distnisF @eA SAX (ltro de rosF vos prmetros de l rutin sonX @A gX el grfo o digrfo representdo medinte un vrinte de List_GraphF @A distX mtriz de ostes mnimos entre pres de nodosF gd entrd disti,j onE tiene el oste mnimo entre los nodos de ndies en l mtriz de dyeni i y j respetivmenteF @A pathX mtriz de reuperin de minosF gd entrd pathi,j ontiene el nodo k que ps por el mino mnimo entre i y jF snspeiones suesivs de pathk,j hst que pathk,j = j permiten reuperr el mino mnimo entre el pr < i, j >F v rutin nterior se implntr en el siguiente loqueX
686b

Rutinas del algoritmo de Floyd-Warshall 686b

template <class GT, typename Distance, class Compare = Aleph::less<typename Distance::Distance_Type>, class Plus = Aleph::plus<typename Distance::Distance_Type>, class SA = Default_Show_Arc<GT> > void floyd_all_shortest_paths (GT & g, Ady_Mat<GT, typename Distance::Distance_Type, SA> & dist, Ady_Mat<GT, long, SA> & path) { }

Inicializar algoritmo de Floyd-Warshall 688a Algoritmo de Floyd 689b

7.9. Caminos mnimos

687

PF
687a

Recuperacin de caminos 687a

687b

template <class Mat> void find_min_path(Mat & p, const long & src_index, const long & tgt_index, Path<typename Mat::List_Graph_Type> & path);
Path
578a.

Uses

hd un mtriz de minos mnimos luld medinte floyd_all_shortest_paths()D l rutin onstruye un mino mnimo entre los pres de nodos on ndies src_index y tgt_indexF QF
687b

Recuperacin de caminos 687a +

687a 692

template <class Mat> void find_min_path(Mat & p, typename Mat::Node * src_node, typename Mat::Node * tgt_node, Path<typename Mat::List_Graph_Type> & path) { find_min_path(p, p(src_node), p(tgt_node, path)); }
Path
578a.

Uses

imilr l nteriorD slvo que los nodos se espei(n diretmente medinte punteros en l representin on lists enlzdsF
7.9.2.2 El algoritmo de Floyd-Warshall

imilr l de rshllD el lgoritmo de ploydErshll emple tres lzos que explornD omprn y seleionn los minos de longitud 1, 2, . . . , V hst urir el nmero de nodosF
Inicializacin

v ide si onsiste en onsiderr nodos intermedios de minos ms ortos jo el mismo prinipio del de rshllF e tl (nD el lgoritmo utiliz un mtriz disti,j de distnis n n uyos vlores iniiles oedeen lo siguienteX Ci,j si existe ro entre i y j dist0 i,j =

si no existe ro entre i y j si i = j

@UFVA

687c

Ci,j es el peso del ro entre el nodo i y jF hdo un grfoD los vlores iniiles se olon medinte l siguiente lseX Inicializacin de matrices 687c template <class AM, class Distance, class SA> struct Initialize_Dist_Floyd { typedef typename AM::List_Graph_Type::Arc_Type Arc_Type; typedef typename AM::List_Graph_Type GT;

688

7. Grafos

typedef typename GT::Node Node; typedef typename GT::Arc Arc; typedef typename Distance::Distance_Type Distance_Type; // inicializa cada entrada de la matriz void operator () (AM & mat, Node * src, Node * tgt, const long & i, const long & j, Distance_Type & entry, void * p) const { Ady_Mat <typename AM::List_Graph_Type, long, SA> & path = * (Ady_Mat <typename AM::List_Graph_Type, long> *) (p); if (i == j) // es diagonal de la matriz? { // s ==> la distancia es cero entry = Distance::Zero_Distance; path(i, j) = j; return; } GT & g = mat.get_list_graph(); Arc * arc = search_arc(g, src, tgt); if (arc == NULL) // existe un arco? { // s ==> se coloca coste infinito entry = Distance::Max_Distance; return; } // existe arco ==> extraiga distancia entry = Distance () (arc); // la coloca en cost(i, j) path(i, j) = j; // coloca camino directo

};
688a

iste operdor es invodo en l fse del iniilizin del lgoritmo de ploydErshllX Inicializar algoritmo de Floyd-Warshall 688a (686b) 688b typedef typename Distance::Distance_Type Dist_Type; typedef Ady_Mat <GT, Dist_Type> Dist_Mat; dist.template operate_all_arcs_matrix <Initialize_Dist_Floyd <Dist_Mat, Distance, SA> > (&path); vo que dej ls mtries en los estdos iniiles segn @UFVAF il resto de l fse de iniilizin es (jr lguns onstntes de mner de filitr el trjo de optimizin del ompildorX Inicializar algoritmo de Floyd-Warshall 688a + (686b) 688a const Dist_Type & max = Distance::Max_Distance; const long & n = g.get_num_nodes();
El algoritmo de Floyd-Warshall

688b

gomo y selmosD el lgoritmo de ploydErshll utiliz tres lzos niddos que explorn minos posiles y deiden el mnimoF in un iterin kD d entrd distk i,j ontiene el oste mnimo pr ir del nodo i hi el nodo j on un ro de longitud kF 1 itrimenteD l kEsim iterin se ilustr en l (gur UFSWF enemos un oste distk i,j previmente luldo pr ir desde el nodo i hst el jF ehor l uestin onsiste en 1 k 1 usr sendos minos priles ( i, k) y ( k, j)D on distnis priles distk i,k y distk,j

7.9. Caminos mnimos

689

k 1 disti,k

k 1 distk,j

k 1 disti,j

pigur UFSWX isquem generl de l kEsim iterin del lgoritmo de ploydErshll


k 1 1 k 1 respetivmenteD y evlur si disti,k + distk k,j es menos ostoso que disti,j F pormlmenteD l deisin se plnte del siguiente modoX 1 distk i,j 1 k 1 distk i,k + distk,j

distk i,j

= min

@UFWA

689a

v ul se modeliz de mner similr l lgoritmo de rshllX Lazo del algoritmo de Floyd-Warshall 689a for (int k = 0; k < n; ++k) for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) if (dist(i, k) + dist(k, j) < dist(i, j)) dist(i, j) = dist(i, k); v difereni esenil on el lgoritmo de rshll es que el if deide si existe un mino de menor oste que pse por un mino on nodo intermedio kF ry un mejor l lgoritmo de ploydErshll sd en l oservin de que si l 1 entrd distk i,k = D entonesD on ertitudD no hr un mino ms orto que pse por el nodo intermedio kF in funin de est oservin podemos plnter un vrinte que horre ls iteriones del lzo ms internoX Algoritmo de Floyd 689b (686b) for (int k = 0; k < n; ++k) for (int i = 0; i < n; ++i) if (dist(i, k) < max) // posible encontrar distancia menor? for (int j = 0; j < n; ++j) { // calcule nueva distancia pasando por k Dist_Type new_dist = Plus () (dist(i, k), dist(k, j)); if (Compare () (new_dist, dist(i,j)))//d(i,j)<d(i,k)+d(k,j) { dist(i, j) = new_dist; // actualice menor distancia path(i, j) = path(i, k); // actualice nodo intermedio } } eordemos que Plus::operator()() implement l sumD mientrs que Compare::operator()() l omprinF v tulizin de l mtriz pathi,j ser explid en UFWFPFS @gF TWPAF r el grfo de l (gur UFTH el lgoritmo lul ls siguientes mtries por iterinF

689b

690

7. Grafos

-2 B 2 5 A F 2 1 C -1 4 E -2 I 1 3 -2 2 -1 D 3 4 G 2 4 2 -1 3 H

pigur UFTHX n grfo on distnis negtivs


A A B C D E F G H I B

D0 =

0 1

2 0

0 1

3 0 2 3 2

4 0 2

5 1 2 0 1

2 0 1 4

4 2 0 3

P = 2 0 0

A B C D E F G H I

A A A A A A A A A A

B B B A A A A A A A

C A A C A A C A A A

D A D A D A D D D A

E A A E A E E A A A

F F F A F A F F A A

G A A A A G A G G G

H A A A H A A H H H

I A A A A I A A A I

A A B C D E F G H I

D1 =

0 1

2 0 3

0 1

3 0 2 3 2

4 0 2

5 1 6 2 0 1

2 0 1 4

4 2 0 3

P = 2 1 0

A B C D E F G H I

A A A A A A A A A A

B B B A A A A A A A

C A A C A A C A A A

D A D A D A D D D A

E A A E A E E A A A

F F F A F A F F A A

G A A A A G A G G G

H A A A H A A H H H

I A A A A I A A A I

A A B C D E F G H I

D2 =

0 1

2 0 3

0 1

5 3 6 0 2 3 2

4 0 2

3 1 4 2 0 1

2 0 1 4

4 2 0 3

P = 2 2 0

A B C D E F G H I

A A A A A A A A A A

B B B A A A A A A A

C A A C A A C A A A

D B D A D A D D D A

E A A E A E E A A A

F B F A F A F F A A

G A A A A G A G G G

H A A A H A A H H H

I A A A A I A A A I

A A B C D E F G H I

D3 =

0 1 0

2 0 3 2

0 1

5 3 6 0 2 3 2

4 0 2

3 1 4 2 0 1

2 0 1 4

4 2 0 3

P = 2 3 0

A B C D E F G H I

A A A A A A C A A A

B B B A A A C A A A

C A A C A A C A A A

D B D A D A D D D A

E A A E A E E A A A

F B F A F A F F A A

G A A A A G A G G G

H A A A H A A H H H

I A A A A I A A A I

A A B C D E F G H I

D4 =

0 1 0

2 0 3 2

0 1

5 3 6 0 2 3 2

4 0 2

3 1 4 2 0 1 0

2 0 1 4

9 7 10 4 2 2 0 3

P = 2 4 0

A B C D E F G H I

A A A A A A C A A A

B B B A A A C A A A

C A A C A A C A A A

D B D A D A D D D A

E A A E A E E A A A

F B F A F A F F D A

G A A A A G A G G G

H B D A H A D H H H

I A A A A I A A A I

7.9. Caminos mnimos

691

A A B C D E F G H I

D5 =

0 1 0

2 0 3 2

0 1

5 3 6 0 2 3 2

4 0 2

3 1 4 2 0 1 0

6 2 4 0 1 4

9 7 10 4 2 2 0 3

2 P = 2 5 0 0

A B C D E F G H I

A A A A A A C A A A

B B B A A A C A A A

C A A C A A C A A A

D B D A D A D D D A

E A A E A E E A A A

F B F A F A F F D A

G A A E A G E G G G

H B D A H A D H H H

I A A E A I E A A I

A A B C D E F G H I

D6 =

0 1 1 2 0 1 0

2 0 3 4 2 1 2

2 0 0 1 1 2 1

1 1 2 0 2 3 2

5 3 4 4 0 2 1 2

3 1 4 2 0 1 0

7 5 6 6 2 4 0 1 4

5 3 6 4 2 1 0 3

3 1 2 2 P = 2 6 0 1 0 0

A B C D E F G H I

A A F A F A C F D A

B B B A F A C F D A

C B F C F A C F D A

D B F A D A D F D A

E B F E F E E F D A

F B F A F A F F D A

G B F E F G E G G G

H B F A H A D F H H

I B F E F I E F D I

A A B C D E F G H I

D7 =

0 1 1 2 1 0 1 2 3

2 0 3 4 3 2 1 0 5

2 0 0 1 0 1 2 3 2

1 1 2 0 1 2 3 4 1

5 3 4 4 0 2 1 0 5

3 1 4 2 1 0 1 2 3

7 5 6 6 2 4 0 1 4

5 3 6 4 3 2 1 0 3

3 1 2 2 P = 2 7 0 1 2 0

A B C D E F G H I

A A F A F G C F G G

B B B A F G C F G G

C B F C F G C F G G

D B F A D G D F G G

E B F E F E E F G G

F B F A F G F F G G

G B F E F G E G G G

H B F A H G D F H H

I B F E F I E F G I

A A B C D E F G H I

D8 =

0 1 1 2 1 0 1 2 1

2 0 3 4 3 2 1 0 3

2 0 0 1 0 1 2 3 0

1 1 2 0 1 2 3 4 1

5 3 4 4 0 2 1 0 3

3 1 4 2 1 0 1 2 1

4 2 5 3 2 1 0 1 2

5 3 6 4 3 2 1 0 3

3 1 2 2 P = 2 8 0 1 2 0

A B C D E F G H I

A A F A F G C F G H

B B B A F G C F G H

C B F C F G C F G H

D B F A D G D F G H

E B F E F E E F G H

F B F A F G F F G H

G B F A H G D G G H

H B F A H G D F H H

I B F E F I E F G I

A A B C D E F G H I

D9 =

0 1 1 2 1 0 1 2 1

2 0 3 4 1 2 1 0 3

2 0 0 1 2 1 2 3 0

1 1 1 0 3 2 3 4 1

5 3 4 4 0 2 1 0 3

3 1 3 2 1 0 1 2 1

4 2 4 3 0 1 0 1 2

5 3 5 4 1 2 1 0 3

3 1 2 2 P = 2 9 0 1 2 0

A B C D E F G H I

A A F A F I C F G H

B B B A F I C F G H

C B F C F I C F G H

D B F E D I D F G H

E B F E F E E F G H

F B F E F I F F G H

G B F E H I D G G H

H B F E H I D F H H

I B F E F I E F G I

7.9.2.3

Anlisis del algoritmo de Floyd-Warshall

r estudir el desempeo del loque sniilizr lgoritmo de ploydErshll 688a D deemos onsiderr l estrutur de l rutin operate_all_arcs_list_graph() desrit en UFTFI @gF TQQA y veri(r que st ejeut O(V 2 ) iterionesD pues en relidd se reorre tod l mtrizF or d iterinD se invo l operdor () de l lse Initialize_Dist_FloydD el ul ejeut un squed linel search_arc() y que es O(V )22 F v iniilizin onsume entones O(V 2 ) O(E) = O(V 2 E)F glrmenteD el loque elgoritmo de ployd 689b es O(V 3 )F il lgoritmo presentdo es entones O(V 2 E)D resultdo que di(ere del trdiionl O(V 3 ) soido l lgoritmo de ploydErshllF v rzn es simpleD el nlisis trdiionl sume que el grfo y est uido en un mtriz de dyeniF
22
Recordemos que la implantacin de

search_arc()

presentada en 7.3.10.2 (Pg. 571) busca entre los

arcos del nodo cuyo grado sea menor y no entre todos los arcos del grafo. De aqu, pues, que la bsqueda de un arco dado sus dos nodos est acotada, para el peor caso, por

O(V ).

692

7. Grafos

7.9.2.4

Correctitud del algoritmo de Floyd-Warshall

v orretitud del lgoritmo de ploydErshll dee sernos meridin si hemos prehenE dido que el lgoritmo de rshll explor todos los minos posiles entre pres de nodosF isto puede eptrse omo orreto si sumimos que el lgoritmo de rshll lul l lusur trnsitiv de l relin inri onformd por el grfo @ver UFTFQ @gF TQSAA23 F il lgoritmo de ploydErshll tmin explor todos los pres de minosD lo ul se orroor preindo l similitud entre ls euiones @UFRA y @UFWAF gd iterin intern del lgoritmo de ploydErshll exmin y ompr un nuevo oste entre un pr de nodosF or d pr de nodosD el lgoritmo de ploydErshll explor todos los minos posiles y seleion el menor de ellosF or tntoD el lgoritmo de ploydErshll desure todos los minos mnimos entre pres de nodosF
7.9.2.5 Recuperacin de caminos

692

v mtriz disti,j luld por el lgoritmo de ploydErshll ontiene los ostes mnimos entre d pr de nodos i y jF gd entrd pathi,j gurd un nodo kD suesor de i que se enuentr en el mino mnimo hi jF or ejemploD si queremos onoer el mino mnimo desde G hi AD entones mirmos l entrds pathG,A = FD pathF,A = C y pathC,A = AD lo ul onform G F C A omo el mino mnimoF il proedimiento find_min_path()D que reuper y olo en path el mino ms ortoD entre los nodos uyos ndies origen y destino en l mtriz de dyeni p son src_index y tgt_indexD se instrument del siguiente modoX Recuperacin de caminos 687a + 687b template <class Mat> void find_min_path(Mat & p, const long & src_idx, const long & tgt_idx, Path<typename Mat::List_Graph_Type> & path) { typedef typename Mat::List_Graph_Type GT; GT & g = p.get_list_graph(); typename GT::Node * src = p(src_idx); path.set_graph(g, src); for (int i = src_idx, j; j != tgt_idx; i = j) { j = p(i, tgt_idx); path.append(p(j)); } }
Uses

Path

578a.

uesto que puede her otros lgoritmos que mntengn mtries de minos similresD este lgoritmo lo inluimos en el rhivo mat_path.HF
7.9.3 Algoritmo de Bellman-Ford

il lgoritmo de fellmnEpord IVD SSD llmdo s en honor sus primeros desuridores onoidos 24 D independientes entre sD enuentr todos los minos mnimos desde un nodo
23 24
En la sub-seccin 7.6.3 (Pg. 635) no se demostr que el algoritmo de Warshall es correcto. En realidad, parece que hay otros autores. Vanse las notas bibliogrcas en 7.15 (Pg. 829) para

aclaratorias al respecto.

7.9. Caminos mnimos

693

693a

ddoF il lgoritmo oper on ilos negtivos y tiene l grn ondd de permitir su deteinF is similr l de hijkstr en el sentido de que onstruye un rol rdor de todos los minos mnimos desde un nodo origenD l igul que requiere soir d nodo l distni umuld desde el origenF il lgoritmo de fellmnEpord reside en el rhivo Bellman_Ford.HD en el ul se exE portn ls siguientes primitivsX Rutinas de algoritmo de Bellman-Ford 693a 704 template <class GT, class Distance, class Compare = Aleph::less<typename Distance::Distance_Type>, class Plus = Aleph::plus<typename Distance::Distance_Type>, class SA = Default_Show_Arc<GT> > inline bool bellman_ford_min_spanning_tree(GT & g, typename GT::Node * start_node, GT & tree) {

} template <class GT, class Distance, class Compare = Aleph::less<typename Distance::Distance_Type>, class Plus = Aleph::plus<typename Distance::Distance_Type>, class SA = Default_Show_Arc<GT> > inline bool q_bellman_ford_min_spanning_tree(GT & g, typename GT::Node * start_node, GT & tree) {

Inicializacin de algoritmo de Bellman-Ford 693b Algoritmo genrico de Bellman-Ford 696a Deteccin de ciclos negativos 700 Construccin rbol abarcador de algoritmo de Bellman-Ford 701

Inicializacin de algoritmo de Bellman-Ford 693b Algoritmo de Bellman-Ford 696b Deteccin de ciclos negativos 700 Construccin rbol abarcador de algoritmo de Bellman-Ford 701

bellman_ford_min_spanning_tree() lul el rol rdor de minos mnimos desde el nodo origen start_node segn el lgoritmo lsioF il prmetro tipo GT repreE sent el grfoD Distance l lse extrtor de los pesos ontenidos en los rosD Compare l omprin entre pesosD Plus l sum entre pesos y SA el (ltro sore los rosF i existe el rol rdor de minos mnimoD entones l rutin retorn trueD de lo ontrrio existe un ilo negtivo y se retorn falseF q_bellman_ford_min_spanning_tree() es un versin mejord que us internmente un ol de nodosD lo que onllev myor onsumo de espio pero tiende sustnilmente elerr el lgoritmoF
7.9.3.1 Inicializacin del algoritmo de Bellman-Ford

693b

r mntener el rol rdorD el lgoritmo utiliz dos rreglos temporlesD uno de nodos predeesoresD prte de los minos mnimosD y otro de rosD todo segn lo trtdo en UFSFII @gF THTAX Inicializacin de algoritmo de Bellman-Ford 693b (693a 705) 694b DynArray<typename GT::Node*> pred(g.get_num_nodes()); DynArray<typename GT::Arc*> arcs(g.get_num_nodes());

694

7. Grafos

Uses

DynArray

34.

694a

or d nodo se mntiene l siguiente informinX Informacin por nodo en Bellman-Ford 694a template <class GT, class Distance> struct Bellman_Ford_Node_Info { int idx; typename Distance::Distance_Type acum; };

694b

idx es el ndie dentro del rreglo predsD utilizdo pr eder en O(1) l nodo predeesor en el mino mnimo prilF acum es l distni pril umuld desde el nodo origen start_nodeF il eso los mpos de est estrutur se filit medinte los mros NI pr idx y ACU pr acum respetivmenteF il vlor iniil de ACU(start_node) es eroD mientrs que el del resto es in(nitoF in trminos de digoD el vlor iniil de ACU(start_node) es Distance::Zero_Distance y Distance::Max_Distance pr el restoF vos nodos y los rreglos se iniin medinte el siguiente lzoX Inicializacin de algoritmo de Bellman-Ford 693b + (693a 705) 693b 694c { typename GT::Node_Iterator it(g); for (int i = 0; it.has_current(); ++i, it.next()) { pred[i] = NULL; arcs[i] = NULL; typename GT::Node * p = it.get_current_node(); g.reset_bit(p, Aleph::Min); // colocar bit en cero Bellman_Ford_Node_Info <GT, Distance> * ptr = new Bellman_Ford_Node_Info <GT, Distance>; ptr->idx = i; ptr->acum = Distance::Max_Distance; // infinito NODE_BITS(p).set_bit(Min, false); NODE_BITS(p).set_bit(Breadth_First, false); NODE_COOKIE(p) = ptr; } }
il it Breadth_First se utilizr pr distinguir nodos que se hyn insertdo en un olF smos Breadth_First porque el lgoritmo de fellmnEpord reorre el grfo en mplitudD lo que mostrremos en UFWFQFR @gF TWTAF il it Min ser explido en UFWFQFT @gF UHIAF il nio nodo on vlor umuldo de distni onoido l prinipio es start_nodeX Inicializacin de algoritmo de Bellman-Ford 693b + (693a 705) 694b ACU(start_node) = Distance::Zero_Distance;
7.9.3.2 Manejo del rbol abarcador

694c

e difereni del lgoritmo de hijkstrD en el de fellmnEpordD ls rms del rol rdor se modi(n durnte el luloF or es rzn es onveniente l representin rol explid en UFSFII @gF THTAF

7.9. Caminos mnimos

695

4 6 2 5 1 3 7 0

pigur UFTIX n rol ejemplo de representin medinte rreglos vlmemos pred el rreglo de pdres pr representr el rolF upongmos un nodo p uyo ndie en pred es kF v entrd pred[i] indi que el nodo orrespondiente l ndie k tiene l vlor pred[k] omo nodo predeesor en el rol rdor de minos mnimos desde el nodo start_nodeF or ejemploD el rol de l (gur UFTI se represent en el rreglo pred omoX ndie en pred xodo puntdo H 4 I 2 P 6 Q 4 R E S 2 T 4 U 3

ist (gur represent los ndies de los nodos en predD pero reordemos que en nuestr implementin se gurdn punteros nodosF i en el trnsurso del lulo se modi( un rm del rolD entones st on modi(r el pdre del nodo en predF
7.9.3.3 El algoritmo genrico Bellman-Ford

695

il prinipio fundmentl del lgoritmo de fellmnEpord reside en lo que se onoe omo relajacin de arco F gonsiderndo que d nodo lmen l mnim distni uE muld desde origenD l reljin de un ro s t onsiste en veri(r si Acc(s) + w(s t) < Acc(t)F i el predido es iertoD entones se tuliz Acc(t) = Acc(s) + w(s t)D de lo ontrrioD Acc(t) permnee invrileF il proeso nterior se odi( del siguiente modoX Relajar arco 695 (696a) const typename Distance::Distance_Type & acum_src = ACU(src); if (acum_src == Distance::Max_Distance) continue;
const typename Distance::Distance_Type & dist = Distance () (arc); typename Distance::Distance_Type & acum_tgt = ACU(tgt); const typename Distance::Distance_Type sum = Plus () (acum_src, dist); if (Compare () (sum, acum_tgt)) // sum < acum_tgt? { const int & idx = IDX(tgt); pred[idx] = src; arcs[idx] = arc; acum_tgt = sum; }

696

7. Grafos

vD est expresin es equivlente X in trminos del ro u

 if Acc(v) > Acc(u) + w =


 

pred[v] = u
Acc(v) = Acc(u) + w

696a

v reljin onsiste en trtr de disminuir el umuldo del nodo tgt_nodeF l disE minuin slo ourre si el predido Acc(v) = Acc(u) + w es iertoD en uyo soD el rreglo pred es tulizdoF guiddo prtiulr deemos prestr on l representin de F i se esoge el myor nmero representleD entones l operin Acc(u) + w puede rrer un desordeF he ll pues el if acum_src == Distance::Max_Distance) que nos supervis tl posiiliddF eun sD es posileD unque esperemos que improleD tener desordes si los vlores de ls distnis son muy grndesD ernos l mximoF qrosso modoD el lulo del rol rdor onsiste en revisr todos los ros y reljrlosD lo ul se he del siguiente modoX Algoritmo genrico de Bellman-Ford 696a (693a 705) for (int i = 0, n = g.get_num_nodes() - 1; i < n; ++i) for (Arc_Iterator<GT, SA> it(g); it.has_current(); it.next()) { typename GT::Arc * arc = it.get_current_arc(); typename GT::Node * src = g.get_src_node(arc); typename GT::Node * tgt = g.get_tgt_node(arc);
}

Relajar arco 695

he este digo podemos notr sin di(ultd que se ejeut en O(V E) veesF i d nodo soi su propio rreglo predD entones l superposiin de los rreglos onform l mtriz de minos pathY extmente en el mismo estilo que en el lgoritmo de ploydErshllF
7.9.3.4 Algoritmo mejorado de Bellman-Ford

696b

il loque elgoritmo genrio de fellmnEpord 696a es simple yD veremos despusD orreto y filmente dptle mtries de dyeniF odemos mejorrlo si oservE mos que undo en un iterin no se modi(quen los umuldos de un pr de nodos onetdos por un roD entonesD en l siguiente iterinD el ro tmpoo se reljrF min deemos notrD omo en efeto se puede oservr en l (gur UFTPD que en ls primers iteriones puede her nodos uyos umuldos permneen invrintesD tenE deni que se poteni medid que el grfo es ms grnde o ms espridoF or tntoD un mejor l lgoritmo onsiste en proesr slo quellos ros uyos umuldos de su nodo destino hyn sido modi(dos yD l vezD segurr que no se repit el proesmiento de un ro sin que previmente se hyn proesdo el resto de los rosF ist ondut de )ujo podemos modelizrl medinte l estrutur de )ujo destind pr elloD es deirD un ol que lmene quellos nodos uyo umuldo hy sido modi(doF l ol se delr omo sigueX Algoritmo de Bellman-Ford 696b (693a) 698b DynListQueue<typename GT::Node*> q;
put_in_queue <GT> (q, start_node);

Colocar centinela 698a

7.9. Caminos mnimos

697

3 H -1 A 1 C 1 2 B 1 2 2 5 5 3 4

3 H -1 A 1 C 2 B 2 1 2 1 2 5 3 3 4 2 D -1 F 2 1

2 -2 3 H -1

B 1 2 A 1 C 1 2 5 3 4

D 1

-2 3

-1 F

2 G

D 1

-2 3

-1 F

2 G

2 G

1 2 2

0 -2

1 2 2

0 -2

1 2

1 -1

4 -1

1 -1

4 -1

1 -1 E

4 -1

-2

-2

-2

-2

1 5

(a) i=0
3 2 B 2 A 1 C 1 2 1 2 5 3 3 4 2 D -1 F 2 1 2 -24 3 H 2 G -2 C -1 A 1 2 B 2 3

(b) i=1
2 D -1 F 2 1 -24 3 H 2 G -2 C -1 A 1 2 B 2 3

(c) i=2
2 D -1 F 2 1 -24 3 H 2 G -2 -1

1 2 1 2 5 3 3 4

1 2 1 2 5 3 3 4

1 2

1 2

1 2

1 -1 E

4 -1 3 I

1 -1 E

4 -1 1 I

1 -1 E

4 -1 0 I

-2

-2

-2

1 5

1 2

1 2

(d) i=3
3 2 B 2 A 1 C 1 2 1 2 5 3 3 4 2 D -1 F 2 1 2 -24 3 H 2 G -2 C -1 A 1 2 B 2 3

(e) i=4
2 D -1 F 2 1 -24 3 H 2 G -2 C -1 A 1 2 B 2 3

(f) i=5
2 D -1 F 2 1 -24 3 H 2 G -2 -1

1 2 1 2 5 3 3 4

1 2 1 2 5 3 3 4

1 2

1 2

1 2

1 -1 E

4 -1 0 I

1 -1 E

4 -1 0 I

1 -1 E

4 -1 0 I

-2

-2

-2

1 2

1 2

1 2

(g) i=6

(h) i=7

(i) i=8

pigur UFTPX rogreso del lgoritmo de fellmnEpord on rz en el nodo eF yserveE mos que el rol rdor de(nitivo permnee invrinte prtir del l quint iterE in @i = 5A v ol ontiene el primer nodo uyo umuldo h sido modi(do y es onoidoX el nodo origenF eordemos que el it Breadth_First se iniiliz undo se prt l memori pr el triuto Bellman_Ford_Node_Info @ UFWFQFI @gF TWQAAF v rutin put_in_queue() enol el nodo y le mr el it Breadth_FirstD l ul es prte del siguiente tro de rutins en torno l olX Rutinas de cola del algoritmo de Bellman-Ford 697 template <class GT> inline static void put_in_queue(DynListQueue<typename GT::Node*> & q, typename GT::Node * p) { q.put(p); NODE_BITS(p).set_bit(Breadth_First, true); } template <class GT> inline static typename GT::Node * get_from_queue(DynListQueue<typename GT::Node*> & q) { typename GT::Node * p = q.get();

697

698

7. Grafos

} template <class GT> inline static bool is_in_queue(typename GT::Node * p) { return IS_NODE_VISITED(p, Breadth_First); }

NODE_BITS(p).set_bit(Breadth_First, false); return p;

698a

il propsito de mnejr l ol on ests rutins es segurrse de no tener duplidos en l olF il nmero totl de repetiiones que ejeut el loque elgoritmo genrio de fellmnEpord 696a es extmente V 1 E veesD orrespondiente ls V 1 reljiones sore los E rosF ist ntidd es importnte porque nos ot l mxim ntidd de vees que deer de iterr l versin on olD dised pr un representin on lists de dyeni tl omo List_DigraphF esD deemos enontrr un mner de simulr ls V 1 iterionesF r herloD edgewik IST propone usr un vlor entinel en l ol que nos indique undo el elgoritmo genrio de fellmnEpord 696a hr heho un reljin de todos los rosX Colocar centinela 698a (696b) typename GT::Node __sentinel; typename GT::Node * sentinel = &__sentinel; put_in_queue <GT> (q, sentinel); he este modoD d vez que squemos de l ol sentinel tendremos l seguridd de her relizdo el mismo trjo que un iterin extern del elgoritmo genrio de fellmnEpord 696a F es ls ossD el lgoritmo mejordo resultnte se onform omo sigueX Algoritmo de Bellman-Ford 696b + (693a) 696b for (int i = 0, n = g.get_num_nodes() - 1; not q.is_empty(); ) { typename GT::Node * src = get_from_queue <GT> (q); if (src == sentinel) // se saca el centinela? if (i++ == n) break; else put_in_queue <GT> (q, sentinel);
// recorrer y relajar arcos del nodo src for (Node_Arc_Iterator<GT, SA> it(src); it.has_current(); it.next()) { typename GT::Arc * arc = it.get_current_arc(); const typename Distance::Distance_Type & acum_src = ACU(src); if (acum_src == Distance::Max_Distance) continue; typename GT::Node * tgt = it.get_tgt_node(); const typename Distance::Distance_Type & w = Distance () (arc); const typename Distance::Distance_Type sum_src = Plus () (acum_src, w); typename Distance::Distance_Type & acum_tgt = ACU(tgt); if (Compare () (sum_src, acum_tgt)) // relajar arco

698b

7.9. Caminos mnimos

699

const int & idx = IDX(tgt); pred[idx] = src; arcs[idx] = arc; acum_tgt = sum_src; if (not is_in_queue <GT> (tgt)) put_in_queue <GT> (q, tgt);

he este digo es menester omentrX IF il it Breadth_FirstD el ul es oultdo en ls utins de ol del lgoritmo de fellmnEpord 697 D evit que un nodo destino @tgtAD uyo umuldo hy sido modi(do en l iterin tulD se dolemente introduido en l olF or l v de un ro que n no hy sido proesdoD es posile modi(r el umuldo de un nodo que se enuentre en l olD ien se de l iEsim iterin tul o de lgun i 1Esim iterin nteriorF PF il orden de l ol grntiz queD l menos en l primer iterin @i = 0AD el reorrido es extmente uno de mplitudF osteriormenteD en un iterin iD en funin de los nodos que hyn sido metidos en l ol @slo quellos uyo umuldo hy sido modi(doAD se proesrn igul o menos ros que en l iterin 0F he qu se dedue por qu este lgoritmo tiende ser ms rpido que el elgoritmo genrio de fellmnEpord 696a F il orden de l ol segur que se proesen ros onetdos nodos uyos umuldos hyn sido modi(dosD lo ul posiilit un reljin que disminuy el umuldoF or el ontrrioD on el elgoritmo genrio de fellmnEpord 696a hr iteriones que oniernn ros uyos umuldos origen y destino son in(nitos y que por tnto no se modi(rn pesr de que el ro se revisdoF or qu tenemos otr ide er de por qu el lgoritmo sdo en l ol tiende ser ms e(iente que el genrioF QF n ro a reljdo uyo nodo destino h sido metido en l ol no volver visitrse hst que todos los ros dyentes los nodos nteriores de l ol hyn sido visitE dosF v iterin 0 visit on ertez todos los rosD pues los umuldos de los nodos tienen vlor in(nitoD lo ul segur su reljinF n ro a reljdo en l iterin i deer esperr l iterin i + 1 pr eventulmente volver ser reljdoF RF i el grfo no ontiene ilos negtivosD entones es seguro que l ol se virD pues undo el lgoritmo estilie los umuldos sus vlores de(nitivosD es deirD sus ostes mnimosD no hr ms inseriones en l olF SF iD por el ontrrioD el grfo ontiene lgn ilo negtivoD entones los umuldos de los nodos prte del ilo siempre sern reljdosD por lo que el lgoritmo no se detendr por l ol vF in este soD el ontdor i lnzr el vlor V 1D lo que detendr el lgoritmoF
7.9.3.5 Deteccin de ciclos negativos

ixisten prolems sore grfos que plnten trnsformr pesos de ros de suerte que stos devengn negtivos o l diin de ros (tiios on pesos negtivosF he hehoD desde

700

7. Grafos

3 H 2 -1 2 B 1 2 5 3 4

B 1 2 2 5 3 4

-2 1 3 2

-2 1 3 2

-1

-1

-1

A 0 1

-1 1

1 2 2

-1 4

G 0 -2

-1 1

1 2 2

-1 4

-2

C 1

-2

C 1

-2

(a)
3 B 2 2 1 2 1 2 5 3 1 3 -1 4 C 2 1 2 E 1 2 -1 1 D -2 4 3 2 -1 2 H 2 2 B 1 2 1 2 5 3 1 3 -1 4 I 1 2 C 1 2 3

(b)
2 D -2 4 -1 1 3 2 -1 H

A 0

1 2

G 3 4 -2 0

1 2 2

G 3 4 -2

-1 -2

-1 -2 0

(c)

(d)

pigur UFTQX rogreso del lgoritmo de fellmnEpord mejordo on rz en el nodo eF gd (gur orresponde E ros inspeiondosD lo que hid uent de l ntidd de (gurs respeto l (gur UFTPD ofree un ide de l elerin del lgoritmo mejordo l perspetiv de l modelizinD es posile imginr ros negtivosY onsiguientementeD undo menos por detein de errorD es plusile modelizr un grfo que onteng ilos negtivosF gmo ser si existe o no un iloc r tr est pregunt es menester tener en uent que l mxim longitud en ros de un mino es lo sumo V 1F esD l ide del for en elgoritmo genrio de fellmnEpord 696a es justmente ejeutr (V 1) E reljionesD ls ulesD en distni umuld uren los minos en ros ms lrgos posilesF vuego de l V 1Esim iterinD d vlor Acc(v) ontiene l mnim distni desde el origenD por lo que no es posile reljr ms rosF v onsiderin nterior es orret slo si no hy ilos negtivosD pues si los hyD entones siempre ser posile ejeutr reljiones diionlesD in(nitmente menudoD que disminuyn el vlor Acc(v) de d nodo involurdo en el iloF gonseuentementeD un mner diret de detetr lgn ilo negtivo onsiste en ejeutr un ltim iterin en l ulD de ourrir un reljinD impli l preseni de un ilo negtivoF he este modoD pr detetr si hy un ilo negtivo st onveri(r si es posile relizr l menos un reljin de msX Deteccin de ciclos negativos 700 (693a 705) bool negative_cycle = false; // recorrer todos los arcos en bsqueda de un ciclo negativo for (Arc_Iterator<GT, SA> it(g); it.has_current(); it.next())

700

7.9. Caminos mnimos

701

typename GT::Arc * arc = it.get_current_arc(); typename GT::Node * src = g.get_src_node(arc); const typename Distance::Distance_Type & acum_src = ACU(src); if (acum_src == Distance::Max_Distance) continue; typename GT::Node * tgt = g.get_tgt_node(arc); const typename Distance::Distance_Type & dist = Distance () (arc); typename Distance::Distance_Type & acum_tgt = ACU(tgt); const typename Distance::Distance_Type sum = Plus ()(acum_src, dist); if (Compare () (sum, acum_tgt)) // se relaja arco? { // s ==> ciclo negativo! negative_cycle = true; const int & idx = IDX(tgt); pred[idx] = src; arcs[idx] = arc; acum_tgt = sum; }

il loque oper orretmente pr los dos lgoritmosF e efetos de queD omo veremos posteriormenteD el ilo quede gurddo en los rreglos pred y arcsD es importnte ulmiE nr entermente el forF i slo se trt de ser si existe o no un ilo negtivoD entones podemos detenernos pens lo detetemosF
7.9.3.6 Construccin del rbol abarcador

701

i no hy ilos negtivosD entones onstruimos el rol rdorD lo que puede herse en un sol psd reorriendo el rreglo arcs e insertndo los nodos y ros l vez que los mpemosF hurnte est psd provehmos pr lierr l memori oupd por los ookiesF r determinr si el ookie lmen un mpeo o un puntero un estrutur Bellman_Ford_Node_Info nos vlemos del it MinF i un nodo est mrdo on MinD entones su ookie mpe l nodo del rol rdorD de lo ontrrioD el nodo no est en el rol rdor y el ookie ontiene un puntero un ojeto Bellman_Ford_Node_InfoX Construccin rbol abarcador de algoritmo de Bellman-Ford 701 (693a) if (negative_cycle) // hay ciclos negativos? // liberar memoria de los cookies de los nodos y terminar for (int i = 0; i < g.get_num_nodes(); ++i) { typename GT::Arc * garc = arcs[i]; if (garc == NULL) continue;
typename GT::Node * gsrc = g.get_src_node(garc); typename GT::Node * tsrc = NULL; if (IS_NODE_VISITED(gsrc, Min)) tsrc = mapped_node<GT> (gsrc); else {

702

7. Grafos

NODE_BITS(gsrc).set_bit(Min, true); // marcar bit delete NI(gsrc); tsrc = tree.insert_node(gsrc->get_info()); GT::map_nodes(gsrc, tsrc);

} return false; // no hay ciclos negativos


Uses

typename GT::Node * gtgt = g.get_tgt_node(garc); typename GT::Node * ttgt = NULL; if (IS_NODE_VISITED(gtgt, Min)) ttgt = mapped_node<GT> (gtgt); else { NODE_BITS(gtgt).set_bit(Min, true); // marcar bit delete NI(gtgt); ttgt = tree.insert_node(gtgt->get_info()); GT::map_nodes(gtgt, ttgt); } typename GT::Arc * tarc = tree.insert_arc(tsrc, ttgt, garc->get_info()); GT::map_arcs(garc, tarc); ARC_BITS(garc).set_bit(Min, true);

mapped_node

560b.

gon el rol rdor tree podemos servirnos de l rutin find_path_depth_first() estudid en UFSFUFP @gF SWUA y s enontrr un mino mnimo desde start_node hi ulquier otro nodoF
7.9.3.7 Anlisis del algoritmo de Bellman-Ford

enlizr el lgoritmo de fellmnEpord requiere nlizr sus utros loque priniplesX sniilizin de lgoritmo de fellmnEpord 693b D elgoritmo genrio de fellmnE pord 696a D hetein de ilos negtivos 700 y gonstruin rol rdor de lgoritmo de fellmnEpord 701 F sniilizin de lgoritmo de fellmnEpord 693b requiere reorrer los nodos y de los rosD lo que rroj un omplejidd de O(V + E)F elgoritmo genrio de fellmnEpord 696a iterD tl omo lo mirmos en UFWFQFQ @gF TWSAD V E veesF hetein de ilos negtivos 700 iter lo sumo O(E)F istoD undo elgoritmo genrio de fellmnEpord 696a se proxim O(V E)F pinlmenteD gonstruin rol rdor de lgoritmo de fellmnEpord 701 tom O(V ) veesF gonseuentementeD el lgoritmo tom O(V + E)+ O(V E)+ O(V ) = O(V E)F v versin elgoritmo de fellmnEpord 696b sd en l ol tiene l mism omplejiddD undo un oste diionl de espio de O(V )Y pero en l prtiD elgoritmo de fellmnE pord 696b tiende ser ms veloz que elgoritmo genrio de fellmnEpord 696a F
7.9.3.8 Correctitud del algoritmo de Bellman-Ford

Proposicin 7.6

de fellmnEpord

696a

il lgoritmo de fellmnEpord sdo en el loque elgoritmo genrio es orreto pr un grfo sin ilos negtivosF

7.9. Caminos mnimos

703

v hiptesis indutiv es que luego de l iEsim iterin el vlor Acc(v) es menor o igul l mino ms orto desde un nodo origen v que est ompuesto por i o menos rosF e u V el nodo origen @start_node en el lgoritmoA y se v V un nodo ulquierF intonesX
Demostracin (por induccin sobre la i-sima iteracin)

IF i = 0X vuego de l primer iterinD v puede englorse jo dos sosX


vD entones Acc(v) = wD el ul es el mnimo mino posile @A i existe un ro u ompuesto por un solo roF w

@A i no existe ro direto entre u y vD entones Acc(v) = y l ntidd de ros involurd es nulY lo que no viol l hiptesis indutivF PF i > 0X ehor sumimos que l hiptesis indutiv es iert pr todo i y veri(mos si n lo es pr i + 1F odemos distinguir dos sos entre minos desde u hi vX @A il vlor Acc(v) y se orresponde on l distni mnim desde u hi vF in este so y se tiene un mino mnimo ompuesto por i o menos ros y ningun reljin hi v fetr el vlor Acc(v)F @A in el so ontrrioD existe un nodo w dyente v uyo ro l reljrlo dismiE nuye Acc(v)F iste mino puede interpretrse del siguiente modoX
i arcos u w v

or l hiptesis indutivD Acc(w) ontiene el oste mnimo desde u hi w posile on i o menos rosF hel loque elgoritmo genrio de fellmnEpord 696a vemos que l iterin i + 1 oservr todos los ros de w y seleionr el ro que v hi v tulizndo su Acc(v) l mnimo
7.9.3.9 Bsqueda de ciclos negativos

in osiones no slo es neesrio ser si existe o no un iloD sino determinrlo extE mente @nodos y rosAF gmo herloc gundo ejeutmos el lgoritmo de fellmnEpord sore un grfo on l menos un ilo negtivoD ls reljiones de los ros omponentes del ilo siempre disminuyen los vlores Acc de sus nodosF gd vez que se relj un roD el pdre de v se tuliz en el rreglo pred[]F gomo esto suede pr todos los nodosD inluidos los del iloD el rreglo pred[] ontiene el @o losA ilo@sA en uestinF v re)exin nterior nos revel un lterntiv pr detetr un iloD l ul onE siste en usr peridimente en el rreglo pred[] l existeni de un iloF i lo enontrmosD entones detenemos el lulo del rol rdor y extremos el ilo del rregloF i pred[] ontiene el iloD entonesD mo usrlocF or simpliiddD sustentd en previos desrrollosD nos vldremos de l lse Compute_Cycle_In_Digraph() sd en el lulo de omponentes fuertemente onexos segn el lgoritmo de rjn en UFUFS @gF TSHAF ero est lse requiere que el digrfo est representdo en un derivin de List_Digraph y no en los rreglos pred[] y arcs[]F r lulr el ilo deemos pues onstruir un ojeto de tipo List_Digraph y sore l enontrr el iloF il proedimiento puede resumirse sX

704

7. Grafos

IF gonstruir un grfo uxilir prtir de los rreglos pred[] y arcs[]F vlmemos aux este grfoD el ul dee estr mpedo l grfo on ilosF

aux ontiene on ertitud un iloD pues est onstruido prtir de los rreglos pred[] y arcs[] resultntes de l detein de un ilo por el lgoritmo de fellmnEpordF
PF impler l lse Compute_Cycle_In_DigraphD esozd en UFUFS @gF TSIAD sore el grfo uxilir pr uir uno de sus ilos @puede her msAF e path tl iloF QF il ilo sore g se de(ne por el mpeo de path en gF intendido este proedimientoD plnteemos l siguiente rutinX Rutinas de algoritmo de Bellman-Ford 693a + 693a 705 template <class GT> bool search_cycle(GT & g, DynArray<typename GT::Node *> & pred, DynArray<typename GT::Arc *> & arcs, Path<GT> & cycle) { const size_t & n = pred.size(); // cantidad de nodos de g DynMapAvlTree<typename GT::Node*, typename GT::Node*> nodes_table; GT aux; for (int i = 0; i < n; ++i) // insertar nodos en aux { typename GT::Node * p = pred.access(i); if (p == NULL or NODE_COOKIE(p) != NULL) // insertado y mapeado? continue; // s ==> avance al siguiente
typename GT::Node * q = aux.insert_node(p->get_info()); GT::map_nodes(p, q); nodes_table.insert(q, p);

704

for (int i = 0; i < n; ++i) // insertar arcos en aux { typename GT::Arc * a = arcs.access(i); if (a == NULL or ARC_COOKIE(a) != NULL) continue; typename GT::Node * gsrc typename GT::Node * gtgt if (NODE_COOKIE(gsrc) == continue; // src o tgt = g.get_src_node(a); = g.get_tgt_node(a); NULL or NODE_COOKIE(gtgt) == NULL) no est en pred ==> no en ciclo

} Path<GT> path; // buscar ciclo en aux mediante algo de Tarjan if (not Compute_Cycle_In_Digraph <GT> () (aux, path)) return false; // no existe ciclo cycle.set_graph(g); // mapear ciclo en aux al camino cyle en g

typename GT::Node * aux_src = mapped_node<GT> (gsrc); typename GT::Node * aux_tgt = mapped_node<GT> (gtgt); aux.insert_arc(aux_src, aux_tgt);

7.9. Caminos mnimos

705

for (typename Path<GT>::Iterator it(path); it.has_current(); it.next()) cycle.append(nodes_table[it.get_current_node()]); }


Uses

return true;
DynArray
34,

mapped_node

560b, and

Path

578a.

705

search_cycle() us en el sugrfo de g de(nido por los rreglos pred[] y arcs[]D resultntes de l ejeuin del lgoritmo de fellmnEpordD l preseni de un iloF i el ilo es enontrdoD entones l funin retorn true y gurd en el mino cycle el iloF he lo ontrrioD retorn falseF vs interfes que hemos desrrolldo en torno l lgoritmo de fellmnEpord indin si existe o no un ilo negtivoD pero no lo determinnF uesto que identi(r ilos negtivos es un tre plusile pr otros lgoritmosD el lgoritmo de fellmnEpord puede emplerse pr lulrlosF in ese sentido diseremos l rutin siguienteX Rutinas de algoritmo de Bellman-Ford 693a + 704 706
template <class GT, class Distance, class Compare = Aleph::less<typename Distance::Distance_Type>, class Plus = Aleph::plus<typename Distance::Distance_Type>, class SA = Default_Show_Arc<GT> > inline bool bellman_ford_negative_cycle(GT & g, typename GT::Node * start_node, Path<GT> & cycle) { GT tree; // rbol sobre el cual opera algoritmo de Bellman-Ford

if (not negative_cycle) return false;

Inicializacin de algoritmo de Bellman-Ford 693b Algoritmo genrico de Bellman-Ford 696a Deteccin de ciclos negativos 700

Search_Cycle <GT> () (g, pred, arcs, cycle); }


Uses

return true;
Path
578a.

gomo preimosD l rutin es esenilmente igul que q_bellman_ford_min_spanning_tree()F il dido es que no se lul el rol rdorD slo se determin si existen o no ilosY de existirD entones se retornD en el prmetro cycleD el ilo donde se detet l negtividdF gomo y indimos l prinipio de l suseinD un vrinte de est tni estri en veri(r l existeni del ilo ntes de llegr l ltim iterinF r que est lterntiv se ompetitiv on l presente rein presentdD es neesrio que l squed del ilo se relie sore el rreglo pred sin neesidd de onstruir un grfo uxilirF min es importnte seleionr el riterio de periodiiddD el ul suele ser un iterin omplet prtir deD por ejemploD l V/2Esim iterinF
7.9.3.10 Clculo de ciclos negativos en un digrafo

v rutin nterior slo lul ilos en el omponente fuertemente onexo l que pertenez start_nodeD lo ul no responde solutmente si g tiene o no ilos negE

706

7. Grafos

tivosF i se pretende generlidd y segurr si existen o no ilos negtivos en un digrfo ulquierD entonesD unque l tni se fundmentlmente l mismD deemos llevr o un poo ms trjoF fsimenteD l tni que empleremos pr usr ilos negtivos se resume enX IF yteng C = {gomponentes fuertemente onexos} PF c C = @A e there_is_is_cycle = Bellman_Ford_Negative_Cycle() ejeutdo sore c prtir de un nodo ulquier de cF @A i there_is_cycle = iF wpee el ilo otenido por Bellman_Ford_Negative_Cycle() hi el diE grfo originl g iiF erminr on vlor de retorno true QF erminr on vlor de retorno false r el primer pso podemos perfetmente usr l rutin Tarjan_Connected_Components(g, list)D desrrolld en UFUFQFP @gF TRPAD lo que nos permite de(nirX
706

Rutinas de algoritmo de Bellman-Ford 693a +

705

template <class GT, class Distance, class Compare = Aleph::less<typename Distance::Distance_Type>, class Plus = Aleph::plus<typename Distance::Distance_Type>, class SA = Default_Show_Arc<GT> > inline bool bellman_ford_negative_cycle(GT & g, Path<GT> & cycle) { DynDlist<DynDlist<typename GT::Node*> > blocks; Tarjan_Connected_Components <GT, SA> () (g, blocks); // recorrer todos los bloques for (typename DynDlist<DynDlist<typename GT::Node*> >::Iterator it(blocks); it.has_current(); it.next()) { DynDlist<typename GT::Node*> & block = it.get_current(); if (block.size() == 1) continue; typename GT::Node * src = block.get_first(); // nodo inicio if (bellman_ford_negative_cycle<GT,Distance,Compare,Plus,SA> (g, src, cycle)) return true;

}
Uses

} return false;
DynDlist

85a and

Path

578a.

7.9. Caminos mnimos

707

n tni ltern onsiste en dir un nodo uxilir sD onetrlo l resto de los nodos on vlor de peso ero y ejeutr el lgoritmo de fellmnEpord desde sF il ilo en uestin se enontrr en el rreglo pred y ser lolizle medinte el lgoritmo de rjnF
7.9.4 Discusin sobre los algoritmos de caminos mnimos

il prolem de mino mnimo es uno de los prolem resolules ms importntes de los grfosF intre los lgoritmos estudidos y otros existentesD undo y mo seleionr unoc sniiemos nuestr disusin presentndo l siguiente tl repitultiv de tiempos de ejeuin y espioX
elgoritmo hijkstr ployd fellmnEpord epresentin vists de dyeni wtries de dyeni vists de dyeni hesempeo
O(E lg V ) O (V 3 ) O(V E)

ispio
O (V ) O (V 2 ) O (V )

ry vrios riterios pr tr es preguntF no primero est determindo por el heho de que el grfo se o no dirigidoF i se trt de un grfo sin pesos negtivosD entonesD deido su mejor rendimientoD el lgoritmo de hijkstr es l esogeni de ftoF vos grfos ponderdos nturles no tienen pesos negtivosY por nturl entendemos que el grfo modeliz diretmente un situin de l vid rel y no es un onseueni de lgun trnsformin mtemtiF or ejemploD en ulquier grfo eulidinoD es deirD en uno que represente distnis eulidinsD o en un grfo temporlD o seD uno que modelie durionesD el lgoritmo de hijkstr es l mejor opin pr lulr el mino mnimo entre un pr de nodosF v existeni de pesos negtivos desrt de plno el lgoritmo de hijkstrF in est situinD el lgoritmo de fellmnEpord es l prefereniD pues no slo exhie mejor tiempoD sino que detet ilos negtivosY unque esto ltimo es ms un onsiderin de vliE din que de relidd mtemtiD no se pg un oste signi(tivo por l veri(inF lnteds ls re)exiones nteriores nos pree entones l siguiente preguntX undo usr el lgoritmo de ploydErshllc n primer respuest onsiste en deirX undo se requiern lulr todos los pres de minos mnimosF e tles efetosD onviene omprr los otros lgoritmos presentdos pr todos lo pres de minos mnimosX
elgoritmo hijkstr ployd fellmnEpord hesempeo esprido
O(V E lg V ) O (V 3 ) O (V 2 E)

hesempeo denso
O(V 3 lg V ) O (V 3 ) O (V 4 )

ispio
O (V 2 ) + O (V ) O (V 2 ) O (V 2 ) + O (V )

r grfos densos en los que E V 2 el lgoritmo de hijkstr es ms ostoso que el de fellmnEpordD pero este ltimo es todv ms ostoso que el de ploydErshllF es ls ossD el lgoritmo de ploydErshll es l esogeni undo requirmos lulr todos los pres de minos mnimos y el grfo se densoD mientrs que el lgoritmo de fellmnEpord lo es undo el grfo se espridoF ero l pregunt y re)exin previs no tienen sentido sin l preguntX undo se requieren lulr todos los pres de minos mnimosc qrosso modoD existen dos situE ionesX undo se requier disponer del mnimo entre ulquier pr de nodos o undo se requier onoer el dimetro de un redF

708

7. Grafos

in grfosD el dimetro se de(ne omo el mino simple ms lrgoF v respuest est interrognte l proporion el ms lrgo mino entre un pr de nodosD dto que se orresponde on el mximo vlor de l mtriz de ostes rrojd por el lgoritmo de ploydErshll o por el lgoritmo de fellmnEpord en su versin pr todos los minos mnimosF

7.10 Redes de ujo


vs oss que nos son muy instituids devienen prte de nuestro fondo y trsfondoF is quiz por eso que tendemos no distinguirls yD muho menosD reonoer l trsendeni que lguns de ells tienen sore nuestr vidF n de ess ossD uiuD fundmentl pr nuestro modo de vidD es el tuo o tuer on el )uido que ste llev y l red de trnsporteD llmd de tuers que est tenolog onllevF hee sernos reminisente un prngn entre un red de tuers y un grfoX ls tuers son ros y los emplmes que juntn dos o ms tuers son nodosF uesto que l red trnsport un )uidoD tmin deemos her prehendido que se trt de un grfo dirigidoD pues el )uido irul en un sol direinF e un digrfo que de lgun form modelie un red de tuers y lgun lse )ujo irulnte se le llm redF
7.10.1 Deniciones y propiedades fundamentales

Denicin 7.8 (Red capacitada) n red es un digrfo G =< V, E > onexo onforE mdo por l quntupl < V, E, s, t, C > dondeX

IF s V es el nodo fuente u origen @gin (s) = 0AF PF t V es el nodo sumidero o terminl @gout (t) = 0AF QF C : E C es un funin de pidd que le sign d ro e E un pidd de )ujo cap(e) irulnte por el ro25 F or lo generlD C = Z + D es deirD ls piddes son enteros positivosF in emrgoD pueden ser perfetmente rionlesD irrionles o lgun otr lse de nillo en el sentido lgerio que represente un mgnitud de )ujoF in lgunos ontextosD est lse de red se le llm  red capacitadaF
K 5 6 E 8 L

9 H

5 3

A 6

F 7

3 1

10

pigur UFTRX n red


25
Tubo o canal, etctera, segn sea el caso.

7.10. Redes de ujo

709

in trminos ms fmilires on el devenir de nuestro disursoD un red es un digrfo on pesos donde se espei( un nodo fuente y uno sumideroF v (gur UFTR ilustr un ejemplo en el ul el nodo e es el fuenteD s el sumidero y los pesos de los ros ls piddes de d tuerF in un red es importnte denotr ojetivmente los onjuntos de ros slientes y entrntes de un nodoF in ese sentidoD ddo un nodo v V D IN(v) es el onjunto de ros entrntes mientrs que OUT(v) el de slientesF in situiones de l vid rel pueden plnterse multiredesD es deirD un multidigrfoF isto se orresponde on el heho de tener dos o ms tuers entre un pr de nodosD lo ul podr ser un poo prolemtio de mnejrD sore todo si usmos mtriesY pero en trminos de modelizinD l didur de un tuer redundnte se stre on un umento de l pidd del ro entre los nodos involurdosD mientrs que un orte de tuer signi( un disminuinF e N =< V, E, s, t, C > un red de )ujoF n )ujo ftile es un funin f : E C que le sign un vlor f(e) d roD denomindo )ujo irulnte que stisfe ls siguiente ondiionesX
Denicin 7.9 (Flujo factible)

IF Condicin de capacidad:

e E = 0 f(e) cap(e)
PF Condicin de conservacin del ujo:

@UFIHA

v V |v = s v = t =

f(e) =
eIN(v) eOUT(v)

f(e)

@UFIIA

K 5/3 5/3

6/2

8/5

4/1

4/1

9/1

5/3 3/3

A 6/4

4/1

7/1

3/3 1/1

4/1

7/1

6/1

10/1

pigur UFTSX n )ujo ftile sore l red de l (gur UFTR v (gur UFTS muestr un ejemplo de un )ujo ftile sore l red de l (gur UFTRF v piddes se uin l izquierd y el )ujo irulnte l derehF egn l ndole del onjunto que represente los )ujosD los vlores en los ros pueden seprrse medinte omsD rrs o simplemente espiosF e exepin del fuente y del sumidero todo nodo stisfe l ondiin de onservin de )ujoF
Denicin 7.10 (Valor de ujo)

il vlor de )ujo en un red N =< V, E, s, t, C > on )ujo fD denotdo omo F(N, f) se de(ne omoX F(N, f) =
eOUT(s)

f(e) =
eIN(t)

f(e)

@UFIPA

710

7. Grafos

in otrs plrsD el vlor de )ujo es l ntidd de )ujo que dej el fuenteD l ul dee ser l mism que lleg l sumideroF in l (gur UFTS el vlor de )ujo es 7F
7.10.2 El TAD

Net_Graph

710a

vs redes pitds modelizn situiones reles de los mundos nturl y tenolgioF uesto que un red es un grfo dirigidoD nos vldremos del eh List_DigraphF il eh resultnte lo llmremos Net_GraphF elgerimenteD en un red deemos mnejr dos vlores nominlesX el ero o eleE mento neutro de l sum y el in(nitoD los ules de(nimos de l siguiente mnerX Miembros de Net_Graph 710a (711b) 711a mutable Flow_Type Infinity; il dido esenil de Net_Graph reside en que los ros mnejen l ide de pidd y )ujoF r eso de(nimos un nuevo tipo de roD hereddo de Graph_ArcD pr ser usdo on Net_GraphX Arco de red 710b template <typename Arc_Info, typename F_Type = double> class Net_Arc : public Graph_Arc<Arc_Info> { typedef F_Type Flow_Type; Flow_Type cap; Flow_Type flow; Miembros de Net_Arc 723 }; v lse Net_Arc slo se destin modelizr e instrumentr lguns vlidionesD no se destin instnirse por el usurio ni ederse medinte lguno de sus mtodosF e efetos de desempeo en tiempoD en detrimento de un poo de espio pero en el inters de l vlidinD de(nimos l lse Net_Node derivd de Graph_NodeX Nodo de red 710c template <typename Node_Info, typename F_Type = double> class Net_Node : public Graph_Node<Node_Info> { typedef F_Type Flow_Type; size_t in_degree; Flow_Type out_cap; Flow_Type in_cap; Flow_Type out_flow; Flow_Type in_flow;
Net_Node() : in_degree(0), out_cap(0), in_cap(0), out_flow(0), in_flow(0) {}

710b

710c

};

in_degree lmen l ntidd de ros entrntes @l de slientes y se enuentr desde Graph_NodeAY ests ntiddes sirven pr determinr en O(1) nodos fuentes y sumiderosF out_cap es l pidd de slidY o se l sum de tods ls piddes de los ros de slidD mientrs que in_cap es l sum de ls de entrdF out_flow es l sum totl de )ujo entrnte mientrs que in_flow l del slienteF ists mgnitudes permiten veri(r

7.10. Redes de ujo

711

711a

l ondiin de onservin de )ujoD segn @UFIIAD medinte el predido out_flow == in_flowF vos triutos un nodo de red son oservles medinte ls siguientes primitiE vsX Miembros de Net_Graph 710a + (711b) 710a 711c Flow_Type get_in_cap(Node * node) const { return node->in_cap; }
Flow_Type get_out_cap(Node * node) const { return node->out_cap; } size_t get_in_degree(Node * node) const { return node->in_degree; } size_t get_out_degree(Node * node) const { return get_num_arcs(node); } Flow_Type get_out_flow(Node * node) const { return node->out_flow; } Flow_Type get_in_flow(Node * node) const { return node->in_flow; }

711b

eprte l informin de triutos Node_Info y Arc_InfoD deemos her notdo que ls lses Net_Arc y Net_Node mnejn omo prmetro plntill un tipo ritmtio llmdo F_TypeD exportdo por ms lses jo el sinnimo Flow_TypeF or omisinD Flow_Type es longD pero ien pudier ser float o ulquier otro tipo lgerioF v red se de(ne medinte el tipo Net_Graph uy espei(in generl es omo sigueX Net_Graph 711b template <class NodeT = Net_Node<Empty_Class, double>, class ArcT = Net_Arc<Empty_Class, double> > class Net_Graph : public List_Digraph<NodeT, ArcT> { typedef List_Digraph<NodeT, ArcT> Digraph; typedef ArcT Arc; typedef NodeT Node; typedef typename Arc::Flow_Type Flow_Type; typedef typename Node::Node_Type Node_Type; typedef typename Arc::Arc_Type Arc_Type; Miembros de Net_Graph 710a };
Uses

List_Digraph

547a.

vos sinnimos de tipos tienen los mismos sentidos que pr los tipos de grfo List_Graph y List_DigraphF
7.10.3 Manejos de varios fuentes o sumideros

711c

is lro que durnte l onstruin de un red hr vrios fuentes y sumiderosF min es plusileD tnto nivel del propio eh omo del fsioD tener un red on vrios fuentes y sumiderosF r onoer rpidmente los nodos fuentes y sumideros se utilizn sendos onjuntos dinmios uy implntin se s en el tipo set<T> de l iliote estndr C++ D el ulD en ALEPH est sdo en roles inrios de squed letorimente equilirdos del tipo trep estudido en TFQ @gF RTRAX Miembros de Net_Graph 710a + (711b) 711a 712a Aleph::set<Node*> src_nodes; Aleph::set<Node*> sink_nodes;

712

7. Grafos

f1 f2 f3
D

f6
I

F D I G E J H

f7
G

FA
S

FI
T

f4
E

f8
J

FB FC

FJ

f5
C

f9 f6
H

(a) Red con varios fuentes y sumi- (b) La misma red con un supra fuente y sumideros dero

pigur UFTTX ijemplo de reduin de un red on vrios nodos fuentes y sumideros un on un suprEfuente y un suprEsumideroF v pidd de los suprEros que emnn desde el fuente es FA = cap(OUT(A)), FB = cap(OUT(B)), FC = cap(OUT(C))D y l de los que rrin l sumidero FI = cap(IN(J)), FJ = cap(IN(J))

712a

src_nodes lmen l list de nodos fuente y sink_nodes l de sumiderosF gundo se re un nodoD ste se insert en mos rolesF gundo se insert un ro se elimin su nodo origen de sink_nodes y su destino de src_nodesF he este modoD en ulquier momento onoemos los fuentes y sumideros de l redF r onoer los nodos fuentes o los sumideros se exportn primitivs de refereni los onjuntosX Miembros de Net_Graph 710a + (711b) 711c 712b
Aleph::set<Node*> & get_src_nodes() { return src_nodes; } Aleph::set<Node*> & get_sink_nodes() { return sink_nodes; }

712b

or rzones prtisD ls referenis estos onjuntos no son onstntesD pero sts no estn destinds modi(inF e efetos de l simpliiddD tnto mtemti omo lgortmiD es preferile trjr on un red que onteng extmente un solo fuente y un sumideroF es puesD si l red posee ms de un fuente o sumideroD entones st se redue olor un nodo suprfuente nioD que no es prte lgi de l redD onetdo los fuentes trvs de ros on pidd igul l sum de ls piddes de los ros de slid de todos los fuentesF hel mismo modoD los sumideros se onetn un solo suprsumidero on ros de pidd igul l sum de tods ls piddes de los ros de entrd de todos los sumiderosF v (gur UFTT ilustr un ejemploF v didur de suprEnodos se reliz trvs de l siguiente fmili de primitivs plisD de ls ules slo mostrmos l instrumentin de ls que oniernen l fuenteX Miembros de Net_Graph 710a + (711b) 712a 713a void make_super_source() { DynDlist<Node*> src_list; for (typename Aleph::set<Node*>::iterator it = src_nodes.begin(); it != src_nodes.end(); ++it) src_list.append(*it);
Node * super_source = insert_node(); while (not src_list.is_empty()) { Node * p = src_list.remove_first(); insert_arc(super_source, p, get_out_cap(p));

7.10. Redes de ujo

713

} void unmake_super_source() { remove_node(*src_nodes.begin()); with_super_source = false; } void make_super_sink() void unmake_super_sink() void make_super_nodes() { make_super_source(); make_super_sink(); } void unmake_super_nodes() { unmake_super_source(); unmake_super_sink(); }
Uses

} with_super_source = true;

DynDlist

85a.

713a

ists primitivsD en prtiulr ls dos ltimsD sern invods por un lgoritmo de lulo de )ujo mximo l prinipio y (nl de sus lulosF gomo puede preirseD ls rutins emplen ls nders lgis with_super_source y with_super_sink pr indir si hy o no suprEnodosF ists nders son triutos de Net_GraphF n vez trnsformd l red medinte make_super_nodes()D se grntiz que se tiene un solo fuente y un solo sumideroF es puesD vle l pen disponer de dos oservdoresX Miembros de Net_Graph 710a + (711b) 712b 713b Node * get_source() { return *get_src_nodes().begin(); } Node * get_sink() { return *get_sink_nodes().begin(); }
7.10.4 Operaciones topolgicas sobre una red capacitada

713b

Net_Graph requiere sorergr y extender lguns funiones de List_DigraphD espe(E mente ls relionds on el mnejo de nodos y rosF gomenemos por l inserin de un nodoX Miembros de Net_Graph 710a + (711b) 713a 714a
Node * insert_node(const Node_Type & node_info) { Node * p = Digraph::insert_node(node_info); src_nodes.insert(p); sink_nodes.insert(p); return p; }

v rutin pel l mquinri de List_DigraphD uyo sinnimo dentro de Net_Graph es DigraphF v sorerg extiende el dir el nuevo nodo los onjuntos src_nodes y

714

7. Grafos

714a

sink_nodesF ehor vemos l extensin pr l inserin de un roX Miembros de Net_Graph 710a + (711b)

713b 714b

virtual Arc * insert_arc(Node * src_node, Node * tgt_node, const typename Arc::Arc_Type & arc_info, const Flow_Type & cap, const Flow_Type & flow) { // insercin en clase base Arc * arc = Digraph::insert_arc(src_node, tgt_node, arc_info); src_nodes.erase(tgt_node); // actualizacin de source/sink sink_nodes.erase(src_node); arc->cap = cap; arc->flow = flow; // ajuste capacidad y flujo de arco

tgt_node->in_degree++; // actualizar info de control de nodo src_node->out_cap += cap; tgt_node->in_cap += cap; src_node->out_flow += flow; tgt_node->in_flow += flow; } return arc;

714b

insert_arc() sorergdo iniiliz el estdo de los )ujos en los nodos origen y desE tinoY s omo el grdo de entrd del nodo destinoF n vez que existe un ro src_nodetgt_nodeD src_node dej on ertitud de ser un sumideroD mientrs que tgt_node dej de ser fuenteY de h ls eliminiones de los onjuntos src_nodes y sink_nodesF e efetos de verstiliddD Net_Graph export versiones sorergds de insert_arc() on distints presentiones pr prmetros de pidd y )ujoD de ls ulesD quiz l ms interesnte seX Miembros de Net_Graph 710a + (711b) 714a 714c
virtual Arc * insert_arc(Node * src_node, Node * tgt_node, const Flow_Type & cap) { return insert_arc(src_node, tgt_node, Arc_Type(), cap, 0); }

714c

v eliminin de un ro requiere tulizr el grdo de entrd del nodo destino y los umuldos de )ujos de los nodosD s omo l didur eventul en los onjuntos src_nodes y sink_nodesF or eso en Net_Graph tmin deemos sorergrX Miembros de Net_Graph 710a + (711b) 714b 715a virtual void remove_arc(Arc * arc) { Node * src = get_src_node(arc); Node * tgt = get_tgt_node(arc);
if ((tgt->in_degree) == 0) src_nodes.insert(tgt); // tgt deviene un nodo fuente

7.10. Redes de ujo

715

src->out_cap src->out_flow tgt->in_cap tgt->in_flow

-= -= -= -=

arc->cap; // actualizar caps y flujos en src y tgt arc->flow; arc->cap; arc->flow;

Digraph::remove_arc(arc); // eliminar en clase base if (get_num_arcs(src) == 0) sink_nodes.insert(src); // src deviene un nodo sumidero

715a

v eliminin de un nodo requiere eliminr de los onjuntos src_nodes y sink_nodes @en so de que el nodo se enuentre en lguno de ellosAD pero tmin tulizr los esE tdos de los nodos onetdos por los ros del nodo elimindoF in l lse List_Graph esto se resuelve llmndo suesivmente remove_arc()F equ hy que her lo mismo ms l eliminin de los onjuntos src_nodes y sink_nodesF urge entones l preE gunt podemos reusr List_Graph::remove_node()c v respuest es (rmtivD pues remove_arc() es un mtodo virtul desde l lse se List_GraphF he este modoD insE trumentr remove_node() es muy simpleX Miembros de Net_Graph 710a + (711b) 714c 715b virtual void remove_node(Node * p) { Digraph::remove_node(p); // eliminacin en clase base src_nodes.erase(p); sink_nodes.erase(p); } v instruin (nl Digraph::remove_node(p) invor l eliminin de los ros de un nodo @ver UFQFIHFS @gF SUQAAF uesto que remove_arc() es virtulD Digraph::remove_node(p) invo Net_Graph::remove_arc()F wuhos prolems de grfos se resuelven trvs de redes de )ujoF is pues plusile y prole onstruir un red prtir de un grfo y existenteD resolver on ell el prolem en uestin y luego regresr l grfo originlF or est rzn es desele disponer de un onstrutor opi de digrfo que nos onstruy un red mpedX Miembros de Net_Graph 710a + (711b) 715a 715c Net_Graph(Digraph & digraph) { Net_Graph::Net_Graph(); // inicializa atributos copy_graph(*this, digraph, true); // copia mapeada } ry otro onstrutor Net_Graph(Net_Graph & net)D el ul no efet l opi mpedF r onoer los triutos de red soidos un r se tienen los oservdores siguienE tesX Miembros de Net_Graph 710a + (711b) 715b 715d const Flow_Type & get_flow(Arc * arc) const { return arc->flow; } const Flow_Type & get_cap(Arc * arc) const { return arc->cap; } e vees es desele reEiniir un redD esto esD poner su vlor de )ujo en eroX Miembros de Net_Graph 710a + (711b) 715c 716 void reset() {

715b

715c

715d

716

7. Grafos

for (Arc_Iterator<Net_Graph> it(*this); it.has_current(); it.next()) it.get_current()->flow = 0; for (Node_Iterator<Net_Graph> it(*this); it.has_current(); it.next()) { Node * p = it.get_current(); p->in_flow = p->out_flow = 0; }

716

rolementeD un de ls primitivs fundmentles es onoer el vlor del )ujo de l redX Miembros de Net_Graph 710a + (711b) 715d 724a Flow_Type flow_value() { return get_source()->out_flow; }
7.10.5 Cortes de red

elgunos prolems de grfos pueden plnterse en trminos de un red e inversmenteF n primer vnulo entre ests dos visiones se notr en l prxim de(niinF
Denicin 7.11 (Corte de una red)

e un red N =< V, E, s, t, C >F en

IF Vs = {s} {v V | v = t} PF Vt = {t} {v V | v = s} les que Vs Vt = V Vs Vt = D es deirD un prtiin disjunt de V D denomind Vs D que ontiene l nodo fuente pero no l destino y Vt D que ontiene l nodo destino pero no l fuenteF n orte de l red ND denotdo < Vs , Vt >D se de(ne por el onjunto de ros que onetn nodos de Vs hi nodos de Vt F xotemos que < Vs , Vt > no ontiene los ros que vn desde Vt hi Vs F iste onjunto se denot omo < Vs , Vt > v (gur UFTU ilustr un orte on Vs = {A, B, D, F, G, K} y Vt = {E, H, I, J, L} donde < Vs , Vt >= {(K E), (D E), (F H), (G H), (G J)} y < Vs , Vt >= {(L F)}F
Vt
L 9 H 5 3 6 10 J I

Vs
5 A 6

K 4 D 3 B

6 5 4

8 4

F 4 7

pigur UFTUX n orte sore l red de l (gur UFTR e menudoD l litertur de grfos denomin < Vs , Vt > omo un orte sEt por el heho de que son los nodos fuente y sumidero los que dominn l prtiinF

7.10. Redes de ujo

717

il sunto esenil del prngn entre l red y el digrfo es el rter dinmio de un )ujo en l tuerF iD por ejemploD rimos un llve y no surte guD entones intuimos que hy un orte en lgun prteF v relin de onetividd de un grfo puede estudirse segn est intuiinF i tenemos un grfo y desemos verigur su onetividdD entones podrmos inyetrle un )ujoY el )uido permer todos los nodos onetdosF
Denicin 7.12 (Valor de ujo de un corte)

e un red N =< V, E, s, t, C > on )ujo f y un orte ulquier < Vs , Vt >F il vlor de )ujo del orte se de(ne omoX F(< Vs , Vt >, f) =
eOUT(<Vs ,Vt >)

f(e)

eIN(<Vs ,Vt >)

f(e)

@UFIQA

honde OUT(< Vs , Vt >) son los ros del orte que vn desde Vs hi Vt yD reproE menteD IN(< Vs , Vt >) son los ros del orte que vn desde Vt hi Vs F
Proposicin 7.7

@Equivalencia de ujo entre una red y un corteA e un red N =< V, E, s, t, C > on )ujo f y un orte ulquier < Vs , Vt >F intonesX F(< Vs , Vt >, f) = F(N, f) vo ul es equivlente X @UFIRA

f(e) =
eOUT(s) eOUT(<Vs ,Vt >)

f(e) n = |Vs )
eIN(<Vs ,Vt >)

f(e)

@UFISA

Demostracin (Por induccin sobre

 n = 1X en este so Vs = {s} y Vt = V {s}F esD < Vs , Vt >= OUT(s) e IN(s) = impli diretmente que F(< Vs , Vt >, f) = eOUT(s) f(e) = F(N, f)F  n > 1X hor sumimos que l proposiin es iert pr todo nF gonsideremos un nodo u < Vs , Vt >F egn el sentido respeto los onjuntos Vs y Vt D lsi(quemos los ros de u enX
   

INs (u) = {ros que llegn u desde Vs } INt (u) = {ros que llegn u desde Vt } OUTs (u) = {ros que slen de u hi s} OUTt (u) = {ros que slen de u hi t}

vos utro onjuntos junto on < Vs , Vt > se ilustrn genrimente en l (gur UFTVEF ehor movmos el nodo u hi el onjunto Vt D lo que rre un nuevo orte < Vs , Vt > ilustrdo en l (gur UFTVEF esD podemos expresr F(< Vs , Vt >, f) del siguiente modoX

F(< Vs , Vt >, f) = F(< Vs , Vt >, f) INs (u) + OUTs (u) + OUTt (u) INt (u)

@UFITA

or l hiptesis indutiv F(< Vs , Vt >, f) = F(N, f)D pues Vs = Vs {u} |Vs | < |Vs |F or l ondiin de onservin del )ujo INs (u) + INt (u) OUTs (u) OUTt (u) = 0F remos ls orrespondientes sustituiones en @UFITA y otenemosX F(< Vs , Vt >, f) = F(N, f) + 0 = F(N, f)

718

7. Grafos

Vs

INs (u) OUTs (u) s

OUTt (u) u < Vs , Vt > t

Vt

OUTs (u) Vs < Vs , Vt > s

Vt OUTt (u) t u INt (u)

INt (u)
(a) Un nodo

INs (u)
nodo

en

< Vs , Vt >

(b) El

movido

hacia

<

Vs , V t >

pigur UFTVX gonsiderin de un u < Vs , Vt > gomo orolrio de l proposiin nterior podemos estleer queD ddo un orte < Vs , Vt >D entonesX F(< Vs , Vt >, f) =
eOUT(s)

f(e) =
eIN(t)

f(e) = F(N, f)

@UFIUA

7.10.6

Flujo mximo/corte mnimo

v ide de red y )ujo or myor inters undo nos preguntmos mo enontrmos un )ujo f de tl mner que ste se mximoc l )ujo mximo se denot omo f F isenilmenteD este es el prolem instrumento de est seinD y lo li(mos de instrumentl porque el prolem del )ujo mximo es vehulo de resoluin de un mpli gm de otros prolemsF in este sentido nos onviene mostrr el prlelismo entre un )ujo mximo y un orte de pidd mnimD lo ul requiere l siguiente de(niinF
Denicin 7.13 (Capacidad de un corte) e un red N =< V, E, s, t, C > y un orte ulquier < Vs , Vt >F v pidd del orteD denotd omo cap(< Vs , Vt >)D se de(ne omo l sum de ls piddes de los ros perteneientes l orteF y seX

cap(< Vs , Vt >) =
e<Vs ,Vt >

cap(e)

@UFIVA

inontrr el )ujo mximo de un red est estrehmente reliondo on enontrr un orte de pidd mnim por l simple rzn de que un )ujo mximo dee ser menor o igul que l mnim pidd posile que se enuentre en un orte de redF in efetoD por l proposiin UFU semos queX F(N, f) cap(e)
e<Vs ,Vt > e<Vs ,Vt >

f(e) = cap(< Vs , Vt >)


e<Vs ,Vt >

f(e)

pues e E = f(e) cap(e)F or tntoD ddo que los )ujos son positivosX F(N, f) cap(< Vs , Vt >) F(N, f ) cap(< Vs , Vt >) isto nos ondue un muy interesnte resultdoF

@UFIWA

gonsiguientementeD si f es un )ujo mximoD entonesX @UFPHA

7.10. Redes de ujo

719

Proposicin 7.8 e f un )ujo sore un red N =< V, E, s, t, C > y < Vs , Vt > un orte sore NF i F(N, f) = cap(< Vs , Vt >) entonesX

IF f es un )ujo mximo y PF < Vs , Vt > es un orte de pidd mnimF e f un )ujo mximo sore N y se < Vs , Vt >min el orte mnimo de NF itoriemos genrimente el orte mnimo de l mner ilustrd en l (gur UFTWF
Demostracin
Vs
s

< Vs , Vt >min

Vt
t

< Vs , Vt >min

pigur UFTWX isquem generl de < Vs , Vt >min IF or de(niin semos que desde s prte un )ujo f on vlor de )ujo F(N, f )D el ul es extmente el mismo que lleg tF glrmenteD pr que f pued psr por < Vs , Vt > se dee umplir que F(N, f ) cap(< Vs , Vt >) yD puesto que l proposiin (rm que F(N, f ) = cap(< Vs , Vt >)D entones f es el mximo posile que puede psr por < Vs , Vt >D lo que orroor @UFPHAF v mximlidd de f est pues demostrd PF upongmos que cap(< Vs , Vt >) = K = F(N, f )D pero que < Vs , Vt > no es mnimoF i s fueseD entones existir otro orte on un pidd K < KD pero por est pidd no puede )uir f D pues F(N, f ) > K F v ontrdiin demuestr pues l minimlidd de < Vs , Vt > v proposiin nos indii que si lulmos el )ujo mximoD entones l ominin uyo onjunto de ros < Vs , Vt > nos d on pidd igul l )ujo orresponde l orte mnimoF e f un )ujo mximo sore un red N =< V, E, s, t, C > on orte mnimo < Vs , Vt >F intonesX
Corolario 7.1

IF

e < Vs , Vt >= f(e) = cap(e)


PF

@UFPIA @UFPPA

e < Vs , Vt >= f(e) = 0


Demostracin

IF snmedito de l proposiin UFV @gF UIWA PF uesto que = = F(N, f )D entones eOUT(s) f(e) eIN(t) f(e) F(< Vs , Vt >, f ) = 0D pues si no se le restr F(< Vs , Vt >, f ) y ste no ser mximo

720

7. Grafos

il orolrio nos (n ms el mputo de un orte mnimo prtir del onoimiento del )ujo mximoF odo ro que pertenez < Vs , Vt > tiene vlor de )ujo igul su piddF enlogmenteD todo ro que pertenez < Vs , Vt > tiene vlor de )ujo eroF i este riterio le unmos omo ondiin que l sum de ls piddes de los ros de < Vs , Vt > tiene que orresponderse on el vlor de )ujo mximoD entones tenemos un mtodo pr lulr el orte mnimoD ddo el )ujo mximoF
7.10.7 Caminos de aumento

vos lgoritmos de lulo de )ujo mximo se sn en enontrr minos espeiles llmE dos de umentoF snformlmenteD un mino de umento es un seueni de ros entre el fuente y el sumidero por l ul se puede umentr el )ujoF in emrgoD no es un mino trdiionl y pr prehender eso requerimos un de(niin intermediF
Denicin 7.14 (Semicamino)

n semimino en un red N =< V, E, s, t, C >D o uE siminoD es un seueni < s, e1 , v1 , e2 , . . . , ek1 , t > de nodos y ros entre el nodo fuente y el sumideroF xotemos que los ros de un semimino no neesrimente vn dirigidos desde el fuente hi el sumideroY puede her ros desde el destino hi el sumideroF n ro desde el fuente hi el sumidero se llm arco de adelanto F imtriE menteD uno desde el sumidero hi el fuente arco de retroceso F or ejemploD en el siguiente semimino de l red mostrd en l (gur UFTRX
K 5/2 4/2 4/3 L

5/2

4/2

vos ros {(A, K), (K, D), (D, F), (L, I)} son de delntoD mientrs que {(L, F)} es de retroesoF gon l ide de semimino podemos de(nir l de mino de umentoF e un red N =< V, E, s, t, C >F n mino de umento Ca es un semimino en N tl que el )ujo de sus ros de delnto puede inrementrse y el de sus ros de retroeso derementrseF i Ca es un mino de umentoD entonesD por de(niinD pr ulquier ro e de delnto f(e) cap(e)D pues sino no hr form de inrementr el )ujoF in el mismo sentidoD pr ulquier ro e de retroeso f(e) > 0F v ntidd en que puede inrementrse el )ujo en un ro de delntoD o derementrse en uno de retroesoD se denomin esln @slkA26 D se design e y se determin de l siguiente mnerX cap(e) f(e) si e es de delnto e = @UFPQA f(e) si e es de retroeso
Denicin 7.15 (Camino de aumento)

hdo un mino de umento Ca D l mxim ntidd en que puede umentrse el )ujo de l red por ese mino est supeditd l ondiin de onservin de )ujo y se
26
Este es el trmino castellano que el autor ha decidido emplear por el trmino ingls slack, el cual se traduce a menudo por holgura.

7.10. Redes de ujo

721

determin omoX

Ca = min e
eCa

@UFPRA

es deirD el mnimo eslabn del mino de umentoF i enontrmos un mino de umento Ca sore un redD entones es seguro que sore sus ros podemos umentr o disminuir el vlor de )ujo en el vlor del mnimo eslnF isto indii el rter lgortmio de los minos de umento en l determinin del )ujo mximoF
4 K 2 3 3 3 A 4 2 B 1 G 1 D 1 3 3 1 F 1 6 1 9 J 5 5 1 2 3 6 H 3 3 I 2 E 3 1 8 1 3 3 5 L 2

pigur UFUHX ed residul del grfo de l (gur UFTS @gF UHWAF vos ros de )ujo restnte son ontinuosD mientrs que los residules son puntedosF

e un red N =< V, E, s, t, C > on vlor de )ujo F(N, f)F il grfo residul de N denotdo omo N =< V, E , s, t, C >D tl que E y C se onstruyen del siguiente modoX
Denicin 7.16 (Red residual)

IF e = (u, v) E = @A e = (v, u) E | cap(e) = f(e) @ro residulAF @A e = (u, v) E | cap(e ) = cap(e) f(e) @ro de )ujo restnteAF

v (gur UFUH ilustr l red residul del grfo on vlor de )ujo mostrdo en l (gur UFTSF v red residul nos permite enontrr minos de umento medintes squeds de minosD se por profundidd o por mplitudD desde el fuente hi el sumideroD en el mismo sentido de los lgoritmos estudidos en UFSFUFP @gF SWUA y UFSFV @gF THHAF e ese tenorD l (gur UFUIE muestr un eventul mino enontrdo por un hipotti squed en profundidd y el orrespondiente mino de umento @UFUIEAF n vez hlldo un mino de umento podemos inrementr el )ujo de l red en el vlor de su mnimo eslnF r l (gur ejemplo UFTS y el mino de umento mostrdo en l (gur UFUIE on mnimo esln Ca = 1D podemos modi(r el )ujo de los ros del mino de umento en el vlor de Ca F isto nos ondue l vlor de )ujo de l (gur UFUPF he l modi(in efetudD que depr en l (gur UFUPD nos onviene estleer ls siguientes oserviones por seprdoX IF il vlor del )ujo de l red se inremento de 7 8F PF vs modi(iones sore el )ujo slo involurn ros del mino de umentoF

722

7. Grafos

4 K 2 3 3 3 A 4 2 B 1 G D 1 3 3 1 F 1 2 3 2 E 3

3 5 L 2 1 6 H 1 6 1 9 J 1 5 5 A D 3 3 2 2 3 F 6 H I 8 I K E L 2 8 1 3 4

(a) Camino encontrado por profundidad

(b) Camino de aumento en la red

pigur UFUIX n mino de umento en l red residul de l (gur UFUHF


K 5/4 5/2 6/3 E 8/5 L

4/1

4/1

9/0

5/4 3/3

A 6/4

4/2

7/2

3/3 1/1

4/1

7/1

6/1

10/1

pigur UFUPX n )ujo ftile sore l red de l (gur UFTR luego de inrementr el )ujo en Ca = 1 orrespondiente l mnimo esln del mino de umento mostrdo en l (gur UFUIE @pg UPPA QF e pesr de ls modi(iones efetudsD se mntiene l ondiin de onservin de )ujo sore los nodos que onformn el mino de umentoF ists oserviones se generlizn jo l siguiente proposiinF
Proposicin 7.9 (Ford-Fulkerson 1956 [54])

e un red N =< V, E, s, t, C > on vlor de )ujo F(N, f)F e Ca un mino de umento sore l red ND luldo medinte un squed de t en l red residul prtir de s y uyo mnimo esln es Ca F intonesD el )ujo de l red puede umentrse en el vlor Ca del siguiente modoX f(e) + Ca si e es un ro de delnto

f(e) =
Demostracin

f(e) Ca f(e)

si e es un ro de retroeso

@UFPSA

en ulquier otro so

vos ros del grfo que son modi(dos son quellos que perteneen Ca F uesto que Ca es el vlor mnimo entre lgn cap(e) f(e) y f(e) @ver de(niin UFIS pgF UPHAD el inremento sore un ro de delnto e no soreps cap(e)F hel mismo modoD el deremento sore uno de retroeso e no es menor que 0F or tntoD se preserv l ondiin de pidd sore todos los nodos involurdos en Ca F or de(niinD los extremos de Ca son s y tF uesto que Ca fue luldo prtir de sD es seguro que el primer ro s v de Ca es de delntoY por tntoD el )ujo de l red se ument l inrementr el )ujo en el ro de delnto en el vlor Ca F imilrmenteD el ltimo ro de Ca D on form w tD que ulmin en t tmin es de delnto y su )ujo se inrement en el mismo vlor Ca F es puesD el vlor de )ujo de l red ument en Ca F

7.10. Redes de ujo

723

r el resto de los nodos de Ca deemos veri(r que se preserv l ondiin de onservin del )ujoF vs posiles ominiones de un nodo ulquier v Ca , v = s, v = t sonX IF

v a X en uyo so el inremento sore el )ujo entrnte es el mismo que pr el )ujo slienteF


C C

+Ca

+C

a a PF v X simtrio l nteriorD pero on derementoF a QF v a X sin importr ules son los ros inidentes o dyentes vD ni untos stos sonD el )ujo se onservD pues en un ro de slid se ument en Ca pero en otro se derement en l mism ntiddF

+C

RF

+Ca

a v X simtrio l so nterior pero pr ros de entrd

7.10.8

Clculo de la red residual

723

i los minos de umento se luln por inspein de l red residulD entones reE querimos enontrr un mner de lulrlF n primer onsiste en her un opi mpedD modi(rle sus ros sus piddes restntes y luego dirle los ros resiE dulesF ore l red residul se puede tulizr el )ujo l esln mnimo de un mino de umento y repetir l squed de minos de umento y tuliziones de )ujo hst mximizrloF ero este enfoque onllev el prolem de duplir el espio en nodos y el dole de rosF uede herse en tiempo equiprle y sin neesidd de duplirc v respuest es (rmtivD es deirD podemos representr l red residul sore l red originlF r eso dimos un triuto l ro que indique si el ro es o no residul y exportmos interfes que muestren los pesos de un ro segn @UFPSAF r ser si el ro es residul o noD gurdmos l imgen residul del ro en un puntero y un indiin lgiX Miembros de Net_Arc 723 (710b) Net_Arc * img_arc; bool is_residual; i this es un ro residulD entones img_arc es un puntero l ro del ul this es residulF enlogmenteD si this es un ro prte de l redD entones img_arc es l direin de su ro residulF il triuto is_residual indi si this es o no residulF vos lgoritmos de lulo de )ujo mximo sdos en squeds de minos de umento sore l red residul se sn en l capacidad restante en el roD l ul llmremos omo Cr (e) = cap(e) f(e) pr un ro normlF r que l ilusin de pidd restnte se l mism sore un ro residul eD dee stisferse que cap(e) f(e) = cap(e) f(e)F esD los vlores de un ro residul siempre se olon enX cap(e) = cap(e) @UFPTA @UFPUA

f(e) = cap(e) f(e)

he este modoD pr un ro ulquier e y su residul eD capr (e) = cap(e)f(e) proporion l pidd restnte de eY mientrs que capr (e) = cap(e) f(e) = f(e) proporion el )ujo irulnte por eF

724

7. Grafos

724a

uesto que un ro residul se orresponde iniilmente on uno relD en su rein se espei( el ro relX Miembros de Net_Graph 710a + (711b) 716 724b void insert_residual_arc(Arc * arc) { Arc * res_arc = Digraph::insert_arc(get_tgt_node(arc), get_src_node(arc));
res_arc->is_residual res_arc->img_arc res_arc->cap res_arc->flow } = = = = true; arc; arc->cap; arc->cap - arc->flow;

arc->img_arc = res_arc;

724b

il (n de l red residul es servir de medio pr lulr minos de umentoF or est rzn no vle l pen preouprse por ls eventules inonsistenis usds por l preseni de los ros residulesD el grdo de slid de un nodo o el reorrer los ros de un redD por ejemplosF il grfo residul se re pr lulr el )ujo mximo y se destruye inmeditmente ste se hy luldoF v eliminin de un ro residul dee relizrse prtiulrmenteY es deirD no podeE mos invor Net_Graph::remove_arc()D pues ste presumir que el ro es prte lgi de l redD lo que no es espe(mente el soF esD lo hemos medinte otr primitiv prtiulrX Miembros de Net_Graph 710a + (711b) 724a 724c void remove_residual_arc(Arc * arc) { Digraph::remove_arc(arc); } iendo insertr y eliminr ros residulesD l onstruin y destruin de l red residul dentro de l propi red son diretsX Miembros de Net_Graph 710a + (711b) 724b void make_residual_net() { size_t n = this->get_num_arcs(); // num arcos residuales a insertar for (Arc_Iterator<Net_Graph> it(*this); it.has_current() and n > 0; it.next()) { Arc * arc = it.get_current_arc(); if (not arc->is_residual) { insert_residual_arc(arc); n; } } } void unmake_residual_net() { for (Arc_Iterator<Net_Graph> it(*this); it.has_current(); ) { Arc * arc = it.get_current_arc();

724c

7.10. Redes de ujo

725

}
D

if (arc->is_residual) { it.next(); remove_residual_arc(arc); } else it.next();

4/0

8/0

4/0

6/0

3/0

4/0

5/0

3/0

4/0

3/0

4/0

7/0

6/0

4/0

5/0

5/0

5/0

3/0

5/0

7/0

6/0

4/0

6/0

4/0

6/0

5/0

(a)

(b)

pigur UFUQX n red ejemplo on )ujo en 0 y su residul

7.10.9

Clculo de caminos de aumento

725

gomo y hemos indidoD l squed de un mino de umento trvs de l red residul se remite un squed de mino desde el fuente hst el sumideroF l squed puede herse por profundidd o mplitud trvs de ls primitivs de lulo de minos estudids en UFSFUFP @gF SWUA y UFSFV @gF THHA respetivmenteF e efetos de utilizr extmente ls misms primitivs deemos her que l lse Node_Arc_Iterator hg l squed sore l red residul y no sore l originlF in otrs osiones ser neesrio que el iterdor slo muestre ros residules y en otrs ms todos los rosF r trtr on esto de(nimos un lse (ltro que (ltre el ro segn el vlor del )ujo restnteD se ste o no un ro residulX Funciones para Net_Graph 725 726 template <class N> class Res_F { bool operator () (typename N::Node *, typename N::Arc * a) const { return (a->cap - a->flow) != 0; } }; gon este (ltroD find_path_depth_first() y find_path_breadth_first()D invods soE re el grfo on l red residulD enontrrn diret y trnsprentemente minos de umento entre el fuente y sumideroF
7.10.10 Incremento del ujo por un camino de aumento

i tenemos un mino de umento gurddo en un ojeto de tipo Path<Net_Graph> @segn UFR @gF SUVAAD entonesD segn @UFPSAD podemos inrementr el )ujo de l

726

7. Grafos

726

redF r eso de(nimos el siguiente proedimientoX Funciones para Net_Graph 725 + 725 727a template <class Net> typename Net::Flow_Type increase_flow(Net & net, Path<Net> & path) { typename Net::Flow_Type slack = net.Infinity; // eslabn mnimo // calcular el eslabn mnimo del camino de aumento for (typename Path<Net>::Iterator it(path); it.has_current_arc(); it.next()) { typename Net::Arc * arc = it.get_current_arc(); const typename Net::Flow_Type w = arc->cap - arc->flow; if (w < slack) slack = w; } // aumentar el flujo de la red por el camino de aumento for (typename Path<Net>::Iterator it(path); it.has_current_arc(); it.next()) { typename Net::Arc * arc = it.get_current_arc(); typename Net::Arc * img = (typename Net::Arc*) arc->img_arc; arc->flow += slack; img->flow -= slack; if (not arc->is_residual) { net.increase_out_flow(net.get_src_node(arc), slack); net.increase_in_flow(net.get_tgt_node(arc), slack); } else { net.decrease_in_flow(net.get_src_node(arc), slack); net.decrease_out_flow(net.get_tgt_node(arc), slack); } } return slack; }
Uses

Path

578a.

gundo se inrement el )ujo de un ro residul se expres que hy un disminuin del )ujo del ro relY nlogmenteD el inremento sore un ro norml impli un umento de l pidd restnte del ro residulF he h que se vlido umentr el )ujo en arc y disminuirlo en img independientemente de que arc se o no residulF
7.10.11 El algoritmo de Ford-Fulkerson

rst el presente hemos desuierto onoimiento er de mo inrementr el )ujo de un redF gmo enontrr el )ujo mximoc pundmentlmente podemos plnter un lgoritmo que progresivmente usque minos de umento e inremente el )ujo hst que ste deveng mximoF gul ser l ondiin de prdc n primer respuest nos l rroj el orolrio UFI pgF UIWD pero est v puede ser omputionlmente ostosD pues requiere mnejr onjuntos omintorilmenteF n v ms e(iente l proporion l siguiente proposiinF

7.10. Redes de ujo

727

Proposicin 7.10

e f un )ujo de un red NF intones f es mximo siD y slo siD no existe un mino de umento en NF v neesidd @A se demuestr por ontrdiinF i f es mximo pero existe un mino de umentoD entonesD segn @UFPSAD es posile inrementr el )ujoD lo que ontrdie (rmr que f se mximo r mostrr l su(ieni @A supongmos que no existe un mino de umentoF v useni de minos de umento indii que el nodo sumidero es inlnzle desde el fuenteD pues el grfo residul estr inonexoD es deirD todo mino en el grfo reduido que prte desde el fuente se ort l lnzr ros on )ujo igul su piddF xo es posile por tnto umentr ms el )ujoD lo ul indi que f es mximo
Demostracin

727a

ist proposiin nos ofree el riterio de prd que estmos usndo y es l se del siguiente lgoritmo genrioX Funciones para Net_Graph 725 + 726 727b template <class Net, template <class, class> class Find_Path> typename Net::Flow_Type aumenting_path_maximum_flow(Net & net, const bool & leave_residual = false) { typename Net::Node * source = net.get_source(); typename Net::Node * sink = net.get_sink(); while (true) // mientras exista un camino de aumento { Path<Net> path(net); if (not Find_Path<Net,Res_F<Net> >()(net, source, sink, path)) break; increase_flow <Net> (net, path); } return ret_val; }
Uses

Path

578a.

727b

il prmetro leave_residual indi l lgoritmo que l red residul no dee lierrse y su uso no se mnej en este digoF isto puede ser de utilidd pr otros lgoritmosD entre ellosD el lulo del orte mnimoF r que este lgoritmo opere orretmenteD ls squeds de minos de umento slo deen onsiderr ros normles uy pidd y est lnzdD o ros residules que ontengn lgn )ujoF r eso instnimos l squed on el (ltro Res_F<Net>F n instni del lgoritmo genrio nterior pr squeds de minos en profundiE dd sore l red residul nos ondue l primer y ms lere lgoritmo desuierto pr )ujo mximoD el lgoritmo de pordEpulkersonX Funciones para Net_Graph 725 + 727a 727c template <class Net> typename Net::Flow_Type ford_fulkerson_maximum_flow(Net & net, const bool & leave_residual = false) { return aumenting_path_maximum_flow<Net, Find_Path_Depth_First> (net, leave_residual); } e efetos de prmetrizr el lgoritmo de )ujo mximoD en otrs pliiones que lo requiernD exportremos este lgoritmo jo el nomre de un lseX Funciones para Net_Graph 725 + 727b 731

727c

728

7. Grafos

template <class Net> class Ford_Fulkerson_Maximum_Flow { typename Net::Flow_Type operator () (Net & net, const bool & leave_residual = false) const { return ford_fulkerson_maximum_flow(net, leave_residual); } };

in lo que sigueD todos los lgoritmos de )ujo mximo que desrrollremos tendrn su lse invonteF il lgoritmo de pordEpulkerson se s en enontrr minos de umento por squed en profundidd e inrementr progresivmente el )ujo en el esln mnimoF vos minos se lolizn en l red residul que se onstruye omo extensin de l red originl y ls tuliziones del )ujo tmin se efetn sore l redF vs (gurs UFUR y UFUS @gsF UPVEUPWA ilustrn tods ls iteriones del lgoritmo de pordEpulkerson sore l red mostrd en l (gur UFUQF
D 4/0 E 8/0 I 4/0 K D 4 E 8 I 4 K

6/0

3/0

4/0

5/0

3/0

4/0

3/0

4/0

7/0

6/0

4/0

5/0

5/0

5/0

3/0

5/0

7/0

6/0

4/0

6/0

4/0

6/0

5/0

(a)
D D 4/0 E 8/0 I 4/0 K 4 E

(b)
8 I 4 K

6 6/0 3/0 4/0 5/0 3/0 4/0 3/0 4/0

A A 7/0 B 6/0 F 4/0 H 5/0 M

2 5 5/3 5/0 3/3 5/0 7/3 6/0 4/0 6/3 3 3 5 3

4 6 4

3 3 2

C C 4/0 G 6/0 J 5/3 L

J 3

(c)

(d)

pigur UFURX ivoluin del lgoritmo de pordEpulkerson sore red de (gur UFUQF vdo izquierdo muestr )ujo de red y reslt mino de umentoY ldo dereho red residul y on mino de umentoY ros on vlor 0 no se muestrn

7.10. Redes de ujo

729

4/0

8/0

4/0

6/0

3/0

4/0

5/0

3/0

4/0

3/0

4/0

5 A 7/2 B 6/2 F 4/0 H 5/0 M A 2 2 5/3 5/0 3/3 5/0 7/5 6/0 4/0 6/5 5 3 3 B

4 F 2 2 5 5 6 4 5 1 4 H 5 M

4/0

6/0

5/5

(a)
D 4/0 E 8/0 I 4/0 K D 4 E

(b)
8 I 4 K

6/0

3/0

4/0

5/0

3/0

4/0

3/0

4/0

4 A 7/3 B 6/3 F 4/0 H 5/0 M A 3 2 5/3 5/0 3/3 5/0 7/5 6/1 4/0 6/6 5 3 3 B

3 F 3 2 5 5 1 5 4 6 4 H 5 M

4/0

6/0

5/5

(c)
D 4/0 E 8/3 I 4/3 K D 4 E

(d)
5 I 3 3 1 1 K

6/0

3/0

4/0

5/0

3/3

4/0

3/0

4/3

3 3

1 A 7/6 B 6/6 F 4/0 H 5/0 M A 6 2 5/3 5/0 3/3 5/0 7/5 6/4 4/3 6/6 5 3 3 5 5 4 1 2 2 3 6 B 6 F 4 H 5 M

4/0

6/0

5/5

(e)
D 4/0 E 8/3 I 4/4 K D 4 E

(f)
5 I 3 2 4 4 1 1 1 3 3 1 3 4 4 K

6/0

3/1

4/0

5/1

3/3

4/1

3/0

4/4

7/6

6/6

4/0

5/0

A 6 2

2 5 3 5 5 5

1 4 6

5/3

5/0

3/3

5/0

7/5

6/5

4/4

6/6

4/0

6/0

5/5

(g)

(h)

pigur UFUSX gontinuin del lgoritmo de pordEpulkerson sore l red de l (gur UFUQ

730

7. Grafos

5 D 4/0 E 8/3 I 4/4 K D 4 E 3 2 6/0 3/3 4/0 5/3 3/3 4/1 3/0 4/4 6 3 4 3 1 A 7/6 B 6/6 F 4/2 H 5/2 M A 6 2 5/3 5/0 3/3 5/0 7/5 6/5 4/4 6/6 5 3 3 5 5 5 2 B 6 F 2 1 4 6 2 H 2 3 3 3 M 1 3 4 I 4 K

4/0

6/0

5/5

(a)
2 D 4/2 E 8/3 I 4/4 K D 2 4 6/2 3/3 4/0 5/5 3/3 4/1 3/0 4/4 3 2 1 A 7/6 B 6/6 F 4/4 H 5/4 M A 6 2 5/3 5/0 3/3 5/0 7/5 6/5 4/4 6/6 5 3 3 B 6 4 E

(b)
5 I 3 1 5 3 3 1 F 4 H 4 2 5 5 5 1 4 6 M 3 4 4 K

4/0

6/0

5/5

(c)
1 D 4/3 E 8/4 I 4/4 K D 3 3 6/3 3/3 4/0 5/5 3/3 4/0 3/0 4/4 3 3 1 A 7/6 B 6/6 F 4/4 H 5/5 M A 6 2 5/3 5/0 3/3 5/0 7/5 6/5 4/4 6/6 5 3 3 B 6 4 E

(d)
4 I 4 4 K

2 5 5 5

1 4 6

4/0

6/0

5/5

(e)

(f)

pigur UFUTX gulminin y estdo (nl del lgoritmo de pordEpulkerson on l red de l (gur UFUQ
7.10.11.1 Anlisis del algoritmo de Ford-Fulkerson

uesto que el grfo residul se onstruye sore l propi red medinte el mtodo make_residual_net() @ UFIHFIH @gF UPSAAD el onsumo de espio es O(E)D ntidd que sore el espio que pued oupr el mino de umento pathF il oste en durin de l onstruin de l red residul es O(E)D pues se requieren revisr todos los ros de l redF v durin mxim o promedi de un squed de mino de umento por exploE rin en profundidd est otd por O(E) pr el peor soD lo ul es vigente pesr de tener el dole de rosF i N fuese l ntidd de vees que repite el whileD entones l durin del lgoritmo es O(E) + N O(E) = N O(E)F or tntoD l durin depende de que tn ueno se el mino de umento enontrdo por find_path_depth_first()F gunto myor se el mnimo esln de un mino de umentoD ms se err el inremento del )ujo l vlor mximoF v ondd de un mino de umento estri enE tones en que su esln mnimo se ltoF in este sentidoD find_path_depth_first() no nos ofree ningn riterioY l rutin enuentr el mino de umento segn ls irE unstnis topolgisD ls ulesD nuestros efetosD pueden onsiderrse letorisF or tntoD sumiendo piddes enters podrn requerirse O(f ) repetiiones pr llegr l mximoF in el dominio enteroD esto suede si find_path_depth_first() siempre

7.10. Redes de ujo

731

nos enuentr minos on esln mnimo unitrioF r prehender mejor el suntoD onsideremos l red de l (gur UFUUF i l suerte deide que el primer mino de umento desuierto por find_path_depth_first() se s v w tD entones ford_fulkerson_maximum_flow() puede efetur N inrementos de )ujo siD prtir del grfo residul de l (gur UFUUED find_path_depth_first() enuentr progresivmente omo mino de umento s w v tD luego s v w tD siempre on esln mnimo de 1D y s suesivmente hst (nlmente mximizr el )ujoF
v N s N w 1 N N t s N w N/1 1/1 N/1 v N-1 N N t s N w 1 1 t 1/1 N/1 v

(a)

Red

residual

con (b) Luego del incremento (c) de ujo

Red

residual

resul-

camino de aumento

tante con otro camino de aumento

pigur UFUUX ijemplo de red uyo peor so on un squed en profundidd requiere O(N) inrementos de )ujo pr el lgoritmo de pordEpulkersonF n de ls rtis l lgoritmo de pordEpulkerson es que su terminin no estr grntizd si ls piddes se representn on irrionlesF v rti es de ndole teriD pues si los irrionles se representn en punto )otnteD entones los suesivos umentos de )ujo terminn lnzndo el vlor de pidd de un roF i se emplen friones omo piddesD entones sts pueden trnsformrse enteros segn su mE nimo omn mltiploF in emrgoD un si supeditmos ls piddes l dominio entero y un explorin en profundidd deterministD el lgoritmo de pordEpulkerson puede exhiirD en el peor soD un e(ieni de O(f E)D lo ulD omo se prei en el ejemplo de l (gur UFUUD podr ser stnte severoF
7.10.12 El algoritmo de Edmonds-Karp

731

n re(nmiento l lgoritmo nterior estri en sustituir l squed en profundidd de un mino de umento por un en mplitudF i ien l squed en mplitud tiende ser un poo ms oneros en memori que l de profundidd deido l enolmiento de minos prilesD este sutil mio segur un rendimiento onsiderlemente ms e(iente que el lgoritmo de pordEpulkersonX O(V E2 )D pr el peor soF rid uent de tod l mquinri desplegdD el lgoritmo de idmondsEurp es estruturlmente idntio l de pordEpulkersonX Funciones para Net_Graph 725 + 727c 736 template <class Net> typename Net::Flow_Type edmonds_karp_maximum_flow(Net & net, const bool & leave_residual = false) { return aumenting_path_maximum_flow<Net, Find_Path_Breadth_First> (net, leave_residual); }

732

7. Grafos

il sutilsimo mio sore un plr Edepth por redthE esD omo veremos prontE menteD fundmentl pr otr el desempeo del lgoritmoF vs (gurs UFUV y UFUW @gsF UQPEUQQA ilustrn tods ls iteriones del lgoritmo de idmondsEurp sore l red mostrd en l (gur UFUQF e pesr de l j esl y del zrD el lgoritmo lul el )ujo mximo en un iterin menos que on el lgoritmo de pordEpulkerson @ver (gurs UFUR y UFUSD pgsF UPV y UPWAF r nuestrs irunstnis hy un gnni en desempeo filmente prensileF e l postreD on este lgoritmoD l rutin increase_flow() oper ms rpido que on el de pordEpulkersonD pues l psd pr lulr el esln mnimo se he sore el mino ms ortoF
D 4/0 E 8/0 I 4/0 K D 4 E 8 I 4 K

6/0

3/0

4/0

5/0

3/0

4/0

3/0

4/0

7/0

6/0

4/0

5/0

5/0

5/0

3/0

5/0

7/0

6/0

4/0

6/0

4/0

6/0

5/0

(a)

(b)

pigur UFUVX ivoluin del lgoritmo de idmondsEurp sore l red de l (gur UFUQ

7.10. Redes de ujo

733

4/0

8/0

4/0

6/0

3/0

4/0

5/0

3/0

4/0

3/0

4/0

7/0

6/0

4/0

5/0

2 5/3 5/0 3/3 5/0 7/0 6/3 4/0 6/3 5 3 3 5 7 3

3 4

3 3

4/0

6/0

5/0

(a)
D 4/0 E 8/0 I 4/0 K D 4 E

(b)
8 I 4 K

6/0

3/0

4/0

5/0

3/0

4/0

3/0

4/0

4 A 7/3 B 6/3 F 4/0 H 5/0 M A 3 2 5/3 5/0 3/3 5/0 7/0 6/6 4/0 6/6 3 5 3 B

3 F 3 4 H 5 M

4/0

6/0

5/0

(c)
D 4/0 E 8/0 I 4/0 K D 4 E

(d)
8 I 4 K

6/0

3/0

4/0

5/0

3/0

4/0

3/0

4/0

1 A 7/6 B 6/6 F 4/3 H 5/3 M A 6 2 5/3 5/0 3/3 5/0 7/0 6/6 4/0 6/6 3 5 3 5 7 B 6 F

1 H 3

2 M 3

4/0

6/0

5/0

(e)
D 4/0 E 8/0 I 4/0 K D 4 E

(f)
8 I 4 K

2 6/0 3/1 4/0 5/1 3/0 4/0 3/0 4/0 6 1 1 A 7/6 B 6/6 F 4/4 H 5/4 M A 6 2 5/3 5/0 3/3 5/0 7/0 6/6 4/0 6/6 3 5 3 5 B 6 4 1

4 3 4 3 4

1 F 4 H 4 M

4/0

6/0

5/0

(g)

(h)

pigur UFUWX gontinuin del lgoritmo de idmondsEurp sore l red de l (gur UFUQF

734

7. Grafos

6 D 4/0 E 8/2 I 4/2 K D 4 E 2 4 6/0 3/3 4/0 5/1 3/0 4/0 3/0 4/2 6 3 4 1 1 A 7/6 B 6/6 F 4/4 H 5/4 M A 6 2 5/3 5/0 3/3 5/0 7/0 6/6 4/0 6/6 5 3 3 5 7 6 B 6 F 4 H 3 4 I

2 K 2 2 3 2 1 M 4

4/0

6/0

5/0

(a)
2 D 4/2 E 8/4 I 4/4 K D 2 4 6/2 3/3 4/0 5/1 3/0 4/0 3/0 4/4 3 2 1 A 7/6 B 6/6 F 4/4 H 5/4 M A 6 2 5/3 5/0 3/3 5/0 7/0 6/6 4/0 6/6 5 3 3 B 6 4 1 E

(b)
4 I 4 4 3 4 3 4 4 K

1 F 4 H 4 M

4/0

6/0

5/0

(c)
1 D D 4/3 E 8/4 I 4/4 K 3 3 6/3 3/3 4/0 5/2 3/0 4/0 3/0 4/4 3 1 A A 7/6 B 6/6 F 4/4 H 5/5 M 2 5 5/3 5/0 3/3 5/0 7/1 6/6 4/1 6/6 3 3 6 B 6 4 2 3 E

(d)
4 I 4 3 3 4 3 4 4 K

6 5 1 4 6 3

1 6

C C 4/0 G 6/0 J 5/1 L

J 1

(e)
1 D 4/3 E 8/4 I 4/4 K D 3 3 6/3 3/3 4/0 5/5 3/3 4/0 3/0 4/4 3 3 1 A 7/6 B 6/6 F 4/4 H 5/5 M A 6 2 5/3 5/0 3/3 5/0 7/5 6/5 4/4 6/6 5 3 3 B 6 4 E

(f)
4 I 4 4 K

2 5 5 5

1 4 6

4/0

6/0

5/5

(g)

(h)

pigur UFVHX istdo (nl del lgoritmo de idmondsEurp on l red de l (gur UFUQF
7.10.12.1 Anlisis del algoritmo de Edmonds-Karp

n squed en mplitud requiere O(E) pr el peor so @ver UFSFR @gF SWIAAF he nuevoD el desempeo del lgoritmo estr otdo por N O(E)D donde N ser l mxim ntidd de inrementos de )ujoF gomo l squed es en mplitudD los minos de umento se desuren desde los ms ortosD en ntidd de rosD hst los ms lrgosF he(nmos d(u, v) omo l distni en ros de un mino entre dos nodos u y vF e Cai un mino de umento luldo por find_path_breadth_first() durnte l iEsim iterin del lgoritmo de idmondsEurpF intonesD luego del iEsimo inremento del )ujoD di+1 (s, t) di (s, t)F
Lema 7.6

7.10. Redes de ujo

735

Demostracin

upongmos que Ci = s v el mino ms orto en ros desde s hst vF ehor supongmos l existeni de un mino de umento Cai D luldo por find_path_breadth_first()D que onteng un mino ms ortoY es deirD que di+1 (Cai ) < d(Ci )F heemos onsiderr dos situiones generlesX IF v / Cai = Ci sigue siendo mnimo en rosF PF w Ci |w Cai = podemos onsiderr dos posiiliddesX

w v ser un ontrdiin on el heho de que Ci es el mnimo @A i Cai = s mino en ros desde s hi vF ist ni posiilidd es un ontrdiinF il lem es pues ierto
Denicin 7.17 (Arco crtico de un camino de aumento)

v w @A i Cai = s di+1 (s, t) di (s, t)F eroD

tD entones Ci sigue siendo mnimo y se stisfr

e Ca = s v1 ...u v vm t un mino de umento ulquier sore un red residulF e die que un ro (u, v) Ca es rtio si su pidd en el grfo residul es igul l mnimo esln de Ca y (u, v) EF

v propiedd fundmentl de un ro rtio es que ste se elimin de l red residul l inrementrse el )ujo si se trt de un ro de delntoD o l derementrse 0 si es uno de retroesoF e prtir de este heho podemos estleer que si el mino de umento Cai ontiene un ro rtio (u, v)D entonesD pr un iterin futurD un mino de umento Cai+k que involure los nodos u y v es seguro que d(Cai+k ) d(Cai ) + 2F r prehender el heho nteriorD oservemos l (gur UFVIF v lne ontinu ilustr
s u Arco crtico v

C ai
t

Cai+k

pigur UFVIX ergumento pitrio del umento de ros por un mino que involure un pr (u, v) un hipottio mino de umento on un ro rtio u, v l iEsim iterin del lgoE ritmo de idmondsEurpD mientrs que l lne punted un mino de umento en un iterin futur i + kF el inrementrse el )ujo el ro rtio despreeF gonseuenE tementeD ulquier mino de umento futuro que involure u y v tiene que ontener undo menos un nodo intermedio w y dos ros de msY esto es seguro porque los minos de umento se usn en mplitudD lo ulD omo y lrmosD retorn minos desde los ms ortos hi los ms lrgosF v mxim longitud posile de un mino de umento es de V nodosF gonseuenteE menteD un ro puede ser rtio en lo sumo V/2 minos de umentoF or tntoD l mxim ntidd posile de minos de umento es E V 2F 2 he lo nterior onluimos que el lgoritmo de idmondsEurp es E V 2 O (E) = O (VE )F i l red es espridD lo que no es infreuenteD entones E c V y el lgoritmo de idmondsEurp ser O(V 3 )

736

7. Grafos

7.10.13

Algoritmos de empuje y preujo

n )ujo es dinmio en el sentido de que el )uido siempre est orriendo por ls tuersY si noD entones no podrmos hlr de )ujoF smginemos un red de tuersD de guD por ejemploF upongmos que desemos mximizr l ntidd de gu que lleg l sumideroF n enfoque que sugiere l intuiin es inundr l mxim pidd posile ls tuers del nodo fuenteF r eso inyetmos un )ujo uy presin sorepse l pidd de los ros slientes del fuenteF vuegoD desde los nodos dyentes l fuenteD se vn inundndo los ros del segundo nivelF il proeso ontinu progresivmente hst otener )ujo en el nodo sumideroF hee sernos lro que el mximo vlor de )ujo tiene que ser menor o igul este )ujo iniilF i tods ls llves estn iertsD entones el )ujo otenido trvs de este proedimiento es mximoF r que este proeso se relist y el nodo fuente rei extmente el )ujo mximoD los nodos destino de ls tuers que emnn del sumidero tendrn que disponer de un espeie de lividero de modo que el )ujo sliente del fuente pued mntenerse onstnte mientrs se vn justndo ls llves del resto de ls tuersF iste ptrn intuitivo es el fundmento de un serie de lgoritmos llmdos de empuje de preujo F
Denicin 7.18 (Preujo)

e un red N =< V, E, s, t, C >F n preujo es un onjunto E E de ros on vlor de )ujo positivo tl que e = (u, v) E X IF f(e) cap(e)D y

PF u = s, v = s = OUT(u) IN(u), OUT(v) IN(v)F in otrs plrsD el )ujo de slid dee ser menor o igul que el de entrdF smportnte oservr que jo est de(niin no se umple EtemporlmenteE l ondiin de onservin del )ujoY de h pues l neesidd strt y fsimente onret de que d nodo pose el livideroF or l mism rznD est fmili de lgoritmos se le llm de pre)ujoD pues durnte l ejeuin del proedimiento intuitivo no hy )ujo sore lgunos nodosD inluido el sumideroF n nodo distinto l fuente o l sumidero es llmdo internoF n nodo interno uyo )ujo de entrd es myor que el de slid es denomindo activo F in funin del eh Net_GraphD l determinin de un nodo tivo es simpleX Funciones para Net_Graph 725 + 731 737 template <class Net> static bool is_node_active(typename Net::Node * p) { return p->in_flow > p->out_flow; } r un nodo tivo uD el vlor IN(u) OUT(u) es llmdo exeso y denotdo omo excess(u)F iguiendo on el proedimiento intuitivoD l ide fundmentl de un lgoritmo de pre)ujo es omenzr empujr desde el fuente l myor ntidd posile de )ujo hst que no se pued empujr ms sore el sumideroF in este momento el )ujo dee ser mximoD pero muy prolemente hr nodos tivos uyo equilirio hy que resturrF

736

7.10. Redes de ujo

737

gmo elegir nodos y ros por donde empujr pre)ujoc el iniio del lgoritmoD l respuest es diretX el fuente y todos sus rosF vuego los nodos tivos son elegiles peroD por ules entre sus ros empujr el pre)ujoc ist pregunt vizor el sunto ms omplejo de est lse de lgoritmoD pues el lulo del )ujo mximo y l terminin depende de un esogeni deud del prximo nodo proesr y por ules entre sus ros de slid empujr pre)ujoF
7.10.13.1 Altura de un nodo

r l fmili de lgoritmos que prontmente de(niremosD l esogeni del prximo nodo suye sore l ide de lturF
Denicin 7.19 (Funcin de altura de un nodo)

e un red N =< V, E, s, t, C > on red residul N =< V, E , s, t, C >F n funin de ltur h : V N es un funin entre los nodos de l red tl queX IF h(t) = 0F PF e = (u, v) E = h(u) h(v) + 1F eordemos que un funin puede interpretrse omo un onjunto de pres ordendosF in nuestro so prtiulr del tipo Ah = {(u1 , h(u1 )), (u2 , h(u2 )), . . . (un , h(un ))}F n ro e = (u, v) se li( de elegible si h(u) = h(v) + 1F r mntener el vlor de l funin de ltur de un nodo usremos su ontdor @vse UFQFSFP @gF SSVAAX Funciones para Net_Graph 725 + 736 742 template <class Net> static long & node_height(typename Net::Node * p) { return NODE_COUNTER(p); } v perteneni o no de un nodo l onjunto Ah determin l funinF v ide de l funin de ltur es mntener un relin de proximidd entre el pre)ujo y los nodos fuente y sumideroF gundo l ltur de un nodo tivo es menor que l del fuenteD entones es prole empujr pre)ujo hi el sumideroF imtrimenteD si l ltur es myorD entones prolemente hy que devolver pre)ujo hi el fuenteF
7.10.13.2 Algoritmo genrico de preujo

737

in virtud de su rter intuitivoD los lgoritmos sdos en empuje de pre)ujo son ms simples que los sdos en squeds de minos de umentoF in didurD prtiE mente si todo lgoritmo de pre)ujo suye sore el siguiente lgoritmo genrioF v entrd es un red N =< V, E, s, t, C >F v slid es l mism red on vlores de )ujo justdo l mximo vlor de )ujoF edems de l red residul N =< V, E , s, t, C >D el lgoritmo us un estruE tur de dtos intern denomind Ah D uyo (n es implntr l funin de lturF gd nodo u soi su vlor h(u) tl omo se expli en l susein nteriorF
Algoritmo 7.6 (Algoritmo genrico de empuje de preujo)

IF glulr l red residul N

738

7. Grafos

PF esignr d nodo u su vlor h(u) orde l de(niin UFIW @gF UQUA QF Ah = @el onjunto de nodos tivosA RF e = (s, u) s re)ujo iniil de ros del nodo fuente @A f(e) = cap(e) [Saturacin] @A i u = t = Ah = Ah {u} [aadir u al conjunto de nodos activos] SF wientrs Ah = [Equilibrar nodos activos] @A e u, e E [Empuje de preujo de u]X @A eleione un nodo tivo u Ah , Ah = Ah {u} iF i e = (u, v) es un arco elegible D es deirD si h(u) = h(v)+ 1 = impujr pre)ujo por ro tul 745b eF fp = min(excess(u), cap(e) f(e)) [Flujo a empujar sobre el arco] fF f(e) = fp gF excess(u) = excess(u) fp @A i excess(u) > 0 = h(u) = h(u) + 1, Ah = Ah {u} @u es n un nodo tivo on un inremento en l funin de lturA il lgoritmo empuj todo el posile pre)ujo por los ros del fuenteF ultinmenteD segn el orden en que se presenten los nodos tivosD el exeso se v propgndo hst lnzr el sumideroF gundo ste deviene sturdoD el exeso retorn hi el fuente drenndoseD si es posileD en quellos nodos que tengn piddF pinlmenteD undo el exeso lnz el fuenteD este se le rest sus ros hst que el )ujo deveng estleF in este estdioD el )ujo es mximo y y no existen nodos tivosF in l instruin S@Ai se determin si se empuj o no pre)ujo por d ro sliente del nodo tulmente seleiondoF i no se logr empujr todo el exesoD entones el nodo es inluido de nuevo en Ah D pero on un vlor h(u) inrementdo en un uniddY esto es lo que permite que eventulmente otr iterin sore el mismo nodo ve omo elegile un ro que en un iterin psd no lo fueD y en lugr de vnzr el pre)ujo hi el sumideroD se retroed hi el fuenteD pudiendo ourrir inlusive que se disminuyn los )ujos emnntes del fuenteF n mner de proximrse l ondd del lgoritmo onsiste en exminr lo que es un ml so pr un lgoritmo ulquier sdo en l squed de un mino de umentoF r eso onsideremos un red generl on l form de l (gur UFVPF in est lse de redD el nodo x tiene siete ifuriones que resultn on destino yF in este so se requiere enontrr siete minos de umento pr poder llenr los nodos x e yY mientrs que un lgoritmo sdo en empuje de pre)ujo prolemente los llenr pens se empuje el exeso de xF
7.10.13.3 Correctitud del algoritmo genrico
745a

hF i u = s y u = t = Ah = Ah {v}

entes de instrumentr el lgoritmo genrio y lgunos prtiulres deemos pror su orretitudD es deirD que lul el )ujo mximoF in lo que sigue plnteremos un serie

7.10. Redes de ujo

739

pigur UFVPX isquem generl de n ml so de mximizin de )ujo pr un lgoritmo sdo en minos de umento de proposiiones destinds pror l proposiin de orretitudF fsremos nuestro disurso en el mgistrl plntemiento de edgewik ISTD el ul su vez se s en el de qolderg y rjn TPF il primer pso hi l prue de orretitud es demostrr que l funin de ltur es vlidF
Proposicin 7.11 Validez de la funcin de altura Sedgewick 2002 [156] e un red N =< V, E, s, t, C > on red residul N =< V, E , s, t, C >F e h : V N un funin de lturF intones el lgoritmo genrio de empuje de pre)ujo UFT onserv l vlidez de l funin de ltur segn l de(niin UFIW @gF UQUAF

r (rmr que h es vlid hy que demostrr que lo lrgo de l ejeuin del lgoritmo h(u) h(v) + 1 pr todo ro de l red residulF il pso P sign vlores orretos segn l de(niinF edemsD Ah es iniilmente voD por lo que l demostrin se remite ompror que los nodos que se introduzn Ah stisfgn l de(niinF smginemos un nodo tivo uF i no existe ningn ro elegileD entones h(u) = h(u) + 1 y u regres l onjunto de los nodos tivos on h(u) inrementdo en uno por l instruin SF entes de est instruin h un onjunto vlido Ah = {(v1 , h(v1 )), (v2 , h(v2 )), . . . (u, h(u)), . . . , (vn , h(vn ))}Y luegoD el onjunto tiene form Ah = {(v1 , h(v1 )), (v2 , h(v2 )), . . . (u, h(u) + 1), . . . , (vn , h(vn ))}D el ul sigue siendo vlido segn l de(niinF i u tiene uno o ms ros elegilesD entones lgunos se sturrn plen piddD despreern de l red residul y preern otros inversosF gonsideremos el ltimo de los ros elegiles u vD el ul determinr que u permnez o no dentro del onjunto de nodos tivosF heemos ontemplr dos posiiliddesX
Demostracin

IF ue u v se sture plen piddX en este soD u v tmin despree de l red residulD se re un ro inverso v u y u dej de ser un nodo tivoD por lo que l funin h es orretF PF ue u v no se sture plen piddX en este soD u v se mntiene en l red residulD pree un nuevo ro v u pero h(u) se inrementF v situin (nl se puede imginr omo en l (gur UFVQF gd ro w u stisfe h(w) h(u) + 1D

740

7. Grafos

. . .
u

Nuevos nodos aA h

pigur UFVQX isquem de demostrin de l proposiin UFII pr el so en que u v no se sture pues u fue inrementdoF r los ros u v y v u tenemos que h(u) = h(v)D lo que stisfe l vlidez de l funin de ltur v otin del vlor de h(u) nos ot l ntidd de ros que ontiene el mino mnimo u tD tl omo estlee l proposiin siguienteF e un red N =< V, E, s, t, C > on red residul N =< V, E , s, t, C >F e h : V N un funin de lturF intonesD v V h(v) es menor o igul que l longitud del mino ms orto en ros desde v hi t en l red residulF
Proposicin 7.12 (Sedgewick 2002 [156])

e d l longitud del mino ms orto en ros desde un nodo v hi tF e Cv,t = v = v1 v2 vd = t el mino ms orto en l red residulF intonesD segn l de(niin UFIW @gF UQUAX
Demostracin

h(v) = h(v1 ) h(v2 ) + 1 h(v3 ) + 1 F F F h(vd ) + d = h(t) + d = d


il lgoritmo siempre mntiene onetdo l exesoD es deirD no hy nodos tivos que estn inonexos en l red residulF sniilmenteD el exeso de )ujo emn del fuente y se dirige hi el sumideroD el ul tiene h(t) = 0 y nun se de Ah F vos exesos son propgdos hi el sumidero en l instruin S@AihF i no se lnz el sumidero o n quedn nodos tivosD entones el exeso es empujdo hi el fuente pr deremenE trloF iste hehoD hst el presente intuitivoD puede on(rmrse ojetivmente medinte l siguiente proposiinF e un red N =< V, E, s, t, C > on red residul N =< V, E , s, t, C >F e Ah : V N un funin de lturF intonesD durnte l ejeuin del lzo del lgoritmo UFT @gF UQUAD pr d nodo tivoX
Proposicin 7.13 (Sedgewick 2002 [156])

IF ixiste un mino en l red residul desde el nodo tivo hst el fuenteF PF xo existe mino desde el fuente hi el sumideroF

7.10. Redes de ujo

741

Demostracin (por induccin sobre los nodos activos)

entes de entrr l lzoD el pso R introdue en Ah todos los nodos {u1 , u2 , . . . , un } dyentes sF istos ros son sE turdos su plen piddD lo ul impli l priin de ros (u1 , s), (u2 , s), . . . (un , s) en l red residul y l despriin de los inversos (s, u1 ), (s, u2 ), . . . (s, un )F vos nodos tivos u1 , u2 , . . . , un tienen minos hst el sumidero y el fuente yD por l despriin de los inversosD s qued desonetdoF or tntoD l entrr l lzo l proposiin es iert pr los nodos tivos iniiles dyentes l fuenteF ehor summos que l proposiin es iert pr todo nodo dentro del onjunto Ah de nodos tivosF v ni mner de que se d un nuevo nodo v Ah D es deirD de que prez un nuevo nodo tivoD es que desde un tul tivo u exist un ro elegile u v @instruin S@AiAF ry dos sos onsiderrX IF v nun h sido tivoX en este so h(u) = h(v) + 1F entes de empujr por u vD no hy mino v sD pues los ros slientes de v no ontienen )ujoF gundo se empuj el exeso por el ro u v pree un ro residul sliente v uF or l hiptesis indutiv existe un mino u sD por tntoD el ro residul v u grntiz que tmin exist un mino desde v sF hel mismo modoD por l hiptesis indutiv no hy mino s ro v u no lter est (rminF

t y l didur del

PF v y fue tivo en un ilo nteriorX este so ourre undo v se s de Ah y no hy ningn ro elegileF e inrement el vlor de h(v) y v regres Ah sin lterr l topolog de l red residul v proposiin es otejle pr dos sos prtiulres de ejeuin mostrdos en l fmili de (gurs UFVS @pgF URWAD UFVU @pgF USQA y UFVW @pgF USVAF ehor tenemos tods ls herrmients neesris pr veri(r l orretitud del lgoE ritmo UFT @gF UQUAF
Proposicin 7.14 (Sedgewick 2002 [156])

il lgoritmo UFT @gF UQUA lul el )ujo

mximo de un redF il primer sunto ompror es que el lgoritmo ulminD o seD veriE (r que un vez que se entr l lzo @instruin SA ste terminF v terminin ourre undo Ah deviene voF xeesitmos entones mirr l mner en que Ah ree y deree y segurrnos de que el lzo progreseY es deirD de que no ig en un ilo in(nitoF Ah ree por dos rzonesF v primer es por empuje de pre)ujo por un ro u v @instruin S@AihAD en uyo so v deviene tivoF v segund es porque no se puede empujr todo el )ujo de un nodo tivo @instruin SAY en este soD u regres Ah on un vlor de h(u) inrementdoF Ah slo deree en l instruin SF or tntoD l terminin del lgoritmo depende de que l ntidd de didurs Ah est otdF in este sentido nos ser muy til el siguiente lemF
Demostracin Lema 7.7

2V F

hurnte l ejeuin del lgoritmo genrio UFT @gF UQUAD u V = h(u) <

742

7. Grafos

Demostracin

emosD segn l proposiin UFIP @gF URHAD que h(u) es menor o igul que l longitud del mino ms orto desde u hi tF gomo trtmos on un red residulD podemos tener hst el dole de ros y puede her minos que psen por el fuenteF or tntoD el mino ms lrgo desde un nodo u hi t no puede exeder de 2V rosD pues sino ontrdir l proposiin UFIP @gF URHA gon el onoimiento de este lem podemos (rmr que l ntidd de vees que l instruin S de nodos Ah est otdF hel mismo modoD pr que l instruin S@Aih d el nodo tivo vD el ro u v tiene que ser elegileD es deirD h(u) = h(v)+1F sndependientemente de ls ominiones que se suednD el vlor de h(u) est otdoD por lo que l mxim ntidd de vees que se d un nodo tivo v por dyeni desde un nodo u tmin lo estF uesto que el lzo extre nodos tivos de Ah y l ntidd de didurs Ah est otdD onluimos que Ah deviene voD por lo que el lzo termin y on l el lgoritmoF n vez que Ah deviene vo l red ontiene un )ujo ftileF in este estdo semosD por l proposiin UFIQ @gF URHAD que no existe ningn mino desde el fuente hi el sumideroD por lo que no existe ningn mino de umentoF gonseuentementeD segn l proposiin UFIH @gF UPTAD el )ujo es mximo il nlisis de desempeo del lgoritmo depende de l mner en que implnte el onjunto de nodos tivos Ah F ero ntes de ordr est implntin deemos esoger un form de signr los vlores iniiles de ltur de d nodoF
7.10.13.4 Valores iniciales de la funcin de altura

ry vris mners de signr vlores iniiles h(u) que stisfgn l de(niin y ejeE uin del lgoritmo UFT @gF UQUAF ero l iniilizin puede ser esenil pr el desempeoF r indiir esto onsideremos l siguiente iniilizinX

h(u) =

V 0

u=s u=s

742

eunque est on(gurin es vlidD st tiende usr extriones vnsD es deirD extriones de nodos sin ros elegilesD pues es slo luego de V iteriones que uno de los nodos dyentes l fuente lnz el vlor V + 1 y deviene elegileF gul es l mejor on(gurincD es un pregunt que d pie diverss investigiones que onsiderenD entre otrs ossD l topolog del grfoD el tipo de red que modelizD sus puntos de orteD etterD que no ordremos en este textoF ehor ienD el lgoritmo de idmondsEurp nos proporion l mner genri ms ort de ir desde el fuente hi el sumideroX el reorrido en mplitudF in lo que sigue onsidermos omo vlor iniil de h(u) l longitud ms ort desde u hst el sumideroD l ul puede lulrse en O(E) medinte un reorrido en mplitud iniE ido desde el sumidero y diretmente ftile por l rutin breadth_first_traversal() estudid en UFSFR @gF SVWAF e efetos de l simpliidd y de l e(ieniD breadth_first_traversal() slo dee onsiderr ros residulesF r eso de(nimos el siguiente riterio de mird de roX Funciones para Net_Graph 725 + 737 743a template <class N> class Res_Arc {

7.10. Redes de ujo

743

};

bool operator () (typename N::Node *, typename N::Arc * a) const { return a->is_residual; }

743a

gon este simple (ltroD l invoin breadth_first_traversal() sore el grfo residul e iniid desde el sumidero oper omo si se trtse de l red invers @sin neesidd de onstruirlAF i signmos h(t) = 0D entones l siguiente funin de visit sore d nodo sign l longitud del mino ms orto hi el sumideroX Funciones para Net_Graph 725 + 742 743b template <class Net> static bool initial_height(Net & net, typename Net::Node * p, typename Net::Arc * a) { node_height<Net>(p) = node_height<Net>(net.get_src_node(a)) + 1; return false; } i visitmos en mplitud l nodo p proviniendo desde el ro aD entones node_height<Net>(net.get_src_node(a)) + 1 @que se orresponde on h(p) + 1A indi que hy un ro de ms desde el sumideroF il pso P del lgoritmo genrio UFT @gF UQUA se implnt del siguiente modoX Funciones para Net_Graph 725 + 743a 743c
template <class Net> static void init_height_in_nodes(Net & net) { breadth_first_traversal <Net, Res_Arc<Net> > (net, net.get_sink(), &initial_height); }

743b

he este modoD l llmd init_height_in_nodes() signr d nodo su distni hst el sumideroF


7.10.13.5 Manejo del conjunto

Ah

743c

il mnejo del onjunto Ah enj perfetmente on los riterios del prolem fundE mentl @ IFQ @gF IUAAF es que en primer instni pudirmos empler ulquier estrutur de dtos entre ls diverss estudidsF in emrgoD el onoimiento sore el riterio de elegiilidd de ro nos ofree mners de empler un estrutur de dtos queD undo extrig un nodo de Ah nos ofrez un grn proilidd de que ste onteng ros elegilesF in este sentidoD ls implntiones preferids son ls orientds hi el )ujoD en prtiulrD ols pspy y de prioriddF e efetos de otener un implntin genri emplemos ls siguientes rutins pr insertr y eliminr del onjunto Ah X Funciones para Net_Graph 725 + 743b 744 template <class Q_Type> static void put_in_active_queue(Q_Type & q, typename Q_Type::Item_Type & p) { if (p->control_bits.get_bit(Aleph::Maximum_Flow)) return; p->control_bits.set_bit(Aleph::Maximum_Flow, true); q.put(p);

744

7. Grafos

template <class Q_Type> static typename Q_Type::Item_Type get_from_active_queue(Q_Type & q) { typename Q_Type::Item_Type p = q.get(); p->control_bits.set_bit(Aleph::Maximum_Flow, false); return p; }

put_in_active_queue() insert el elemento p en un ol q de tipo genrio Q_TypeD mientrs que get_from_active_queue extre un elementos de l ol qF r detetr e(ientemente y evitr inseriones duplidsD mrmos el it de ontrol Maximum_Flow undo un nodo est dentro de Q_TypeF gundo luego de empujr el pre)ujo de un nodo uD ste n permnee tivoD l regres Ah on un vlor inrementdo de h(u)F n uestin de inters es un prole es que on el vlor inrementdo de h(u) u onteng ros elegilesc
7.10.13.6 Implantacin del algoritmo genrico

744

el igul que on los lgoritmos sdos en squed de minos de umentoD los de pre)ujo tmin englorse en uno genrio27 X Funciones para Net_Graph 725 + 743c 748 template <class Net, class Q_Type> typename Net::Flow_Type generic_preflow_vertex_push_maximum_flow (Net & net, const bool & leave_residual = false) { init_height_in_nodes(net); typename Net::Node * source = net.get_source(); typename Net::Node * sink = net.get_sink();
Q_Type q;

Preujo inicial de arcos del nodo fuente 745a

// instancia el conjunto de nodos activos

while (not q.is_empty()) // mientras haya nodos activos { typename Net::Node * src = get_from_active_queue(q); typename Net::Flow_Type excess = src->in_flow - src->out_flow; for (Node_Arc_Iterator<Net, Res_F<Net> > it(src); it.has_current() and excess > 0; it.next()) { typename Net::Arc * arc = it.get_current_arc(); typename Net::Node * tgt = net.get_tgt_node(arc); if (node_height<Net>(src) != node_height<Net>(tgt) + 1) continue; // el nodo no es elegible } if (excess > 0) // src an sigue activo?
27
Se omite, por simplicidad, la creacin de los supra fuente y sumidero.

Empujar preujo por arco actual 745b

7.10. Redes de ujo

745

} const typename Net::Flow_Type ret_val = source->out_flow; } return ret_val;

{ // s ==> incremente h(src) y re-inserte en q node_height<Net>(src)++; put_in_active_queue(q, src); }

745a

v estrutur es si idnti Ey desde lguns perspetivs ms omprensileE l expreE sd en jerg mtemti en UFT @gF UQUAF v instruin I se orresponde on l invoin l mtodo net.make_residual_net()D mientrs que l P se orresponde on l llmd l rutin init_height_in_nodes(net)F il empuje de pre)ujo iniil por los ros emnntes del fuente @instruin RA se efet sX Preujo inicial de arcos del nodo fuente 745a (744) for (Node_Arc_Iterator<Net, Res_F<Net> > it(source); it.has_current(); it.next()) { typename Net::Arc * arc = it.get_current_arc(); typename Net::Node * tgt = net.get_tgt_node(arc); arc->flow = tgt->in_flow = arc->cap - arc->flow; // inunde arco arc->img_arc->flow = 0; if (tgt != sink) put_in_active_queue(q, tgt); // tgt deviene activo } source->out_flow = source->out_cap; yservndo l ondiin de onservin del )ujo es tentdor pr los progrmdores noveles empujr l pidd mnim entre el totl de slid del fuente y el totl de entrd del sumideroF he ese modo podrn disminuirse ls iterionesF ero esto no neesrimente funion porque podr ourrir que lgunos de los nodos dyentes l fuente no deviniese tivoD lo ul posiilitr que el lgoritmo jms lo vieseF il primer empuje dee ser su mxim piddF il empuje de pre)ujo por el ro es filmente omprensile si se entiende el mnejo de l red residul28 X Empujar preujo por arco actual 745b (744) const typename Net::Flow_Type flow_avail_in_arc = arc->cap - arc->flow; typename Net::Flow_Type flow_to_push = std::min(flow_avail_in_arc, excess); arc->flow += flow_to_push; arc->img_arc->flow -= flow_to_push; if (arc->is_residual) { net.decrease_out_flow(tgt, flow_to_push); net.decrease_in_flow(src, flow_to_push); } else {
28
Vase tambin el mtodo

745b

increase_flow()

en 7.10.10 (Pg. 725).

746

7. Grafos

} excess -= flow_to_push;

net.increase_out_flow(src, flow_to_push); net.increase_in_flow(tgt, flow_to_push);

if (is_node_active<Net>(tgt) and tgt != sink and tgt != source) put_in_active_queue(q, tgt);


7.10.13.7 Anlisis del algoritmo de preujo

il nlisis se entr en lsi(r y ot l ntidd de operiones que ourren denE tro del while (not q.is_empty()) Einstruin S en lgoritmo genrioEF el respetoD lsi(quemos ls operiones enX IF impuje sturnteX l ejeuin del loque impujr pre)ujo por ro tul 745b Einstruin S@Ai en el lgoritmo genrioE que logr llenr el ro su plen piddF n empuje sturnte impli l didur de un nodo l onjunto Ah y l despriin del ro en l red residulF PF impuje no sturnteX un ejeuin del loque impujr pre)ujo por ro E tul 745b que no logr llenr el ro su plen piddF QF snremento o reetiquetdoX ejeuin del if (excess > 0) Einstruin S en el lgoE ritmo genrioEF v ntidd de inrementos es lo ms fil de ontilizrD segn muestr el lem siguienteF e un red N =< V, E, s, t, C > on red resiE dul N =< V, E , s, t, C >F intones l ntidd de inrementos que ourre en el lgoritmo UFT @gF UQUA es lo sumo 2V 2 F
Lema 7.8 (Cantidad de incrementos)

vos inrementos ourren sore V 2 nodos de l redD pues el fuente y el sumidero nun son tivosF gd nodo se inrement en uno hst un mximo de 2V 1D segn el lem UFU @gF URIAF or tntoD l ntidd de inrementos es (V 1) (2V 1) < 2V 2
Demostracin

ehor ontilizmos l ntidd de empujes sturntesF e un red N =< V, E, s, t, C > on red residul N =< V, E , s, t, C >F intones l ntidd de empujes sturntes es menor que 2VEF
Lema 7.9 (Cantidad de empujes saturantes) Demostracin

upongmos dos nodos ulesquier u y v los ules desemos onE tilizr l ntidd de empujes sturntesF r que ourr tl empujeD dee existir en l red residul o un ro u v o uno v uF upongmos que ourre un empuje sturnte en el ro u vF isto impli que h(u) = h(v) + 1F isenil notr que pr que ourr otro empuje sturnte en u v primero dee ourrir un empuje en v uD pues pr que u v deveng elegile dee umplirse de nuevo que h(u) = h(v) + 1F h(v) dee inrementrse en l menos 2 uniddesF

7.10. Redes de ujo

747

emosD por el lem UFU @gF URIAD que x V = h(x) < 2V F or tntoD l ntidd de vees que un nodo puede inrementrse es menor que 2V F ryD puesD lo sumo 2V empujes sturntes en u vF wultiplindo por l ntidd de ros tenemos un totl mximo de 2VE empujes sturntes xos flt ontilizr l ntidd de empujes no sturntesD l ul se estlee por el siguiente lemF e un red N =< V, E, s, t, C > on red residul N =< V, E , s, t, C >F intones l ntidd de empujes sturntes es menor que 4V 2 (V + E)F
Lema 7.10 Demostracin

he(nmos l siguiente funin potenil sore el onjunto Ah X

(Ah ) =
u Ah

h(u)

@UFPVA

ry dos mners en que puede inrementrse el vlor de (Ah )X IF n empuje sturnteX en est operin se de un nuevo nodo Ah D pero no se ument ningn vlor de h(u) pr ulquier nodo uF or el lem UFU @gF URIA semos que h(u) < 2V pr ulquier uF n empuje sturnte ument (Ah ) en lo sumo 2V F uesto que l ntidd de empujes sturntes est otd por 2VE @lem UFW @gF URTAAD el inremento de los empujes sturntes sore (Ah ) est otdo por 2V 2VE = 4V 2 EF PF n inremento de lturX d inremento de un nodo u ument (Ah ) en unoF v inideni de un nodo ulquier u sore (Ah ) esD por el lem UFU @gF URIAD menor que 2V F or el lem UFV @gF URTA semos que l ntidd mxim de inrementos es menor que 2V 2 F or tntoD l inideni de los inrementos sore (Ah ) es menor que 2V 2 2V = 4V 2 V F u er de los empujes noEsturntesc upongmos que ourre un empuje no sturnte sore un ro u vF in este momentoD u deviene intivo y v prolemente tivoF es puesD (Ah ) = (Ah ) h(u)+ h(v)D peroD puesto que h(u) = h(v)+ 1D entones (Ah ) = (Ah ) h(v) 1 + h(v) = (Ah ) 1F y seD (Ah ) deree l menos en un uniddF riendo onluido que los empujes no sturntes no inrementn el vlor de (Ah )D otr l funin potenil estr ddo porX

(Ah ) <

4V 2 E
Incrementos

4V 2 V
Empujes saturantes

= 4V 2 (V + E)

ehor tenemos tods ls herrmients neesris pr onluir er del desempeo de lgoritmo genrioF
Proposicin 7.15

e un red N =< V, E, s, t, C > on red residul N =< V, E , s, t, C >F e Ah : V N un funin de lturF intones l ntidd de operiones que ejeut el lgoritmo genrio UFT @gF UQUA es O(V 2 E)F

748

7. Grafos

Demostracin

snmedit de los lems UFV @gF URTAD UFW @gF URTA y UFIH @gF URUA

7.10.13.8

Empuje de preujo FIFO

748

il orden en que se empuje el pre)ujo trvs de los nodos puede inidir notlemente en el rendimiento de un lgoritmo de pre)ujoF i trtmos de que el pre)ujo lne lo ms rpidmente posile el sumideroD entones un enfoque que extrig de l ol los nodos en profundidd prolemente tieneD heurstimente hlndoD ms posiiliddes de rrir ms rpido l sumideroF in este sentidoD un mner de emulr el proesmiento en profundidd onsiste en enolr pspy los nodos tivosF iste enfoque es diretmente instrumentle prtir del lgoritmo genrioX Funciones para Net_Graph 725 + 744 752a template <class Net> typename Net::Flow_Type fifo_preflow_maximum_flow (Net & net, const bool & leave_residual = false) { return generic_preflow_vertex_push_maximum_flow <Net,DynListQueue<typename Net::Node*> >(net, leave_residual); } e trt del lgoritmo genrio on prmetro tipo Q_Type instnido un ol de tipo DynListQueue<T> estudido en PFTFT @gF IQHAF
4 D 6 0 4/0 3 E 3 0 8/0 2 I 0 0 4/0 1 K 0 0

6/6

3/3

4/0

5/0

3/0

4/0

3/0

4/0

0 21

7/7 3

7 0

6/0 2

0 0

4/0 1

0 0

5/0 0

0 0

5/5

5/0

3/0

5/0

7/0

6/0

4/0

6/0

5 0 4/0 4

0 0 6/0 2

0 0

5/0 1

0 0

pigur UFVRX pse iniil de un lgoritmo de pre)ujo sore l red de l (gur UFUQ @gF UPSAF vos ros slientes del fuente son inunddos @y estn resltdosAF vs lturs de d nodo estn uids l suroeste n ejeuin omplet de este lgoritmo sore el grfo de l (gur UFUQ se muestr en l (gur UFVS @pgsF URWEUSPAF xtese que el sumidero es lnzdo en l otv (gur on un vlor de )ujo de 6F v heursti intent reorrer en profundidd trvs de ros elegilesD pero no se trt de un reorrido en profundidd trdiionlF e destrse el sentido heurstioD pues en l elegiilidd de los ros iniden los vlores de piddes y el orden en que stos se presenten durnte ls iterionesF iste lgoritmo es O(V 3 )F n v de demostrin onsiste en de(nir omo funin 0 , Ah = potenil (Ah ) = y exminr el vlor de (Ah ) segn max{h(u) | u Ah } , Ah =

7.10. Redes de ujo

749

fses de metids en l olF v primer fse l delimit el onjunto de nodos tivos [u1 , u2 , . . . um ] justo despus de ejeutr re)ujo iniil de ros del nodo fuente 745a F vuegoD ls fses siguientes estn delimitds por el onjunto de nodos tivos luego de que um sle de l olF il nlisis se he suesivmenteF
4 D 6 0 4/0 3 E 3 0 8/0 2 I 0 0 4/0 1 K 0 0 4 D 6 0 4/0 3 E 3 0 8/0 2 I 0 0 4/0 1 K 0 0

4/0

5/0

3/0

4/0

3/0

4/0

4/0

5/0

3/0

4/0

3/0

4/0

0 21 7 3

7 0

6/0 2

0 0

4/0 1

0 0

5/0 0

0 0 4

0 21 7 3

7 0

6/0 2

3 0

4/0 1

0 0

5/0 0

0 0

5/0

3/0

5/0

7/0

6/0

4/0

6/0

5/0

5/0

7/0

6/0

4/0

6/0

5 0 4/0 4

0 0 6/0 2

0 0

5/0 1

0 0 4

5 3 4/0 4

0 0 6/0 2

0 0

5/0 1

0 0

6 0

4/0 3

3 0

8/0 2

0 0

4/0 1

0 0 4

6 0

4/0 3

3 3

8/0 2

0 0

4/0 1

0 0

5/3 6 3 4/0 5/0 3/0 4/0 3/0 4/0 6 3 4/0 3 3/0 4/0 3/0 4/0

0 21 7 4

7 6 6 2

9 0

4/0 1

0 0

5/0 0

0 0 4

0 21 7 4

7 6 6 2

12 0

4/0 1

0 0

5/0 0

0 0

5/0

5/0

7/0

6/0

4/0

6/0

5/0

5/0

7/0

6/0

4/0

6/0

5 3 4/0 4

0 0 6/0 2

0 0

5/0 1

0 0 4

5 3 4/0 4

0 0 6/0 2

0 0

5/0 1

0 0

6 4 4 3

7 3

8/0 2

0 0

4/0 1

0 0 5

6 4 4 3

7 3

8/0 2

0 0

4/0 1

0 0

5/3 6 3 4/0 3 3/0 4/0 3/0 4/0 6 3 4/0 3

5/3 3/0 4/0 3/0 4/0

0 21 7 4

7 6 6 2

12 0

4/0 1

0 0

5/0 0

0 0 4

0 21 7 5

7 6 6 3

12 10 4 1

4 0

5/0 0

0 0

5/0

5/0

7/0

6/0

4/0

6/0

5/0

5/0

7/0

4/0

6/0

5 3 4/0 4

0 0 6/0 2

0 0

5/0 1

0 0 5

5 3 4/0 4

0 0 6/0 2

0 0

5/0 1

6 0

pigur UFVSX elgoritmo pre)ujo on ol sore red de l (gur UFUQ @gF UPSAF il nodo extrdo junto on los ros elegiles se resltnF il )ujo entrnte se ui l noreste del nodoD el sliente l sureste y l ltur suroeste

750
8/4 D 6 4 4 3 E 7 7 4 5/3 6 3 4/0 3 3/0 4/0 3/0 4/0 4 6/4 3 4/0 3 2 I 4 0 4/0 1 K 0 0 5 D 4 4 4 3 E 7 7 4 5/3 3/0 4/0 3/0 4/0 2 8/4 I 4 0 4/0 1 K 0 0

7. Grafos

0 21 7 5

7 6 6 3

12 10 4 1

4 0

5/0 0

0 0 4

0 19 7 5

7 6 6 3

12 10 4 1

4 0

5/0 0

0 0

5/0

5/0

7/0

4/0

6/0

5/0

5/0

7/0

4/0

6/0

5 3 4/0 4

0 0 6/0 2

0 0

5/0 1

6 0 5

5 3 4/0 4

0 0 6/0 2

0 0

5/0 1

6 0

8/4 D 4 4 4 3 E 7 7 4 6/4 3 4 4/0 3 5/3 3/0 4/0 3/0 4/0 4 6/4 3 4/0 3 2 I 4 0 4/0 1 K 0 0 5 D 4 4 4 3 E 7 7

8/4 I 4 0 4/0 1 K 0 0

2 4 5/3 3/0

4/0

3/0

4/0

5/4 A 0 19 7 5 B 7 6 6 3 F 12 10 4 1 H 4 0 5/0 0 M 6 0 4 A 0 19 7 5 B 7 6 6 3 F 12 10 4 1 H 4 4 4 0 M 10 0

5/0

5/0

7/0

4/0

5/0

5/0

7/0

4/0

5 3 4/0 4

0 0 6/0 2

0 0

5/0 1

6 6 5

5 3 4/0 4

0 0 6/0 2

0 0

5/0 1

6 6

8/4 D 4 4 4 3 E 7 7 4 6/4 3 4 4/0 3 5/4 A 0 19 7 5 B 7 6 6 3 F 12 12 4 1 H 4 4 4 7/2 5 5/0 3 5/0 2 6 4/0 6 3 5/3 5/0 3 5/0 0 M 10 0 4 A 0 17 7 5 B 7 6 6 3 F 5/3 3/0 4/0 3/0 4/0 4 6/4 3 4/0 3 2 I 4 0 4/0 1 K 0 0 5 D 4 4 4 3 E 7 7

8/4 I 4 0 4/0 1 K 0 0

2 4 5/3 3/0

4/0

3/0

4/0

5/4 12 12 4 1 H 4 4 4 7/2 6 2 4/0 6 0 M 10 0

5 3 4/0 4

0 0 6/0 2

2 0

5/0 1

6 6 5

3 3 4/0 4

0 0 6/0 2

2 0

5/0 1

6 6

8/4 D 4 4 4 3 E 7 7 4 6/4 3 4 7/6 A 0 16 6 5/3 5/0 3 3 5/0 2 7/2 6 4/0 6 3 5 B 6 6 6 3 F 12 12 4 1 H 4 4 4 0 4/0 3 5/4 M 10 0 4 A 0 16 6 5/3 5/0 3 5/0 5 5/3 3/0 4/0 3/0 4/0 4 7/6 B 6 6 6 3 F 6/4 3 4/0 3 2 I 4 0 4/0 1 K 0 0 5 D 4 4 4 3 E 7 7

8/4 I 4 4 4 1 K 4 0

2 4 5/3 3/0

4/0

3/0

4/0

5/4 12 12 4 1 H 4 4 4 7/2 6 2 4/0 6 0 M 10 0

3 3 4/0 4

0 0 6/0 2

2 0

5/0 1

6 6 5

3 3 4/0 4

0 0 6/0 2

2 0

5/0 1

6 6

8/4 D 4 4 4 3 E 7 7 4 6/4 3 4 7/6 A 0 16 6 5/3 5/0 3 3 5/0 2 5/2 C 3 3 4/0 4 G 0 0 6/0 2 J 2 2 2 1 L 8 6 5 C 3 3 4/0 4 G 0 0 6/0 7/2 6 4/0 6 3 5 B 6 6 6 3 F 12 12 4 1 H 4 4 4 0 4/0 3 5/4 M 10 0 4 A 0 16 6 5/3 5/0 3 5/0 5 5/3 3/0 4/0 3/0 4/0 4 7/6 B 6 6 6 3 F 6/4 3 4/0 3 2 I 4 4 4 1 K 4 0 5 D 4 4 4 3 E 7 7

8/4 I 4 4 4 1 K 4 4

2 4 5/3 3/0

4/0

3/0

5/4 12 12 4 1 H 4 4 4 7/2 6 2 5/2 J 2 2 2 2 L 8 6 4/0 6 0 M 14 0

7.10. Redes de ujo


8/4 D 4 4 4 3 E 7 7 4 6/4 3 4 7/6 A 0 16 6 5/3 5/0 3 3 5/0 2 7/2 6 4/2 5/2 C 3 3 4/0 4 G 0 0 6/0 2 8/4 D 4 4 4 3 E 7 7 4 6/4 3 4 7/6 A 0 16 6 5/3 5/0 3 3 5/0 2 7/2 6 4/2 5/2 C 3 3 4/0 4 G 0 0 6/0 2 J 2 2 2 2 L 8 8 5 C 3 3 4/0 4 G 0 0 6/0 2 J 2 2 2 2 2 6 3 5 B 6 6 6 3 F 12 12 4 3 H 6 6 5 0 M 15 0 4 A 0 16 6 5/3 5/0 3 5/0 2 7/2 6 4/2 5/2 L 8 8 2 6 5 4/0 3 5/3 3/0 4/1 1 3/0 4 4 7/6 B 6 6 6 3 F 12 12 4 3 H 6 6 5 0 M 15 0 6/4 3 4/0 3 4 I 5 4 4 1 K 4 4 5 D 4 4 4 4 E 7 6 3 5/3 3/0 4/1 1 3/0 4 4 J 2 2 2 8/3 I 4 4 4 1 K 4 4 2 L 8 8 5 C 3 3 4/0 4 G 0 0 6/0 2 J 2 2 2 2 2 6 3 5 B 6 6 6 3 F 12 12 4 1 H 6 4 4 0 4/0 3 5/4 M 14 0 4 A 0 16 6 5/3 5/0 3 5/0 2 7/2 6 4/2 5/2 L 8 8 2 6 5 5/3 3/0 4/0 3/0 4 4 7/6 B 6 6 6 3 F 12 12 4 3 H 6 5 5 0 M 15 0 6/4 3 4/0 3 2 I 4 4 4 1 K 4 4 5 D 4 4 4 3 E 7 7 4 5/3 3/0 4/0 3/0 4 2 8/4 I 4 4 4 1 K 4 4

751

8/3 D 4 4 4 4 E 7 7 3 6/4 3 4 7/6 A 0 16 6 5/3 5/0 3 3 5/0 2 7/2 6 4/2 5/2 C 3 3 4/0 4 G 0 0 6/0 2 J 2 2 2 2 L 8 8 5 C 3 3 4/0 4 G 0 0 6/0 2 6 3 5 B 6 6 6 3 F 13 12 4 3 H 6 6 5 0 M 15 0 4 A 0 16 6 5/3 5/0 3 5/0 5 4/0 4 5/4 3/0 4/1 1 3/0 4 4 7/6 B 6 6 6 3 F 6/4 3 4/0 4 4 I 4 4 4 1 K 4 4 5 D 4 4 4 4 E 7 7

8/3 I 4 4 4 1 K 4 4

4 3 5/4 3/0

1 3/0 4/1 4

13 13 4 3

6 6 5 0

15 0

7/3 6 3 4/2 5/2 J 3 2 2 2

2 6

8 8

8/3 D 4 4 4 4 E 7 7 3 6/4 3 4 7/6 A 0 16 6 5/3 5/0 3 3 5/0 3 7/3 6 4/2 5/3 C 3 3 4/0 4 G 0 0 6/0 3 J 3 3 3 4 L 9 8 5 C 3 3 4/0 4 G 0 0 6/0 2 6 3 5 B 6 6 6 3 F 13 13 4 3 H 6 6 5 0 M 15 0 4 A 0 16 6 5/3 5/0 3 5/0 5 4/0 4 5/4 3/0 4/1 1 3/0 4 4 7/6 B 6 6 6 3 F 6/4 3 4/0 4 4 I 4 4 4 1 K 4 4 5 D 4 4 4 4 E 7 7

8/3 I 4 4 4 1 K 4 4

4 3 5/4 3/0

1 3/0 4/1 4

13 13 4 4

7 6 5 0

15 0

7/3 6 3 4/3 5/3 J 3 3 3 4

3 6

9 9

8/3 D 4 4 4 4 E 7 7 3 6/4 3 4 7/6 A 0 16 6 5/3 5/0 3 3 5/0 3 5 B 6 6 6 4 F 13 12 3 7/3 6 4/3 5/3 C 3 3 4/0 4 G 0 0 6/0 3 J 3 3 3 4 L 9 9 5 C 3 3 4/0 4 G 0 0 6/0 3 6 3 4 4/0 4 5/4 3/0 4/1 4/3 H 6 6 5 0 M 15 0 4 A 0 16 6 5/3 5/0 3 5/0 5 1 3/0 4 4 7/6 B 6 6 6 4 F 6/4 3 4/0 4 4 I 4 4 4 1 K 4 4 5 D 4 4 4 4 E 7 7

8/3 I 4 4 4 1 K 4 4

4 3 5/4 3/0

1 3/0 4/1 4/3 4

13 13 3 7/4 6 4 4

6 6 5 0

15 0

3 6 4/3 5/3

4 3 3 4

9 9

7.10.13.9

Empuje de preujo con mayor distancia

v segund heursti ms populrD l ul emprimente result mejor que l ol pspyD onsiste en mirr los nodos tivos en mplitudF v ide intuitiv es empujr todo el pre)ujo posile ntes de vnzr un nivelD es deirD desde los nodos ms distntes del sumidero hst los ms ernosF v estrutur de dtos que nos ofree est disiplin es un ol de prioridd uy extrin retorne el nodo tivo on myor lturD o seD se le d prioridd l nodo tivo ms erno fuente Eo ms lejno l sumidero segn

752
8/3 D 4 4 4 4 E 7 7 3 6/4 3 4 7/6 A 0 16 6 5/3 5/0 3 1 C 3 3 4/0 6 G 1 0 6/1 5 J 4 4 3 4 3 5/0 4 5 B 6 6 6 4 F 13 13 3 7/4 6 4/3 5/3 L 9 9 5 C 4 3 4/1 6 3 6 3 1 G 1 1 6/1 5 1 J 4 4 3 4 4 4/0 4 5/4 3/0 4/1 4/3 H 6 6 5 0 M 15 0 4 A 0 16 6 5/3 5/0 3 5/0 4 5 1 3/0 4 4 7/6 B 6 6 6 4 F 13 13 3 7/4 6 4/3 5/3 L 9 9 3 6 4 6/4 3 4/0 4 4 I 4 4 4 1 K 4 4 5 D 4 4 4 4 E 7 7 3 5/4 3/0 4/1 4/3 H 6 6 5 0 M 15 0 1 3/0 4 4 8/3 I 4 4 4 1 K 4 4

7. Grafos

4 4

4/4 4

7 7

8/3 4

4 4

4/4 1

4 4

6/4

3/3

4/0

5/4

3/0

4/1

3/0

4/4

0 15

7/6 5

6 6

6/6 4

13 13

4/3 4

6 6

5/5 0

15 0

5/2

5/0

3/3

5/0

7/4

6/6

4/3

6/6

3 3 4/1 6

1 1 6/1 5

4 4

5/3 4

9 9

pigur UFVTX istdo (nl de ejeuin lgoritmo de pre)ujo sore l (gur UFUQ @gF UPSA pr ol pspy onveng verEF vs ols de prioridd estn disponiles jo ulquier de los tipos soidos los hepsF in nuestro so empleremos el tipo DynBinHeap<Key>D el ul es l versin dinmi del tipo BinHeap<Key> estudido en RFUFT @gF PWQAF il riterio de omprin entre los elementos del hep se de(ne de l siguiente mnerX Funciones para Net_Graph 725 + 748 752b template <class Net> struct Compare_Height { bool operator () (typename Net::Node * n1, typename Net::Node * n2) const { return node_height<Net>(n1) > node_height<Net>(n2); } }; v omprin est invertid efetos de grntizr que siempre se extrig el nodo on myor prioriddF istleido el riterio de omprinD el empuje on l heursti por mplitud es diretoX Funciones para Net_Graph 725 + 752a 757 template <class Net> typename Net::Flow_Type heap_preflow_maximum_flow(Net & net, const bool & leave_residual = false) { return generic_preflow_vertex_push_maximum_flow <Net, DynBinHeap<typename Net::Node*, Compare_Height<Net> > > (net, leave_residual); } v ejeuin omplet de este lgoritmo sore el grfo de l (gur UFUQ es mostrd en l (gur UFVU @pgsF USQEUSTAF il nodo sumidero se lnz en l onev iterinD on un vlor de )ujo de 4Y tres iteriones ms que on l ol pspy y un vlor de )ujo menosF in trminos de l heursti podemos deir que puesto que se trt de ir en mplitudD

752a

752b

7.10. Redes de ujo

753

se demor ms en lnzr el sumideroF v mism oservin pli pr el vlor de )ujo inferiorY el )ujo est onentrdo hi el fuenteD mientrs que on l ol pspy est dispersdo trvs de los minos que l suerte en profundidd hy determindoF is demostrle que este lgoritmo se ejeut en O(V 3 ) psosF r eso se de(ne l mism funin potenil que pr l ol pspyD pero se mir l seueni on que los nodos tivos son exmindosF
4 D 6 0 4/0 3 E 3 0 8/0 2 I 0 0 4/0 1 K 0 0 5 D 6 4 4 3 E 7 0 8/0 2 I 0 0 4/0 1 K 0 0

4/0

5/0

3/0

4/0

3/0

4/0

4/0

5/0

3/0

4/0

3/0

4/0

0 21 7 3

7 0

6/0 2

0 0

4/0 1

0 0

5/0 0

0 0 4

0 21 7 3

7 0

6/0 2

0 0

4/0 1

0 0

5/0 0

0 0

5/0

3/0

5/0

7/0

6/0

4/0

6/0

5/0

3/0

5/0

7/0

6/0

4/0

6/0

5 0 4/0 4

0 0 6/0 2

0 0

5/0 1

0 0 3

5 0 4/0 4

0 0 6/0 2

0 0

5/0 1

0 0

pigur UFVUX elgoritmo de pre)ujo on hep sore l red de l (gur UFUQ @gF UPSA

754

7. Grafos

4 4 4 3

7 0

8/0 2

0 0

4/0 1

0 0 5

4 4 4 3

7 0

8/0 2

0 0

4/0 1

0 0

6/4 3 4 4/0 5/0 3/0 4/0 3/0 4/0

6/4 3 4 4/0 5/0 3/0 4/0 3/0 4/0

0 19 7 3

7 0

6/0 2

0 0

4/0 1

0 0

5/0 0

0 0 4

0 19 7 3

7 0

6/0 2

3 0

4/0 1

0 0

5/0 0

0 0

5/0

3/0

5/0

7/0

6/0

4/0

6/0

5/0

5/0

7/0

6/0

4/0

6/0

5 0 4/0 4

0 0 6/0 2

0 0

5/0 1

0 0 5

5 3 4/0 4

0 0 6/0 2

0 0

5/0 1

0 0

4 4 4 3

7 0

8/0 2

0 0

4/0 1

0 0 5

4 4 4 3

7 0

8/0 2

0 0

4/0 1

0 0

6/4 3 4 4/0 5/0 3/0 4/0 3/0 4/0

6/4 3 4 4/0 5/0 3/0 4/0 3/0 4/0

0 17 7 3

7 0

6/0 2

3 0

4/0 1

0 0

5/0 0

0 0 4

0 17 7 5

7 6 6 2

9 0

4/0 1

0 0

5/0 0

0 0

5/3 5/0 3 3 5/0 7/0 6/0 4/0 6/0 3

5/3 5/0 3 5/0 7/0 6/0 4/0 6/0

3 3 4/0 4

0 0 6/0 2

0 0

5/0 1

0 0 5

3 3 4/0 4

0 0 6/0 2 8/2

0 0

5/0 1

0 0

4 4 4 3

7 0

8/0 2

0 0

4/0 1

0 0 5

4 4 4 3

7 7 2 2

2 0

4/0 1

0 0

6/4 3 4 7/6 A 0 16 6 5/3 5/0 3 3 5/0 7/0 6/0 4/0 6/0 5 B 6 6 6 2 F 9 0 4/0 1 H 0 0 5/0 0 M 0 0 4 A 4/0 5/0 3/0 4/0 3/0 4/0

6/4 3 4 7/6 0 16 6 5/3 5/0 3 3 5/0 7/0 6/0 4/0 6/0 5 B 6 6 6 2 F 14 0 4/0 1 H 0 0 5/0 0 M 0 0 4/0 5 3/0 4/0 3/0 4/0

3 3 4/0 4

0 0 6/0 2

0 0

5/0 1

0 0 5

3 3 4/0 4

0 0 6/0 2

0 0

5/0 1

0 0

8/2 D 4 4 4 3 E 7 7 2 6/4 3 4 7/6 A 0 16 6 5/3 5/0 3 3 5/0 7/0 6 4/0 6/0 3 5 B 6 6 6 3 F 14 10 4 1 H 4 0 5/0 0 M 0 0 4 A 0 16 6 5/3 5/0 3 5/0 5 4/0 5 3/0 4/0 3/0 4/0 4 7/6 B 6 6 6 3 F 6/4 3 4/0 5 2 I 2 0 4/0 1 K 0 0 5 D 4 4 4 3 E 7 7

8/2 I 2 0 4/0 1 K 0 0

2 2

3/0

4/0

3/0

4/0

14 14 4 1

4 0

5/0 0

0 0

7/4 6 4 4/0 6/0

3 3 4/0 4

0 0 6/0 2

0 0

5/0 1

6 0 5

3 3 4/0 4

0 0 6/0 2 8/2

4 0

5/0 1 4/2

6 0

8/2 D 4 4 4 3 E 7 7 2 6/4 3 4 7/6 A 0 16 6 5/3 5/0 3 3 5/0 4 7/4 6 5 B 6 6 6 3 F 14 14 4 1 H 4/0 5 3/0 4/0 2 I 2 2

4/2 K 2 0 6/4 5

4 4 4 3

7 7 2 2

2 2 2 1

2 0

1 2

3 3/0 4/0 4 7/6 A 0 16 6 5/3 5/0 4/0 6/0 3 5 B 6 6

4/0

3/0

4/0

3/0

4/0

4 0

5/0 0

0 0

14 14 4 1

4 0

5/0 0

0 0

7/4 3 5/0 4 5/4 6 4/0 6/0

3 3 4/0 4

0 0 6/0 2

4 0

5/0 1

6 0

3 3 4/0 4

0 0 6/0 2

4 4 4 1

10 0

7.10. Redes de ujo


8/2 D 4 4 4 3 E 7 7 2 6/4 3 4 7/6 A 0 16 6 5/3 5/0 3 3 5/0 4 5/4 C 3 3 4/0 4 G 0 0 6/0 2 J 4 4 4 2 L 10 6 5 C 3 3 4/0 4 G 0 0 6/0 2 J 4 4 4 2 7/4 6 4/0 6 3 5 B 6 6 6 3 F 14 14 4 1 H 4 0 5/0 0 M 6 0 4 A 0 16 6 5/3 5/0 3 5/0 4 5/4 L 10 10 7/4 6 4 6 5 4/0 5 3/0 4/0 3/0 4/0 4 7/6 B 6 6 6 3 F 14 14 4 1 H 8 0 5/0 0 M 6 0 2 I 2 2 2 6/4 3 4/0 5 3/0 4/0 3/0 4/0 1 4/2 K 2 0 5 D 4 4 4 3 E 7 7 2 2 8/2 I 2 2 2 1 4/2 K 2 0

755

8/2 D 4 4 4 3 E 7 7 2 6/4 3 4 7/6 A 0 16 6 5/3 5/0 3 3 5/0 4 7/4 6 5 B 6 6 6 3 F 14 14 4 3 H 4/0 5 3/0 4/0 2 I 2 2

4/2 K 2 0 5 D 4 4 4 3 E 7 7

8/2 I 5 2

4/2 K 2 0

1 2

2 2

1 2 3

6/4 3/0 4/0 4 7/6 8 5 5 0 M 11 0 4 A 0 16 6 5/3 4 6 3 5/4 C 3 3 4/0 4 G 0 0 6/0 2 8/2 D 4 4 4 3 E 7 7 2 4 I 5 4 4 1 K 4 0 5 D 4 4 4 5 E 7 6 1 3 3 4 7/6 4/0 5 3/0 4/3 3/0 4/0 4 7/6 B 6 6 6 3 F 14 14 4 3 H 8 8 5 0 M 11 0 4 A 0 16 6 7/4 5/0 3 5/0 4 5/4 C 3 3 4/0 4 G 0 0 6/0 2 J 4 4 4 2 L 10 10 5 C 3 3 4/0 4 G 0 0 6/0 2 J 4 4 6 4 6 3 5/3 5/0 3 5/0 4 7/4 6 5 B 6 6 6 3 F 14 14 4 3 6/4 3 4/0 5 3/0 4/3 4 J 4 4 4 8/1 I 4 4 2 L 10 10 5 C 3 3 4/0 4 G 0 0 6/0 2 J 4 4 5/0 3 5/0 4 7/4 6 5 B 6 6 6 3 F 14 14 4 3 3 4/0 5 3/0 4/3

3/0

4/0

8 8 5 0

11 0

5/4 L 10 10

2 4

4 0

6/4

3 3/0 4/0

0 16 6 5/3 3 5

8 8 5 0

11 0

5/4 L 10 10

2 4

8/2 D 4 4 4 5 E 7 7 2 6/4 3 4 7/6 A 0 16 6 5/3 5/0 3 3 5/0 4 5/4 C 3 3 4/0 4 G 0 0 6/0 2 J 4 4 4 2 L 10 10 5 C 3 3 4/0 4 G 0 0 6/0 7/4 6 4 6 3 5 B 6 6 6 3 F 14 14 4 3 H 8 8 5 0 M 11 0 4 A 0 16 6 5/3 5/0 3 5/0 5 4/0 5 3/0 4/3 3 3/0 4/0 4 7/6 B 6 6 6 3 F 6/4 3 4/0 5 4 I 5 4 4 1 K 4 0 5 D 4 4 4 5 E 7 7

8/2 I 4 4 4 1 K 4 0

4 2

2 3/0 4/2 3/0 4/0

14 14 4 3

8 7 5 0

11 0

7/4 6 4 5/4 J 4 4 4 2 L 10 10 4 6

8/2 D 4 4 4 5 E 7 7 2 6/4 3 4 7/6 A 0 16 6 5/3 5/0 3 3 5/0 4 7/4 6 4/3 5/4 C 3 3 4/0 4 G 0 0 6/0 2 J 4 4 4 3 L 10 9 5 C 3 3 4/0 4 G 0 0 6/0 3 6 3 5 B 6 6 6 3 F 14 14 4 3 H 7 7 5 0 M 11 0 4 A 0 16 6 5/3 5/0 3 5/0 5 4/0 5 3/0 4/2 2 3/0 4/0 4 7/6 B 6 6 6 3 F 6/4 3 4/0 5 4 I 4 4 4 1 K 4 0 5 D 4 4 4 5 E 7 7

8/2 I 4 4 4 1 K 4 0

4 2

2 3/0 4/2 3/0 4/0

14 14 4 3

7 7 5 0

11 0

7/4 6 4 4/3 5/3 J 4 3 3 3

3 6

9 9

7.10.13.10

Empuje de preujo con cola aleatoria

is muy prole extrer nodos tivos sin ros elegilesF or eso es desele minimizr l ntidd de est lse de extriones vnsD lo ul depende de l suerte topolgi del grfoD de l suerte on que se miren los ros y de l suerte on que se presenten los vlores de ls piddesF esD tnto pree inidir l suerte que es tentdor introduirl en el lgoritmoF e ese tenorD un estrutur de dtos pr representr Ah se llm cola aleatoria D l ul

756

7. Grafos

8/2 D 4 4 4 5 E 7 7 2 6/4 3 4 7/6 A 0 16 6 5/3 5/0 3 3 5/0 4 7/4 6 4/3 5/4 C 3 3 4/0 4 G 0 0 6/0 4 J 4 4 4 4 L 10 9 5 C 3 3 4/0 4 G 0 0 6/0 3 6 3 5 B 6 6 6 3 F 14 14 4 3 H 7 7 5 0 M 11 0 4 A 0 16 6 5/3 5/0 3 5/0 5 4/0 5 3/0 4/2 2 3/0 4/0 4 7/6 B 6 6 6 3 F 6/4 3 4/0 5 4 I 4 4 4 1 K 4 0 5 D 4 4 4 5 E 7 7

8/2 I 4 4 4 1 K 4 0

4 2

2 3/0 4/2 3/0 4/0

14 14 4 4

8 7 5 0

11 0

7/4 6 4 5/4 J 4 4 4 4 L 10 10 4 6

8/2 D 4 4 4 5 E 7 7 2 6/4 3 4 7/6 A 0 16 6 5/3 5/0 3 3 5/0 4 5/4 C 3 3 4/0 4 G 0 0 6/0 4 J 4 4 4 4 L 10 10 5 C 3 3 4/0 6 G 1 0 6/0 5 B 6 6 6 5 F 14 13 3 7/4 6 4 6 3 4 4/0 5 3/0 4/2 4/3 H 7 7 5 0 M 11 0 4 A 0 16 6 5/3 5/0 3 1 5 2 3/0 4/0 4 7/6 B 6 6 6 5 F 6/4 3 4/0 5 4 I 4 4 4 1 K 4 0 5 D 4 4 4 5 E 7 7

8/2 I 4 4 4 1 K 4 0

4 2

2 3/0 4/2 4/3 14 14 3 7/4 6 5/1 4 5/4 J 4 4 4 4 L 10 10 4 6 4 H 7 7 5 0 M 11 0 3/0 4/0

8/2 D 4 4 4 5 E 7 7 2 6/4 3 4 7/6 A 0 16 6 5/3 5/0 3 1 C 4 3 4/1 6 G 1 1 6/0 4 J 4 4 4 4 3 5/1 4 5/4 L 10 10 5 C 3 3 4/1 6 1 5 B 6 6 6 5 F 14 14 3 7/4 6 4 6 2 1 G 1 1 6/0 4 4/0 5 3/0 4/2 4/3 H 7 7 5 0 M 11 0 4 A 0 15 6 5/2 5/0 3 1 5 2 3/0 4/0 4 7/6 B 6 6 6 5 F 6/4 3 4/0 5 4 I 4 4 4 1 K 4 0 5 D 4 4 4 5 E 7 7

8/2 I 4 4 4 1 K 4 0

4 2

2 3/0 4/2 4/3 14 14 3 7/4 6 5/1 4 5/4 J 4 4 4 4 L 10 10 4 6 4 H 7 7 5 0 M 11 0 3/0 4/0

4 4

4/4 5

7 7

8/2 4

4 4

4/4 1

4 4

6/4

3/3

4/0

5/5

3/0

4/2

3/0

4/4

0 15

7/6 5

6 6

6/6 5

14 14

4/3 4

7 7

5/5 0

15 0

5/2

5/0

3/3

5/1

7/4

6/6

4/4

6/6

3 3 4/1 6

1 1 6/0 4

4 4

5/4 4

10 10

pigur UFVVX istdo (nl de ejeuin lgoritmo de pre)ujo sore l (gur UFUQ @gF UPSA on ol de prioridd
Heurstica Cola FIFO Cola prioridad Cola aleatoria Cantidad de iteraciones 44 43 min = 28 - promedio = 40,34 - max = 50

le UFIX gntidd de iteriones pr ls heurstis de empuje de pre)ujo puede implntrse muy filmenteX tpl_random_queue.H 756 template <class T> class Random_Set { DynArray<T> array; gsl_rng * r;

756

7.10. Redes de ujo

757

void put(const T & item) { array[array.size()] = item; } T get() { const size_t pos = gsl_rng_uniform_int(r, array.size()); // al azar T ret_val = array.access(pos); array.access(pos) = array.access(array.size() - 1); array.cut(array.size() - 1); return ret_val; }
DynArray
34.

};
Uses

757

y seD un ol uy operin get() seleion l zr el elemento eliminrF gon est estrutur podemos implntr l siguiente espeilizinX Funciones para Net_Graph 725 + 752b 761 template <class Net> typename Net::Flow_Type random_preflow_maximum_flow(Net & net, const bool & leave_residual = false) { return generic_preflow_vertex_push_maximum_flow <Net, Random_Set<typename Net::Node*> > (net, leave_residual); } n ejeuin ompletD uenD on est olD se muestr en l (gur UFVW @gsF USVEUTHAF il promedio se lul pr 100 ejeuionesF r el ejemploD l ol letori ofree un ejeuin promedio mejor ls otrs dos heurstisF in el ejemplo mostrdo se tuvo l suerte de lnzr el sumidero en ino iterionesF

758

7. Grafos

6 0

4/0 3

3 0

8/0 2

0 0

4/0 1

0 0 5

6 4 4 3

7 0

8/0 2

0 0

4/0 1

0 0

4/0

5/0

3/0

4/0

3/0

4/0

4/0

5/0

3/0

4/0

3/0

4/0

0 21 7 3

7 0

6/0 2

0 0

4/0 1

0 0

5/0 0

0 0 4

0 21 7 3

7 0

6/0 2

0 0

4/0 1

0 0

5/0 0

0 0

5/0

3/0

5/0

7/0

6/0

4/0

6/0

5/0

3/0

5/0

7/0

6/0

4/0

6/0

5 0 6 4 4 3 4/0 4

0 0 7 0 6/0 2

0 0 0 0

5/0 1

0 0 0 0 5 3

5 0 6 4 4 3 4/0 4

0 0 7 0 6/0 2

0 0 0 0

5/0 1

0 0 0 0

8/0 2

4/0 1

8/0 2

4/0 1

4/0

5/0

3/0

4/0

3/0

4/0

4/0

5/0

3/0

4/0

3/0

4/0

0 21 7 4

7 6 6 2

6 0

4/0 1

0 0

5/0 0

0 0 4

0 21 7 4

7 7 6 2

6 0

4/0 1

0 0

5/0 0

0 0

1 5 5/0 3/0 5/0 7/0 6/0 4/0 6/0 5 5/1 3/0 5/0 7/0 6/0 4/0 6/0

5 0 6 4 4 3 4/0 4

0 0 7 0 6/0 2

0 0 0 0

5/0 1

0 0 0 0 5 3

6 0 6 4 4 3 4/0 4

0 0 7 0 6/0 2

0 0 0 0

5/0 1

0 0 0 0

8/0 2

4/0 1

8/0 2

4/0 1

4/0

5/0

3/0

4/0

3/0

4/0

4/0

5/0

3/0

4/0

3/0

4/0

0 21 7 4

7 7 6 2

6 6

4/0 1

0 0

5/0 0

0 0 4

0 21 7 4

7 7 6 2

6 6

4/0 1

0 0

5/0 0

6 0

1 5 5/1 3/0 5/0 7/0 6 4/0 6/0 5

1 3/0 5/1 5/0 7/0 6 4/0 6

6 0 4 4 4 3 4/0 4

0 0 7 0 6/0 2

0 0 0 0

5/0 1

6 0 0 0 5 4 4 4 3 7 0 3

6 0 0 0 4/0 4

0 0 0 0 6/0 2

0 0

5/0 1

6 6

8/0 2

4/0 1

8/0 2

4/0 1

6/4 3 4 4/0 5/0 3/0 4/0 3/0 4/0

6/4 3 4 4/0 5/0 3/0 4/0 3/0 4/0

0 19 7 4

7 7 6 2

6 6

4/0 1

0 0

5/0 0

6 0 4

0 19 7 4

7 7 6 2

9 6

4/0 1

0 0

5/0 0

6 0

1 5 5/1 3/0 5/0 7/0 6 4/0 6 5

1 3 5/1 5/0 7/0 6 4/0 6

6 0 4/0 4

0 0 6/0 2

0 0

5/0 1

6 6 5

6 3 4/0 4

0 0 6/0 2

0 0

5/0 1

6 6

pigur UFVWX n ejeuin omplet fvorle @QP iterionesA del lgoritmo de pre)ujo on ol letori sore l red de l (gur UFUQ @gF UPSA

7.10. Redes de ujo

759

4 4 4 3

7 0

8/0 2

0 0

4/0 1

0 0 5

4 4 4 3

7 0

8/0 2

0 0

4/0 1

0 0

6/4 3 4 4/0 5/0 3/0 4/0 3/0 4/0

6/4 3 4 4/3 4/0 5/0 3/0 4/0 3/0 4/0

0 16 7 4

7 7 6 2

9 6

4/0 1

0 0

5/0 0

6 0 4

0 16 7 4

7 7 6 2

9 9 3 1

3 0

5/0 0

6 0

5/2 1 3 2 5/1 5/0 7/0 6 4/0 6 2

5/2 1 3 5/1 5/0 7/0 6 4/0 6

3 3 4/0 4

0 0 6/0 2 8/2

0 0

5/0 1

6 6 5

3 3 4/0 4

0 0 6/0 2 8/2

0 0

5/0 1

6 6

4 4 4 3

7 7 2 2

2 0

4/0 1

0 0 5

4 4 4 3

7 7 2 2

2 0

4/0 1

0 0

6/4 3 4 4/3 A 0 16 7 4 B 7 7 6 2 F 14 9 3 5/2 1 3 2 5/1 5/0 7/0 6 4/0 6 1 H 3 0 5/0 0 M 6 0 4 A 4/0 5 3/0 4/0 3/0 4/0

6/4 3 4 4/0 5 3/0 4/0 3/0 4/0

0 16 7 4

7 7 6 3

14 10 4 1

4 0

5/0 0

6 0

5/2 1 3 2 5/1 5/0 7/0 6 4/0 6

3 3 4/0 4

0 0 6/0 2 8/2

0 0

5/0 1 4/2

6 6 5

3 3 4/0 4

0 0 6/0 2 8/2

0 0

5/0 1 4/2

6 6

4 4 4 3

7 7 2 2

2 2 2 1

2 0 5

4 4 4 3

7 7 2 2

2 2 2 1

2 0

6/4 3 4 4/0 5 3/0 4/0 3/0 4/0

6/4 3 4 5/4 4/0 5 3/0 4/0 3/0 4/0

0 16 7 4

7 7 6 3

14 10 4 1

4 0

5/0 0

6 0 4

0 16 7 4

7 7 6 3

14 10 4 1

4 4 4 0

10 0

5/2 1 3 2 5/1 5/0 7/0 6 4/0 6 2

5/2 1 3 5/1 5/0 7/0 6 4/0 6

3 3 4/0 4

0 0 6/0 2

0 0

5/0 1

6 6 5

3 3 4/0 4

0 0 6/0 2 8/2

0 0

5/0 1 4/2

6 6

8/2 D 4 4 4 3 E 7 7 2 6/4 3 4 4/0 5 3/0 4/0 2 I 2 2

4/2 K 2 0 6/4 5

4 4 4 3

7 7 2 2

2 2 2 1

2 0

1 2

3 3/0 4/0 4

4/0

3/0

4/0

3/0

4/0

5/4 5/4 A 0 16 7 4 B 7 7 6 3 F 14 14 4 1 H 4 4 4 5/2 1 3 6 4 3 3 4/0 4 0 0 6/0 2 4 4 4 8/2 K 2 2 5 D 4 4 4 3 E 7 7 2 4/2 3 4/0 5 3/0 4/0 3/0 2 5/4 4 6/4 3 4/0 5 3/0 4/0 3/0 2 5/4 M 12 0 4 A 0 16 7 4 B 7 7 6 3 F 14 14 4 1 H 8 4 4 5/2 1 6 4 5/4 4/0 6 2 5/1 3 5/0 4 5/4 L 10 6 5 C 3 3 4/0 4 G 0 0 6/0 2 J 4 4 4 2 L 10 10 7/4 6 4 6 0 M 12 0 2 I 2 2 2 4/2 1 4/2 K 2 2 1 4/0 6 2 5/1 5/0 4 5/4 C G J L 10 6 7/4 6 4/0 6 0 M 10 0

0 16 7 4

7 7 6 3

14 14 4 1

4 4 4 0

10 0

5/2 1 3 2 5/1 5/0

7/4

3 3 4/0 4

0 0 6/0 2 8/2

4 0

5/0 1 4/2

6 6

4 4 4 3

7 7 2 2

2 2 2 1

6/4 4

0 16 7 4

7 7 6 3

14 14 4 1

4 4 4 0

5/2 1 3 2 5/1 5/0

7/4

3 3 4/0 4

0 0 6/0 2

4 4 4 2

760

7. Grafos

8/2 D 4 4 4 3 E 7 7 2 6/4 3 4 4/0 5 3/0 4/0 2 I 2 2

4/2 K 2 2 5 D 4 4 4 3 E 7 7

8/2 I 5 2

4/2 K 2 2

1 2

2 2

1 2 3

4/2 3/0 2

6/4 3 4 4/0 5 3/0 4/3

4/2 3/0 2

0 16 7 4

7 7 6 3

14 14 4 3

8 5 5 0

13 0 4

0 16 7 4

7 7 6 3

14 14 4 3

8 8 5 0

13 0

5/2 1 3 2 5/1 5/0 4

7/4 6 4 6 2 5/4

5/2 1 3 5/1 5/0 4

7/4 6 4 6

5/4 L 10 10 5 C 3 3 4/0 4 G 0 0 6/0 2 J 4 4 4 8/2 2 L 10 10

3 3 4/0 4

0 0 6/0 2

4 4 4 2

8/2 D 4 4 4 3 E 7 7 2 6/4 3 4 4/0 5 3/0 4/3 3 3/0 2 4 4/2 6/4 3 4/0 5 4 I 5 4 4 1 K 4 2 5 D 4 4 4 3 E 7 7

4 2

5 4 4 1

4 4

3 3/0 4/3 3/0 4

0 16 7 4

7 7 6 3

14 14 4 3

8 8 5 0

13 0 4

0 16 7 4

7 7 6 3

14 14 4 3

8 8 5 0

15 0

5/2 1 3 2 5/1 5/0 4

7/4 6 4 6 2 5/4

5/2 1 3 5/1 5/0 4

7/4 6 4 6

5/4 L 10 10 5 C 3 3 4/0 4 G 0 0 6/0 2 J 4 4 4 8/1 2 L 10 10

3 3 4/0 4

0 0 6/0 2

4 4 4 2

8/1 D 4 4 4 5 E 7 6 1 6/4 3 4 4/0 5 3/0 4/3 3 3/0 4 4 6/4 3 4/1 1 5 4 I 4 4 4 1 K 4 4 5 D 4 4 4 5 E 7 7

4 1

4 4 4 1

4 4

3 3/0 4/3 3/0 4

0 16 7 4

7 7 6 3

14 14 4 3

8 8 5 0

15 0 4

0 16 7 5

8 7 6 3

14 14 4 3

8 8 5 0

15 0

5/2 1 3 2 5/1 5/0 4

7/4 6 4 6 2 5/4

5/2 1 3 5/1 5/0 4

7/4 6 4 6

5/4 L 10 10 5 C 3 3 4/0 4 G 0 0 6/0 2 J 4 4 4 2 L 10 10

3 3 4/0 4

0 0 6/0 2

4 4 4 2

8/1 D 4 4 4 5 E 7 6 1 6/4 3 4 4/0 5 3/0 4/3 3 3/0 4 4 6/4 3 4/1 1 5 4 I 4 4 4 1 K 4 4 5 D 4 4 4 5 E 7 7

8/1 I 4 4 4 1 K 4 4

4 1

3 3/0 4/3 3/0 4

0 16 7 4

7 7 6 3

14 14 4 3

8 8 5 0

15 0 4

0 16 7 5

8 7 6 3

14 14 4 3

8 8 5 0

15 0

5/2 1 3 2 5/1 5/0 4

7/4 6 4 6 2 5/4

5/2 1 3 5/1 5/0 4

7/4 6 4 6

5/4 L 10 10 5 C 3 3 4/0 4 G 0 0 6/0 2 J 4 4 4 2 L 10 10

3 3 4/0 4

0 0 6/0 2

4 4 4 2

4 4

4/4 5

7 7

8/1 4

4 4

4/4 1

4 4

6/4

3/3

4/1

5/5

3/0

4/3

3/0

4/4

0 15

7/6 5

7 7

6/6 3

14 14

4/4 3

8 8

5/5 0

15 0

5/2

5/1

3/3

5/0

7/4

6/6

4/4

6/6

3 3 4/0 4

0 0 6/0 2

4 4

5/4 2

10 10

pigur UFWHX istdo (nl de ejeuin lgoritmo de pre)ujo sore l (gur UFUQ @gF UPSA on ol letori

7.10.13.11

Algoritmo genrico de empuje de preujo por arcos

n lterntiv l lgoritmo genrio onsiste en mnejr un estrutur de dtos orienE td l onjunto de ros elegiles en lugr del de los nodos tivosF v extrin de l ol ser l de un ro elegile segn lgn riterio omindo on l ltur del nodoF

7.10. Redes de ujo

761

761

heemos tener espeil uiddo on el reetiquetdoD pues undo ourre un inremento de ltur de un nodoD ros devienen elegilesD pero otros que ern elegiles devienen inelegilesF v estrutur de dtos dee mnejr tnto los nodos tivos omo los ros elegilesF ry vris mners de mntener el onjunto de ros elegilesF yptremos por empler dos onjuntosX el de los ros elegilesD llmdo q on tipo genrio QA_TypeD y el de los nodos tivosD llmdo p on tipo genrio QN_TypeF xo nos preoupremosD en lneD por sr ros que dejen de ser elegiles undo ourr un inrementoF hiho lo nteriorD onsideremos el siguiente lgoritmo genrioX Funciones para Net_Graph 725 + 757 764b template <class Net, class QN_Type, class QA_Type> typename Net::Flow_Type generic_preflow_edge_maximum_flow(Net & net, const bool & leave_residual = false) { QA_Type q; // conjunto de arcos elegibles QN_Type p; // conjunto de nodos activos typename Net::Node * source = net.get_source(); typename Net::Node * sink = net.get_sink(); init_height_in_nodes(net);

Inundar arcos del fuente 762a


while (true) { while (not q.is_empty()) // mientras haya arcos elegibles { typename Net::Arc * arc = get_from_active_queue(q); typename Net::Node * src = net.get_src_node(arc); typename Net::Node * tgt = net.get_tgt_node(arc); if (node_height<Net>(src) != node_height<Net>(tgt) + 1) continue; // No ==> ignore arco typename Net::Flow_Type excess = src->in_flow - src->out_flow; if (excess == 0) // fuente descargado en iteracin anterior? { // s ==> ignore arco remove_from_active_queue(p, src); continue; // avance al siguiente arco elegible }

Empujar preujo por arc 762b


if (is_node_active<Net>(tgt) and tgt != source and tgt != sink)

Meter en q arcos elegibles de tgt 763

if (excess == 0) // se descarg el fuente? { // s ==> fuente deviene inactivo remove_from_active_queue(p, src); continue; } if (src != source and src != sink and // empuje no saturante?

762

7. Grafos

not has_arcs_in_active_queue<Net>(src)) { // s ==> incremente h(active) y re-inserte arc en q remove_from_active_queue(p, src); node_height<Net>(src)++; put_in_active_queue(p, src); }

Meter en q arcos elegibles de src 764a

} if (p.is_empty()) // quedan nodos activos? break; // ya no hay nodos activos typename Net::Node * src = get_from_active_queue(p); node_height<Net>(src)++; put_in_active_queue(p, src); } // fin while (true) return source->out_flow;

Meter en q arcos elegibles de src 764a

762a

il lgoritmo mnej dos lzos ontinuos @whileAD d uno soido extrer y proesr un elemento de un onjuntoF il primer onjunto qD de tipo QN_TypeD represent el de nodos tivosD mientrs que el segundo pD de tipo QA_TypeD el de ros elegilesF emos lzos son prte de un suprlzo que rompe undo y no hy ms nodos tivosF vos onjuntos q y p son iniilizdos por el loque iniil snundr ros del fuente 762a D uyo (n lgortmio es el mismo que el re)ujo iniil de ros del nodo fuente 745a X rer el mximo pre)ujo iniilX Inundar arcos del fuente 762a (761) for (Node_Arc_Iterator<Net, Res_F<Net> > i(source); i.has_current(); i.next()) { typename Net::Arc * arc = i.get_current_arc(); typename Net::Node * tgt = net.get_tgt_node(arc); arc->flow = tgt->in_flow = arc->cap - arc->flow; // inundar arco arc->img_arc->flow = 0;
// meter arcos elegibles de tgt for (Node_Arc_Iterator<Net, Res_F<Net> > j(tgt); j.has_current(); j.next()) { typename Net::Arc * a = j.get_current_arc(); if (node_height<Net>(tgt) == node_height<Net>(net.get_tgt_node(a)) + 1) put_in_active_queue(q, a); } put_in_active_queue(p, tgt); // mete en cola de nodos activos

} source->out_flow = source->out_cap;

762b

il loque impujr pre)ujo por r 762b D es similr impujr pre)ujo por ro tul 745b Y Empujar preujo por arc 762b (761) const typename Net::Flow_Type push = std::min(excess, arc->cap - arc->flow); arc->flow += push; arc->img_arc->flow -= push;

7.10. Redes de ujo

763

if (arc->is_residual) { net.decrease_out_flow(net.get_tgt_node(arc), push); net.decrease_in_flow(net.get_src_node(arc), push); } else { net.increase_in_flow(net.get_tgt_node(arc), push); net.increase_out_flow(net.get_src_node(arc), push); } excess -= push;

763

gundo se empuj el pre)ujo por arcD el nodo destino tgt prolemente deveng tivoF in ese soD hy que meter en l ol q los ros slientes de tgt que sen elegiles y tgt en pX Meter en q arcos elegibles de tgt 763 (761) { for (Node_Arc_Iterator<Net, Res_F<Net> > it(tgt); it.has_current(); it.next()) { typename Net::Arc * a = it.get_current_arc(); if (node_height<Net>(tgt) == node_height<Net>(net.get_tgt_node(a)) + 1) put_in_active_queue(q, a); } put_in_active_queue(p, tgt); } hespus de weter en q ros elegiles de tgt 763 puede sueder que src se hy desrgdo ompletmenteF in ese soD src deviene intivo y hy que eliminrlo del onjunto de nodos tivosF is es l funin del if (excess == 0)F il loque dentro del if (src != source and ...) es quiz l prte ms difil de omprenderF equ hy que veri(r si el nodo src devino intivoD lo ul se onoe medinte el predido excess > 0F i es flsoD entones y es on seguridd intivoD pues el exeso fue drendo en el roF he lo ontrrio deemos veri(r si impujr pre)ujo por r 762b fue o no sturnteD uestin que determin l exisE teni de ros de slid de src que estn dentro de l olY este es el (n de l rutin has_arcs_in_active_queue<Net,Q_Type>(q, src)D uy implntin slo se remite inspeionr el it Maximum_Flow en los ros sliente de srcF in el inremento de ltur de un nodo hy que segurrse de oservr vrios suntosX  uesto que src est tivoD ste se enuentr dentro del onjunto pF egn l estruE tur de dtos e interfz de QN_TypeD no se puede llevr o diretmente el inremento node_height<Net>(src)++ si src est ontenido dentro del onjuntoD pues se fet l disiplin de orden de l estrutur de dtosF or es rznD el inremento s src de pD inrement l ltur y mete de nuevo en pF  il inremento node_height<Net>(src)++ puede provor l priin y despriin de ros elegilesD tnto slientes desde omo entrntes srcF or los ros slientes no hy prolem en revisrlosD son diretmente esilesD pero los entrntes no lo sonF in este soD el her esogido que l red residul est dentro de l propi red umple un ppel esenilD pues por d ro entrnte src existe un ro residul que nos

764

7. Grafos

permite onoer en O(1) el ro entrnte srcF


764a

Meter en q arcos elegibles de src 764a

(761)

for (Node_Arc_Iterator<Net> it(src); it.has_current(); it.next()) { typename Net::Arc * a = it.get_current_arc(); // sale de src if ((node_height<Net>(src) == node_height<Net>(net.get_tgt_node(a)) + 1) and (a->cap - a->flow > 0)) put_in_active_queue(q, a); typename Net::Arc * i = a->img_arc; // arco entrante a src if ((i->cap - i->flow > 0) and // i es elegible? (node_height<Net>(net.get_src_node(i)) == node_height<Net>(src) + 1)) put_in_active_queue(q, i);

il iterdor no utiliz el (ltro Res_F de(nido en UFIHFW @gF UPSAD pues ste nos (ltrr justmente ros sturdos y nos impedir ver el nodo origen de un ro entrnte srcF vos ros ontenidos en q que dejn de ser elegilesD simplemente se ignornF odrmos diser un estrutur de dtos que permit el inremento direto y elimine los ros no elegiles en O(1)F r qu este enfoque segn los ros elegilescD en qu di(ere del lgoritmo genrio segn nodos tivosc esult que on este lgoritmo es intuitivmente ms senillo pensr el orden de trtmiento de los nodos tivosF gonsideremos lguns espeilizionesF
Seleccin de arcos por profundidad
764b

n primer riterio onsiste en emulr el reorrido en profundiddX Funciones para Net_Graph 725 + 761 765a template <class Net> typename Net::Flow_Type depth_first_preflow_edge_maximum_flow (Net & net, const bool & leave_residual = false) { typedef DynSetTreap<typename Net::Node*> Active; typedef DynListStack<typename Net::Arc*> Stack; return generic_preflow_edge_maximum_flow <Net,Active,Stack> (net, leave_residual); }
Uses

DynListStack

105c.

vos nodos tivos se gurdn en un trep @ TFQ @gF RTRAA uy operin get() retorn el myor vlorD o seD el nodo de myor lturF n inremento uest O(lg V )D oste que puede llevrse O(1) si se elor on uiddo un tl hshD uy funin hsh inluy l ltur y l direin del nodoF odr srseD por ejemploD en el tipo ODhashTable de(nido en SFIFRFS @gF RHQAF vos ros elegiles se enuentrn en un pilD por lo que su proesmiento oedee l rquetipo en profundiddF

7.10. Redes de ujo

765

Seleccin de arcos por amplitud

765a

ytr versinD estruturlmente muy similr pero de proesmiento muy distintoD onE siste en emulr el reorrido en mplitud y se de(ne omoX Funciones para Net_Graph 725 + 764b 765b template <class Net> typename Net::Flow_Type breadth_first_preflow_edge_maximum_flow (Net & net, const bool leave_residual = false) { typedef DynSetTreap<typename Net::Node*> Active; typedef DynListQueue<typename Net::Arc*> Queue; return generic_preflow_edge_maximum_flow<Net, Active, Queue> (net, leave_residual); } v ul reorre los ros elegiles en profundiddF
Seleccin de arcos por prioridad

765b

odemos espei(r un prioridd de elegiilidd entre dos rosD por ejemploX Funciones para Net_Graph 725 + 765a 765c template <class Net> struct Compare_Arc { bool operator () (typename Net::Arc * a1, typename Net::Arc * a2) const { typename Net::Node * src1 = (typename Net::Node *) a1->src_node; typename Net::Node * src2 = (typename Net::Node *) a2->src_node; if (src1->counter == src2->counter) return a1->cap - a1->flow > a2->cap - a2->flow;
} return src1->counter > src2->counter;

};

765c

il riterio mir ls lturs de los nodos origen de d roF i sts son igulesD entones se elige el ro que teng myor pidd disponileD jo l expettiv de que se empuje l myor ntidd de )ujoF iD por el ontrrioD ls lturs di(erenD entones se sigue el riterio de prioridd y se seleion el ro on myor lturF ehor podemos de(nir otr lse de lgoritmoX Funciones para Net_Graph 725 + 765b 766 template <class Net> typename Net::Flow_Type priority_first_preflow_edge_maximum_flow (Net & net, const bool & leave_residual = false) { typedef DynSetTreap<typename Net::Node*> Active; typedef DynBinHeap<typename Net::Arc*, Compare_Arc<Net> > Prio_Queue; return generic_preflow_edge_maximum_flow <Net, Active, Prio_Queue> (net, leave_residual); }
Seleccin de arcos al azar

766

7. Grafos

766

pinlmenteD tmin podemos elegir l zrX Funciones para Net_Graph 725 + 765c 767 template <class Net> typename Net::Flow_Type random_first_preflow_edge_maximum_flow (Net & net, const bool & leave_residual = false) { typedef DynSetTreap<typename Net::Node*> Active; typedef Random_Set <typename Net::Arc*> Random_Queue; return generic_preflow_edge_maximum_flow <Net, Active, Random_Queue> (net, leave_residual); }
7.10.13.12 Conclusin sobre algoritmos de preujo

il estudio de heurstis de orden de proesmiento de nodos tivos es un mpo de investigin frtilF e ese tenor es importnte destr lguns vs de explorin pr el desurimiento de mejores lgoritmos o su dptin lses de prolems prtiulresF v primer v es l signin iniil de l funin de lturF in nuestro estudio slo hemos onsiderdo l distni hst el sumideroD pero podrmos pensr en otrosF or ejemploD podrmos priorizr que se lnen de primero quellos nodos uyos grdos de slid sen stntes grndes de modo que stos tengn l myor posiilidd de devenir intivos en su primer oservinY tmin podr onsiderrse l pidd totl de entrdD es deirD dr prioridd quellos nodos que en onjunto pueden envir y reiir myores )ujosF ytro mino de explorin lo onform el diseo de estrutur de dtos ltmente e(ientes pr mnejr los onjuntos de ros elegiles y nodos tivosF gomo vimosD el lgoritmo genrio orientdo hi ros @ UFIHFIQFII @gF UTIAA es ms mlele en unto l orden de explorin de l redD pero el lgoritmo desperdii unos untos ilos deido extriones de ros no elegilesF n estrutur de dtos que dems de insertr en O(1) tmin permit eliminr ros no elegiles luego de un inremento umentr l e(ieniF v terer vD por supuestoD onsiste en enontrr mejores lgoritmosF e ese tenorD un vrinte de empuje de pre)ujo se llm por loquesF v ide onsiste en seprr l red en loques @sugrfosA por donde se lleve el pre)ujoF or ejemploD el grfo ejemplr de l (gur UFUQ podrmos desomponerlo en los loques onformdos por {D, E, I, K}, {B, F, H} y {C, G, J, L}F ist ideD prte de que puede her ms rpido el luloD es nturlmente prlelizleD es deirD los loques pueden proesrse en prlelo por vrios proesdores segn el hrdwreF
7.10.14 Clculo del corte mnimo

l vez es momento de onversr sore pliiones onrets que nos hgn ms prenE siles los onoimientosF gonsideremosD por ejemploD el )ujo utomotor de un iuddF is ien posile otener un modelo uyo (n se mximizr el )ujo de utomviles durnte hors ritis entre un extremo fuente y otro sumideroF in ese sentidoD el )ujo mximo ser muy til pr diser un polti de direin de trnsitoX progrmin de los semforosD de desvosD de vigilni de vs rtisD etterD tendiente desongestionr

7.10. Redes de ujo

767

767

el tr(oF gon muho emrgoD en est vid postmodern se enuentrn numerossimos ejemplos en que pesr de onoer el )ujo mximo y de emprender orretmente poltiE s pr preservrloD el )ujo utomotriz es liennte pr l iuddnF in estos sos podr plnterse umentr l pidd vilF gules son los lugres de l iudd en donde dee umentrse l piddc v respuest omienz por el orte mnimoF in efetoD el orte mnimo represent un onjunto de ros que si se redujesen menosr el )ujo de l redF e trt de vs rtisD de lo que menudo llmmos uello de otellF ry muhs ms irunstnis de l postmodern vid rel en ls ules el prolem del )ujo mximo y su dul orte mnimo pueden ser de rti utiliddD desde un red de gu itdinD un red ferroviri o de trnsporte en perodos de fuerte demnd o un red de trnsmisin eltriF egresemos l sunto forml del orte mnimo trtdo en UFIHFT @gF UIVAF in quel entones desurimos onoimientoD prtiulrmente el estleido por el orolrio UFI @pgF UIWAD que nos permite (nr un lgoritmo de lulo de orte mnimoF in el mismo sentidoD l proposiin UFV @pgF UIWA nos ofree ertitud de que por l v del )ujo mximo podemos enontrr el orte mnimoF e efetos de prehender l importni lgortmi de quellos onoimientosD perE mitmosnos mirr un poo l omplejidd de enontrr fuerz rut el orte mnimoF fsimente tendrmos que determinr ls ominiones posiles de los onjuntos Vs y Vt junto on sus ros de rueF n lgoritmo sdo en este prinipio requerirD proE V 2 V 2 ominiones de Vs y Vt posilesF or d uno de ximdmenteD exminr i =0 i ellosD hr que reorrer los E ros pr determinr el orteF e requerirn entones V 2 V 2 E iterionesY ntidd omintorilmente explosiv e intrtle prtir i=0 i de esls medinsF eprehendemos pues que el estimdo sore los ros de rue que nos proporion el orolrio UFI @pgF UIWA nos redue muy signi(tivmente l di(ultd del prolemY st on onstruir el onjunto de ros sturdos o plenosD es deirD quellos uyo )ujo se igul su piddD y ulquier ominin entre estos ros uy sum se igul l mximo vlor de )ujo on ros de retroeso on )ujo ero es un orte mnimoF impero un on este onoimientoD el prolem sigue siendo lgo omplejoF uede simpli(rse el lulo del ortec v proposiin UFIH @pgF UPTAD nos segur que si no existe un mino de umentoD entones el )ujo es mximoF eroD qu suye trs este onoimiento que nos permit lulr rpid y ertermente el orte mnimoc v respuest puede plnterse omo orolrio de l proposiin UFIH @pgF UPTAX puesto que no existe mino de umentoD entones es imposile llegr l sumideroF or tntoD Vs es el onjunto de nodos lnzles desde s y Vt es V Vs F n simple reorrido en profundidd sore l red residul resultnte luego de mximizr el )ujoD nos puede desurir el onjunto Vs F e prtir del heho nterior podemos en un primer instni diser un funin de visit pr el reorrido en profundidd de l red residul que nos d l onjunto vs_ptr los nodos perteneientes Vs Funciones para Net_Graph 725 + 766 768c template <class Net> static bool add_vertex_to_vs(Net &, typename Net::Node * node, typename Net::Arc*) { ((Aleph::set<typename Net::Node*>*)vs_ptr)->insert(node); return false; // indica que debe seguir explorando }

768

7. Grafos

768a

vs_ptr es un puntero glol l onjunto Vs F he este modoD podemos plnter el lulo de Vs sX Calcular Vs 768a
vs_ptr = &vs; depth_first_traversal <Net, Res_F<Net> > (net, source, &add_vertex_to_vs);

(769)

768b

vuego del reorridoD vs ontiene todo el onjunto Vs F il onjunto Vt podr lulrse por inspein en Vs D pero un v ms expedit onsiste el mirr el it Depth_First que mr l llmd depth_first_traversal()Y si nodo no est mrdoD entones ste pertenee Vt F il lulo de Vt se plnte del siguiente modoX Calcular Vt 768b (769) const size_t size_vt = net.get_num_nodes() - vs.size(); for (Node_Iterator<Net> it(net); it.has_current() and vt.size() < size_vt; it.next()) { typename Net::Node * p = it.get_current(); if (not IS_NODE_VISITED(p, Aleph::Depth_First)) vt.insert(p); } vuego de onoidos vs y vt lo que flt es onoer los respetivos ros de rueF r eso reorremos todos los ros que no sen residules y seleionmos quellos que stisfE gn ls ondiiones del orolrio UFI @pgF UIWAF isto requiere (ltrr los ros residulesX Funciones para Net_Graph 725 + 767 769 template <class N> class No_Res_Arc { bool operator () (N&, typename N::Arc * a) const { return not a->is_residual; } }; gon este (ltro inspeionmos los ros de l red residul y proesmos quellos on f(e) = 0 y f(e) = cap(e)X Calcular arcos de cruce del corte mnimo 768d (769) for (Arc_Iterator<Net, No_Res_Arc<Net> > it(net); it.has_current(); it.next()) { typename Net::Arc * arc = it.get_current(); if (arc->flow == 0) // candidato a arco de retroceso? if (vt.count(net.get_src_node(arc)) > 0 and // de vt hacia vs? vs.count(net.get_tgt_node(arc)) > 0) { cutt.insert(arc); continue; } if (arc->flow == arc->cap) // candidato a arco de cruce? if (vs.count(net.get_src_node(arc)) > 0 and // de vs hacia vt? vt.count(net.get_tgt_node(arc)) > 0) cuts.insert(arc); }

768c

768d

7.10. Redes de ujo

769

769

vos loques desrrolldos se juntn seuenilmente pr her el lulo del orte mnimoX Funciones para Net_Graph 725 + 768c 770a template <class Net, template <class> class Maxflow> typename Net::Flow_Type min_cut(Net & net, Aleph::set<typename Net::Node*> & vs, Aleph::set<typename Net::Node*> & vt, DynDlist<typename Net::Arc *> & cuts, DynDlist<typename Net::Arc *> & cutt, const bool leave_residual = false) { Maxflow <Net> () (net, true); // calcula flujo mximo y red residual
typename Net::Node * source = net.get_source();

Calcular Vs Calcular Vt

768a 768b

Calcular arcos de cruce del corte mnimo 768d


if (not leave_residual) { net.unmake_residual_net(); net.unmake_super_nodes(); } return source->out_flow;
DynDlist
85a.

}
Uses

min_cut() prmetriz el tipo de red l ul se le dese lulr el )ujo mximo y el orte mnimo y el lgoritmo de lulo de )ujo mximo que se dese emplerF vos prmetros de l funin son l red netD el onjunto Vs vsD el onjunto Vt vtD el onjunto de ros < Vs , Vt > cuts y el onjunto de ros < Vs , Vt > cuttF
D 4/1 E 1/1 I 4/1 K

6/1

3/3

4/0

3/3

3/0

4/0

3/0

4/1

3/3 A 7/3 B 1/0 F 4/4 H 5/4 M

5/3

5/0

3/3

5/0

7/2

3/3

4/0

6/5

4/0

6/0

5/2

pigur UFWIX n orte mnimo sore un red pitdF vos ros perteneientes < Vs , Vt > son resltdosD mientrs que los perteneientes < Vs , Vt > en lne ortdF

7.10.15

Aumento o disminucin de ujo de una red

in ls redes reles no siempre se requiere mximizr el )ujoF hentro de ls irunstnis es posileD omo requerimientoD un juste del )ujo un vlor ddoF

770

7. Grafos

770a

gonsideremos un )ujo de petrleo por un red de oleodutos que omprende desde los pozos hst los tnques llenderosF xos interes est lse de )ujo porque no se dee detener29 F in este soD segn l demnd en los llenderosD puede ser neesrio mntener el )ujo un vlor espe(oF gmo inrementr o derementr el )ujo en un vlor ddoc in est situin or muho sentido l ide de mino de umentoD pues su esln mnimo determin un ot de inremento @o derementoA del )ujo por el mino en uestinF emosD por l proposiin UFW @gF UPPAD que si tenemos un mino de umento Ca on mnimo esln es Ca D entones el )ujo puede umentrse en un vlor x Ca F r inrementr o derementr el )ujo en un vlor x deemos enontrr un mino on esln mnimo Ca xF inontrr un mino de umento ondiiondo que su esln mnimo se myor o igul un x es senillo si emplemos un (ltro pr el iterdor sore los ros que ignore los ros uyo )ujo restnte es menor que xF r eso de(nimos l siguiente lse (ltro del iterdor de rosX Funciones para Net_Graph 725 + 769 770b template <class N> class Flow_Filter { static typename N::Flow_Type min; typename N::Arc * operator () (typename N::Node *, typename N::Arc * arc) { return arc->cap - arc->flow >= min ? arc : NULL; } }; v lse Flow_Filter<N> (ltr ros uyo )ujo restnte es menor que el vlor de min30 F he este modo podemos progrmr l squed de un mino de umentoD on umrl minD de l siguiente mnerX Funciones para Net_Graph 725 + 770a 771a template <class Net, template <class, class> class Find_Path> bool find_aumenting_path(Net & net, Path<Net> & path, const typename Net::Flow_Type & min_slack) { Flow_Filter<Net>::min = min_slack; typename Net::Node * src = net.get_source(); typename Net::Node * sink = net.get_sink();
if (not net.residual_net) net.make_residual_net(); }
Uses

770b

return Find_Path<Net, Flow_Filter<Net> > () (net, src, sink, path);


Path
578a.

find_aumenting_path() us un mino de umento on esln mnimo su(iente pr umentr el )ujo en el vlor min_slackF il tipo de squed @en profundidd o en
29 30
El petrleo, cuando se encuentra inmvil, tiende a solidicarse. Un problema del diseo de esta clase es que no es reentrante. Durante el tiempo en que un algo-

ritmo est empleando

Flow_Filter,

la variable

min

no puede ser utilizada. Futuras versiones de

manejarn este parmetro de forma reentrante.

ALEPH

7.10. Redes de ujo

771

mplitudA es un prmetro tipo de l rutinF i el mino existeD entones l rutin retorn trueY de lo ontrrioD retorn falseF
D 4/0 E 8/0 I 4/0 K D 4/0 E 8/0 I 4/0 K

6/0

3/0

4/0

5/0

3/0

4/0

3/0

4/0

6/0

3/0

4/0

5/0

3/0

4/0

3/0

4/0

7/0

6/0

4/0

5/0

7/3

6/3

4/0

5/0

5/1

5/0

3/1

5/0

7/1

6/0

4/0

6/1

5/1

5/0

3/1

5/0

7/4

6/0

4/0

6/4

4/0

6/0

5/1

4/0

6/0

5/4

(a)
D

slack = 1
4/0 E 8/0

(profundidad)
I 4/0 K D

(b)

slack = 3
4/4 E 8/0

(profundidad)
I 4/0 K

6/0

3/0

4/0

5/0

3/0

4/0

3/0

4/0

6/4

3/0

4/0

5/4

3/0

4/0

3/0

4/0

7/3

6/3

4/0

5/0

7/3

6/3

4/4

5/4

5/3

5/0

3/3

5/0

7/4

6/2

4/0

6/6

5/3

5/0

3/3

5/0

7/4

6/2

4/0

6/6

4/0

6/0

5/4

4/0

6/0

5/4

(c)

slack = 2

(amplitud)

(d)

slack = 4

(amplitud)

pigur UFWPX snrementos suesivos del )ujo medinte minos de umento enontrdos por find_aumenting_path() u suede si se dese enontrr un mino de desEumentocD o seD uno por el ulD en lugr de umentr el )ujo en un vlor ddoD se disminuyF v tni es similrD on l sutil difereni de que l squed dee herse desde el sumidero hi el fuenteX Funciones para Net_Graph 725 + 770b 771b template <class Net, template <class, class> class Find_Path> bool find_decrementing_path(Net & net, Path<Net> & path, const typename Net::Flow_Type & min_slack) { Flow_Filter<Net>::min = min_slack; typename Net::Node * src = net.get_source(); typename Net::Node * sink = net.get_sink();
if (not net.residual_net) net.make_residual_net(); }
Uses

771a

return Find_Path<Net, Flow_Filter<Net> > () (net, sink, src, path);


Path
578a.

r inrementr el )ujo se emple un vrinte de l rutin increase_flow()D desrE rolld en UFIHFIH @gF UPSAD on un prmetro diionl valF i se deseD por ejemploD umentr el )ujo en un vlor val trvs de un mino de umentoD entones se invo increase_flow(net, path, val)D l ul inrement el )ujo en val y no en el esln mnimo de pathF enlogmenteD otr rutinD llmd decrease_flow()D he el trjo inversoD o seD derementr el )ujo en un vlor valF
771b

Funciones para Net_Graph 725 +


template <class Net>

771a

772

7. Grafos

void increase_flow(Net & net, Path<Net> & path, const typename Net::Flow_Type & val) { // aumentar flujo de red por el camino de aumento for (typename Path<Net>::Iterator it(path); it.has_current_arc(); it.next()) { typename Net::Arc * arc = it.get_current_arc(); typename Net::Arc * img = (typename Net::Arc *) arc->img_arc; if (arc->cap - arc->flow < val) // ERROR! arc->flow += val; img->flow -= val; if (not arc->is_residual) { net.increase_out_flow(net.get_src_node(arc), val); net.increase_in_flow(net.get_tgt_node(arc), val); } else { net.decrease_in_flow(net.get_src_node(arc), val); net.decrease_out_flow(net.get_tgt_node(arc), val); }

template <class Net> void decrease_flow(Net & net, Path<Net> & path, const typename Net::Flow_Type & val) { // decrementar flujo de red por camino de decremento for (typename Path<Net>::Iterator it(path); it.has_current_arc(); it.next()) { typename Net::Arc * arc = it.get_current_arc(); typename Net::Arc * img = (typename Net::Arc *) arc->img_arc; if (arc->cap - arc->flow < val) // ERROR ! arc->flow -= val; img->flow += val; if (not arc->is_residual) { net.decrease_out_flow(get_src_node(arc), val); net.decrease_in_flow(net.get_tgt_node(arc), val); } else { net.increase_out_flow(get_tgt_node(arc), val); net.increase_in_flow(net.get_src_node(arc), val); }

7.11. Reducciones al problema del ujo mximo

773

}
Uses

Path

578a.

is importnte menionr que l rutin no veri( que se trte estritmente de un mino de umentoF isto ofree l posiilidd de inrementr el )ujo por un mino que no neesrimente prt desde el fuente y llegue l sumideroF hel mismo modoD el mino puede ser un iloD lo que orr inters ms delnte undo estudiemos iruliones @ UFIIFS @gF UVQAA y )ujos mximos de oste mnimo @ UFIP @gF UWPAAF

7.11 Reducciones al problema del ujo mximo


in l sein psd estudimos un serie de lgoritmos y estrutur de dtos tendientes resolver el prolem del )ujo mximoF esult que este prolem queD dirmosD no nos fue muy simple de resolverD es fundmento de modelizin e instrumento de soluin de un vst ntidd de prolems msF in est sein menionremos lguns situiones del mundo tenolgio en que el )ujo mximo es plileD enuniremos vrintes de prolems reduiles l )ujo mximo y estudiremos on lgn grdo de detlle lgunos de ellosF v litertur menion omo primer vrinte el mnejo de vrios fuentes y sumiderosF iste prolem fue estudido y resuelto en UFIHFQ @gF UIIAF in ules ontextos puede preerc in los ontextos ulturlesD por deirlo de lgun mnerD es muy prole que l red teng vrios fuentes y sumiderosD s que por est v nos resultn prtis ls primitivs make_super_nodes() y unmake_super_nodes() presentds en UFIHFQ @gF UIIAF
7.11.1 Flujo mximo en redes no dirigidas

v ide de un lquido que )uye por un red de tuers no sume el sentidoF he hehoD por un tuo puede irulr )uido en ulquier sentidoF es puesD est dentro de ls expettivs del mundo tenolgio enontrr situiones en ls ules se desee mximizr el )ujo y onoer sus tuers rtisY o seD el orte mnimoF in situiones de este tipo tendrmos ros por los ules es permisile el )ujo en mos sentidosF n red no dirigid G =< V, E, C >D on pesos interpretles omo piddesD tiene un equivlente dirigido direto < V, E , C >X por d ro (u, v) = e E de pidd cap(e) existen dos ros eu = (u, v) E y ev = (v, u) E mos on pidd cap(eu ) = cap(ev ) = cap(e)F
B D B D

(a) Red no dirigida

(b) Equivalente dirigido con fuente y sumidero

pigur UFWQX iquivleni entre un red no dirigid y un red

774

7. Grafos

n efeto prente de l trnsformin nterior es que l red no tiene fuente ni suE mideroF in un red de tuersD este podr preer ser el soF or ejemploD onsideremos un sistem de refrigerin en el ul es menester mximizr el )ujo de lquido refrigerE nteD un sistem de ire ondiiondo o de lefin por itr ourrenis prtiulresF in tod lse de sistems de )ujo se requiere omer el )uido desde l menos un tuo iniilF r que el )uido se ontinuo se requiere errr el lzo de omeoF epreen pues el fuente y el sumideroF v (gur UFWQ ilustr un red no dirigid y su equivlente en red pitd on un fuente s desde donde se envir un )ujo iniilD y un sumidero por donde se reoger el )ujo pr omerlo de nuevoF vos vlores de piddes de los ros desde el fuente y hi el sumidero deen orresponderse on l pidd de )ujo disponileD l ul puede ser myor que el vlor de )ujo mximo que puede irulr por l redF v vlidez mtemti del equivlente es fil de demostrrF gulquier )ujo irulnte por l red no dirigid puede perfetmente irulr por l red equivlenteY en ese so uno de los dos ros en l red dirigid tiene vlor de )ujo eroF hevolverse de l red l grfo no es prolemtioF upongmos ulquier pr de ros u v y v u on vlores de )ujo f(u v) y f(v u) respetivmenteF i f(u v) > f(v u)D entones f(u v) = f(u v) f(v u) y el )uido v en el sentido u vY de lo ontrrioD f(u v) = f(v u) f(u v) y el )uido v en el sentido v uF uesto que ests reduiones son ftiles medinte ls interfes de los eh List_Graph y Net_GraphD sts son delegds en ejeriiosF
7.11.2 Capacidades en nodos

n situin tenolgimente esperleD pero tmin til pr lguns situiones de modelizinD es el onsiderr piddes en los nodosF in este soD un vlor de piE dd de nodo indi un )ujo mximo que ste puede reiirF v (gur UFWRE muestr un ejemploF n red on piddes en los nodos puede trnsformse un red trdiionl medinte el mtodo siguienteF
Algoritmo 7.7 Conversin de una red con capacidades en los nodos a una red tradicional

v entrd es un red G =< V, E, C, s, t > on piddes en los nodosF v slid es un red trdiionl N G =< V , E , C , s, t >F | u ,u V F

IF u V prtiione en dos nodos u y u

or d prtiinD d E un ro u u E on pidd cap(u u ) = cap(u)F

PF e = (u v) E se orresponde on e = (u v ) E F v (gur UFWRE muestr el equivlente segn el mtodo l red de l (gur UFWREF v iliote ontiene un implementin de este esquem llmdD Net_Cap_GraphD ontenid en el rhivo tpl_netcapgrah.HF
7.11.3 Flujo factible

in lguns irunstnis se requieren provisiones de )ujoY es deirD lgunos nodos de l red requieren reiir un ntidd espe( de )ujoF is posile tmin que otros nodos

7.11. Reducciones al problema del ujo mximo

775

B 3 B,4 3 A,8 5 C,3 3 2 4 4 D,3 1 2 F,5 C 3 E,4 5 2 4 G,6 5 A

E 5

4 3 3

2 D 1 2 4 G 6 G

D 2

(a) Red con capacidades en los nodos

(b) Red capacitada equivalente

pigur UFWRX ijemplo de un red on pidd en los nodos y su equivlente un red trdiionl proven )ujoF upongmos por ejemplo un red de trnsporte vil y l relizin de evento exepionlD tl omo unos juegos deportivosD que mie ls demndsF gomo l red vil sigue siendo l mismD l topolog de l red no miD pero el inters de sisteni y dispersin geogr( de los lugres de ls ompetiiones trnsform ls demndsF in situiones de este tipo suele umentrse l pidd de trnsporte tryendoD por ejemploD uses diionlesF ituiones omo l que mos de desriir pueden modelizrse poniendo sore los nodos vlores de demnd y de provisinF n vlor positivo indi que el nodo puede suplir en )ujo el vlor en uestinY un vlor negtivo signi( un demnd de )ujoD es deirD en el nodo en uestin se requiere reiir el )ujo demnddoF e est lse de red se le llm red pitd on provisin de )ujoF

8 8 B 20 B,-8 F,8 K,8 L F 10 K

P 19

A,20

C,-6

E,10

L,4

P,-19 8

D 6 4

G 8

D,-4

G,-8

M,5

(a) Red de demanda/provisin

(b) Red Capacitada equivalente

pigur UFWSX ijemplo de equivleni entre red de demndGprovisin y un red piE tdF e omiten ls piddes de los ros en l red originl y en l equivlenteY est ltim muestr piddes equivlentes provisiones wodelos de est lse no son pr nd exepionlesF in ests irunstnisD l pregunt de inters es verigur si se puede o no stisfer ls demnds en funin de ls posiiliddes de provisinF n respuest negtivD mostrtivD indiir que hy que enontrr ms provisinD mientrs que un (rmtiv nos dir que on l provisin e infrestrutur dds se pueden stisfer ls demndsF i l respuest es (rmtivD

776

7. Grafos

entones deimos que existe un )ujo ftileD pues todos los nodos de demnd pueden otener su )ujo requeridoY de lo ontrrio deimos que el )ujo no es ftileF gmo ser si existe un )ujo ftilec in sorpresD l respuest nos l d el lulo del )ujo mximo sore un red equivlenteF in prinipio podemos lulr el )ujo mximo y luego veri(r si ste stisfe ls provisiones ddsF in emrgoD si enontrmos nodos on flls de provisionesD prtiulrmente en demndsD no podemos onluir que no existe otro )ujo menor que se ftileF v soluin es trnsformr l red un equivlente y sore ell lulr el )ujo mximoF n red pitd on provisin de )ujo tiene un equivlente en un red pitdF v equivleni requiere dir un suprfuente y un suprsumideroF hesde el suprfuente emnn ros hi los nodos proveedores on pidd igul l vlor de provisinF ri el suprsumidero iniden ros desde los nodos demndntes on pidd igul l )ujo demnddoF in l red equivlente no es neesrio olor vlores de provisinD pues stos estn expresdos en ls piddes de los ros entre suprfuente y el suprsumidero respetivmenteF
-6 D 6/0 0 E 8/0 -4 I 4/0 0 K -6 D 6/6 0 E 8/4 -4 I 4/4 0 K

6/6

3/3

4/0

5/3

3/0

4/0

3/0

4/0

6/6

3/3

4/0

5/5

3/0

4/0

3/0

4/4

0 A 7/1

0 B 1/1

-5 F 1/0

0 H 5/0

-15 M

0 A 7/1

0 B 1/1

-5 F 1/1

0 H 5/3

-15 M

5/3

5/0

3/3

5/2

7/0

6/0

4/0

6/0

5/3

5/0

3/3

5/0

7/2

6/6

4/2

6/6

0 C 4/0

-4 G 6/0

0 J 5/0

-3 L

0 C 4/0

-4 G 6/0

0 J 5/2

-3 L

(a) Flujo mximo sobre red extendida


-6 D 6/3 0 E 8/7 -4 I 4/3 0 K -6 D 6/6 0 E 8/4 -4 I 4/4

(b) Flujo mximo


0 K

9/9

9/9

4/0

5/5

3/0

4/0

3/0

4/3

9/6

9/5

4/2

5/5

3/0

4/0

3/0

4/4

0 A 7/7

0 B 8/7

-5 F 1/0

0 H 5/0

-15 M

0 A 7/3

0 B 8/4

-5 F 1/1

0 H 5/5

-15 M

5/3

5/0

11/5

5/5

7/1

6/6

4/0

6/3

5/1

5/1

11/6

5/4

7/5

6/5

4/4

6/6

0 C 4/2

-4 G 6/1

0 J 5/0

-3 L

0 C 4/4

-4 G 6/0

0 J 5/5

-3 L

(c) Flujo mximo sobre red extendida

(d) Flujo mximo

pigur UFWTX hos ejemplos de )ujo ftile sore demndsF v (gur @A muestr un )ujo mximo on orte mnimo sore l red extendid que no stisfe ls provisionesY luego en l (gur @AD el )ujo mximo l red que muestr un )ujo mximo instisftorioF hel nlisis del orte mnimo se inrementn piddes en los ros del orteD lo ul ondue un )ujo ftileD tnto en l red extendid mostrd en l (gur @A omo en l red simple mostrd en l (gur @dA n red on provisin de )ujo es ftile si el )ujo mximo de l red equivlente logr llenr todos los ros didosD es deirD los que emnn desde el suprfuente y lo que llegn l suprsumideroF in lgunos sos es posile ser que el )ujo no es ftile si l pidd sliente del suprfuente es distint l entrnte por el suprsumideroF isto es deido l ondiin de onservin del )ujo y es el so pr l red ejemplo de l (gur UFWSED l ulD pr l red equivlente de l (gur UFWSE tiene un pidd sliente del suprfuente de 55 mientrs que l entrnte l suprsumidero es de 45F iste onoimiento

7.11. Reducciones al problema del ujo mximo

777

es visile desde l red originl en el sentido de que pr que el )ujo se ftileD el totl de provisin tiene que ser myor o igul l demndD pero lo ontrrio no neesrimente es iertoY por esoD si l provisin es myor o igul l demndD entones es neesrio lulr el )ujo mximo sore l red equivlente pr responder si el )ujo es o no ftileF in un situin de )ujo no ftileD el orte mnimo nos identi( otros puntos por donde puede umentrse l provisin oD en su imposiiliddD reduirse o redireionrse l demndF e tenor del )ujo ftileD en l iliote se instrument el Net_Sup_Dem_NodeD esE pei(do en el rhivo tpl_net_sup_dem.HF in emrgoD vees es preferile plir l tni en el ontexto del prolem en lugr de empler este ehF
7.11.4 Mximo emparejamiento bipartido

gonsideremos n persons y n tipos de trjosF r d person se tiene un list de posiles trjos oD nlogmenteD por d trjo se tiene un list de persons que pueden herloF ixiste un signin de persons trjos que ur todos los trjos y personsc i existeD ul escY si no existeD ul es l signin que ure l myor ntidd de persons o trjosc iste prolemD trdiionlmente onoido omo el de signinD onstituye l vE rinte ms simple de un fmili de prolems ms generl que trtremos ms delnteF or los momentosD es menester introduir lguns de(niiones formlesF
L R

(a) Un emparejamiento no bipartido

(b)

Un

empare-

jamiento bipartido

pigur UFWUX ijemplos de emprejmientoF vos ros del emprejmiento son resltdos
Denicin 7.20 (Emparejamiento) hdo un grfo G =< V, E >D un emprejmiento es un suonjunto de ros M E tl que no existen dos ros en M que inidn sore un nodo omnF n emparejamiento es de cardinalidad mxima si |M| es mximoD es deirD si inluye l myor ntidd de rosF n emparejamiento es bipartido si el grfo es iprtidoF n emparejamiento es perfecto si inluye todos los nodos del grfoF gundo tenemos un grfo on pesosD un emparejamiento es mximo si l sum de los pesos de los ros de M es mximF imtrimenteD es mnimo si l sum es mnimF

778

7. Grafos

esignr n persons n trjos puede resolverse medinte un grfo iprtido que modelie ls reliones entre ls persons y los posiles trjos tl omo el mostrdo en l (gur UFWUEF il emprejmiento de rdinlidd mxim nos proporion l signin que ms ure persons y trjosF uesto que tr ndidmente el prolem de l signinD o seD explorr tods ls ominiones posiles de emprejmientoD deviene intrtleD quiz est se l primer situin en l que podmos preir el potenil de l teor de redes de )ujo pr l resoluin de prolems sore grfosF n grfo iprtido sore el ul desemos enontrr un emprejmiento de rdinlidd mxim puede modelizrse medinte un red de )ujoF qrosso modoD el proedimiento es el siguienteF
Algoritmo 7.8 (Transformacin de un grafo bipartido a una red de ujo)

intrdX un grfo iprtido G =< V, E > | V = L R yL R = @L y R son los onjuntos de l iprtiinAF lidX un red pitd G =< V , E , C, s, t > equivlente sore l ul puede lulrse un emprejmiento de rdinlidd mximF IF V = V {s} {t}F PF e = (u, v) E = E = E {(u, v)} | cap(e) = 1F QF u L = E = E {(s, u)} | cap((s, u)) = 1F RF u R = E = E {(u, t)} | cap((u, t)) = 1F v (gur UFWV ilustr el resultdo (nl de ejeuin de este lgoritmo sore el gro de l (gur UFWUEF

pigur UFWVX qrfo dirigido equivlente l de l (gur UFWUE

7.11.4.1

Flujo mximo y emparejamiento bipartido

v trnsformin nterior nos ofree un red pitd uyo )ujo mximo nos muestr en sus ros sturdos un emprejmiento de rdinlidd mximF odos los ros de l trnsformin tienen pidd 1F odo nodo en L tiene E pidd de entrd 1 y pidd de slid igul l nmero de ros que se onetn on RF imtrimenteD todo nodo en R tiene pidd de entrd igul l nmero de ros de entrd y pidd de slid 1F glrmenteD el mximo )ujo de est red es

7.11. Reducciones al problema del ujo mximo

779

igul |L| |R|D o seD l nmero de ros de slid del fuente o el de entrd del suE mideroF n mino de umento ulquierD uyo esln mnimo siempre es 1D desure un signin (u, v) | u L, v RF gundo el mino de umento se inrementD los nodos u y v quedn inonexos en l red residulF il nodo u es inesile desde el fuente s y t es inesile desde vF gonseuentementeD ulquier prximo mino de umento no ontendr u ni vF n vez que no existen ms minos de umentoD el )ujo es mximo @proposiin UFIH @gF UPTAAF uesto que el )ujo es mximo y los ros tienen piddes unitrisD l ntidd de ros on )ujo unitrio que vn desde L hi R es mximF il emprejmiento de rdinlidd mxim est ddo por quellos ros entre L y R uyo )ujo se unitrioF
7.11.4.2 Anlisis del emparejamiento bipartido por ujo mximo

v durin del lulo del emprejmiento iprtido es l sum de duriones del lgoE ritmo UFVD luegoD l mximizin del )ujo yD (nlmenteD el reonoimiento de los ros que perteneen l emprejmientoF eplir el lgoritmo UFV sore un grfo iprtido pr otener l red equivlente sore l ul mximizr el )ujo tom O(E) psosY l mism omplejidd se requiere pr reonoer los ros del emprejmiento luego de mximizdo el )ujoF in unto l durin de l mximizin de )ujo deemos oservr que ls durE iones de los lgoritmos estudidos fueron deduids pr los peores sosD onsiderndo topologs ritrrisD lo ul no es l situin de un grfo iprtidoD menos n l de l red equivlenteF uesto que l red trnsformd slo tiene piddes unitrisD ulquier mino de umento y su inremento ort un ro de slid del fuente y uno del sumideroY qu el lgoritmo de pordEpulkerson no tiene el prolem de l integridd de ls piddesF or tntoD l mxim ntidd de minos de umento se present undo l ntidd de ros desde el fuente y hi el sumidero es mximF l ntidd es V/2F wximizr el )ujo de l red trnsformd tom V 2 O (E) = O (VE) psos de ejeuinF
7.11.4.3 Clculo de la biparticin

i tenemos un grfo G iprtidoD un pso esenil pr l instrumentin de nuestro lgoE ritmo es lulr l iprtiinF gomo este prolem puede verse por seprdoD meree un trtmiento generl que lo desrrollremos en el rhivo de l iliote tpl_bipartite.HD el ul ontiene rutins utilitris onernientes grfos iprtidosD espe(mente l prue de iprtiin test_bipartite() y su lulo compute_bipartite()F ry vris mners de veri(r el rter iprtido de un grfoF i un grfo es iprE tidoD entones ste no tiene ningn ilo de longitud imprF r demostrrlo onsideremos un ilo de longitud imprF elgo s omo u1 u2 u3 u4 u5 u1 F i seguimos el ilo y lterntivmente signmos ls prtiiones podemos her L = {u1 , u3 , u5 } e R = {u2 , u4 }D pero el ro u5 u1 rompe l iprtiinF sgul ourre si omenzmos desde ulquier otro nodo del iloF i generlizmos este ontrejemplo pr ulquier longitud impr nos enontrmos on l mism ontrdiinF ytr form menos lr pero omputionlmente ms e(ienteD es veri(r si el grfo es ioloreleD es deirD si puede pintrse on slo dos olores sin que el mismo olor

780

7. Grafos

780

olindeF il siguiente lgoritmo utiliz el oloredo pr onstruir l iprtiinX Rutinas para grafos bipartidos 780 782b template <class GT, class SA = Default_Show_Arc<GT> > void compute_bipartite(GT & g, DynDlist<typename GT::Node *> & l, DynDlist<typename GT::Node *> & r) { DynDlist<typename GT::Node *> red, blue; typename GT::Node * p = g.get_first_node(); color<GT>(p) = Bp_Red; red.put(p); l.put(p);
while (true) if (not red.is_empty()) // Hay rojo con arcos no mirados? { typename GT::Node * p = red.get(); for (Node_Arc_Iterator<GT, SA> it(p); it.has_current(); it.next()) { typename GT::Arc * a = it.get_current(); if (color<GT>(a) == Bp_Red) throw std::domain_error("Graph is not bipartite"); else if (color<GT>(a) == Bp_Blue) continue; color<GT>(a) = Bp_Red; typename GT::Node * q = it.get_tgt_node(); if (color<GT>(q) == Bp_Red) throw std::domain_error("Graph is not bipartite"); else if (color<GT>(q) == Bp_Blue) continue; color<GT>(q) = Bp_Blue; blue.put(q); r.put(q);

} else if (not blue.is_empty()) // Hay azul con arcos no mirados? { typename GT::Node * p = blue.get(); for (Node_Arc_Iterator<GT, SA> it(p); it.has_current(); it.next()) { typename GT::Arc * a = it.get_current(); if (color<GT>(a) == Bp_Blue) throw std::domain_error("Graph is not bipartite"); else if (color<GT>(a) == Bp_Red) continue; color<GT>(a) = Bp_Blue; typename GT::Node * q = it.get_tgt_node(); if (color<GT>(q) == Bp_Blue) throw std::domain_error("Graph is not bipartite");

7.11. Reducciones al problema del ujo mximo

781

else if (color<GT>(q) == Bp_Red) continue; color<GT>(q) = Bp_Red; red.put(q); l.put(q);

}
Uses

} } else break;
DynDlist

85a.

v rutin dispr l exepin std::domain_error si el grfo no es iprtidoF i lo esD entones se retornn en ls lists l y r los nodos que onformn l prtiinF
7.11.4.4 Construccin de la red bipartita

781a

gon los onjuntos de l iprtiin y tenemos l pidd pr lulr un red equivE lente mped l grfoF vlmemos g el grfo iprtido y net l red uxilir que desemos trnsformrD l ul se espei( de l siguiente mnerX Construir red equivalente 781a (782b) 781b typedef Net_Graph<Net_Node<Empty_Class>, Net_Arc<Empty_Class> > AN; AN net; il lulo de net se he entones del siguiente modoX Construir red equivalente 781a + (782b) // recorrer nodos de g e insertar imagen en net for (Node_Iterator<GT> it(g); it.has_current(); it.next()) { typename GT::Node * p = it.get_current(); NODE_COOKIE(p) = net.insert_node(); NODE_COOKIE((typename GT::Node *)NODE_COOKIE(p)) = p; }
typename AN::Node * source = net.insert_node(); // recorrer nodos de l, atarlos a fuente e insertar sus arcos for (typename DynDlist<typename GT::Node*>::Iterator i(l); i.has_current(); i.next()) { typename GT::Node * p = i.get_current(); typename AN::Node * src = mapped_node<GT, AN> (p); net.insert_arc(source, src, 1); for (Node_Arc_Iterator<GT, SA> j(p); j.has_current(); j.next()) { typename GT::Arc * arc = j.get_current_arc(); typename AN::Node * tgt = mapped_node <GT, AN> (g.get_tgt_node(arc)); typename AN::Arc * a = net.insert_arc(src, tgt, 1); ARC_COOKIE(arc) = a; ARC_COOKIE(a) = arc; }
781a

781b

782

7. Grafos

typename AN::Node * sink = net.insert_node(); // recorrer nodos de r y atarlos al sumidero for (typename DynDlist<typename GT::Node*>::Iterator it(r); it.has_current(); it.next()) { typename GT::Node * p = it.get_current(); net.insert_arc(mapped_node<GT, AN> (p), sink, 1); }
Uses

DynDlist

85a and

mapped_node

560b.

7.11.4.5

Extraccin del emparejamiento de la red maximizada

782a

i matching es l list de ros que onformn el emprejmientoD su determinin se efet medinte inspein de l red uxilir net en squed de los ros sturdosY su imgen en el grfo g pertenee l emprejmientoF Extraer de net los arcos saturados 782a (782b) for (Arc_Iterator<AN> it(net); it.has_current(); it.next()) { typename AN::Arc * a = it.get_current(); if (a->flow == 0) continue;
typename GT::Arc * arc = mapped_arc <GT> (a); if (arc == NULL) continue; } matching.append(arc);

7.11.4.6

Implantacin nal del emparejamiento de cardinalidad mxima

782b

gon los loques nteriores se onform el lgoritmo (nlX Rutinas para grafos bipartidos 780 + 780 template <class GT, template <class> class Max_Flow = Ford_Fulkerson_Maximum_Flow, class SA = Default_Show_Arc<GT> > void compute_maximum_cardinality_bipartite_matching (GT & g, DynDlist<typename GT::Arc *> & matching) { DynDlist<typename GT::Node *> l, r;
compute_bipartite(g, l, r);

Construir red equivalente 781a


Max_Flow <AN> () (net); }

Extraer de net los arcos saturados 782a

7.11. Reducciones al problema del ujo mximo

783

Uses

DynDlist

85a.

7.11.5

Circulaciones

uede oneirse un red sin fuentes ni sumiderosc gonsideremos un red trdiionl N =< V, E, C, s, t > y un liger modi(in sore ell onsistente en dir un ro on pidd igul max(cap(OUT(s)), cap(IN(t)))F v ide generl es pitorizd en l (gur UFWW y evideni queD l menos en este so genrioD es oneile un red sin fuentes ni sumideros reduile un on un fuente y un sumideroF
t s

Nodos internos

Arco que hace el ciclo

pigur UFWWX higrm generl de un irulin e un )ujo por un red sin fuentes ni sumideros se le llm circulacin D pues legoriz un situin en l ul ni entr ni sle )ujo de l redY simplementeD posiilitdo por lgun extr ineri31 D o efetos del modeloD el )uido irul estlemente por l red sin neesidd de espei(r un entrd y slid de )ujoF xotemos que un irulin rre l menos un ilo en un grfo dirigidoD situin que explitmente no hemos estudido hst el presenteF vos lgoritmos de mximizin de )ujo presentdos opern sore redes que pueden ontener ilos internosD pero on un slo fuente y un sumideroF is en generl un red sin fuentes ni sumideros reduile un red trdiionlc v respuest es (rmtivD ulquier red pitd vlidD sin fuente ni sumideroD puede reduirse un red on un fuente y un sumidero y sore est ltim plir los lgoritmos estudidosF
B 4/4 2/1 3/2 A 5/2 2/1 3/3 5/3 C 6/5 D 3/3 G 2/1 H 4/4 E 3/3 F 5/4

pigur UFIHHX n irulin n ilo puede reduirse un sured on un fuente y un sumideroD simplemente on ortr el ilo y sumir sus extremos omo fuentes y sumiderosF v red se desompone desde los ilos ms simplesD que no tienen nodos omunesD hi los ms omplidosD que tienen nodos omunes on otros ilosF il grdo de slid de d nodo rroj un primer proximinD pero hy otr mtriD que presentremos prontmenteD que ofree mejor informin er de l onetividd del grfo y que se llm onetividd en rosF il lgoritmo de onversin generl es delegdo en ejeriioF
31
Fsicamente es concebible mantener una circulacin por la mera inercia, pero en el mundo real es improbable.

784

7. Grafos

n speto interesnte de un irulin es que su vlor de )ujo puede representrse omo un onjunto de )ujos irulntes por sus ilosF or ejemploD l irulin de l (gur UFIHH puede expresrse medinte los siguientes ilosX
gilo
ABEA ABEFHGDCA ABEFHDCA ABEDCA CEDC DFHD DFHGD

lor de )ujo I I I I P I I

v interpretin nterior de un )ujo evideni queD pr un red sin fuentes ni suE miderosD el )ujo mximo se redue enontrr un irulin que mximie el )ujo en d roF odemos sin prolem umentr el )ujo de l red desurindole ilosD lE ulndoles su pidd restnte mnim y umentndo el )ujo en este vlor lo lrgo de todo el iloF v tl de ilos nterior nos evideni el sentido de irulinF in efetoD d ilo es un irulinF in el so de l tl enontrmos 7 irulionesF xotemos que si tuvisemos un red on un fuente y un sumideroD tr un ro desde el sumidero hi el fuente nos d tnts iruliones omo minos distintos existn desde el fuente hi el sumideroF il vlor de )ujo de l red puede expresrse omo un sum de ilos y )ujosF ero l mism red y su vlor de )ujo tmin pueden representrse omo un omposiin de ilos y )ujoD tl omo evideni l proposiin siguienteF
Proposicin 7.16 (Descomposicin de ujo) Demostracin

gulquier irulin puede represenE trse omo un )ujo entre un onjunto de lo ms |E| ilos distintosF gonsideremos el siguiente lgoritmo de desomposiinX

Algoritmo 7.9 (Descomposicin de una circulacin en ciclos)

IF e E = el onjunto de ilos que desomponen l irulinF E ontiene elementos de l form (e , )D donde e es un ilo y el vlor de )ujo que irul por el iloF PF while existn ros sore N @A inuentre un ilo e F @A hetermine el esln mnimo del ilo F @dA e e = f(e) = f(e) F @A E = E {(e , )}

@eA ilimine de N @o del iloA todos los ros on )ujo eroF

n ejemplo de ejeuin de este lgoritmo es evidenido en l (gur UFIHIF ry tres oserviones ruiles de este lgoritmo que nos yudn omprender l demostrinX IF il onjunto resultnte E permite reonstruir entermente l redF PF uesto que d iterin elimin un iloD los ilos ontenidos en E son distintosF

7.11. Reducciones al problema del ujo mximo

785

B 4/3 2/0

4/3

3/3

F 5/4

B 4/3 2/0 H

4/3

3/3

F 5/4

3/2 A 5/2

2/1 2/1 3/3

3/0 A 5/0

2/1 2/1 3/3

5/3 C 6/5 D 3/3 G

5/3 C 6/3 D 3/3 G

(a)
B 4/3 2/0

ABEA
4/3 E 3/3 F 5/3 3/0 B 4/0 2/0 2/0 2/0 3/3 H 3/0 A 5/0 2/0 2/0 4/0 E 3/0 F

(b)

CEDC

5/0

5/0

3/0 5/0 C 6/0 D 3/0 G

5/3 C 6/3 D 3/3 G

(c)

DFHD

ABEFHGD CA
(d)

pigur UFIHIX ijemplo del teorem de desomposiin de )ujo sore l irulin de l (gur UFIHH QF il lgoritmo termin en lo sumo |E| iterionesD que es l mxim ntidd posile de ilosF guent hid de ests oserviones l proposiin es iert
7.11.6 Conectividad de grafos

egresemos l ide de onetividd de un grfoF in ese sentidoD un onexo puede onsiderrse un grfoc hos mtris dn uent de l pregunt y se llmn conectividad en arcos y conectividad en nodos respetivmenteF v onetividd en ros es l mnim ntidd de ros que deen eliminrse de un grfo pr que ste quede dividido en dos omponentes inonexosF imilrmenteD l onetividd en nodos es l mnim ntidd de nodos remover pr que el grfo deveng desonetdoF xosotros y hmos estudido ides (nes l onetividdF in UFSFIR @gF TIQA estudimos los puntos de rtiulin o de orteD los ules expresn de lgun mner onetividdes en nodos unitris y msD porque qu desrrollmos un lgoritmo que en O(E) nos lul todos los nodos de orteF edemsD pr muhs situiones es su(iente lulr los nodos de orteD que es rto en tiempo y espio @O(E) y O(1) respetivE menteAD en lugr de lulr onetividdes queD omo veremos en est suseinD son ms ostossF or otr prteD durnte nuestro estudio de roles rdores mnimos presentmos l de(niin de orte @UFVFPFP pgF TTRAF v onetividd en ros no es otr os que lulr un orte de pidd mnim l exepin de que deemos herlo en trmino de un grfo y no de un digrfoF rr flt pues un prlelo entre ls redes de )ujos y los grfosD el ul fue mostrdo en UFIIFI @gF UUQAF

786

7. Grafos

7.11.6.1

El teorema de Menger

e menudoD un vlor de onetividd en ros k se le llm kEonexin y se denot formlmente omo Ke (G)F heimos que un digrfo es  kEonetdo desde s hi t siD pr todo onjunto C de k 1 nodosD exeptundo s y tD existe un mino desde s hi tF hiho de otro modoD no es posile desonetr s de t sin eliminr k nodosF hos minos entre s y t se denominn independientes si stos no tienen nodos en omn @ l exepin de s y tAF istmos listos pr enunir uno de los teorems ms interesntes de l teor de grfosD desuierto ntes de l omputin modernD el teorem de wengerF
Proposicin 7.17 (Karl Menger 1928 [123])

i un digrfo es kEonetdo desde un nodo s hi otro tD entones existen k minos independientes desde s hi tF
Demostracin

hdo un digrfo ulquierD onsideremos un red pitd on los mismo nodos y ros puestos pidd unitriF vuego eliminemos todos los ros entrntes s y todos los slientes de tF ehor mximiemos l redF or l proposiin UFV @gF UIWA semos que l rdiE nlidd del orte mnimo es kD pues tods ls piddes son unitris y el digrfo es k onetdoF emosD por el teorem UFIT @gF UVRA de desomposiin de )ujoD que podemos representr el )ujo desde s hi t omo un onjunto de minos disjuntos32 uy sum de )ujos @por d minoA es el vlor de )ujo de l redF uesto que l rdinlidd del orte mnimo es kD existen k minos distintos desde s hi tD uno por d ro del orte mnimo il teorem de wenger nos port diretmente el onoimiento pr diser un lgoE ritmo que lule Ke (G) yD ms nD pr lulr el orte rtio o mnimoD es deirD el onjunto espe(o de ros que hy que suprimir pr que el grfo deveng prtido en dos o ms sugrfosF
7.11.6.2 Clculo de

Ke ( G )

vlmemos G l red trnsformd equivlente un red no dirigidF r enontrr Ke (G) podemos plir el siguiente lgoritmoF
Algoritmo 7.10 (Clculo de

Ke ( G ) ) intrdX n grfo G =< V, E >F lidX Ke (G)F

IF glule G F PF e s el nodo en G orrespondiente l nodo de menor grdo en GF


QF Ke (G) = RF v V | v = s
tese un lazo

32

ts

que conforme el ciclo

ts

y se tiene la circulacin.

7.11. Reducciones al problema del ujo mximo

787

@A t = v @A e l red N =< V, E , C, s, t > tl que C = {1 | e E cap(e) = 1} @A wximizr N y lulr el orte de pidd mnim < Vs , Vt >F iF Ke (G) = | < Vs , Vt > | iiF equ eventulmente se puede gurdr < Vs , Vt >F
7.11.6.3 Implantacin del algoritmo de clculo de

@dA if )ujo de N < Ke (G) =

Ke (G)

787

v implntin del lulo de l onetividd es reltivmente simpleD hid uent de que y disponemos de tod l mquinri neesriF gomenemos entones on el lulo de G X Calcular G 787 (788c) typedef Net_Graph<Net_Node<Empty_Class>, Net_Arc<Empty_Class> > Net; Net net; typename Net::Node * source = NULL; long min_degree = numeric_limits<long>::max(); for (Node_Iterator<GT> it(g); it.has_current(); it.next()) { typename GT::Node * p = it.get_current(); NODE_COOKIE(p) = net.insert_node(); if (g.get_num_arcs(p) < min_degree) { source = mapped_node<GT, Net> (p); min_degree = g.get_num_arcs(p); } } if (min_degree <= 1) return min_degree;
for (Arc_Iterator<GT, SA> it(g); it.has_current(); it.next()) { typename GT::Arc * a = it.get_current(); typename Net::Node * src = mapped_node<GT, Net> (g.get_src_node(a)); typename Net::Node * tgt = mapped_node<GT, Net> (g.get_tgt_node(a)); if (src != source) net.insert_arc(tgt, src, 1); if (tgt != source) net.insert_arc(src, tgt, 1);
560b.

}
Uses

e efetos de horrr espio y no tener que empler un tlD d nodo de G se gurd en el ookie del nodo en GF eprovehmos l psd sore los nodos de G pr determinr el nodo de menor grdoF el (nl del primer forD source es l imgen en G del nodo de menor grdo en GF i el grdo es inferior o igul l uniddD entones no vle l pen proseguirD pues l onetividd no puede ser myorF

mapped_node

788

7. Grafos

22

23

24

25

26

22

23

24

25

26

16

17

18

19

20

21

16

17

18

19

20

21

11

12

13

14

15

11

12

13

14

15

10

10

(a)

Ke (G) = 4

(b)

K e ( G) = 3

pigur UFIHPX hos grfos de distints onetividdes on sus ortes

788a

il loque glulr G 787 nos ure los psos I y P del lgoritmo UFIHF il pso R se instrument on un for que reorr todos los nodos de G @net en l implntinA y veri(que de no proesr el fuenteF e sink el nodo tul sore el ul se enuentr el for meniondoF il pso R onsiste en suprimir los ros que slen de sink @de este modo deviene sumideroAD pero deemos gurdr estos ros suprimidos pr resturrlos en l siguiente iterinF isto se implnt de l siguiente formX Eliminar arcos salientes de sink 788a (788c 789) DynDlist<typename Net::Arc*> from_sink_arcs;
for (Node_Arc_Iterator<Net> it(sink); it.has_current(); it.next()) from_sink_arcs.append(it.get_current()); for (typename DynDlist<typename Net::Arc*>::Iterator it(from_sink_arcs); it.has_current(); it.next()) net.disconnect_arc(it.get_current());
Uses

DynDlist

85a.

788b

implemos un list de ros eliminr from_sink_arcsF ifetumos dos psdsD l primer pr gurdr los rosD l segund pr eliminrlosF vo hemos de est mner porque es delido eliminr un ro dentro de un iterdor de rosF vos ros slientes de sinkD gurddos en from_sink_arcsD deen ser resturdos medinteX Restaurar arcos salientes de sink 788b (788c 789) while (not from_sink_arcs.is_empty()) net.connect_arc(from_sink_arcs.get()); gon todos los loques desrrolldosD el lgoritmo UFIH se implnt sX Conectividad en arcos 788c 789 template <class GT, template <class> class Max_Flow = Random_Preflow_Maximum_Flow, class SA = Default_Show_Arc<GT> > long edge_connectivity(GT & g) {

788c

Calcular

787

long min_k = min_degree;

7.11. Reducciones al problema del ujo mximo

789

for (Node_Iterator<Net> it(net); it.has_current(); it.next()) { typename Net::Node * sink = it.get_current(); if (sink == source) continue;

Eliminar arcos salientes de sink 788a


const typename Net::Flow_Type flow = Max_Flow <Net> () (net); if (flow < min_k) min_k = flow;

Restaurar arcos salientes de sink 788b


net.reset(); // colocar flujo en cero } return min_k;

789

v onetividd en ros es un medid muy importnte de densidd del grfoF in muhos ontextosD Ke (G) expres l roustez del grfo en sentido de su onetividdF in lguns situiones puede ser importnte lulr el orte mnimo de GF r eso l iliote provee l rutin compute_min_cut()D uy estrutur es l mism que l de edge_connectivity()D on el dido de que st lul el orte mnimo de G yD medinte mpeo GD otiene el vlor del orteX Conectividad en arcos 788c + 788c template <class GT, template <class> class Max_Flow = Heap_Preflow_Maximum_Flow, class SA = Default_Show_Arc<GT> > long compute_min_cut(GT & g, Aleph::set<typename GT::Node*> & l, Aleph::set<typename GT::Node*> & r, DynDlist<typename GT::Arc *> & cut) {

Calcular y mapear

790

Aleph::set<typename Net::Node*> tmp_vs, tmp_vt; DynDlist<typename Net::Arc*> tmp_cuts, tmp_cutt; long min_k = numeric_limits<long>::max(); for (Node_Iterator<Net> it(net); it.has_current(); it.next()) { typename Net::Node * sink = it.get_current(); if (sink == source) continue;

Eliminar arcos salientes de sink 788a


Aleph::set<typename Net::Node*> vs, vt; DynDlist<typename Net::Arc *> cuts, cutt; const typename Net::Flow_Type flow = Min_Cut <Net, Max_Flow> () (net, vs, vt, cuts, cutt);

790

7. Grafos

if (flow < min_k) { min_k = flow; tmp_vs.swap(vs); tmp_vt.swap(vt); tmp_cuts.swap(cuts); tmp_cutt.swap(cutt); } net.reset(); // colocar flujo en cero }

Restaurar arcos salientes de sink 788b

Determinar corte (l, r y cut) con tmp_vs, tmp_vt y tmp_cuts 791


}
Uses

return min_k;
DynDlist
85a.

gonsttmos que l estrutur es idnti edge_connectivity()F ry un sutil difeE reni no mostrd en el loqueX si l onetividd es menor o igul que l uniddD no se lul el orteY onseuentementeD el invonte dee onsultr el vlor de retorno pr indgr si ste se lul o noF v rzn de est deisin es doleF in primer lugrD si l onetividd es unoD entones es stnte prole que el grfo se espridoD on ms de un nodo de grdo unitrioF in este soD el lgoritmo lulr )ujos vnos y deer de onsiderr en ls iteriones l desonexin del vlor tul de sinkF in segundo lugrD en UFSFIR @gF TIQA onsgrmos un mpli susein pr trtr on los puntos de orteD que es el so prtiulr pr Ke (G) = 1F iventulmenteD on los vlores de lD r y cut podemos empler tnis similres ls desrrollds en UFSFIS @gF TPPA pr lulr los loquesF
790

Calcular y mapear

G 790 (789) typedef Net_Graph<Net_Node<Empty_Class>, Net_Arc<Empty_Class> > Net; Net net; typename Net::Node * source = NULL; long min_degree = numeric_limits<long>::max(); for (Node_Iterator<GT> it(g); it.has_current(); it.next()) { typename GT::Node * p = it.get_current(); typename Net::Node * q = net.insert_node(); GT::map_nodes (p, q);

} if (min_degree <= 1) return min_degree;

if (g.get_num_arcs(p) < min_degree) { source = mapped_node<GT, Net> (p); min_degree = g.get_num_arcs(p); }

7.11. Reducciones al problema del ujo mximo

791

for (Arc_Iterator<GT, SA> it(g); it.has_current(); it.next()) { typename GT::Arc * a = it.get_current(); typename Net::Node * src = mapped_node<GT, Net>(g.get_src_node(a)); typename Net::Node * tgt = mapped_node<GT, Net>(g.get_tgt_node(a)); if (src != source) { typename Net::Arc * arc = net.insert_arc(tgt, src, 1); ARC_COOKIE(arc) = a; } if (tgt != source) { typename Net::Arc * arc = net.insert_arc(src, tgt, 1); ARC_COOKIE(arc) = a; } }
Uses

mapped_node

560b.

791

Determinar corte (l, r y cut) con tmp_vs, tmp_vt y tmp_cuts 791


for (typename Aleph::set<typename Net::Node*>::iterator it = tmp_vs.begin(); it != tmp_vs.end(); it++) l.insert(mapped_node <Net, GT> (*it));

(789)

for (typename Aleph::set<typename Net::Node*>::iterator it = tmp_vt.begin(); it != tmp_vt.end(); it++) r.insert(mapped_node <Net, GT> (*it)); for (typename DynDlist<typename Net::Arc*>::Iterator it(tmp_cuts); it.has_current(); it.next()) { typename Net::Arc* arc = it.get_current(); cut.append(mapped_arc<Net, GT> (arc)); }
Uses

DynDlist

85a and

mapped_node

560b.

7.11.6.4

Anlisis del algoritmo 7.10

in los trminos en que lo hemos plntedoD el rendimiento del lgoritmo UFIH se orresponde on el de l rutin edge_connectivity()F he ll se not lrmente que se ejeutn |V | 1 mximiziones sore G F or tntoD el desempeo ser V 1 @desempeo de Max_Flow <Net> () (net)AF i emplemos un lgoritmo de emE puje por preE)ujoD que es el lgoritmo por omisinD entones podemos enontrr Ke (G) en (V 1) O(V 2 E) = O(V 3 E) psosF glulr G 787 tom O(E) psosD los ules son sinttimente soridos por el forF hel mismo modoD iliminr ros slientes de sink 788a y esturr ros slientes de sink 788b tomn el grdo de slid sinkD el ul lo sore sinttimente Max_Flow <Net> () (net)F

792

7. Grafos

7.11.7

Clculo de

Kv (e)

yvimenteD l onetividd en nodos est estrehmente reliond on su equivlente en rosF is diretmente deduile que Kv (G) Ke (G)D pues los ros que determinn Ke (G) no slo deen relionr los nodos que desonetn GD sino que es posile que uno o ms ros de los involurdos en el orte que rroje Ke (G) omprt nodos involurdos en Kv (G)F odemos lulrD puesD Kv (G) prtir del orte mnimoF r elloD medinte compute_min_cut()D lulmos el orte mnimo del grfo y luego mirmos el onjunto de nodos que ontiene el orteF he este onjuntoD en relin los ros del orteD lulmos Kv (G)F ytr lterntiv onsiste en desrrollr un lgoritmo similr l UFIHF ero pr eso deemos interpretr @o plnterA el teorem de wenger @UFIUA en funin de noE dos y no de rosF in este sentidoD un primitiv de lulo de Kv (G)D llmd vertex_connectivity()D del mismo estilo que edge_connectivity pero pr los nodosD es exportd en ALEPHF

7.12 Flujos de coste mnimo


in osionesD mntener un )ujo por un red rre ostesF gonsideremos lguns situE ionesX IF in un red que modelie lgn )uidoD mntener un vlor de )ujo onllev un oste energtio o eonmio vees proporionl l longitud de l tuerF PF in un red de tr(o reo mntener un )ujo ddo por lgun rut tmin involur ostes de omustileD ntidd de vionesD etF QF n red eltri requiere ostes de mntenimiento segn su uiin geogr(F istos ejemplos nos permiten vislumrr que hy situiones en ls ules no slo uent mximizr l ntidd de )ujoD sino stisfer lgn riterio de sustentilidd segn se l ndole de los ostesF vos ostesD no neesrimente son de ndole eonmi y los )ujos no neesrimente representn lquidosF e tenor de ejemploD un pliin lsi se relion on el trnsE porte de insumos o mernsF in este so hlmos de un red de trnsporteF v pidd de )ujo represent l de trnsporte soid un durinF epree pues el prolem de mximizr l ntidd de insumos trnsportr en el menor tiempo posileF r trtr prolems que enjen en l mximizin de )ujo l mnimo osteD plnteremos el siguiente modeloF
Denicin 7.21 (Modelo de red capacitada con costes)

n red pitd de )ujo on ostes es un red pitd N =< V, E, s, t, C, C >F C : E CD l ul le soi d ro un triuto diionl llmdo coste que represent el oste por unidd de )ujoF il oste soido un ro se denot omo c(a) y represent lo que uest )uir un uniddF il oste de un )ujo por un ro a se de(ne omoX cf (a) = f(a) c(a) @UFPWA

7.12. Flujos de coste mnimo

793

S 50/50 C 30/5 50/40 30/10 D 80/30 30/15 40/35 50/30 50/20 H 15/4 50/25 G 50/30 K 30/2 60/15 J 70/20 T 60/50 40/90 E 20/30 I 30/5 20/8 F B 10/1 40/20 60/10 70/20 A 30/20

pigur UFIHQX ijemplo de un red pitd on ostesF rimer vlor de d ro orresponde ls piddesD mientrs que el segundo l oste de llevr un unidd de )ujo il osto de un )ujo de un red se de(ne omoX cf (N) =
eE

cf (e) =
e E

f(e) c(e)

@UFQHA

gon est de(niin y estmos preprdos pr enunir un prolem generl que nos servir de fundmento de soluin un uen vriedd de otros prolemsF
Denicin 7.22 (Flujo mximo de coste mnimo)

e N =< V, E, s, t, C, C > un red pitd on ostesF n )ujo mximo se die de coste mnimo si no existe otro )ujo mximo on oste menorF in un red pitd puede her vris on(guriones de )ujos que onduzn un )ujo mximoF or ejemploD pr l red ilustrd en l (gur UFIHQ tenemos dos @o msA on(guriones que mximizn el )ujo y que son mostrds en ls (gurs UFIHRE y UFIHQED respetivmenteF emos )ujos son mximosD pero el primero tiene un oste de 14860 mientrs que el segundo de 16400F emos que un red pitd puede tener vris on(guriones que mximien el )ujoF es ls ossD puede preerse omo enfoque de soluin el enontrr tods ls on(guriones mxims y entonesseleionr l de menor osteD pero entones emos en el terreno de lo intrtleF uesto que ms tnis de mximizin de )ujo se sirven de l red residulD es de inters de(nir un red residul en el mito de osteF

794

7. Grafos

S 50/50/50 C 30/0/5 50/40/40 30/10/10 D 80/0/30 30/0/15 40/40/35 50/0/30 50/0/20 H 15/0/4 50/40/25 G 50/20/30 K 30/0/2 60/60/15 J 70/60/20 T 60/60/50 K 40/0/90 E 20/0/30 I 30/0/5 20/20/8 F H 15/15/4 50/10/25 G B 10/0/1 40/10/20 60/60/10 D 80/0/30 30/20/15 40/0/35 50/25/30 50/0/20 E 70/70/20 A 30/10/20 50/20/40 30/0/10 C

S 50/50/50 70/70/20 A 30/30/5 B 10/0/1 40/40/20 60/60/10 30/10/20

20/0/30 I 30/0/5 40/20/90 20/15/8 F

50/50/30

60/60/50

30/10/2 60/50/15 J 70/70/20 T

(a) Edmonds-Karp

(b) Ford-Fulkerson

pigur UFIHRX hos on(guriones de )ujo mximo pr l red de l (gur UFIHQ


Denicin 7.23 (Red residual en una red capacitada con costes)

e N =< V, E, s, t, C, C > un red pitd on ostesF espeto l )ujoD su red residul es idnti l de l de(niin UFIT @gF UPIA on l que y hemos trjdoD pero respeto l osteD los ros residules tienen oste negtivosF il oste negtivo pr un ro residul or ms sentido undo se piens en un ro de retroesoF el derementr el )ujo por un ro de retroeso ument el vlor de )ujo y on ello el oste totlF esD umentr )ujo por un ro residul hi el sumidero @un ro de retroesoA equivle disminuir el oste totlD pues en relidd se disminuye el )ujoF v (gurs UFIHSE y UFIHSE muestrn ls redes residules de los )ujos mximos mostrE dos en ls (gurs UFIHRE y UFIHRE respetivmenteF in ms (gurs se pueden notr l preseni de ilos negtivos segn el oste del )ujoF emos pues que entre distintos )ujos posilesD mximos inlusiveD se pueden tener ilos de oste negtivoD lo ul sugiereD undo menos por surdoD que el )ujo en uestin no puede ser de mnimo osteF ge entones replnter l ide de )ujo ftileF
Denicin 7.24 (Flujo factible sobre una red capacitada con costes) e N =< V, E, s, t, C, C > un red pitd on ostesF n )ujo mximo es ftile siD y slo siD ste no ontiene ilos de oste negtivoF

v ftiilidd estri en que es surdo tener ilos negtivosF ero este rter de surdo tiene pidd reveldorD tl omo veremos en l siguiente proposiin fundE mentlF n )ujo mximo es de oste mnimo siD y slo siD su red residul no ontiene ilos negtivosF
Proposicin 7.18

7.12. Flujos de coste mnimo

795

F 60/-50 F 60/-50 H 40/-25 30/5 50/20 50/30 40/90 40/-35 60/-10 S 50/-50 30/15 10/-10 C 10/40 70/-20 D 10/1 B 20/20 A 10/-20 40/-40 30/5 I 20/30 E 20/10 80/30 10/-20 30/20 20/-15 10/15 80/30 20/-40 D 10/1 B 10/-20 20/20 A 20/-8 I 20/30 E 30/10 C 30/40 30/-5 40/-20 70/-20 40/35 50/-50 S 15/4 20/-30 G 10/20 J 10/25 K 30/30 20/90 20/-90 5/8 15/-8 50/20 25/30 25/-30 60/-10 30/2 T 60/-20 60/-15 30/5 G 50/-30 15/-4 40/25 H K 10/-25 10/-2 50/-15 J 70/-20 T 10/15 20/2

(a) 7.104-a

(b) 7.104-b

pigur UFIHSX edes residules de pr los )ujos mximos de ls (gurs UFIHRE y UFIHREF r d (gur se reslt ilos negtivos segn el oste r l prensin es menester reordr l ide de irulin y el teoE rem UFIT @gF UVRA de desomposiin de )ujo en irulionesF in este sentido onsiE deremos un ilo @negtivo o noA omo un irulin en l redF ehor plnteemos los dos minos mostrtivosX
Demostracin

 @por ontrdiinAX supongmos que tenemos un )ujo mximo de oste mnimo uy red residul ontiene un ilo de oste negtivoF e u el ro del ilo on menor pidd restnte on vlor cm F ehor umentemos el )ujo de l red trvs del ilo en cm sumndoselo todos los ros de oste positivo @de delntoA y restndoselo todos los ros de oste negtivo @de retroesoAF uesto que estos mios no fetn l propiedd de onservin del )ujoD el )ujo irulnte es el mismo yD por tntoD n mximoD pero su oste disminuye en cm D lo que ontrdie l suposiin de que el oste es mnimoF or tntoD si un )ujo mximo es de mnimo osteD entones ste no puede tener ilos negtivos  @por ontrdiinAX supongmos que onoemos un )ujo mximo f D sin ilos negE tivosD uyo oste no es mnimoF hel mismo modoD supongmos que onoemos un )ujo fm mximo de oste mnimoF in est hipotti situin sermos pes de onoer los vlores de los ostes y mirr l difereni de oste fm f F egn el teorem UFIT @gF UVRA de desomposiin de )ujoD por l v de pliin del lgoritmo UFW @gF UVRA podemos operr sore f medinte squeds suesivs de ilosD umentos y reduionesD y s deprr en l mism on(gurin de )ujo fm F in emrgoD puesto que f no tiene ilos negtivosD est serie de operiones no podr jr el oste totlF xos enontrrmos entones on un )ujo f idntio en vlor de )ujo fm pero on oste @el de f A distintoD lo ul es un ontrdiinF or onsiguienteD si un )ujo no tiene ilos negtivosD entones ste es mximo y de oste

796

7. Grafos

mnimo il onoimiento que nos rroj este teorem es l se de un gm de lgoritmos que luln el )ujo mximo uyo oste es mnimoF pundmentlmenteD est lse de lgoritmos se estruturn omo sigueF
Algoritmo 7.11 (Algoritmo genrico de eliminacin de ciclos negativos)

v entrd del lgoritmo es un red pitd de ostes NF v slid es l mism red on el )ujo mximo uyo oste es mnimoF IF glule un )ujo iniil sore N @puede ser un )ujo mximoA PF while N onteng ilos de oste negtivo @A e C un ilo de oste negtivo sore NF e cm l mnim pidd restnte del iloF @A eumente el )ujo de N en el vlor de cm F
7.12.1 El TAD

Net_Max_Flow_Min_Cost

il eh Net_Max_Flow_Min_Cost instrument l mquinri neesri pr opE err redes de )ujo on ostes soidosF u espei(in reside en el rhivo tpl_maxflow_mincost.HF Net_Max_Flow_Min_Cost se fundment sore Net_GraphD on el dido de que sus ros lergn informin pr el osteX
796a

Arco con coste 796a

template <typename Arc_Info, typename F_Type = long> class Net_Cost_Arc : public Net_Arc<Arc_Info, F_Type> { typedef F_Type Flow_Type; Flow_Type cost; }; Flow_Type flow_cost() const { return this->flow*cost; }

gomo vemosD slo se de el oste por unidd de )ujoF vos nodos son los mismos que pr Net_GraphF gon lo nterior y podemos de(nir el eh Net_Max_Flow_Min_Cost X
796b

Clase Net_Max_Flow_Min_Cost

template <class NodeT, class ArcT> class Net_Max_Flow_Min_Cost : public Net_Graph<NodeT, ArcT> { Mtodos pblicos de Net_Max_Flow_Min_Cost 796c };
796b

796c

il uso es similr l de los grfos y redesX se espei(n los nodos trvs del tipo Net_Node D los ros on Net_Cost_Arc y l red on Net_Max_Flow_Min_Cost F n primer mtodo de Net_Max_Flow_Min_Cost onsiste en ofreer l pidd de onsultr o modi(r el oste soido un roX Mtodos pblicos de Net_Max_Flow_Min_Cost 796c (796b) 797a Flow_Type & get_cost(Arc * a) { return a->cost; }

7.12. Flujos de coste mnimo

797

797a

s omo de onsultr el oste del )ujoX Mtodos pblicos de Net_Max_Flow_Min_Cost 796c + (796b) 796c 797b const Flow_Type & flow_cost(Arc * a) const { return a->flow_cost(); } uesto que en este modelo se requiere del osteD tenemos l neesidd de sorergr l inserin de roX Mtodos pblicos de Net_Max_Flow_Min_Cost 796c + (796b) 797a 797c virtual Arc * insert_arc(Node * src_node, Node * tgt_node, const Flow_Type & cap, const Flow_Type & cost) { Arc * a = Net::insert_arc(src_node, tgt_node, Arc_Type(), cap, 0); a->cost = cost; return a; } ytr lterntiv es empler ulquier primitiv de inserin de Net_Graph y luego espeiE (r el osteD el ulD segn el onstrutor de Net_Cost_ArcD tmin tom vlor omisin eroF il oste del )ujo irulnte por l red se lul segn @UFQHA @pg UWQA y se instrument sX Mtodos pblicos de Net_Max_Flow_Min_Cost 796c + (796b) 797b Flow_Type compute_flow_cost() { Flow_Type total = 0; for (Arc_Iterator<Net_MFMC> it(*this); it.has_current(); it.next()) { Arc * a = it.get_current(); if (not a->is_residual) total += a->flow_cost(); } return total; } he(nido el eh Net_Max_Flow_Min_Cost D nos oremos desrrollr otrs piezs que requerimos pr instrumentr el lgoritmo UFIIF
7.12.1.1 Acceso al coste de un arco

797b

797c

797d

r detetr ilos negtivos nos servimos del lgoritmo de fellmnEpord presentdo en UFWFQ @gF TWPAF iste lgoritmo requiere un lse de eso l distni @vse UFVFI @gF TTHAAF in nuestro so deemos modelizr el oste en funin del vlor de )ujo irulnte por el ro y onsiderr si ste es o no residulF isto lo hemos siguiendo ls regls de de(niin de eso de pesos los rosX Funciones para Net_Max_Flow_Min_Cost 797d 798 template <class Net> class Access_Cost { typename Net::Flow_Type operator () (typename Net::Arc * a) const { return a->is_residual ? -((typename Net::Arc *) a->img_arc)->cost : a->cost; } };

798

7. Grafos

7.12.2

Algoritmos de mximo ujo con coste mnimo mediante eliminacin de ciclos

ehor disponemos de todo lo neesrio pr instrumentr vrintes del lgoritmo UFIIF pundmentlmente presentremos dos lgoritmosD uy difereni estri en l mner en que se lul un vlor de )ujo iniilF
7.12.2.1 Eliminacin de ciclos con ujo mximo inicial

798

xuestr primer vrinte emple un )ujo mximo iniilF uesto que disponemos de un omplet fmili de lgoritmos pr mximizr )ujoD el riterio de mximizin ser un prmetro de l primitivX Funciones para Net_Max_Flow_Min_Cost 797d + 797d 800 template <class Net, template <class> class Max_Flow_Algo> void max_flow_min_cost_by_cycle_canceling (Net & net, bool leave_residual = false) { // tipos sinnimos para hacer ms simple la lectura typedef Aleph::less<typename Access_Cost<Net>::Distance_Type> Cmp; typedef Aleph::plus<typename Access_Cost<Net>::Distance_Type> Plus; typedef Res_F<Net> Filter;
Max_Flow_Algo <Net> () (net, true); // obtiene flujo mximo inicial Path<Net> cycle(net); // aqu se guardan ciclos negativos // eliminar ciclos negativos mientras stos existan while (Bellman_Ford_Negative_Cycle <Net, Access_Cost<Net>, Cmp, Plus, Filter>()(net, cycle)) if (increase_flow <Net> (net, cycle) == 0) break;
Path
578a.

}
Uses

v red mximizd oste mnimo luld medinte este progrm on el lgoritmo de pordEpulkerson es mostrd en l (gur UFIHTF il oste mnimo del )ujo mximo es 13620F in este momento puede deirse que nos enontrmos en un punto ulminnte de este textoF gomo vemosD l rutin max_flow_min_cost_by_cycle_canceling() instrument el lgoritmo UFII de un mner prtimente idnti su espei(inD simpliidd posile gris que nos poymos sore tod un mquinri de estrutur de dtos y lgoritmosF in este so podemos menionr el eh List_GraphD s omo sus lses derivdsF hel mismo modoD este lgoritmo suye sore otros lgoritmosD de los ules e menionr l squed de minos de umentoD mximizin de )ujoD squed de ilos negtivosD minos ms ortos y omponentes fuertemente onexosD entre otrosD los ules su vez suyen en ms estruturs de dtos y lgoritmosF
7.12.2.2 Eliminacin de ciclos mediante supra arco negativo

ytro lgoritmo sdo eliminin de ilos negtivos prte desde un vlor de )ujo nuloF vuego se ument el )ujo en un vlor ddoD se eliminn ilos negtivos y se vuelve umentr el )ujoF il proedimiento se pli suesivmente hst que y no hy ilos

7.12. Flujos de coste mnimo

799

S 50/50/50 C 30/20/5 50/0/40 30/30/10 D 80/0/30 30/10/15 40/0/35 50/30/30 50/10/20 H 15/0/4 50/40/25 G 50/20/30 K 30/0/2 60/60/15 J 70/60/20 T 60/60/50 E 20/0/30 I 30/0/5 20/20/8 40/0/90 F B 10/10/1 40/20/20 60/60/10 70/70/20 A 30/10/20

pigur UFIHTX plujo mximo oste mnimo de l red de l (gur UFIHQ @gF UWQA produido por l eliminin de ilos on )ujo mximo iniil

negtivosY momento en el ulD por el onoimiento que nos port l proposiin UFIV @gF UWRA @=AD semos que el )ujo es mximoF ehor ienD por ul vlor de )ujo omenzrc i ien existen vris y ntigus tnis SWD IQVD IHUD un de ls ules se rteriz por su simpliidd y veloidd Ereltiv l lse de lgoritmoED y que onsiste en dir un lzo entre el fuente y el sumidero on )ujo myor l mximo y oste negtivo uyo vlor soluto se myor l oste totl de ulquier mino entre el fuente y el sumideroF e este lzo lo llmmos supr roF iste truo nos permitir evdir el lulo iniil del )ujo mximo e ir itertivmente lulndo el mnimo oste l vez que mximizmos l redF v ide es rer un ilo negtivo iniilD ul puede pitorizrse del siguiente modoX

Red

f > max/ V C

vos ilos que ontienen l supr ro fungen de minos de umentoD pues inluyen un mino entre el fuente y el sumideroF n intento de eliminin de este ilo mueve l myor ntidd posile de )ujo del supr ro hi el mino de umento entre el fuente y el sumideroF egn se el vlor del esln mnimoD el ilo puede o no eliminrseF esD est lse de ilos ument el )ujoF vos ilos que no ontienen l supr ro estn domindosD en el sentido de ser negtivos por ros de retroeso @o residulesAF u eliminin redue el oste totl del )ujoF il enfoque de supr ro tiene l ventj de ser ms senillo de implementr que el

800

7. Grafos

800

nteriorD pues no requiere explitmente pensr en lgortmi de )ujo mximoD minos de umento y otrs ossF il primer pso hi el diseo de este lgoritmo es l inserin del supr roX Funciones para Net_Max_Flow_Min_Cost 797d + 798 801 template <class Net, template <class> class Cost> static typename Net::Arc * create_dummy_arc(Net & net) { const typename Net::Flow_Type max_cost = net.get_num_nodes() * search_max_arc_cost <Net, Cost> (net);
net.make_residual_net(); typename Net::Node * src = net.get_source(); typename Net::Node * tgt = net.get_sink(); const typename Net::Flow_Type max_flow = std::min(net.get_out_cap(src), net.get_in_cap(tgt)); typename Net::Net::Digraph * digraph = &net; typename Net::Arc * a = digraph->insert_arc(src, tgt); net.get_cookie() = a; typename Net::Arc * img = digraph->insert_arc(tgt, src); digraph->disconnect_arc(a); // no supra-arco, dejarlo por coste a->is_residual a->img_arc a->cap a->cost a->flow = = = = = false; img; max_flow; max_cost; 0; = = = = = true; a; max_flow; max_cost; 0;

img->is_residual img->img_arc img->cap img->cost img->flow } return img;

r que l lse de oservin de distni Access_Cost onsidere l supr ro negtivoD ste dee ser residulF he ll que remos dos rosD uno residulD que es el supr roD y otro normlD que es desligdo de l red medinte disconnect_arc()Y de este modoD el ro prlelo l supr ro no es visto por ningn iterdor de rosF create_dummy_arc() pel dos rutinsF v primerD compute_max_possible_flow()D retorn el mximo vlor de )ujo que puede lnE zr l red en funin de ls piddes de slid del fuente y de entrd del sumideroF v segund rutinD search_max_arc_cost()D retorn el myor vlor del oste C entre todos los ros de l redF il oste mximo de lgn )ujo de red est otdo por V CD ul es myor que l mxim longitud en ros de un ilo @irulinAF imtrio create_dummy_arc()D hy otr primitiv llmd destroy_dummy_arc()D

7.12. Flujos de coste mnimo

801

801

l ul elimin el supr ro y l red residulF ehor y estmos listos pr desrrollr el lgoritmoX Funciones para Net_Max_Flow_Min_Cost 797d + 800 template <class Net> void max_flow_min_cost_by_cycle_canceling(Net & net) { typedef Aleph::less<typename Access_Cost<Net>::Distance_Type> Cmp; typedef Aleph::plus<typename Access_Cost<Net>::Distance_Type> Plus; typedef Res_F<Net> Res_Filter;
create_dummy_arc <Net, Access_Cost> (net); Path<Net> cycle(net); // aqu se guardan ciclos negativos while (Bellman_Ford_Negative_Cycle <Net, Access_Cost<Net>, Cmp,Plus, Res_Filter> () (net, cycle)) if (increase_flow <Net> (net, cycle) == 0) break; }
Uses

destroy_dummy_arc(net);
Path
578a.

S 50/50/50 C 30/20/5 50/0/40 30/30/10 D 80/0/30 30/10/15 40/0/35 50/30/30 50/10/20 H 15/0/4 50/40/25 G 50/20/30 K 30/0/2 60/60/15 J 70/60/20 T 60/60/50 40/0/90 E 20/0/30 I 30/0/5 20/20/8 F B 10/10/1 40/20/20 60/60/10 70/70/20 A 30/10/20

pigur UFIHUX plujo mximo oste mnimo de l red de l (gur UFIHQ produido por l eliminin de ilos sin )ujo iniil y supr ro il )ujo y oste del supr ro se luln un poo ms ltos que el )ujo mximo y el oste mximo posileF v primer iterin rroj on ertez un ilo que ontiene l supr roF odo ilo que involur l supr ro onform un mino de umentoD pues ste inluye l fuente y l sumideroF or onsiguienteD tod nelin de ilos negtivos por el supr ro se orresponde on un mino de umentoF egn l suerteD el lgoritmo umentr )ujo por un ilo que onteng l supr ro o mermente eliminr ilos negtivos sin umentr el )ujoF n vez que el )ujo se mximo el lgoritmo no

802

7. Grafos

enuentr ms ilos que ontengn l supr ro y slo se remite usr ilos negtivos y nelrlosF
7.12.3 Anlisis de los algoritmos basados en eliminacin de ciclos negativos

r nlizr l lse de lgoritmos que mos de estudir deemos pelr los nlisis previos de )ujos mximos y el lgoritmo de fellmnEpordF v siguiente proposiin eluid l respetoF
Proposicin 7.19 e N =< V, E, s, t, C, C > un red pitd on ostesF e F el vlor de )ujo mximoF e C el mximo oste de un )ujo mximoF intonesD si el digrfo es espridoD l durin de ejeuin del lgoritmo UFII @gF UWTA est otd por O (V 3 C F )F Demostracin

il peor esenrio que podemos enontrr es que d ro teng E pidd F y oste C F in est situin puede lnzrse un oste mximo de red de O (E C M )F v squed de ilos en digrfos se s en el lgoritmo de rjn @ UFUFQFP @gF TRPAAD el ul emple un squed en profundidd que uest O(E)F hesde el nlisis del lgoritmo de pordEpulkerson @ UFIHFIIFI @gF UQHAA semos que pueden requerirse O(F ) repetiiones pr mximizr el )ujoD so extremo undo se umentn iruliones en un uniddF or tntoD mximizr el )ujo puede requerir O(EF )F ero un nlisis nlogo l del prrfo nterior nos rroj l posiilidd de que puedn requerirse O(E C F ) disminuiones de oste pr disminuir el oste l mnimoF gd un de ests disminuiones requiere invor l lgoritmo de fellmnEpordD el ul esD segn lo nlizdo en UFWFQFU @gF UHPAD O(V E)F gonseuentementeD el lgoritmo puede tomr O(E C F ) O(V E) = O(V E2 C F )F i el grfo es espridoD entones E cV D donde c es onstnteD lo ul nos rroj un omplejidd de O(V 3 C F ) in rigor l prtiD este nlisis es muy pesimistF in promedioD l durin es muho mejorF in emrgoD por d squed de iloD est lse de lgoritmo no proveh el lulo relizdo y onoimiento otenido por squeds nteriores de ilosF or didurD el lgoritmo de fellmnEpord retorn ilos negtivos en rutoF no neesrimente los que ms puedn elerr el umento del )ujo o l reduin del osteF
7.12.4 Problemas que se reducen a enunciados de ujo mximo a coste mnimo

e efetos de mejorr nuestr ompresinD onsideremos un hipotti situin mroeE onmi que vinule produtos gropeuriosD regiones o pses produtores y iuddes que demnden los produtosF in el sentido y explidoD supongmos omo produtos l rneD polloD pesdo y rroz y omo produtores plnD ureD ortuguesD uliD ergentinD iudorD golomE i y frsilF vs piddes de produin de d zon se pitorizn en el grfo de l (gur UFIHVEFD el ul puede interpretrse omo un esquem de provisinF

7.12. Flujos de coste mnimo

803

40 80 120 Barquisimeto 310 280 Pescado

6 450

Falcon

Caracas 300 400 Pescado 400 140 500

Sucre

Argentina 350 600 Zulia 700 450 550 Pollo Brasil 500 Carne de res

Pollo

70 200 50 Mrida

Arroz

Carne de res

80

200 170 Maracaibo

240 Colombia 450 280 700 330 Ecuador Arroz 57 300 Puerto Ordaz 90

Portuguesa

(a) Proveedores

(b) Demandantes

pigur UFIHVX qrfos de proveedores y demnds de limentos hel mismo modoD ls regiones ejeren un demnd de los produtosF in nuestro hipottio ejemploD el grfo de l (gur UFIHVE ilustr ls neesiddes de los produtos por d reginF
140 40 6 Falcn Sucre Portuguesa Argentina 350 600 Zulia 700 300 200 400 Ecuador 700 330 280 500 Colombia 550 240 Brasil 450 500 Carne de res 280 50 Puerto Ordaz Caracas 57 450 Mrida Barquisimeto T Arroz 170 310 200 Maracaibo 300 400 80 Pescado 80

Pollo

120 70 450 90

pigur UFIHWX ed equivlente pr lulr ftiilidd provisinGdemnd

804

7. Grafos

r estudir l ftiilidd de stisfin de neesiddes segn ls piddes puede usrse un vrinte de l tni explid en UFIIFP @gF UURAD l ul se pitoriz en l (gur UFIHWF v ide onsiste en fusionr los nodos produtos y s onetr produtores on demndntesF in este soD l pidd de un ro entre produto y iudd represent l demnd Esin neesidd de prtir el nodo iudd omo se expli en UFIIFP @gF UURAF vuegoD se enlzn los produtores on un suprfuente medinte ros de pidd in(nit y los demndntes on un suprsumidero on ros de pidd in(nit @en so de que se desee vlidr l ftiiliddAF vuego de mximizr el )ujoD si d ro desde produto hi demndnte tiene )ujo igul su piddD entones el )ujo es ftileD es deirD l demnd puede ser stisfehF er si el )ujo es ftile o no es esenil ntes de pensr en los ostes soidos l produtoD pues l estrutur de l red de(ne l ftiiliddF v sum de demnds versus l sum de provisiones no neesrimente rroj l ftiiliddD pues st depende de l posiilidd de llevr el produto hi el demndnteD lo ulD en trminos de un redD depende de ls piddes entre los ros que onetn l produtor on el demndnte y de l topologF rst el presente slo hemos estudido redes de )ujo on un solo tipo de )uido irulnteF in este momento es en sumo importnte notr que l estr en juego utro produtos distintosD el plntemiento de este prolem podr interpretrse on utro )uidos distintosD orrespondientes l pesdoD rrozD pollo y rneF i ien eso es orretoD en este so es equiprle un solo )uido orrespondiente l vlor de l demndF ytr mner de interpretr esto es desomponer l red de l (gur UFIHW en suredes por produtosF in este soD ulesquier que sen ls soluiones otenidsD sts son idntis ls que nos rroj un sol redF wenionremos muy revemente ls redes on vrios )uidos en UFIRFS @gF VPSAF
7.12.4.1 Transporte

in trminos generlesD en el prolem del trnsporte se tienen m proveedores y n demnE dntesF gd proveedor tiene un iert pidd de provisin y d demndnte tiene un neesidd o demnd de provisinF or d soiin entre un proveedor i y un demndnte j existe un oste de trsporte ci,j F gomo ejemplo onsideremos l siguiente instniX
Demandantes: Demanda: Proveedores Provisin 30 50 25 80 70 250 78 15 100 25 85 30 20 120 50 35 90 76 85 30 40 16 10 75 75 76 17 20 40 20 40 20 20 50 30 15

D1
30

D2
40

D3
10

D4
25

D5
15

D6
20 140

P1 P2 P3 P4 P5

iste prolem puede modelizrse y resolverse medinte un red pitdF il nodo fuente onet los proveedores on piddes igules ls provisiones y ostes nulosF vos nodos demndntes se onetn l sumidero on piddes igules sus demnds y ostes nulosF pinlmenteD d oste de trnsporte se represent por un ro desde el proveedor hi el demndnte on pidd in(nit Eo un vlor superior o igul que l provisinE y on oste igul l de trnsporte desde el proveedor hi el demndnteF v (gur UFIIH ilustr el modelo en red pitd de nuestr instni ejemploF

7.12. Flujos de coste mnimo

805

/35 /40 /120 /50 /30 /20 /40 /40 /20 /17 /20 P5 70/0 P3 25/0 S 80/0 30/0 50/0 P1 P4 /50 /30 /20 /20 /40 /75 /75 /16 /10 /85 /85 /30 /90 /76 /100 /25 /78 /15 D1 D3 30/0 D4 10/0 T 25/0 D6 20/0 /76 15/0 D2

D5 40/0

P2

pigur UFIIHX ed que modeliz el prolem del trnsporte segn l tl nterior


450/130 450/210 500/110 500/60 Mrida

450/80 500/185 Carne 600/20 600/10 700/12 Brasil 600/100 Carne 600 Zulia 700/5 600/30 Puerto Ordaz Pollo 700/60 600/15 Caracas 700/25 Barquisimeto 700/8 500/45 500/30 500/10 500/88 Barquisimeto Puerto Ordaz Maracaibo Arroz 500 240 Pollo Mrida 450 500/100 450/60 500/70 500/30 450/100 Caracas Maracaibo

700

(a) Zulia

(b) Brasil

pigur UFIIIX eliones de oste de trnsporte pr lgunos proveedores y demndntes egn ls reliones de provisin y demnd expresds en l (gur UFIHW @gF VHQAD hy vris mners de plnter el trnsporteF or ejemploD podrmos mirr los proveeE dores y otenerD pr el so de uli y frsilD ls reliones de oste de trnsporte que se muestrn en l (gur UFIII @gF VHSAF is importnte destr que estos grfos estn

806

7. Grafos

orientdos hi el ene(io de los produtores y no del de los demndntesF r que un modelo del tipo mostrdo en l (gur UFIII @gF VHSA lule l distriuE in en uestinD es onveniente lulr d ruro por seprdo y otr l demnd de d iuddF v rneD en nuestros ejemplosD rrojr grfos omo los de l (gur UFIIP @gF VHTAF
Mrida 600/20 600/100 Zulia 600 Carne 600/10 600/15 600/30 Barquisimeto Puerto Ordaz 200/0 600/0 700/0 450/0 900/0 T Brasil 450 Carne 450/130 450/60 450/210 450/100 450/80 Barquisimeto Puerto Ordaz Mrida 200/0 600/0 700/0 450/0 900/0 T

Maracaibo

Maracaibo

Caracas

Caracas

(a)

(b)

pigur UFIIPX qrfos de provisin de rne pr uli y frsilF gpiddes desde l iudd hi el sumidero representn ls demnds de l iudd i mirmos el grfo ms senilloD el de uliD nos pertmos queeste solo produtor no st pr urir l demndF in l vid rel se pel soliitr l proveedor un umento de produinD usr otros produtores o mos esquemsF in trminos de un red de trnsporteD esto equivle dir todos los produtores posiles y otener grfos omo los de l (gur UFIIQ @gF VHTAF
550/75 450/130 600/20 350/140 Mrida 350/40 280/20 700/5 240/60 Mrida

350/200 550/170 200/0 450/60 600/100 Argentina 350 Colombia 550 450 Brasil 600 350/125 Zulia 550/65 900/0 Portuguesa Carne 450/210 600/10 450/0 Colombia Maracaibo 700/0 T 550/50 Ecuador 600/0 Brasil 240 350 280 700 Arroz Puerto Ordaz

240/10 350/120 80/0 280/100 700/15 200/0 350/30 280/10 700/4 150/0 240/100 350/35 400/0 200/0 Puerto Ordaz

Maracaibo

450/100 600/15 350/135 550/80 450/80 600/30 350/120

Barquisimeto

280/15 700/3 240/45 350/50

Barquisimeto

Caracas

280/30 700/6 240/30

Caracas

(a) Carne de res

(b) Arroz

pigur UFIIQX gostes de trnsporte pr lgunos produtos segn ls reliones de l red UFIHV i estleidos todos los proveedores y piddes posiles no tenemos ftiiliddD es deirD que l ntidd provist por los proveedores no stisfe l demndD ul es el so de l rneD entones podemos onsiderr priorizr sumiderosD o seD iuddesF r eso podemos de(nirD por ejemploD un digrfo de prioriddes entre ls iuddes tl omo el de l (gur UFIIRY por simpliiddD ls demnds de d iudd son notds en el nodoF in este so lulmos l demnd totlD ul es l sum de demnds de d iuddF enlogmente deemos lulr l provisin totlD ul es l sum de provisionesF in el

7.12. Flujos de coste mnimo

807

Maracaibo 700 Mrida 200 Barquisimeto 450 Caracas 900 Puerto Ordaz 600

pigur UFIIRX qrfo de prioriddes de distriuin entre l iuddes pr l demnd de rne ejemplo tenemos omo demnd totl 2900 y provisin totl 1950F ehor omenzmos suprimir los nodos iuddes y restr l demnd totl desde el ltimo rngo topolgio hst el primero y detenemos el proedimiento undo l demnd se menor que l provisinF in el so de l rne @(gur UFIIQ @gF VHTAAD omenzmos por uerto yrdz Eltimo rngo topolgioED lo que nos dej un demnd de 2300F vuego restmos grs Epenltimo rngo topolgioED lo que nos dej un demnd de 1400D l ul es menor que l provisin de 1950F egn esto nos qued l sured de l (gur UFIIS @gF VHUAED l ul nos permite lulr l signin oste mnimoF in est sured es esenil restringir l pidd de un iudd hi el sumidero l vlor de l demndD pues de lo ontrrioD el lgoritmo puede llevr ms )ujo del demnddoF
550/75 450/130 600/20 350/140 Argentina 350 Colombia 550 450 Brasil 600 Carne 600/10 350/125 550/50 450/100 Zulia Colombia 600/15 Barquisimeto 350/135 550/65 Zulia Brasil Carne Caracas Puerto Ordaz Maracaibo 450/210 600/0 500/0 Argentina 200/0 Mrida

(a) Subred con demanda asegurada

(b) Subred con demanda insuciente

pigur UFIISX uredes de lulo segn prioriddes eguidmente tenemos dos lterntivs generles pr distriuir l provisin restnteF v primer es onstruir un sured on los nodos del primer rngo topolgio segn l prioriddY l segund es her un red on todos los nodos restntesD de mner de dr ms minimliddF iste ltimo riterio nos rroj un sured estruturlmente similr l de l (gur UFIISEF in ulquier de ls dos lterntivs se distriuye tod l provisin restnte l mnimo osteF
7.12.4.2 Trasbordo

in el prolem del trsordo se tienen m proveedoresD n demndntes y k depsitos o puntos de trsordoF imilr l prolem del trnsporteD d proveedor tiene un E pidd de provisinD s omo d demndnte un de demndF v difereni on el prolem de trnsporte reside en que puede her nodos depsitos entre los proveedores y demndntes que representn puntos de trsordoF eprte de los ostes de envo desde

808

7. Grafos

los proveedores hi los depsitos y desde los depsitos hi los demndnteD tmin se or por lmenmientoF ixtendiendo el ejemplo de l susein preedenteD onsiE deremos l tl UFPF
Demandantes Demanda Proveedores Provisin 60 50 55 165 Depsitos Coste depsito 30 40 35  55 40  20 35 10 Costes envo hacia el demandante 78 15 100 30 20 120 90 76 85  10  costes envo desde proveedor

D1
60

D2
70

D3
40

D4
55

Total 270

W1
30 5 

W2
15  20

P1 P2 P3
Total

W1 W2

le UFPX n ejemplo del prolem de trsordo il prolem es un extensin del de trnsporteD on los depsitos omo nodos interE mediosF xotemos que lguns entrds en l tl no tienen vloresD lo ul signi( que no existe onexin diret entre el proveedor o depsito y el demndnteF isto puede representr diverss situionesD desde imposiiliddes geogr(s hst emrgosF
/10

/15 W1 60/30 /20 60/30 50/0 /78 /100 S 60/0 55/0 P1 35/15 35/40 35/20 P3 W2 /90 /120 /85 W2 /30 /76 W1

60/35 60/35 35/10 60/55 55/0 D4

60/5 P2

D1

60/0 70/0 T

D2 35/40

40/0

35/20

D3

pigur UFIITX ed que modeliz el trsordo segn l tl nterior v soluin onsiste en simplemente dividir los nodos depsitos en dosF n depsito w se divide en dos nodos w w F ri w iniden ros desde los proveedores que modelizn ls piddes de envo y sus ostesF hesde w emn un slo ro orresE pondiente l oste de depsito por uniddF hesde w emnn ros los demndntes segn l pidd de trsporte y oste de envoF v (gur UFIIT @gF VHVA ilustr l representin en red pitd on ostes de l tl nteriorF il oste por depsito puede omitirse si no pliD en uyo so no es neesrio dividir en dos los nodos depsitosF gomo se veD el prolem de trsordo es un prolem de trnsporteD on el dido de que existen nodos intermedios @los trsordosAF in sD su vlor es de strin en el sentido de que puede sernos ms fil interpretr un situin en trminos del trsordo que en el del trnsporte o redes pitdsF wuhs situiones mundns son modelizles en trminos de trsordoF vs ruts

7.12. Flujos de coste mnimo

809

Punto Fijo

Colombia San Antonio Maracaibo

Ecuador

Panam

Puerto Cabello

Mrida

Barquisimeto Argentina La Guaira Maiqueta Estados Unidos Caracas

Santa Elena Brasil Puerto La Cruz

Puerto Ordaz

pigur UFIIUX n red hipotti de proveedoresD puntos de trsordo y iuddes deE mndntesF vos trsordos terrestres son reonoidos on un romoD los reos on un retngulo y los mrtimos on un hexgono resD mrtimsD importionesD omeriosD etFD onstituyen sos prdigmtiosD por ejemploD l red mostrd en l (gur UFIIUF
7.12.4.3 Asignacin de trabajos

he mner genriD en el prolem de signin se tienen n trjos o proyetos y m trjdoresF gd trjdor puede her lgunos @o todosA trjos un oste (jdo por lF v met es mximizr l ntidd de trjos l mnimo osteF n ejemplo puede esquemtizrse sX
Trabajo Trabajador

t1
20

t2

t3
30

t4
10 25

t5

t6
20 15

T1 T2 T3 T4

10 15 15 30

25 30 10

40 20 35

il prolem se modeliz y resuelve medinte un red pitd on ostes en l ul ls piddes entre los trjdores y trjos son unitris y los ostes los orresponE dientes delrdosF il nodo fuente se onet on los trjdores piddes myores o igules que l ntidd de trjos y ostes nulosF vos trjos se onetn un suE midero on piddes myores o igules que l ntidd de trjdores y ostes nulosF n ejemplo pr l tl nterior es mostrdo en l (gur UFIIVF v mximizin del )ujo rroj l signin que ure ms trjosF gonseuenteE menteD l minimizin del oste proporion l mxim signin mnimo osteF i es eptle que un trjdor efete ms de un trjoD entones l pidd del ro desde el fuente hi el trjdor se inrement por l ntidd de trjos signlesF
7.12.4.4 Camino mnimo

r lulr el mino mnimo entre un pr de nodos u y v de un digrfoD onetmos u un fuente s on pidd myor o igul l mximo oste entre un mino ulquier en

810

7. Grafos

1/20 1/20 1/15 T1 1/10 1/15 1/30 1/0 1/25 1/20 T2 1/25 1/10 T3 1/30 1/10 T4 1/15 1/40 t5 1/30 1/35 t2 /0 t3 T4 t1 /0 t6

/0 /0 /0 /0 T

1/0 S 1/0 1/0

pigur UFIIVX ed pitd del prolem de signin segn l tl nterior el digrfoF enlogmenteD onetmos v un sumidero tF il resto de l red l onformn los ros del digrfo on pidd unitri y oste igul l peso del roF vuegoD l mximizr el )ujo de l red nterior oste mnimoD los ros on )ujo igul su piddD que son unitriosD onformn el mino mnimo entre u y vF in el so de un grfo G el lgoritmo es similrD pero previmente lulmos el equivlente dirigido G F

7.13 Programacin lineal


fsimenteD un progrm linel se ompone de los siguientes elementos estndrX IF riles de deisin @o simplemente vrilesA x1 , x2 , . . . , xn X representn puntos justles uyos vlores son desonoidos l iniio del prolemD y desde los ules se ontrol l situin de intersF v met es enontrr los vlores de ls vriles que mximizn o minimizn un funin ojetivoF PF punin ojetivoX es un expresin mtemti que involur ls vriles de deisin pr expresr un (n o metD uy form generl esX

Z = c1 x1 + c2 x2 + + cn xn
QF estriionesX son expresiones mtemtis que involurn ls vriles de deisin

7.13. Programacin lineal

811

y que expresn lmites ls soluiones posiles y expresds en formX

a1,1 x1 + a1,2 x2 + + a1,n xn b1 a2,1 x1 + a2,2 x2 + + a2,n xn b2 F F F am,1 x1 + am,2 x2 + + am,n xn bm x1 0, x2 0, . . . xn 0


ist form generl de expresr un progrm linel se lsi( de forma estndar F epelemos un ejemplo lsioF upongmosD por ejemploD un empres produtor de iilets on tres plnts y dos tipos de iiletX de mont y de rutD preios de vent de 2000 y 1400 respetivmenteF vos udros de ls iilets se frin en l plnt ID los omponentes en l plnt P y el ensmlje se efet en l plnt QF v plnt que fri los udros puede produir l mes 70 udros de mont y 30 de rutD pero por restriiones en su lne de solddur puede frir lo sumo 80 udros l mesF enlogmenteD l plnt P puede produir l mes 40 omponentes pr iilet de mont y 90 de rutD pero por restriiones de su proeso de romdoD el mximo de omponentes que puede frir l mes es de 100F pinlmenteD l plnt Q @l de ensmljeA puede ensmlr por mes 50 iilets monters y 60 de rutY sin emrgoD tmin por restriiones de mno de orD l plnt no puede ensmlr ms de 80 iilets l mesF
Planta 1 (cuadros) 2 (componentes) 3 (ensamblaje) Precio por bicicleta Bici montaa 70 40 50 2000 Bici Ruta 30 90 60 1400 Capacidad 80 100 80

le UFQX l resumen de ostes y restriiones pr el ejemplo de friin de iilets r restringir que el fn lurtivo lleve l empres ometer injustiisD el qoierno impone l empres l ondiin de que por d iilet de rut que produz l empres tiene que produir l menos 0, 8 de montF es ls ossD se dese onoer ls ntiddes de iilets de d tipo que se deen frir l mes pr mximizr l gnniF i x1 represent l ntidd de iilets de mont y x2 ls de rutD entonesD sumiendo que ls iilets sern vendids en su totliddD se plnte l siguiente funin ojetivoX mximizr Z = 2000x1 + 1400x2 = 10x1 + 7x2 gondiiondo ls siguientes restriionesX @UFQIA

40x1 + 90x2 100 4x1 + 9x2 10 50x1 + 60x2 80 5x1 + 6x2 8 0, 8x1 > x2 0, 8x1 x2 0

70x1 + 30x2 80 7x1 + 3x2 8

812

7. Grafos

3 2.5 2 1.5 1 0.5 0 7x1 + 3x2 8

10x1 + 7x2 (funcin objetivo)

Solucin ptima
0, 8x1 x2 0 4x1 + 9x2 9 10 0 0.5 1 5x1 + 6x2 8 1.5 2 2.5 3

pigur UFIIWX snterpretin geomtri del progrm linel y su soluin ptim e le die progrm linel porque tods ls desigulddes y euiones involurds son linelesF in efetoD tl omo se ilustr en l (gur UFIIW @gF VIPAD ls rets orrespondientes ls restriiones delinen un polgono @somredo en l (gurA en donde se stisfen ls restriionesF esD vemos que el mximo de l funin ojetivo supeditdo ls restriiones se umple en el punto de intersein entre el polgono y l ret de l funin ojetivoF rogrms lineles de este tipo pueden resolverse medinte un lere lgoritmo llE mdo simplex QSD desuierto por vez primer por qeorge hntzig en IWRUD pilr de l investigin de operiones y que revisremos en UFIQFR @gF VISAF in geometrD un simplex es un polgono o politopo nEdimensionl de n + 1 vrtiesF esD el mtodo he lusin que l soluin est delimitd por el politopo uyos vrties orresponden on ls interseiones entre ls rets de ls desigulddes orrespondientes ls restriionesF v ftiilidd de soluin depende de que l funin ojetivo pse o no por el politopoF
7.13.1 Forma estndar de un programa lineal

n progrm linel en form estndr espei( n vriles de deisin x1 , x2 , . . . , xn D n nmeros reles c1 , c2 , . . . , cn orrespondientes los oe(ientes en l funin ojetivoD m reles b1 , b2 , . . . , bm soidos ls ots de ls restriiones y n m reles ai,j pr i = 1, 2, . . . , m y j = 1, 2, . . . , n orrespondientes los oe(ientes de ls restriionesF esD genri y omputionlmenteD el (n de un progrm linel es enontrr n reles x1 , x2 , . . . , xn tl queX
n

Z=
j =1

cj xj se mxim

@UFQPA

ujeto X
n j=1

ai,j xj bi pr i = 1, 2, . . . , m xj 0 pr j = 1, 2, . . . , n

@UFQQA @UFQRA

7.13. Programacin lineal

813

v ide de l form estndr es un homogeneidd neesri pr un soluin omE putionlF ry diverss mners de expresr un progrm linelD ls ules vrn segn l irunstni y que pueden ontrvenir l form estndrF in lo que sigueD lsi(reE mos ls posiles ontrveniones y ls mners en que sts se solventn pr logrr l form estndrF
7.13.1.1 Minimizacin de la funcin objetivo

in este soD l funin ojetivo se trnsform l mximizin de l neginF is deirD si l funin ojetivo es minimizr ZD entones mximizr Z = Z es equivlenteF
7.13.1.2 Variables sin restricciones de negatividad

i el modelo permite que un vrile xi dquier vlores negtivosD entones d ouE rreni de xi se sustituye por xi xi on restriiones xi 0 y xi 0F i l funin ojetivo ontiene un trmino ci xi D entones ste se sustituye por ci (xi xi )F hel mismo modoD todo trmino aj,i xi que prez en un restriin i se reemplz por aj,i xi aj,i xi F
7.13.1.3 Restricciones de igualdad

e vees se tienen restriiones de igulddD por ejemploD x1 + x2 = 5F ist lse de restriin f(x1 , x2 , . . . , xn ) = b se divide en dos restriiones f(x1 , x2 , . . . , xn ) b y f(x1 , x2 , . . . , xn ) bF
7.13.1.4 Restricciones mayor o igual

v form estndr de un restriin es n j=1 ai,j xj bi F imperoD vees se presentn omo myor o igulD por ejemploD 2x1 + x2 2F n n restriin del tipo j=1 ai,j xj bi se trnsform dos restriiones n a x b respetivmenteF i,j j i j=1
7.13.2 Un ejemplo de estandarizacin

upongmos el siguiente progrm linelX winimizr 2x1 x3 ujeto X

2x1 + x2 3x3 3 2x2 + x3 = 4


@UFQSA

x1 + x2 2x3 2 x1 , x2 0
eplindo ls trnsformiones referids el progrm resultnte esX wximizr 2x1 + (x3 x3 )

814

7. Grafos

ujeto X

2x1 + x2 + 3x3 3x3 2x2 + x3 x3 2x2 + x3 x3 x1 x2 + 2x3 2x3 x1 , x2 , x3 , x3

@UFQTA

or simpliiddD en un progrm linel en su form estndr slo se espei( l funin ojetivo y sus restriiones menor o igulY ls restriiones de no negtividd no se espei(nF
7.13.3 Forma holgada de un programa lineal

v form estndr puede revirse omo l funin ojetivo Z y desiguldd mtriil sX Ax b @UFQUA honde A es l mtriz de oe(ientes de ls restriionesD x el vetor de vriles de deisin y b el vetor de ots de ls restriionesF vs restriiones de no negtividd se sumen pr d elemento xi y no se ponen por omisinF ehor ienD l myor de los mtodos de soluin de progrms lineles requieren omo entrd un sistem linel de formX

Ax = b

@UFQVA

is deirD l exepin de l no negtividd pr d xi D tods ls restriiones son de igulddF upongmos un restriinX


n j=1

ai,j xj bi

@UFQWA

ehor introduzmos un nuev vrile s y plntemos l desiguldd jo dos restriE ionesX


n

s = bi
j =1

ai,j xj

@UFRHA @UFRIA

s 0

v vrile s se li( de holgd @slkAD porque expres l difereni entre los dos ldos de l desiguldd @UFQWAF r onvertir un progrm linel en form estndr uno en form holgdD se usn m vriles diionles de holgur del tipoX
n

xj+k = bj
j =1

ai,j xj

@UFRPA @UFRQA

xj+k 0 pr k = 1, 2, . . . , m

7.13. Programacin lineal

815

or ejemploD el progrm en form estndrX

Z = x1 2x2 + x3 2x1 3x2 2x3 3 x1 + x2 + 2x3 2


e trnsform en su form holgd enX

x1 + 2x2 x3 4

Z = x1 2x2 + x3 x4 = 4 x1 2x2 + x3 x5 = 3 2x1 + 3x2 + 2x3 x6 = 2 x1 x2 2x3


7.13.4 El mtodo simplex

n uen mner de entender el prinipio del simplex onsiste en plnterlo omo l resoluin de un sistem de euionesF gonsideremos pues el siguiente prolemX wximizrX Z = 25 x3 + 40 x2 + 30 x1 ujeto X 2 x3 + 4x2 + 3 x1 500

5 x3 + 2 x2 + 5x1 650 2 x3 + 6 x2 + x1 820

il ul l llevrlo su form holgd nos quedX wximizXr z = 25 x3 + 40 x2 + 30 x1 ujeto X x4 = 2 x3 4 x2 3 x1 + 500 @UFRRA @UFRSA @UFRTA @UFRUA

x5 = 5 x3 2 x2 5 x1 + 650 x6 = 2 x3 6 x2 x1 + 820

e un sistem de euiones de este tipo suele llmrsele diionrioF in este estdoD el vlor de l funin ojetivo es 0 orrespondiente l vrtie (0, 0, 0)D el ul es un soluin vlid respeto l onjunto de restriionesD pero no mximF gomenemos por umentr el vlor de Z despejndo x2 de lguns de ls restriionesF r umentr ls posiiliddes de irunsriirse ls restriiones deemos esoger l ms severF r eso evlumos el impto que tendr el umento de vlor de x2 D que tiene el oe(iente ms lto en Z @40AD en d un de ls restriionesX

x4 0 4 x2 + 500 0 x2 < 125 x5 0 2 x2 + 650 0 x2 < 325 410 136.67 x6 0 6 x2 + 820 x2 < 3 esD despejmos x2 de @UFRSAD pues est restriin es l que ms nos ot su vlorX x2 = x4 x3 3 x1 + 125 4 2 4
@UFRVA

816

7. Grafos

ehor reemplzmos est euin en el diionrio preedente y otenemosX wximizrX Z = 10 x4 + 5 x3 + 5000 @UFRWA x4 x3 3 x1 ujeto X x2 = + 125 @UFSHA 4 2 4 7 x1 x4 4 x3 + 400 @UFSIA x5 = 2 2 3 x4 7 x1 x6 = + x3 + + 70 @UFSPA 2 2 equ el sistem se enuentr en el punto (0, 125, 0)D el ul d un gnni en Z de 5000F ixminndo Z en este nuevo diionrio vemos que l ni posiilidd de umentrl es por l vrile x3 D pues l otr restnte es negtivF esD seleionmos x3 omo l vrile umentr y l despejmos de l restriin ms severD l ul es @UFSIAF isto nos d el siguiente diionrioX 5 x5 75 x4 35 x1 wximizrX Z = + 5500 @UFSQA 4 8 8 x5 5 x4 5 x1 + 75 @UFSRA ujeto X x2 = 8 16 16 x5 x4 7 x1 + 100 @UFSSA x3 = + 4 8 8 x5 13 x4 21 x1 + + 170 @UFSTA x6 = + 4 8 8 el ser todos los oe(ientes de Z negtivos podemos onluir que no es posile umenE trl msF gonsiguientementeD Z es mximD on vlor 5500D orrespondiente l vrtie (0, 75, 100)F il proeso que mos de ejempli(r puede generlizrse un ntidd genri de vriles y utomtizrseF r esoD en primer instniD de(nimos l lse Simplex<T>D l ul reside en el rhivo implexFr 816a D y que grndes rsgos se de(ne omo sigueX Simplex.H 816a template <typename T> class Simplex { public: enum State { Not_Solved, Solving, Unbounded, Solved, Unfeasible };
};

816a

Miembros privados de Simplex 818a Miembros pblicos de Simplex 816b

816b

v lse Simplex es un soluiondor de progrms lineles espei(dos en form estnE drD uy ntidd de vriles dee indirse en tiempo de onstruinX Miembros pblicos de Simplex 816b (816a) 816c Simplex(int n)

n es l ntidd de vriles de deisin del sistemD ls ules se enumern desde el 0 hst n 1F il vlor de n puede onsultrse medinte l primitiv get_num_vars()F
7.13.4.1 Denicin de la funcin objetivo

816c

gundo se instni un sistemD los oe(ientes de l funin ojetivo son nulos y no hy restriionesF esD su espei(in se remite indir sus oe(ientes medinteX Miembros pblicos de Simplex 816b + (816a) 816b 817a void put_objetive_function_coef(int i, const T & coef)

7.13. Programacin lineal

817

honde i es el nmero de l vrile y coef su oe(iente en l funin ojetivoF


7.13.4.2 Denicin de las restricciones

817a

ry vrios esquems pr de(nir ls restriionesF il primeroD ul pree ser el ms usulD onsiste en indir l sistem l existeni de un restriinX Miembros pblicos de Simplex 816b + (816a) 816c 817b T * put_restriction(T * coefs = NULL) n llmd put_restriction() re en el sistem un nuev restriin en form estndr on oe(ientes nulosF v rutin retorn un puntero un rreglo de oe(ientes de l restriin enumerdos entre 0..num_varF v otenin de este puntero d refereni diret d uno de los oe(ientesD de mner tl que se puedn espei(r o modi(rF is posile otener el mismo puntero medinteX Miembros pblicos de Simplex 816b + (816a) 817a 821a T * get_restriction(int rest_num)

817b

get_restriction(i) retorn un puntero l iEsimo rreglo restriinF min es posile psr diretmente los vlores de los oe(ientes en un rreglo medinte un llmd put_restriction(ptr)D donde ptr es el puntero l rreglo de oe(ientesF
7.13.4.3 La estructura de datos

n lve ruil en l utomtizin del simplex reside en el empleo de un deud estrutur de dtosF xo es difil pertrse de que el mtodo es stnte reminisente resolver un sistem linel de euionesF in ese sentidoD sus mtodos de resoluin son pliles pr el simplexF gonsideremos omo ejemplo el siguiente sistem en form estndrX

Z = 40x0 + 50x1 + 60x2 + 30x3


ujeto X

2x0 + x1 + 2x2 + 2x3 205 x0 + x1 + 3x2 + x3 205 x0 + 3x1 + 4x2 255

3x0 + 2x1 + 2x2 + 2x3 250

il progrm linel se representn medinte un mtriz m (n + m + 1) (m + 1)D donde n @num_varA es l ntidd de vriles de deisin y m @num_restA l de restriionesF v primer (l ontiene Z f(x0 , x1 , . . . , xn1 ) y el resto ls restriiones en form holgdF esD pr muestro ejemploD l mtriz resultnte se de(ne omo sigueX
40.00 2.00 1.00 1.00 3.00 50.00 1.00 1.00 3.00 2.00 60.00 2.00 3.00 4.00 2.00 30.00 2.00 1.00 0.00 2.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 205.00 205.00 255.00 250.00

818

7. Grafos

egn l ntidd de vriles que teng el sistemD es muy importnteD efetos de eonom de memoriD que l mtriz se espridF in ese sentidoD l lse Simplex<T> emple un lse llmd DynMatrix<T>D l ul est fundmentd en DynArray<T> PFIFR @gF QRAD lo que posiilit el horro de elds de memori pr elementos nulosF
7.13.4.4 Seleccin del pivote

818a

n vez onstruid l mtriz iniil se proede itertivmente seleionr el elemento pivote y pivoter hst que todos los oe(ientes de l funin ojetivo Elos de l primer (lE devengn positivosF il primer pso onsiste en determinr l olumnD l ul es l del menor oe(iente negtivo de l funin ojetivoD o seD el oe(iente por el ul hy myor posiilidd de umentr ZX Miembros privados de Simplex 818a (816a) 818b int compute_pivot_col() const { T minimum = numeric_limits<T>::max(); int p = -1; for (int i = 0, M = num_var + num_rest; i < M; i++) { const T & c = m->read(0, i); if (c < minimum) { p = i; minimum = c; } } return minimum >= 0 ? -1 : p; } i no hy oe(ientes negtivosD entones el sistem y se enuentr en un soluin ptim y se retorn -1F he lo ontrrio se retorn el ndie de l olumn del pivoteD el ul llmmos pF r determinr l (l del pivote lulmos el menor rdio positivo m(i,p)/m(i,n+m)D lo ul nos proporion l restriin ms severX

818b

Miembros privados de Simplex 818a +

(816a)

818a 819

int compute_pivot_row(int p) const { int q = -1; T min_ratio = numeric_limits<T>::max(); for (int i = q + 1, M = num_var + num_rest; i <= num_rest; i++) { const T val = m->read(i, M); if (val < 0) continue; const T den = m->read(i, p); if (den <= 0) continue;

7.13. Programacin lineal

819

} return q;

const T ratio = val / den; if (ratio < min_ratio) { q = i; min_ratio = ratio; }

819

i no se enuentr ningn rdio positivoD entones se trt de un sistem ilimitdoD es deirD que no tiene un politopo de(nido @lo que ser un error de modelizdoA y se retorn -1F he lo ontrrio se retorn el ndie de l (l del pivote llmdo qF r pegr ls dos rutins nteriores emplemos un mtodo explito que determine el elemento pivoteX Miembros privados de Simplex 818a + (816a) 818b 820 State select_pivot(int & p, int & q) { const int col = compute_pivot_col(); if (col == -1) return state = Solved;
const int row = compute_pivot_row(col); if (row == -1) return state = Unbounded; p = row; q = col; } return state = Solving;

yriginlmenteD ntes de l primer llmd select_pivot(p, q)D el sistem se enuenE tr en el estdo Not_SolvedF es pr el progrm y l mtriz ejemplosD l rutin nterior identi( el siguiente pivote @enerrdo en ruloAX
40.00 2.00 1.00 1.00 3.00 50.00 1.00 1.00 3.00 2.00 60.00 2.00 3.00 30.00 0.00 0.00 0.00 0.00 0.00 2.00 1.00 0.00 0.00 0.00 205.00 1.00 0.00 1.00 0.00 0.00 205.00 0.00 0.00 0.00 1.00 0.00 255.00 2.00 0.00 0.00 0.00 1.00 250.00

RFHH
2.00

il ul se orresponde on l olumn P uyo mnimo oe(iente de l funin ojetivo es 60 y l (l Q orrespondiente l mnimo rdio min(205/2, 205/3, 255/4, 250/2) = 255/4F
7.13.4.5 Pivoteo

il pivoteo onsiste en lulr los nuevos oe(ientes de l mtriz on el siguiente riterioX IF r l (l del pivote pX d elemento de est (l se divide entre m(p, q)F

820

7. Grafos

iste pso es equivlente despejr l vrile xq de l restriin pF PF r el resto de ls (lsX se m (p) l (l del pivote trnsformd segn el pso nteriorF gd (l m(i) se lul omo m(i) = m(i) m(i, p) m (p)F

istos por (lsD estos psos equivlen evlur Z y ls restriiones on l diin de l vrile xq F

820

il proeso nterior se puede odi(r omo sigueX Miembros privados de Simplex 818a + (816a) 819 void to_pivot(size_t p, size_t q) { const int M = num_var + num_rest; // cantidad de columnas const T pivot = m->read(p, q); for (int j = 0; j <= M; j++) // fila del pivote if (j != q) m->write(p, j, m->read(p, j) / pivot);
m->write(p, q, 1);

821b

for (int i = 0; i <= num_rest; i++) // resto de las filas for (int j = 0; j <= M; j++) if (i != p and j != q) m->write(i, j, m->read(i,j) - m->read(i,q)*m->read(p,j)); for (int i = 0; i <= num_rest; i++) // col de pivote en 0 salvo q if (i != p) m->write(i, q, 0);

il pivoteo es l mism operin sore l ul se fundment un mtodo muy populr de resoluin de sistems lineles de euiones llmdo de qussEtordnF r nuestr mtriz ejemploD el vlor iniil de l funin ojetivo es 0D el ul se orresponde on el vrtie del simplex (0, 0, 0, 0)F el her el primer pivoteo se inrement el vlor de l funin ojetivo y heD exepin de l (l pivoteD todos los elementos de su olumn eroF esD pr p = 2 y q = 3D el pivoteo produeX
25.00 1.50 0.25 0.25 2.50 5.00 0.50 1.25 0.75 0.50 0.00 0.00 0.00 1.00 0.00 30.00 0.00 0.00 2.00 1.00 0.00 15.00 0.00 3825.00 0.50 0.00 77.50 0.75 0.00 13.75 0.25 0.00 63.75 0.50 1.00 122.50

IFHH
0.00 2.00

0.00 0.00 0.00

1.00 0.00 0.00

v operin elimin l olumn P y llev el vlor de l funin ojetivo 3825D orresE pondiente l vrtie del simplex (0, 0, 63.75, 0)F gontinundo on el lulo pree omo nuevo pivote p = 3 @del 30A y q = 2 @de min(77.5/2, 13.75, 122.5/2)AD lo que nos rrojX
17.50 1.00 0.25 0.25 2.00 42.50 0.00 0.00 0.00 0.00 0.00 1.00 30.00 2.00 1.00 0.00 2.00 7.50 1.00 0.00 0.00 4237.50 50.00 13.75 63.75 95.00

PFHH
1.25 0.75 3.00

0.00 1.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00

0.75 0.00 0.25 0.00 1.00 1.00

7.13. Programacin lineal

821

xos enontrmos en el vrtie (0, 0, 63.75, 13, 75) on vlor de funin ojetivo 4237.5F ivotemos on m(1, 1)D lo ul nos produeX
3.75 0.00 0.00 0.00 0.50 1.00 0.00 0.00 0.88 0.00 0.00 1.00 0.12 0.00 1.00 0.00 0.50 0.00 0.00 0.00 21.25 0.50 0.62 0.38 1.50 12.50 1.00 0.25 0.75 13.75 0.00 5300.00 0.50 0.00 25.00 0.12 0.00 45.00 0.12 0.00 45.00 0.50 1.00 20.00

IFHH

is deirD el punto (0, 25, 45, 45) on vlor de funin ojetivo de 5300F xos flt un ltimo pivoteo de m(4, 4)D uyo resultdo (nl esX
10.00 1.00 1.00 0.50 0.50 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 1.00 0.00 0.00 2.50 1.00 0.25 0.75 1.50 0.00 0.00 0.00 0.00 1.00 7.50 0.00 0.25 0.25 0.50 12.50 5550.00 1.00 45.00 0.25 50.00 0.75 30.00 1.00 20.00

821a

y seD el vrtie (0, 45, 30, 50) pr un vlor mximo de 5550F il proeso nterior se utomtiz medinte el siguiente mtodoX Miembros pblicos de Simplex 816b + (816a) 817b 822 State solve() { for (int i, j; true;) { const Simplex<T>::State state = select_pivot(i, j); if (state == Simplex<T>::Unbounded or state == Simplex<T>::Solved) return state;
} to_pivot(i, j);

821b

gomo podemos notr del lgoritmoD el vlor (nl de un vrile i se determin mirndo su olumn El ul dee ontener eros y un unoE y exminndo el vlor de m(i, num_rest)D donde j es el ndie del vlor uno en l olumnF isto se puede efetur on l siguiente rutinX Miembros privados de Simplex 818a + (816a) 820 T find_value(const size_t j) const { T ret_val = 0.0; for (int i = 1, count = 0; i < num_rest; i++) { const T & value = m->read(i, j); if (value == 0.0) continue;
if (value == 1.0) if (count++ == 0) ret_val = m->read(i, num_var + num_rest); else return 0.0;

822

7. Grafos

}
822

} return ret_val;

else return ret_val;

esD un vez resuelto el sistem podemos rgr l soluin medinteX Miembros pblicos de Simplex 816b + (816a) void load_solution() { for (int j = 0; j < num_var; j++) solution[j] = find_value(j); }
7.13.5 Conclusin sobre la programacin lineal

821a

in est sein hemos presentdo un pnorm muy generl y super(il sore l progrE min linel y uno de sus mtodos de resoluin ms populresX el simplexF il lgoritmo simplex es extremdmente difil de nlizrF wtemtimente es un lgoritmo exponenil y se hn enontrdo sos que degenern l ejeuin este tipo de rendimientoF e pesr de elloD en l prti el promedio de ejeuin del simplex es espetulrD unque n no se omprende ien l rznF e pesr de l priin de nuevos mtodos de optimin @vse sein de referenis UFIS @gF VQHAA por su simpliidd de implementin y rendimientoD el simplex sigue siendo un de ls esogenis priniples omo soluiondor de progrms linelesF v importni de l progrmin linel suye sore el heho de que existe un ntim onexin entre el simplexD s omo otros mtodos de optimizinD y ls redes de )ujoF gonseuentementeD est onexin es extensiv los grfos en generlF e los spetos de este vnulo nos oremos revemente en l siguiente seinF

7.14 Redes de ujo y programacin lineal


n red de )ujo puede expresrse omo un progrm linelD resolule medinte ulquier de los mtodos de l progrmin linelF
7.14.1 Conversin de una red capacitada de costes a un programa lineal

gonsideremos un representin mtriil pr un red pitd on ostes de n nodosF gd nodo se sel por un ndie mtriil y el ro por su entrd en l mtrizF esD el prolem de )ujo mximo oste mnimo puede plnterseD genrimenteD omo uno de optimizinD del siguiente modoX
n n

winimizr Z =
i =1 j =1

ci,j xi,j

@UFSUA

ujeto los onjuntos de restriionesX


n n

xi,j
j=1 k =1

xk,i = bi , xi,j 0,

i = 1, 2, . . . , n i, j = 1, 2, . . . , n

@UFSVA @UFSWA

7.14. Redes de ujo y programacin lineal

823

or d ro i jD su vlor de )ujo represent un vrile de deisin xi,j F v sum ZD orrespondiente l vlor de )ujo de l redD represent l funin ojetivoF or d nodo iD el vlor bi D orrespondiente l difereni entre el )ujo de entrd y el de slidD represent un restriinF e exepin del fuente y del sumidero33 D bi = 0D mientrs que pr el fuente y sumidero bs y bt respetivmenteF pinlmenteD puesto que el )ujo no puede ser negtivoD d vrile xi,j 0F emos entones un mpeo direto desde un red de ostes un progrm linelF l mpeo es de enorme importni por dos rzones vinulds entre siX IF gulquier prolem de )ujo mximoD on o sin oste mnimoD puede resolverse meE dinte el simplex u otro mtodo de l progrmin linelF PF elgunos prolems de progrmin linel pueden resolverse medinte un red E pitdF v lgortmi pr resolver prolems on redes pitds es on rees ms e(iente que l de l progrmin linelD pero no todo progrm linel puede expresrse omo un red pitdF
7.14.2 Redes generalizadas

rst el presenteD pr todos los modelos de redes pitds hemos sumido l ondiin de onservin de )ujo de(nid en UFWE pgF UHWF edes que no stisfgn quell ondiin son llmdsD jo ierts restriionesD redes generlizdsF in ls redes generlizds los ros poseen un ftor de gnni o prdid de )ujoF in el modelo pitrioD un ftor de gnni @o de prdidA a entre un ro u v se expres multiplindolo por l pidd c del roX
u a c v

i a = 1D entones se trt de un nodo normlF i 0 < a < 1D entones se trt de un ftor de prdidD por ejemplosD un )ujo de orriente eltri que ps por un resisteni o un )ujo de gu que sufre lgun prdid por evporin34 F i c > 1D entonesD se trt de un gnni de )ujoD lo que en un primer mird pree fsimente improleF ixisten empero sos no tn exepionlesD ejemplosD redes por donde iruln pitles eonmiosD redes de gentes iolgios @iFeF terisAD gus l intemperie @que umentn por lluvisAD etF n ftor ero no tiene sentidoD pues equivle l useni de roF eunque mtemtimente posileD un ftor negtivo tmpoo tiene muho sentido fsioD pues modeliz un espeie de retroeso de )ujoD el ul prolemente se modelizE le desde l perspetiv topolgi de l redF
33 34
Recurdese que la red puede reducirse a un solo fuente y un solo sumidero. En algunos casos no se trata en si de un factor de prdida, sino de una reduccin a la capacidad, la

cual modelizarse mediante un nodo intermedio

w:
w ac v

824

7. Grafos

in trminos de un progrm linelD pr un nodo ulquier vD l onservin del )ujo puede expresrse omoX

f(e)
eIN(v) eOUT(v)

ae f(e) = be

@UFTHA

xotemos que l difereni de @UFTHA on l onservin del )ujo expresd en @UFIIA @defF UFWE pgF UHWA es un ftor multiplitivo ae en d ro eF edes generlizds pueden resolverse trvs de un lgoritmo llmdo simplex de redF
7.14.3 Capacidades acotadas

in este tipo de red el )ujo de los ros est otdo est otdo por los extremosX uno mnimo y uno mximoD este ltimo orrespondiente l piddF in el modelo pitrioD d ro ontiene dos vloresX el )ujo mnimo requerido y el mximo permitidoD los ules suelen expresrse entre orhetes omo en l (gur UFIPHEF
u [min, max] v s min u max v

(a) Arco con cota de ujo

(b) Transformacin equivalente

pigur UFIPHX ero on ots de )ujo y su trnsformin v ot inferior puede interpretrse omo un demnd de )ujo en el nodo uD mientrs que l superior es l pidd del roF esD segn lo visto en UFIIFQ @gF UURAD un ro de este tipo es equivlente l de l (gur UFIPHEF
7.14.4 Redes con restricciones laterales

in lguns osiones se tienen restriiones diionles que involurn vrios )ujosF uE pongmos por ejemplo tres ros aDbD cX
a c b

y omo restriin sore el )ujo de ellos 2f(a) f(b) + 3f(c) 12F n restriin de este tipo se li( de lterlF gonseuentementeD redes on est lse restriiones se tildn de on restriiones lterlesF vs restriiones lterles no neesrimente tienen que estr relionds los ros de un nodoF odr trtrse de un restriin entre ros que no estn diretmente reliondosD por ejemploD seprdos por l menos m ros de distniF glrmenteD ls restriiones lterles no enjn en el modelo de red pitdD pero s omo un progrm linelD lo que podr sugerir que l red se resuelv on un mtodo de l progrmin linelF il prolem on este enfoque es que se pierde l gnni en desempeo que un lgoritmo de red tiene sore ulquier de l progrmin linelF n mner prtiulr de trtr on restriiones lterlesD posile en muhos sosD onsiste en monitorer l vlidez de l restriin durnte l ejeuin de l soluinF il prolem de est tni es que no es generlizleF r el so generlD pr trtr on restriiones lterles l red se prtiion en loques @sugrfosA seprdos por ls ndoles de sus restriiones medinte un mtodo

7.14. Redes de ujo y programacin lineal

825

llmdo reljin lgrngin 35 D el ul no ser trtdo en este textoF in este so se onsidern dos tipos de loquesX los que ontienen restriiones y los que son redes pitdsF he este modoD los loques on restriiones lterles se resuelven on mtodos de progrmin linelD mientrs que los de red se solventn on redes de )ujoF vs soluiones priles se ontenn itertivmente hst que onverjnF
7.14.5 Redes multiujo

rst el presenteD todos los modelos de red pitd sumen que ls uniddes de )ujoD o seD el )uidoD son ls mismsY entindseD por los ros @tuersA irul un slo tipo de )uido36 F ry situiones en ls que por los mismos ros pueden irulr distints lses de )uidoD emndos desde vrios fuentes independientesD l menosD tntos omo distintos tipos de )uido se tengnF xo hy restriin sore l ntidd de sumiderosD y ulquier de stos puede reiir ulesquier de los distintos tipos de )ujoF n situin trdiionl de est lse de red se present on el modeldo de trE (o utomotor o petonlF e pueden onsiderrD por ejemploD vris zons geogr(s z1 , z2 , . . . , zn omo proveedors de )ujo utomotorF e un iert hor pio Els IPpmD por ejemploED los utomviles se desplzn desde y hi ls zons en uestin trvs de vs omprtidsF gomo puede inferirseD en est situinD los )uidos en lgn momento se enuentrnF ytros ejemplos los onstituyen los prolems del trnsporte @ UFIPFRFI @gF VHRAA y del trsordo @ UFIPFRFP @gF VHUAAD en los ules se poseen ls misms lnes y lmenesD pero stos se emplen pr trnsportr y lmenr diversos tipos de ienesF rst el presente slo se onoe un mner polinomil de resolver este prolemX trnsformrlo un progrm linel y desde ll soluionrloF in osionesD un red multiE)ujo pueden enontrrsele pedzos @loquesA de un slo )ujoF esD de l mism mner que pr ls redes generlizdsD l red puede dividirse en loques segn los distintos tipos de )ujoD resolverse y luego pegrse hst enontrr l soluin37 F
7.14.6 Redes de procesamiento

n red de proesmiento es un red pitd espeil que sirvepr modelizr y estudir sistems de produinF l red ontiene dos lses de nodosF vos normlesD en los ules se stisfe l onservin de )ujo o son fuentes o sumiderosD y los de proesmientoD en el sentido de que modelizn un proesmiento que no stisfe l onservin del )ujoF v (gur UFIPI ejempli( un hipotti red de proesmiento pr frir otells de vidrio en l ul se muestrn dos nodos de proesmientoF il nodo rorno represent un eventul proeso en el ul se mezl siliio on oxgeno pr otener urzoF iste proesoD por s deirloD dee stisfer funiones de fundidoD
35 36 37
Para detalles sobre este mtodo pueden consultarse [10, 16, 21]. Si hay distintos tubos para cada clase de uido, entonces se pueden separar tantas redes como tipos Igual que para las redes generalizadas, tcnicas para resolver redes multi-ujo pueden consultarse

de uidos se tengan. Este fue el caso para el ejemplo del transporte presentado en 7.12.4.1 (Pg. 804). [10, 16, 21, 101].

826

7. Grafos

Silicio 1200 Oxigeno 240 Cuarzo 12 Calor 1200 Metano 20 Carbono 100 Horno C O2 350 Soplado Botellas 10

pigur UFIPIX n ejemplo de red de proesmiento que modelien los produtos resultntesD por ejemploD el horno podr modelizrse sX

C O2 = 3 O2 + 2 C Si O2 = 5 Si + 3 O2
wientrs que el sopldo sX

6 12 C = 10 fotells = fotells = C 5
or lo generlD un red de proesmiento se represent medinte un red multi)ujo on restriiones lterlesF il poder de un red de proesmiento es su verstilidd pr l modelizin de un muy mpli gm de sistems ingenierilesD en prtiulrD muhos proesos onernientes l friin de ienesF
7.14.6.1 Cadenas de produccin

upongmos l produin de un ierto ien o l prestin de un ierto serviioF r elorr un iert ntidd del ien se requieren de otros ienes y serviiosD los ulesD su vezD tmin requieren de otros ienes y serviiosF vos ienes y serviios son elordos por gentes llmdos produtoresF n produtor es nodo de proesmiento del tipoX
B0 150/20 150/250 B1 P 150/30 B2

e este sugrfo lo llmmos grfo produtorF in este soD en un lpso de tiempo (jo pr todos los produtoresD el produtor P elor ISH uniddes del ien B2 que se vende un preio de QH por uniddF r frir B2 D el produtor P requiere los ienes B0 y B1 ls ntiddes y ostes seldos en el grfoF is posile tener vrios produtores del mismo ienY podr her inlusive produtores que nte el mismo ien de slid di(riesen de otros en lgunos ienes de entrdD lo ul podr deerseD entre otrs ossD proesos distintos de friin u orgnizinF i estudimos los ienes de entrdD entones podemos identi(r sus produtores y elorr un grfo produtor pr d uno de ellosF odemos ontinur este proeso pr los nuevos ienes que prezn hst que (nlmente nos enontremos on ienes primriosD es deirD quellos los ules no se les puede identi(r un produtorY ien se porque son mteri primD ienes importdos u otr situin equivlenteF

7.14. Redes de ujo y programacin lineal

827

Py B2 450/20 B2 300/90 B0 750/30 B0 1000/30 P0 P2 B2 150/20 B2 180/125 B3 150/20 B1 400/40 B3 100/95 B2 550/75 B3 300/80 P3 P5 P4

B4 200/450 B5 100/450

P7

B6 95/650 B6 300/250 B6 800/550 B7 1200/90

B5 400/250

Px

P10

B4 400/200 B5 95/250

P6

B7 400/150 P1 B4 200/350 B4 200/350 P8 B6 600/350 P9 B7 200/300

pigur UFIPPX n den produtiv e un grfo que represente reliones entre los produtores segn uno o ms ienes (nles le llmmos den produtivF in este grfoD que relion produtoresD los ros representn ienes y los pesos sus ntiddes y ostesF v (gur UFIPP muestr un ejemplo hipottioD uyos extremos izquierdos representn los ienes primrios y derehos los ienes (nlesF egn l ndole del sistem produtivo pueden representr mteri prim @minerles siosD guD etFAF in nuestro ejemploD los ienes primrios son B0 y B1 respetivmenteF vos extremos (nles representn el ien (nl ojeto de estudioD el ul llmmos B7 F vos nodos del grforepresentn produtores de produtos intermedios que entre los ienes primrios B0 y B1 y el ien (nl B7 38 F r prehender l importni de este ejemplo yD on lD l de ls redes de proeE smientoD plnteemos lgunos esenrios en los ules ls dens produtivs yuden vislumrr respuestsX  smpto que tendr sore l produin un sequX si sumimos por simpliidd que l sequ fet proporionlmente todo el territorioD entonesD exminndo d uno de los grfos produtores on ros de entrd uferos podemos restr l disminuinF vuegoD lulmos el impto que sore los ienes de slid teng l disminuin deid l sequF eplindo el riterio y propgndolo trvs de ls dens podemos exminr ls onseuenis que un sequ tiene sore l produin de d ienF  hdo un ien espe(oD determinr ul es el ien intermedio rtioX pr este proE lem se onstruye tod l den produtiv detrs del ien de intersF vuego se lul el orte mnimoD el ul rroj los ros uy pidd limit l produin del ien de intersF vos produtores vinuldos estos ros son quellos que hy que grntizr el umento pr que en ltim instni se pued umentr l produinF  e dese onoer ules ruros y produtores hy que poyr o proteger pr umentr l produin de lgn ien espe(oF equD prte de determinr los eslones rtiE osD podemos plnter nuevos mps produtivosF or ejemploD podrmos simulr l onstruin de fris nuevs de ienes rtios y evlur su efeto en l produinF
38
En algunos mundos vinculados a la economa, los eslabones de las cadenas productivas se clasican en aguas altas, medias y bajas, en parfrasis a un ro con un aserradero y la cadena productiva de la madera. los bosques madereros se encuentran en las aguas altas del ro. Los rboles se cortan y los troncos se echan al ro cuya corriente los arrastra hasta el aserradero que se encuentra en las aguas media (o intermedias). El aserradero recibe los troncos y los transforma en productos intermedios (tablas, bloques, etc.) que se distribuyen a diversas industrias tales como los astilleros, muebleras, constructoras de casas, etc.. Esta metfora, an en uso, ilustra la importancia que tiene el cuidado del bosque para la sustentabilidad de la cadena productiva.

828

7. Grafos

hel mismo modo podrmos olor fris del ien de inters y oservrD segn riteE rios estostios o determinists @el lgoritmo de )ujoD por ejemploA qu suede on el estdo de l produinF istos esenriosD entre muhos otrosD re)ejn l importni de ls redes de proeE smientoY omo onsolidin de l redes de )ujoD s omo su verstilidd en represenE tin y modelizdoF
7.14.7 Conclusin sobre el problema del ujo mximo a coste mnimo

il prolem prdigm de est sein tiene dos fuentes de estudioF v primer es l de investigin de operionesY l segundD l de l lgortmiF he l investigin de operiones tenemos el prolem genrio de optimizin forE muldo en UFIQ @gF VIHA y sus mtodos de resoluinD entre ellos el simplex @ UFIQFR @gF VISAAF ist vertiente h inidido el pensmiento mtriil y geomtrioF hurnte los os SH y TH del siglo D l investigin de operiones tom l teor de grfos omo un vehulo de modelizinF e prtir de entonesD se hn desuierto onexiones ntims entre mos mundosF v grn ventj de l investigin de operiones es su enorme experieni en modE elos genrios de prolems y su mpeo situiones de l vid relY los prolems de trnsporte @ UFIPFRFI @gF VHRAAD de trsordo @ UFIPFRFP @gF VHUAA y de signin de trjos @ UFIPFRFQ @gF VHWAAD formuldos desde l investigin de operionesD sE tnte relists en el mundo produtivoD son pliles muhs otrs situionesF emos prolems fueron plntedos en trminos de mtries y de grfosF ws generl omo proE lem es l progrmin linel @ UFIQ @gF VIHAAD pero de st slo un onjunto es representle Ey resoluleE on grfosF or su mpli experieniD un utntio investigdor de operiones es un sujeto onsultr undo se est modelizndo un prolemF ero el omputist tmin es otro sujeto l que el investigdor de operiones dee onsultr l hor de her el modeloF xo es omn enontrr un person que onoz y omprend lmente los dos mundosF ero el modelo orientdo grfosD trvs del de red pitdD tiene soeris ventjs sore l progrmin linelF v primer de ells es l rpidez lgortmiD l ul depr en l otenin ms lere de resultdos respeto los enfoques de l progrmin linelF v susein UFIRFI @gF VPPA muestr l mner generl de interpretr un red pitd omo un progrm linelF gd vez que se pued identi(r est orrespondeni es preferile el modelo de red l progrm linel por l senill rzn de que los rdenes de ejeuin de ls redes de )ujo estn lrededor de un orden de mgnitud superior los de l progrmin linelF v segund ventj es que el rter gr(o de ls redes pitds he ms fil y prehensileD pr l myor de ls persons que no tengn fuerte formin mtemti y strtD l modelizin e interpretin de situiones del mundo relF hespus de todoD dien que en este mundo posmoderno est domindo por lo visulF pinlmenteD en ls redes pitds hy un gm ms mpli de ominiones de lgoritmosD lo que ul proporion un holgur importnte l hor de mejorr los tiempos de ejeuinF or otr prteD tmin hemos visto l pliilidd de ls redes pitds otros prolems ms pertinentes l mundo de los grfosF il prolem del mino mnimo entre un pr de nodosD efetivmente trtdo en UFW @gF TURAD tmin puede resolverse

7.15. Notas bibliogrcas

829

medinte redes pitds @ UFIPFRFR @gF VHWAAF elgo preido ourre on los puntos de orte estudidos en UFSFIR @gF TIQA y el orte mnimo mnimo osteD no estudido explitmente pero deduile prtir de UFIIFTFQ @gF UVWAF in iert formD el modelo de red pitd es los grfosD y quiz l progrmin linelD lo que l trnsformd de vple es l lulo diferenilX otr perspetiv de interpretr un prolemD pr el ulD en ierts situionesD es ms simple enontrr soluionesF

7.15 Notas bibliogrcas


n grfoD omo los estudimos en este textoD onform un representinD gr(mente orientdD de un relidd onretD o seD de lgo presenteD de l vid relD tl omo un mpD o de un representin de un strinD tl omo un relin mtemtiF esD los grfos son inherentes l onoimiento humnoF he lgun form u otr estn presentes desde tiempos inmemorilesY prtimente desde los lores del ser humnoF uesto que l ide de grfo es prte del ervo humno desde tiempos milenriosD no pree justo triuirle lgun utor prtiulr o individulF e hn desuierto mps ilonios que se remontn l PQHH FgF es que proleE mente prolems omo el de l rut ms ort entre dos sitios hn sido plntedos en distintos tiemposD en lugres diferentesD por diverss ultursF ehor ienD sin pretensin de demritoD l histori o(il de los grfos se remont l primer y lere rtulo ient(o esrito por el mtemtio suizo veonrd iuler y su estudio sore un prolem itdino onoido omo los uentes de unigsergF or est iudd ps el ro regelD del ul existen dos isls enmrds en el permetro de l iuddF hesde ls riers hi ls isls y entre ells se uentn siete puentes distriuidos de l siguiente mnerX

vos itdinos se preguntn si h lgun mner de reorrer todos los puentes exE tmente un vezY es deirD sin psr dos vees por el mismo puenteF iuler modeliz el sunto medinte el siguiente grfoX

iuler desrii l mner generl de resolver el prolemD ul es hoy onoid jo el rtulo de ilo eulerinoF hesde entonesD iuler lo onsidern el preursor de l teor de grfos oD ms justmenteD de l topologF xtivo de unigserg fue qustv oert uirhho'D quienD tenor de ls orrientes y voltjes en redes eltrisD plnte queX IF v sum de ls orrientes soids los ros inidentes de un nodo es eroD y PF v sum de los voltjes soidos ulquier ilo es eroF

830

7. Grafos

re qu un reminiseni on l ondiin de onservin de )ujo @UFIIA @pgF UHWA y el teorem UFIT @pgF UVRA de l desomposiin de )ujo presentdo en UFIIFS @gF UVQAF vos reorridos rquetpios sore grfosD de profundidd y de mplitudD fueron reporE tdos por primer vez por oertF iF rjn ITTF il prolem del rol rdor mnimo se onoe desde los os PH del siglo F foruvk report un primer soluin en IWPT PQ yD prtimenteD el hoy onoido lgoritmo de rim fue desuierto tminD y vris dds ntesD por trnik VRF gomo y hemos indidoD ls redes )ujo fueron preedids por los trjos de uirhho'F in este tem result interesnte onsiderr el prism ulturlF inontrr minos de umento no slo es neesrio pr mximizr )ujoD sino tmin pr suplir un demnd de )ujo de petrleo en un intrind red de oleodutosF il teorem del orte mnimo estudido en UFIHFT @gF UIVAD ul dio pie los suesivos lgoritmos de mximizin sdos en mino de umentoD fue presentdo independientementeD en el mismo o por pord y pulkerson SR y por ilisD peinstin y hnnon RIF osteriormenteD idmonds y urp RH demostrron un mejor sustnil los lgoritmos primndo l squed en mplitud pr enontrr minos de umentoF or otro ldoD los lgoritmos de pre)ujo fueron preedidos por el trjo de urznov WPF il pre)ujo tiene ms sentido pr mximizr un )ujo en un red donde l visosidd del )uido es muy jD lo ul es el so del gu y los sistems de riegoF ore ls redes de )ujo hy liros importntesD yendo desde lsios de optimizin omintori omo el vwler IHU o el pdimitriou y teiglitz IQV hst otros ms reientes omo el uorte y ygen IHID el o IRV y el xoedl right IQQF min hy textos espeilizdos en ls redes de )ujoY los ms notles son el ehujD wgnnti y yrlin IH y el fzrD trvis y herli ITF uede deirse que l progrmin linelD y su lere mtodo simplexD (gurn entre los desurimientos ms importntes del siglo F etulmente no existe orgnizin seri que no rte sus ostes de produinD gestinD serviioD etF medinte el empleo y resoluin de modelos de progrmin linelF in ese sentidoD el lgoritmo simplexD visE lumrdo (nles de los os QH del siglo D (nl y formlmente pulido en IWRW QSD no slo n es uno de los priniples lgoritmos de l progrmin linelD sino que se enuentr entre los diez lgoritmos ms importntes del siglo IURF il IWUWD el mtemtio ruso veonid uhhiyn puli un nuevo mtodo de soluin uyo tiempo es polinomil WSF u trjo es un hito mtemtio que dio iniio un gm de lgoritmos denomindos de de puntos internos y desuiertos por xrendr urmrkr en IWVR WHF in progrmin linel se enuentrn muy uenos y modernos textosD lgunos de ellos previmente itdos IQQD IHID IRVD IT y otros ms espeilizdosD entre los ules e notr el vuenerger y e IIIF ore grfos en generl es menester menionr el lsio terioD unque y doleE ente de flt de desurimientos importntesD de rrry UHF e l feh de est puE liinD riterio de este utor el mejor texto terio sore grfos es el texto de tungE nikel VWF n exelente texto entre lo terio y lo instrumentl lo onstituye el liro de qross y ellen IVUF r textos instrumentles @lgortmiosAD un exelente liro es el de eln qions SWD y ms reientemente el edgewik ISTF elgunos de los grfos mostrdos en este texto fueron diujdos medinte el muy

7.16. Ejercicios

831

uen visulizdor Graphviz RPF r otros grfos se emple un progrm de diuE jdo desrrolldo por este utorD denomindo en l iliote graphpicD medinte el ul se diujron muhs de ls (gurs de este ptuloF in el desrrollo de graphpicD el liro de uozo ugiym ITS fue muy tilF ytro texto l respeto es el fttistD idesD mssi y ollis IQF

7.16 Ejercicios
IF esumiendo que no hy ros prlelosD unt es l ntidd mxim de ros que puede tener un grfoc PF esumiendo que no hy ros prlelosD unt es l ntidd mxim de ros que puede tener un digrfoc QF r el grfo de l (gur UFIPQX @A hetermine y diuje un rol de reorrido en profundidd prtir del nodo AF @A hetermine y diuje un rol de reorrido en mplitud prtir del nodo AF @A hetermine y diuje un rol rdor prtir del nodo FF @dA inuentre el @o los Amino@sA ms lrgo@sAF @eA inuentre el grfo omplementoF @fA inuentre todos los liques o sugrfos ompletosF
J B E G

pigur UFIPQX n grfo de ejerio RF lntee desventjs de los digrms de sgitles pr expresr reliones inrisF r d plntemientoD estlez l difereni on un grfoF SF hisee un rutin que relie el reorrido en profundidd sin utilizr reursinF TF hisee l primitiv test_for_cycle() presentd en UFSFS @gF SWPA y sd en un explorin en mplitudF UF hisee l primitiv test_for_cycle(g, node, len) l ul retorn true si existe un ilo en el nodo node uy longitud se extmente len rosF VF gmo puede espei(rse un mino en un grfo o digrfo trvs de sus ros undo stos no estn etiquetdosc

832

7. Grafos

WF lntee un lgoritmo fuerz rut que veri(que si dos grfos son o no isomorfosF IHF lntee esquems pr representr un mtriz de dyeni orrespondiente un multigrfoF IIF isri el lgoritmo de reorrido en profundidd sin reursinF IPF wodi(que el loque iniilizr rreglo de rreglos elementos por rri de l digonlF IQF wodi(que el loque iniilizr rreglo de rreglos
543

pr que slo prte los

543

pr usr el tipo BitArrayF

IRF hisee un eh Ady_Bit que represente un mtriz de dyeni de itsF se un rreglo dinmio DynArray<T> de rreglos de its BitArrayF winimie el onsumo de memoriF ISF hdo un grfo < V, A > y sen sv y sa los tmos de los tipos lmendos en los nodos y ros respetivmenteF e sp el tmo de un puntdorF gul es l relin entre l ntidd de ros respeto l de nodos de modo tl que se menos o ms ostoso en espio l representin on lists de dyeni que on l de mtriesc ITF in ules sos l veri(in de existeni de ro on mtries de dyeni es O(lg(n))c IUF hetermine los puntos de rtiulin pr del grfo de l (gur UFIPRF
J B E G

pigur UFIPRX n grfo de ejeriio pr el lulo de puntos de rtiulin IVF v prue de orretitud del lgoritmo de detein de puntos de orte presentd en UFSFIRFQ @gF TIWA slo demuestr que los riterios de detein presentdos en UFSFIRFI @gF TITA son orretosD es deirD que el lgoritmo efetivmente enuentr puntos de orteF in emrgoD l prue no demuestr que el lgoritmo enuentr todos los puntos de orte de un grfoF es puesD demuestre que el lgoritmo desrrolldo en UFSFIRFP @gF TITA enuentr todos los puntos de orteF IWF gomo se de(ni en UFSFIR @gF TIQAD un grfo sin puntos de rtiulin se le li( de ionexoF hesrrolle un lgoritmoD sdo en un versin simpli(d de compute_cut_nodes()D que determine si un grfo es o no ionexoF

7.16. Ejercicios

833

PHF in funin del eh List_GraphD onstruy un lgoritmo que lule el omplemento de un grfoF PIF gonstruy un versin del mtodo sort_arcs() que no use un rreglo dinmio temE porlD sino que ordene diretmente l list de rosF PPF in l rutin copy_graph() @ UFQFIHFW @gF SUUAAD ules son los inonvenientes de implntr el mpeo on un tl hshc PQF smplnte el reorrido en profundidd pr que explore todos los rosF PRF smplnte l squed en profundidd pr l representin on mtries de dyeniF PSF smplnte el reorrido en mplitud pr que explore todos los rosF PTF smplnte l squed en mplitud pr l representin on mtries de dyeniF PUF upong un tipo strto de dto derivdo de List_Graph denomindo LaberintoF iste tipo model un lerinto uyos ros representn los psillos y nodos ls interseE iones @o enruijdsA entre los psillosF @A gonsidere l siguiente interfz

Path * escapar(Laberinto & g, Laberinto::Node * s, Laberinto::Node * t)


guy (nlidd es enontrr un mino desde s hi tF il nodo s represent un lugr en el lerinto y el t un slidF isri un lgoritmo que enuentre un mino on l mnim ntidd de psillosF @Q ptosA @A gonsidere l siguiente interfz

Path * escapar(Laberinto & g, Laberinto::Node * s, Laberinto::Node * t, Laberinto::Node * p)


v ul enuentr un mino desde el nodo s hi l slid t psndo por el rue pF isri un lgoritmo que enuentre el mino psndo por l mnim ntidd de psillosF @Q ptosA PVF isri un lgoritmo que determine el grdo de un grfoF PWF smplnte un lulo de rol rdor sdo en un reorrido en mplitudF ixplique ls diferenis del rol resultnte respeto l lgoritmo sdo en squed en proE fundidd desrrolldo en UFSFW @gF THQAF QHF smplnte un rutin que onviert un rol rdor lmendo en un ojeto de tipo List_Graph un rol de lse Tree_Node F istudie minuiosmente mo her l onversin de los tipos soidos los nodos y rosF QIF hisee un lgoritmo que lule los puntos de orte y durnte el mismo reorrido oloree los omponentes onexos soidos los puntos de orteF @CA

834

7. Grafos

QPF upong que posee el grfo de orte @otenido trvs de map_cut_graph()A y los loques @otenidos on llmds map_subgraph() on los diferentes olores ddos por compute_cut_nodes()AF hisee un lgoritmo que lule el grfo originl sin pelr los ookiesF QQF hesrrolle un versin del eh Bit_Mat_Graph<GT> que mneje estritmente its y que se fundmente en el tipo DynArray<T>D de mner tl que muhs entrds de vlor ero no oupen memoriF QRF hdo un grfo G y un list l de nodosD disee un lgoritmo on prototipoY
template <class GT> void cut(GT & g, const DynDlist<typename GT:Node*> & l, GT & g1, GT & g2);

el ul retorn un orte del grfo tl que g1 ontiene los nodos de l list l y g2 los restntesF QSF isri el lgoritmo de hijkstr pr mtries de dyeniF esegrese de queD omo en el lgoritmo de ploydD se lulen todos los pres de minos ms ortosF QTF isri el lgoritmo de fellmnEpord pr mtries de dyeniF QUF wodi(que el lgoritmo de ploydErshll pr detetr ilos negtivosF @CA QVF upong un grfo on ilos negtivosD esri un lgoritmo que identi(que los ilos y onstruy un list minos orrespondiente los ilos en uestinF @CA eyudX ve UFWFQFS @gF TWWAF QWF in se lo disutido l (nl de UFWFQFW @gF UHSAD disee un lgoritmoD sdo en el de fellmnEpordD que enuentre un ilo negtivo durnte l fse de relinF hisee el lgoritmo pr que usque el ilo sore el rreglo pred sin neesidd de onstruir un grfo uxilirF @CA RHF gon se en lo disutido l (nl de UFWFQFIH @gF UHUAD disee un lgoritmo que d un nodo uxilir onetdo on peso ero l resto de los nodos y que el ejeute el lgoritmo de fellmnEpord pr enontrr un ilo negtivoF @CA RIF istudie minuiosmente l detein de ilos del lgoritmo de fellmnEpordD en prE tiulr bellman_ford_negative_cycle()D presentd UFWFQFIH @gF UHSA y explique mo podr este lgoritmo enontrr vrios ilos negtivosF @CCA RPF il prolem de enontrr el mnimo ilo negtivo de un digrfo on pesos es onoido omo intrtleF hemuestre l susodih intrtiliddF @CCA RQF gomo es ien sidoD el lgoritmo de hijkstr no oper pr ros on distnis negE tivsF n tni pr plir el lgoritmo de hijkstr un grfo on distnis negtivs onsistir en usr l mnim distni del grfo yD entonesD sumrle el negdo todos los ros del grfoF he este modoD el grfo slo ontendr distnis positivsF hemuestre que est tni no es vlid y que los minos mnimos sore el grfo trnsformdo pueden ser distintos los del grfo originlF @CA

7.16. Ejercicios

835

RRF gonsidere el grfo de l (gur UFIPSX @A glule el mino mnimo desde el nodo hst el nodo kF @A glule el rol rdor mnimo ondiiondo que ste onteng el mino mnimo entre x e yF @A glule el mino desde hi k ondiiondo que ste onteng el mino mnimo entre x e yF
a 1 3 5 b 1 x 3 1 1 e 3 d 3 c 3 2 f 2 1 4 h 2 5 2 3 2 g 1 y 5 i 2 j 6 4 3 3 k

pigur UFIPSX n grfo de ejeriio pr minos mnimos RSF egn lo estudido sore el hep exlusivo en UFVFQFQ @gF TTUAD disee un estrtegi generl de reorrido en mplitud uyo onsumo en espio no exed de O(V )F @CA RTF isri el ordenmiento topolgio sdo en el digrfo inversoF RUF hesrrolle un lgoritmo de lulo de omponentes fuertemente onexos sdo en el lgoritmo de rshllF RVF hemuestre que el lgoritmo uosrju osquejdo en UFUFQFI @gF TRHA es orretoF RWF snstrumente ompletmente el lgoritmo de uosrju estudido en UFUFQFI @gF TRHAF SHF gonsidere un plno de ompuesto por W H puntosY W es el nho y H es l lturF

n punto en el plno se espei( por un pr de vlores (x, y)F il punto (0, 0) est situdo en l esquin inferior izquierd y el (W 1, H 1) en l esquin superior derehF

vos puntos pueden mnejrse trvs de l lse Point on los triutos x e y respeE tivmenteF @A gonsidere el siguiente prototipo de funinX

BinNode<Point> * points(int n)
v ul retorn un rol inrio de squed que ontiene n puntos en el plno generdos l zrF vs lves del rol inrio son de tipo Point sndo l funin random() de l pregunt nteriorD instrumente l funinF @A gonsidere l siguiente funinX

template <class GT> GT * min_spanning_tree(DynDlist<Point> * points)

836

7. Grafos

v ul retorn un grfo que ontiene el rol rdor mnimo entre todos los puntosF gd nodo del rol rdor represent un puntoF gd ro del rol rdor represent l distni entre los puntosF hisee e smplemente un lgoritmo que instrumente l funin nteriorF @A v mism que l nterior pero emplendo mtries de dyeniF SIF hdo un digrfo G =< V, E >D el digrfo G =< V, E > se de(ne on los mismos omponentes fuertemente onexos @en nodosA y ls misms reliones de onexin entre los omponentesD pero E E mnimoF @A ixplique mo lulr el digrfo G F @A hesri un lgoritmo e(iente pr lulr G F SPF wodi(que los lgoritmos de lulo del )ujo mximo de red pr que lulen el esln mnimo en l mism psd que el lulo del mino de umentoF SQF hemuestre @UFIUA @pgF UIVAF SRF rg el nlisis del lgoritmo de empuje de pre)ujo on ol pspy estudido en UFIHFIQFVF SSF rg el nlisis del lgoritmo de empuje de pre)ujo on myor distni estudido en UFIHFIQFWF STF wodi(que tods ls funiones diseds pr lulr el )ujo mximo segn empuje de pre)ujo pr que tengn omo prmetro l operin de iniilizin de l ltur de los nodos @vse UFIHFIQFII @gF UTIAAF SUF hisee un rutin de onversin de un grfo on piddes un red del tipo Net_GraphF SVF hisee un rutin de onversin de un red del tipo Net_Graph un grfo List_GraphF SWF hisee e instrumente un lgoritmo generl que onviert un irulin on un nE tidd ritrri de ilos un red on un fuente y un sumideroF THF hisee un lgoritmo genrio que onviert un red de irulin un red on un solo fuente y un sumideroF TIF gonsidere el lgoritmo genrio de empuje de pre)ujo por ros estudido en UFIHFIQFII @gF UTHAF @A isri un espeilizin del lgoritmo que mneje el onjunto de nodos tivos medinte un tl hshF @A hisee un estrutur de dtos que permit en O(1) inrementr diretmente el )ujo y l vez detetr los ros de l ol q que devienen inelegilesF @CCA TPF ropong y relie un estudio de rendimiento pr tods ls ominiones posiles de lgoritmos estudidos de mximizin de )ujoF @CA

7.16. Ejercicios

837

TQF in funin del onoimiento que port el teorem de desomposiin de )ujo UFITD instrumente el lgoritmo UFW empledo pr l demostrinF TRF inunie y demuestre el teorem de wenger pr grfos no dirigidosF TSF in un orgnizin se tienen n trjdores {t1 , t2 , . . . , tn } y m proyetos {p1 , p2 , . . . , pm }F gd trjdor est interesdo en prtiipr en lgunos proyetos {px , py , . . . }F gd proyeto tiene un ot de prtiipntes de N(pi )Y es deirD en el proyeto pi lo sumo pueden prtiipr N(pi ) trjdoresF @A wodelie el prolem pr mximizr l ntidd de trjdores que prtiiprn en los proyetosF @A upong que un trjdor ti or un ntidd S(ti , pj ) por prtiipr en el proyeto pj F gmo se enuentr l prtiipin de trjdores mxim l mE nimo ostec @A upong que un trjdor ti tiene un e(ieni E(ti , pj ) en el proyeto pj F gmo se enuentr l prtiipin de trjdores en l myor ntidd de proyetos on l mxim e(ienic TTF hdo un orte de un grfo luldo medinte compute_min_cut() @ UFIIFTFQ @gF UVWAAD lule los loques que desonetr l supresin del orte mnimoF TUF hisee un lgoritmo que lule Kv (G) onoido el orte mnimo de GF TVF wodi(que el eh Net_Graph pr que inluy ftores de gnni en los ros de l mner explid en UFIRFP @gF VPQAF evise tods l rutins de l iliote relionds on redes de )ujoD identi(que ls que mnejen inrementos o derementos de )ujo y modifquels pr que onsideren este ftorF TWF ixprese un red genri multi)ujo en trminos de un progrm linelF UHF gonsidere l siguiente red pitd de l (gur UFIPT en l ul el vlor de )ujo de l red es eroF
A 17 3 18 D 10 18 G 19 J 9 20 K 10 5 N 10 t 8 M 8

9 B

6 19

16 11 E H

10 11

7 11 13 C 10

16

17

12

17 25

15

7 27

17

pigur UFIPTX n red de ejeriio @A inuentre un mino de umento on esln mnimo de 11F @A wximie el vlor de )ujo de l red @iniido ste en eroAF @A in funin de l respuest nteriorD enuentre un mino de umento que permit disminuir el vlor de )ujo de l red en 5F

838

7. Grafos

@dA glule el orte de pidd mnimF eslte los ros que son prte del orte mnimoF @eA glule l onetividd en ros de l red entre los nodos s y tF @fA esumiendo un vlor de )ujo eroD inyete el myor )ujo posile por el mino de umento s C B A D H K N M t y luego mximie l redF UIF in iert niversidd se desen orgnizr ursos intensivos durnte los diversos peroE dos de vionesF ry m ursos intensivos de un onjunto C = {C1 , C2 , . . . , Cm } d uno de H1 , H2 , . . . , Hm hors que se pueden ditr l oF or simpliiddD se sume que d urso intensivo tiene un progrm tn ien detlldo que ulquier profesorD onoiendo el estdo del ursoD est en l pidd de ditr ulquier prte del progrmF ry n profesores P1 , P2 , . . . , Pn F r d profesor Pi se soi l siguiente informinX @A Mi X ntidd mxim de hors de urso intensivo que puede ditr l oF @A {C1 , C5 , . . . } CX list de ursos intensivos que puede ditrF @A gtegor l que perteneeX instrutorD sistenteD gregdoD soido y titulrF

il ojetivo del prolem es diser un lgoritmoD on omplejidd polinomilD que tome l informin dd y determine l mejor signin de profesores ursos intensivos on l restriinD impertivD de que los profesores de ms lts tegors tienen preferenis sore los de menoresF il lgoritmo dee retornr un signin orret o indir que no existeF ixplique mo se modelizr un red de )ujo que instrumente el lgoritmo en uestinF

Bibliografa
I iletri feneF http://www.pf-lug.de/projekte/haya/efence.phpF P plw(nderF http://www.dwheeler.com/flawfinder/F Q httpXGGenFwikipediForgGwikiGirthdyprolemF R httpXGGhttpXGGwwwFefghFomGmthGirthdyFhtmF S httpXGGwwwFgnuForgGsoftwreGgperfGF T qF wF edel9sonEel9skii nd iF wF vndisF en lgorithm for the orgniztion of informtionF oviet wthemtis hokldyD QXIPSW!IPTQD IWTPF U ehoD roproftD nd llmnF ht trutures nd elgorithmsF eddisonEesleyD edingD IWVQF V ehoD roproftD nd llmnF istruturs de dtos y lgoritmosF eddisonEesley seromerinD IWVVF rduicn de emcrio rgs illzcn y torge vozno worenoF W elfred F ehoD tohn iF roproftD nd te'rey hF llmnF he hesign nd enlysis of gomputer elgorithmsF eddisonEesleyD edingD weD eD IWURF IH F uF ehujD F vF wgnntiD nd tF fF yrlinF xetwork plowsX heoryD elgorithmsD nd epplitionsF rentie rllD IWWQF II ul fhmnnF hie enlytishe hlentheorieF hlentheorieD ptF PF fF qF eunerD viepzigD IVWRF IP tF F fkus nd F F reisingF pyexF siii rnstions on iletroni gomputersD igEIQ@RAXQVP!QVSD IWTRF IQ qF hi fttistD F idesD F mssiD nd sF qF ollisF qrph hrwingY elgorithms for the isuliztion of qrphsF rentie rllD IWWWF IR udolf fyerF ymmetri inry fEtreesX ht struture nd mintenne lgoE rithmsF et snformtiD I@RAXPWH!QHTD xovemer IWUPF IS udolf fyer nd idwrd wF wgreightF yrgniztion nd mintenne of lrge ordered indiesF et snformtiD IXIUQ!IVWD IWUPF IT wokhtr F fzrD tohn tF trvisD nd rnif hF herliF viner rogrmming nd xetwork plowsF ileyD fourth editionD PHHWF VQW

840

BIBLIOGRAFA

IU httpXGGinvisileEislndFnetGppF IV ihrd fellmnF yn routing prolemF urterly of epplied wthemtisD IT@IAXVU!WHD IWSVF IW tF vF fentleyF rogrmming erlsF eddisonEesleyD IWVTF PH hniel tF fernsteinF gin we de dniel jF ernsteinF PI himitri F fertseksF xetwork yptimiztionX gontinuous nd hisrete wodelsF ethen ienti(D felmontD wsshusettsD IWWVF PP httpXGGwwwFtnForgF PQ yF foruvkF  y jistm prolmu minimlnmF re worvsk rodovdek polenostiD QXQU!SVD IWPTF sn gzehF PR predrik F frooksF he wythil wnEwonthX issys on oftwre ingineeringD PHth enniversry iditionF eddison esleyD edingD wssFD seond editionD IWWSF PS tF fhiF ek seondEorder logi nd (nite utomtF F wthF vogik qrundlgen wthFD SXTT!WPD IWTHF PT fyteD editorF peil issue on mlltlkD volume TD eugust IWVIF PU eter glingertF essemlersD ompilersD nd progrm trnsltionF gomputer iene ressD IWUWF PV grter nd egmnF niversl lsses of hsh funtionsF sn ygX egw ympoE sium on heory of gomputing @ygAD IWUUF PW FtF gihelliF winiml perfet hsh funtions mde simpleF gommunitions of the egwD PQ@IAXIU!IWD tnury IWVHF QH httpXGGwwwFmkeForgF QI pF tF gortoD tF rF ltzerD nd gF F glingenF wultis ! the (rst seven yersF sn pring toint gomputer gonfereneD pges SUI!SVQF eps ressD wy IWUPF QP F rF gormenD gF iF veisersonD nd F vF ivestF sntrodution to elgorithmsF ws ressD gmridgeD weD eD IWVWF QQ gF eF grneF viner lists nd priority queues s lned inry treesF hh thesisD gomputer iene heprtmentD tnford niversityD IWUPF QR yF tF hhl nd uF xygrdF swve ! n evqyvEsed simultion lngugeF gommunitions of the egwD W@WAXTUI!TVPD eptemer IWTTF QS qF fF hexsqF rogrmming in liner strutureF ionometriD IUD IWRWF QT httpXGGwwwFgnomeForgGprojetsGdiF QU iF F hijkstrF sn honour of (oniF sn pF vF fuer nd wF froyD editorsD rogrm gonstrutionD volume TW of veture xotes in gomputer ieneD pges RW!SHF pringer erlgD IWUVF

BIBLIOGRAFA

841

QV httpXGGwwwFdoxygenForgF QW ernold sF humeyF sndexing for rpid rndom ess memory systemsF gomputers nd eutomtionD S@IPAXT!WD heemer IWSTF pirst pper in open literture on hshingF pirst use of hshing y tking the modulus of division y prime numerF wentions hining for ollision hndlingD ut not open ddressingF ee RU for the ltterF RH idmonds nd urpF heoretil improvements in lgorithmi e0ieny for network )ow prolemsF tegwX tournl of the egwD IWD IWUPF RI F ilisD eF peinstinD nd gF iF hnnonF xote on )ow through networkF si rnsF on snformtion heoryD pges IIU!IIWD IWSTF RP illsonD qnsnerD uoutso(osD xorthD nd oodhullF qrphviz ! open soure grph drwing toolsF sn qhesxqX gonferene on qrph hrwing @qhAD PHHIF RQ tohn illsonD imden F qnsnerD ileftherios uoutso(osD tephen gF xorthD nd qordon oodhullF qrphviz nd dyngrph ! stti nd dynmi grph drwing toolsD PHHQF RR httpXGGwwwFgnuForgGsoftwreGemsGF RS hwson inglerD hvid u ghenD eth rllemD endy ghouD nd fenjmin ghelfF fugs s devint ehviorX e generl pproh to inferring errors in systems odeD eugust HW PHHIF RT hwson F inglerD fenjmin ghelfD endy ghouD nd eth rllemF gheking system rules using systemEspei(D progrmmerEwritten ompiler extensionsF sn roeedings of the Uth ymposium on yperting ystem hesign nd smplementtionD pges I!ITD PHHHF RU eF F irshovF hokldy edkF xuk D IIVXRPU!RQHD IWSVF edisovery nd (rst pulition of liner open ddressingF RV illim pellerF en sntrodution to roility heory nd sts epplitionsD olF IF ileyD IWUHF RW illim pellerF en sntrodution to roility heory nd sts epplitionsD olF PF ileyD IWUHF SH F pljoletD hF qrdyD nd vF himonierF firthdy prdoxD oupon olletorsD hing lgorithms nd selfEorgnizing serhF ehnil eport exEgEVUEIIUTD heprtment of gomputer ieneD tnford niversityD IWVUD eugustF SI hilippe pljoletD F tF qrnerD F uirshenhoferD nd rF rodingerF yn rmnuE jn9s EfuntionF ehnil eport EIUTHD snriD snstitut xtionl de eherhe en snformtique et en eutomtiqueF SP F ploydF elgorithm WUX hortest pthF gommunF egwD S@TAXQRSD IWTPF SQ F F ploydF elgorithm PRS X reesort QF gommF egwD UXUHID IWTRF

842

BIBLIOGRAFA

SR vF F pord nd hF F pulkersonF wximl )ow through networkF gndin tF of wthemtisD VXQWW!RHRD IWSTF SS vestor F pordD trF nd hF F pulkersonF plows in xetworksF rineton niversity ressD IWTPF ST mss puenmyorF snterpretndo yrgnizionesFFF n eor istmioE snterperttiv de yrgnizionesF niversidd de vos endes E gonsejo de puliE iones E gonsejo de istudios de ostgrdoD PHHIF SU iF qmmD F relmD F tohnsonD nd tF lissidesF hesign tternsF eddisonE esleyD IWWSF SV imden qnsnerD ileftherios uoutso(osD nd tephen xorthF hrwing grphs with dotF ehnil reportD e8 fell vortoriesD wurry rillD xtD eD perury PHHPF SW eln qionsF elgorithmi qrph heoryF gmridge niversity ressD gmE ridgeD IWVSF TH httpXGGwwwFgnuForgF TI httpXGGwwwFgnuplotFinfoF TP qolderg nd rjnF e new pproh to the mximumE)ow prolemF tegwX tournl of the egwD QSD IWVVF TQ wF F qoodrih nd F mssiF ht trutures nd elgorithms in tvF tohn iley 8 onsD IWWVF TR F vF qrhmD hF iF unuthD nd yF tshnikF gonrete wthemtisX e pounE dtion for gomputer ieneF eddisonEesley uFD IWWRF TS yjet wngement qroupF ywq ni(ed wodeling vnguge PFH roposlD eE vised sumission to ywq ps dGHHEHWEHI nd dGHHEHWEHPD ersion HFTUIF ywqD httpXGGwwwFomgFomGumlGD PHHPF TT httpXGGwwwFgnuForgGsoftwreGgslGF TU quis nd edgewikF e dihromti frmework for lned treesF sn pygX siii ymposium on poundtions of gomputer iene @pygAD pges V!PID IWUVF TV ko qunji nd iiihi qotoF tudies on hshing " IF omprison of hshing lgorithms with key deletionF tournl of the snformtion roessing oiety of tpnD Q@IAXI!IPD cccc IWVHF TW hvid F rnson nd ghristopher F prserF e etrgetle g gompilerX hesign nd smplementtionF eddison esleyD IWWSF UH prnk rrryF qrph heoryF eddisonEesleyD edingD weD IWTWF

BIBLIOGRAFA

843

UI gF eF F roreF elgorithms TRX uiksortF gommunitions of the egwD R@UAXQPID IWTIF UP er rolgerD tenEwr tzquelD nd fertrnd weyerF vettersX ling the lme for erine SF gomputerD QH@SAXTD VD wy IWWUF UQ roltzmnnF he power of IHX ules for developing sfetyEritil odeF gywE iX siii gomputerD QWD PHHTF UR qF tF rolzmnnF he pin wodel ghekerD rimer nd eferene wnulF eddisonEesleyD edingD wsshusettsD PHHQF US qerrd tF rolzmnnF hesign nd lidtion of gomputer rotoolsF rentie rllD inglewood gli'sD xtD IWWIF UT qerrd tF rolzmnnF he model heker spinF siii rnstions on oftwre ingineeringD PQ@SAXPUW!PWSD wy IWWUF UU qerrd tF rolzmnnF en nlysis of itstte hshingF porml wethods in ystem hesignD IQ@QAXPVW!QHUD IWWVF UV tF iF roproft nd F iF rjnF i0ient lgorithms for grph mnipultionF gomE munF egwD I@TAXQUP!QUVD tune IWUQF UW F gF ru nd eF gF ukerF yptiml omputer serh trees nd vrile length lpheti odesF sew tF epplied wthFD PIXSIR!SQPD IWUIF VH hF eF ru'mnF e method for the onstrution of minimum redundny odesF roF sFFiFD RHXIHWV!IIHID IWSIF VI hvid eF ru'mnF e method for the onstrution of minimumEredundny odesF roeedings of the siD RH@WAXIHWV!IIHID eptemer IWSPF VP httpXGGxorgFfreedesktopForgF VQ hF rF rF sngllsF hesign priniples ehind smlltlkF fiD T@VAXPVT!PWVD eugust IWVIF VR F trnkF y jistm prolmu minimlnmF polenostiD TXSU!TQD IWQHF in gzehF r worvsk rodovk

VS tenEwr tzquel nd fertrnd weyerF yjet tehnologyX hesign y ontrtX he lessons of erineF gomputerD QH@IAXIPW!IQHD tnury IWWUF ee lso letters UPF VT endrew vF tohnson nd frd gF tohnsonF viterte progrmming using noweF vinux tournlD pges TR!TWD otoer IWWUF VU F gF tohnsonF vsx X e C progrm hekerF sn xs rogrmmer wnulF fivv vsFD 7th editionD IWUWF VV xioli wF tosuttisF he gCC tndrd virryX tutoril nd refereneF puE eD puEeXdrD IWWWF

844

BIBLIOGRAFA

VW hieter tungnikelF qrphsD xetworks nd elgorithmsF pringerD PHHRF WH xF urmrkrF e new polynomil!time lgorithm for liner progrmmingF gomiE ntoriD RXQUQ!QWSD IWVRF WI urp nd inF i0ient rndomized ptternEmthing lgorithmsF sfwthX sfw tournl of eserh nd hevelopmentD QID IWVUF WP eF F urznovF hetermining the mximl )ow in network y the method of pre)owsF oviet wthF hoklFD ISXRQR!RQUD IWURF WQ frin F uernighn nd o ikeF he rtie of rogrmmingF eddisonEesleyD edingD weD IWWWF WR frin F uernighn nd hennis ithieF he g rogrmming vngugeD eond iditionF rentieErllD IWVVF WS vF qF uhhiynF e polynomil lgorithm in liner progrmmingF oviet wtheE mtis hokldyD PHXIWI!IWRD IWUWF WT honld iF unuthF viterte progrmmingF he gomputer tournlD PU@PAXWU!IIID IWVRF WU honld iF unuthF pundmentl elgorithmsD volume I of he ert of gomputer rogrmmingF eddisonEesleyD edingD weD eD third editionD IWWUF WV honld iF unuthF eminumeril elgorithmsD volume P of he ert of gomputer rogrmmingF eddisonEesleyD edingD weD eD third editionD IWWUF WW honld iF unuthF orting nd erhingD volume Q of he ert of gomputer rogrmmingF eddisonEesleyD edingD weD eD seond editionD IWWVF IHH honld iF unuthF eleted pers on enlysis of elgorithmsF gvs ulitionsD tnfordD geD eD PHHHF IHI fernhrd uorte nd tens ygenF gomintoril yptimiztionX heory nd elE gorithmsF pringerEerlgD fourth editionD PHHVF IHP honld vF ureher nd hougls F tinsonF gomintoril elgorithmsF gg ressD IWWWF sfx HEVRWQEQWVVEF IHQ futler F vmpsonF rints for omputer system designF siii oftwreD I@IAXII!PVD tnury IWVRF IHR edidyh vngsmD woshe eugensteinD nd eron wF enenumF ht strutures using g nd gCCF rentieErllD pper ddle iverD xt HURSVD eD IWWTF IHS vrsonF hynmi hsh tlesF gegwX gommunitions of the egwD QID IWVVF IHT httpXGGwwwFtnForgF IHU iF vF vwlerF gomintoril yptimiztionX xetworks nd wtroidsF inehrtEinstonD xew orkD IWUTF roltE

BIBLIOGRAFA

845

IHV rrry F vewis nd vrry henenergF ht trutures nd heir elgorithmsF rrper gollins ulishersD xew orkD IWWIF IHW viskov nd illesF rogrmming with strt dt typesF igpln xotiesD WD IWURF IIH itold vitwinF viner hshingX e new lgorithm for (les nd tles ddressingF sn sgyhD pges PTH!PUTD IWVHF III hvid qF vuenerger nd inyu eF viner nd xonliner rogrmmingF pringE erEerlgD third editionD PHHVF IIP tF vuksiewizF y znzeniu i potrezeh logiki mtemtyznej @on the importne nd needs of mthemti logiAF xuk olskD IHXTHR!TPHD IWPWF IIQ elsdir wsntyreD editorF efter irtueF niversity of xotre hme ressD IWVRF IIR teve wguireF riting solid odeX wirosoft9s tehniques for developing ugE free g progrmsF wsgyypD IWWQF IIS F wnn nd eF nueliF pei(tion nd veri(tion of onurrent progrms y EutomtF sn gonferene reord of the IRth egw ymposium on riniples of rogrmming vnguges @yvAD pges I!IPD IWVUF IIT ohr wnn nd ihrd ldingerF he origin of the inryEserh prdigmF ehnil eport eportD tnford niversityD tnfordD geD IWVUF IIU gonrdo wrtnez nd lvdor ourF ndomized inry serh treesF tournl of the egwD RS@PAXPVV!QPQD wrh IWWVF IIV wkoto wtsumoto nd oshihru uuritF wisted qp genertorsF egw rnsE tions on wodeling nd gomputer imultionD P@QAXIUW!IWRD tuly IWWPF IIW wkoto wtsumoto nd oshihru uuritF wisted qp genertors ssF egw rnstions on wodeling nd gomputer imultionD R@QAXPSR!PTTD tuly IWWRF IPH wkoto wtsumoto nd kuji xishimurF he dynmi retion of distriuted rndom numer genertorsF sn gD IWWWF IPI httpXGGmximFsoureforgeFnetF IPP teve wgonnellF gode gompleteF wirosoft ressD edmondD eFD IWWQF IPQ uF wengerF ntersuhungen er llgemeine wetrikF wthF ennFD IHHXUS!ITQD IWPVF IPR fertrnd weyerF hesign y ontrtD omponents nd deuggingF tyyD II@VAXUS! UWD IWWWF IPS ott meyerF wore e'etive C++ X QS new wys to improve your progrms nd designsF eddisonEesleyD IWWTF sfx HEPHIETQQUIEF IPT ott weyersF i'etive gCCF eddison esleyD IWWPF IPU ott weyersF wore i'etive gCCF eddison esleyD IWWTF

846

BIBLIOGRAFA

IPV qF tF wyersF he ert of oftwre estingF tohn iley 8 onsD IWUVF IPW xihols xetherote nd tulin ewrdF lgrindX e progrm supervision frmeE workF iletrF xotes heorF gomputF iD VW@PAD PHHQF IQH xihols xetherote nd tulin ewrdF lgrindX e progrm supervision frmeE workF iletrF xotes heorF gomputF iD VW@PAD PHHQF IQI ellen xewell nd tF gF hwF rogrmming the logi theory mhineF sn roeedings of the IWSU estern toint gomputer gonfereneD pges PQH!PRHF siD IWSUF IQP ellen xewellD tF gF hwD nd rF eF imonF impiril explortions with the logi theory mhineF sn estern toint gomputer gonfereneD volume ISD pges PIV! PQWD IWSUF IQQ torge xoedl nd tephen tF rightF xumeril optimiztionF pringer series in opertions reserhF pringerEerlgD puEXdrD seond editionD PHHTF IQR e wngeril iew of the wultis ystem hevelopmentF pF tF orto nd gF F linE genF sn gonferene on eserh hiretions in oftwre ehnologyD rovideneD hode sslndD ytoer IWUUF IQS eF yrm nd qF ilsonD editorsF feutiful godeX veding rogrmmers ixplin row hey hinkF y9eillyD PHHUF IQT tohn uF yusterhoutF riptingX righerElevel progrmming for the PIst enturyF siii gomputerD QI@QAXPQ!QHD IWWVF IQU yzn igit ozdnexusFyorkuFF gin we del proyeto sdmF IQV gF rF pdimitriou nd uF teiglitzF gomintoril yptimiztionF rentieErllD IWVPF IQW sn rerryF rolems on lgorithmsF rentieErllD inglewood gli'sD xtD IWWSF IRH hF vF rnsF e tehnique for softwre module spei(tion with exmplesF gomE munitions of the essoition of gomputing whineryD IS@SAXQQH!QQTD wy IWUPF IRI eF tF erlis nd gF horntonF ymol mnipultion y threded listsF gommuniE tions of the egwD Q@RAXIWS!PHRD epril IWTHF IRP F erretF puntionhekF http://sourceforge.net/projects/fnccheckF IRQ F F etersonF eddressing for rndom ess storgeF sfw tournl of eserh nd hevelopmentD I@PAD epril IWSUF IRR FtFwker nd he pree oftwre poundtionF he qx xexe homepgeF IRS eF nueliF he temporl logi of progrmsF sn fosUUD pges RT!SUD IWUUF IRT wwwFhttpXGGrEprojetForgF

BIBLIOGRAFA

847

IRU xormn mseyF viterte progrmming simpli(edF siii oftwreD II@SAXWU!IHSD eptemer IWWRF IRV ingiresu F oF ingineering yptimiztionF tyrx svi 8 yxD sxgFD fourth editionD PHHWF IRW hvid F osenlumF gorretion to e prtil pproh to progrmming with ssertionsF siii rnstions on oftwre ingineeringD PI@QAXPTSD wrh IWWSF ISH hvid F osenlumF e prtil pproh to progrmming with ssertionsF siii rnstions on oftwre ingineeringD PI@IAXIW!QID tnury IWWSF ISI wF ozierD F erossimovD pF ermndD sF fouleD wF qienD wF quillemontD pF rerE rmnnD gF uiserD F vngloisD F veonrdD nd F xeuhuserF gry distriuted operting systemsF ixs gomputing ystemsD I@RAXQHS!QUHD IWVVF ISP tmes iF umughF ywX he ojet modelF tyyD U@VAXPI!PUD IWWSF ISQ heo gF uys nd qerrd tF rolzmnnF edvned sx tutorilF sn usnne qrf nd vurent wounierD editorsD wodel gheking oftwreD IIth snterntionl sx orkshopD frelonD pinD epril IEQD PHHRD roeedingsD volume PWVW of veture xotes in gomputer ieneD pges QHR!QHSF pringerD PHHRF ISR tF ltzerD hF eedD nd hF glrkF indEtoEend rguments in system designF egw rnstions on gomputer ystemsD P@RAD IWVRF ISS oert edgewikF elgorithms in gX rts I!RX pundmentlsD dt struturesD sortingD serhingF eddisonEesleyD edingD weD eD IWWVF IST oert edgewikF elgorithms in gX rt SX qrph lgorithmsF eddisonEesleyD puEeXdrD PHHPF ISU oert edgewik nd hilippe pljoletF en sntrodution to the enlysis of elE gorithmsF eddisonEesley ulishing gompnyD IWWTF ISV F eidel nd gF F ergonF ndomized serh treesF elgorithmiD IT@RGSAXRTR! RWUD ytoerGxovemer IWWTF ISW teven F kienF he elgorithm hesign wnulF pringerEerlgD ferlinD qerE mny G reidelergD qermny G vondonD u G etFD IWWVF ITH hFhF letor nd oert i rjnF elfEdjusting finry erh reesF tournl of the egwD @QPAXIWS!PHRD IWVSF ITI ihrd tllmn nd olnd rF eshF heugging with qhfX the qx soureE level deuggerF pree oftwre poundtionD snFD puEppXdrD RFHW for qhf version RFW editionD IWWQF revious edition pulished under titleX he qhf mnulF eugust IWWQF ITP gF tF tephensonF e method for onstruting inry serh trees y mking inserE tions t the rootF snterntionl tournl of gomputer nd snformtion ienesD W@IAXIS!PWD perury IWVHF

848

BIBLIOGRAFA

ITQ fjrne troustrupF he hesign nd ivolution of gCCF eddison esleyD eding wssFD IWWRF ITR fjrne troustrupF he gCC rogrmming vngugeF eddisonEesleyD Qrd ediE tionD PHHHF ITS uozo ugiymF qrph hrwing nd epplitions for oftwre ingineering nd unowledge ingineersD volume II of oftwre ingineering nd unowledge ingineeringF orld einti(D PHHPF ITT F iF rjnF hepth (rst serh nd liner grph lgorithmsF sew tF gomputFD I@PAXIRT!ITHD tune IWUPF ITU oert iF rjnF emortized omputtionl omplexityF ilgdisD TXQHT!QIVD IWVSF ITV vrry eslerF he mlltlk environmentF fyteD T@VAXWH!IRUD eugust IWVIF ITW httpXGGtugForgGtetexGF IUH httpXGGwwwFkdeForgF IUI eter vn der vindenF ixpert g rogrmming E heep g eretsF unoft ress Ee rentie rll ittleED IWWRF sfx HEIQEIUURPWEVF IUP qF vn ossum nd pF vF hrkeD trFD editorsF en sntrodution to ythonF xetwork heory vtdD eptemer PHHQF IUQ F vn lekF hree questions out eh ug you (ndF IWVWF IUR riosF quest editor9s introdutionX he top IH lgorithmsF gomputing in iene nd ingineering @giAD P@IAXPP!PQD tnury PHHHF IUS tohn iegD tF F flohD dyoshi uohnoD nd qry wqrwF sRX e stti vulnerility snner for g nd gCC odeF sn ITth ennul gomputer eurity epplitions gonfereneF egwD heemer PHHHF IUT ten uilleminF e dt struture for mnipulting priority queuesF gommuniE tions of the egwD PI@RAXQHW!QISD epril IWUVF IUU vrry ll nd ndl vF hwrtzF rogrmming erlF y9eilly 8 essoitesD snFD IWWHF IUV tephen rshllF e theorem on foolen mtriesF tournl of the egwD W@IAXII! IPD tnury IWTPF IUW qry tsonF hmllo E deug mllo lirryF http://dmalloc.com/F IVH wF eF eissF ht trutures nd elgorithm enlysis in gF eddisonesleyD IWWUF h nd e e not in gD fenjmingummingsD 9WPF IVI tF F tF illimsF elgorithm PQP X rieyF gommF egwD UXQRU!QRVD IWTRF IVP xiklus irthF elgorithms + ht trutures = rogrmsF rentieErll eries in eutomti gomputtionF rentieErllD pper ddle iverD xt HURSVD eD IWUTF

BIBLIOGRAFA

849

IVQ ierre olper nd henis veroyF elile hshing without ollosion detetionF sn gosts gourouetisD editorD gomputer eided eri(tionD Sth snterntionl gonfereneD ge 9WQD iloundD qreeeD tune PV E tuly ID IWWQD roeedingsD volume TWU of veture xotes in gomputer ieneD pges SW!UHF pringerD IWWQF IVR herik oodF ht truturesD elgorithmsD nd erformneF eddisonEesleyD edingD IWWQF IVS httpXGGwwwFx(gForgF IVT tunfeng ngD gn rD nd hwson inglerF plodeX lightweightD generl system for (nding serious storge system errorsF sn roeedings of the Uth ymposium on yperting ystem hesign nd smplementtionD PHHTF IVU ty ellen nd tonthn vF qrossF qrph heory 8 sts epplitionsF gg ressD IWWVF sfxX H!VRW!QQWVP!HF IVV F (ropuloD gF estD rF udinD hF gownD nd hF frndF owrds nlysing nd synthesizing protoolsF siii rnstions on gommunitionD gommE PV@RAXTSI PHIQTTID IWVHF IVW endres eller nd horothe vtkehusF hhh E e free grphil frontEend for xs deuggersF sqvex xotiesD QI@IAXPP!PUD IWWTF

ndice de trminos
rol ltur de unD PUS ompleto representin on rreglo seuenilD PVP de(niinD PPT rol rdor de un grfoD SQV rol rdor de mplitudD THQ rol inrio de(niinD PQQ nodo ompletoD PVH nodo inompletoD PVH nodo llenoD PVH reorrido in(joD PQS reorrido por nivelesD PQS reorrido pre(joD PQS reorrido su(joD PQS rol inrio de squed squedD QIS de(niinD QIR elimininD QPR inserinD QPH inserin en rzD QPT supresinD @QPRD QPT rol inrio de squed extendido inserin en rzD QRH roles nestros de un nodoD PPT inrios de squedD @QIQD QQP nlisisD @QPWD QQP squedD @QISD QIW squed de pdreD QIU squed de rngoD QIU squed del predeesorD QIU squed del suesorD QIU rtiD @QPWD QQP de(niinD QIR inserinD @QPHD QPI mximoD QIT mnimoD QIT supresinD @QPRD QPT generin de un nodoD PPU grdo de un nodoD PPU representin en memoriD PQI roles inrios lulo de l lturD PRW lulo de l rdinliddD PRW omprinD PSH destruinD PSH equivleniD PSI extensiones lulo de l posiin in(jD QQV inserin por lveD QQV seleinD QQU hildosD @PSSD PTH joinD QPU join exlusivoD QPQ prtiinD QPI por posiinD QRH prtiin por lveD QQW reorridos no reursivosD PRT rotinD QRR splitD QPI uninD QPU unin exlusivD QPQ roles inrios on rngosD QQT roles inrios de squedD @QIQ nlisisD @QPWD QQP rtiD @QPWD QQP extendidosD QQT roles inrios extendidosD @QQSD AQRR eliminin por lveD QRP eliminin por posiinD QRQ inserin por posiinD QRI rotinD QRS

VSH

NDICE DE TRMINOS

851

unin exlusivD QRP roles esttios ptimosD @QSVD QTQ removellnddelete@AD VP estrutur de dtos orientd hi el oneptoD PI orientd hi el )ujoD PI orientds hi los dtosD PI triutosD QVS uetsD QVR inserinD QVT VHEPH reglD PIP eff squedD QIS squeds espeilesD QIU onteninD QPU ontenin exlusivD QPQ elimininD QPR inserinD QPH inserin en rzD QPT joinD QPU join exlusivoD QPQ prtiinD QPI predeesorD QIU splitD QPI suesorD QIU uninD QPU unin exlusivoD QPQ effe unin exlusivD RSV effi lulo de l posiin in(jD QQV desempeoD QRQ eliminin por lveD QRP eliminin por posiinD QRQ inserin en rzD QRH inserin por lveD QQV inserin por posiinD QRI prtiinD QQW prtiin por posiinD QRH seleinD QQU splitD QQW unin exlusivD QRP eso fuer de loqueD PHV iliiddD SWI tudorD W lnziliddD TQT

letorizinD IVH lger de OD ISW!ITH lgoritmo de lulo de Ke (G)D UVR de omprin de rol inrioD PSH de desomposiin de )ujoD UVP de destruin de rol inrioD PSH de urusklD TSW!TTR de rimD TTR!TUP reursivo de ltur de un rol inrioD PRW reursivo de rdinlidd de un rol iE nrioD PRW lgoritmo de pordEpulkersonD UPR nlisisD UPV lgoritmo de idmondsEurpD UPW nlisisD UQP lgoritmo de lulo de Ke (G))D UVR lgoritmo de lulo de onetividd de rE osD UVR lgoritmo de onversin de red on piE ddes en nodos un red trdiE ionlD UUP elgoritmo de inEurpD RQI elgoritmo de rshll pr l lusur trnsitivD TQQ!TQS lgoritmo simplexD VIQ!VPH lgoritmos letoriosD IVH ltur de nodo en red de )ujoD UQS de un rolD PPV de un nodoD PPU ltur de un rolD PUS ltur de un rol inrioD PRW ltur negr en un rol rojoEnegroD RWH nlisis mortizdoD IVU nlisis ontleD IWI!IWP nlisis de lgoritmosD IRU nlisis de los roles inrios de squedD @QPWD QQP nlisis del lgoritmo de pordEpulkersonD UPV nlisis del lgoritmo de idmondsEurpD UQP nlisis del lgoritmo genrio de pre)ujoD URR

852

NDICE DE TRMINOS

nlisis del mnejo de olisiones por direE ionmiento ierto y sondeo linelD QWW nlisis del mnejo de olisiones por endeE nmiento errdoD QWP nlisis del mnejo de olisiones por endeE nmiento seprdoD QVU nlisis del mergesortD IUI nlisis del sondeo idelD QWQ nlisis potenilD IVW!IWI nlisis mortizdo nlisis ontleD IWI!IWP nlisis potenilD IVW!IWI selein de rditosD IWP!IWQ selein de funin potenilD IWP!IWQ nlisis de los roles letorizdosD RTH!RTR nlisis de los roles splyD SIQ!SIV nlisis de los trepsD RUH!RUI nlisis del quiksortD IUT nlizdor externoD PHH nestros de un nodoD PPT pliiones de ls olsD IPQ puntdores y rregloD PW rol rojoEnegroD RVW de pioniD RVR rol ev rtioD RVT rol rdor de profundiddD THI rol rdor mnimoD TSV!TUP rol inrio de squed letorioD RSS roles lmenmientoD QII ev nlisisD RVQ!RVW elimininD @RUVD RVQ inserinD @RUQD RUV equilirio perfetoD RSP nodo inrio eh BinNode<Key>D PQV rojoEnegroD RVW!SHT nlisisD SHP!SHT elimininD @RWTD SHP inserinD @RWPD RWT splyD SHT!SIV roles evD RUI!RVW nlisisD RVQ!RVW

de(niinD RUI elimininD @RUVD RVQ inserinD @RUQD RUV roles letorizdosD RSS!RTR nlisisD RTH!RTR onteninD RSV elimininD RSU inserinD RST supresinD RSU trepD RTV roles inrios similriddD PSI roles inrios letorizdos unin exlusivD RSV roles inrios extendido splitD QQW roles de pioniD RVR!RVU lturD RVS rdinliddD RVS roles equilirdosD RSP!RSR roles splyD SHT!SIV nlisisD SIQ!SIV roles treps nlisisD RUH!RUI roles inrios de squedD QQP roles ompletos representin en memoriD PVH roreseniD PPT reorridosD PTPD PUH eh Tree_Node D PTW ro reljinD TWQ ro inidenteD SQT ro prleloD SQU ros de un grfo implntinD STR ritmti de polinomios uso de lists enlzdsD WI ritmti de punterosD PW rreglo en memori dinmiD QQ squed inriD QH squed por lveD QH lulo de direinD PW oneptos generlesD PV de itsD SQ!SV

NDICE DE TRMINOS

853

squed dinmioD QR!SQ eliminin por lveD QI sore rreglosD IVR en memori esttiD QP squed letori en pilD QQ en rregloD IVR inserin por lveD QI en listsD IVS multidimensionlD SV squed inriD QHD ITS!ITT squed de minos por mplitudD SWV pr representr rolesD PQP sertosD PHR squed de minos por profundiddD SWR signinD UUS squed de ilos en un grfoD SWH )ujo mximo oste mnimoD VHU lulo de nodos perteneientes un nivelD LhashTable<Key>D QVS PSR triutos de ontrol de nodos y ros de un lulo del nmero de hewyD PUP grfoD SSQ digos de ru'mnD QRS!QSV utmtD PHP odi(in de textoD QSQ ev deodi(inD QRW rolesD RUI!RVW ingreso de freuenisD QSP squed optiminD QSS de ros en grfoD SSP heD PIS de ilos negtivosD UHI dens de produin de nodos en grfoD SRU )ujo mximo oste mnimoD VPR seuenilD IS lulo de red residul en un red de )ujoD squed inriD QH UPI squed de ros en un grfo mino implementinD STQ squed en profundiddD SWS squed de extremosD IST entre nodos de un rolD PPT squed de mximoD IST longitud en un rolD PPT squed de mnimoD IST prue de existeniD SWRD TQQ squed de nodos en un grfo simpleD SQT implementinD STQ mino de gtlnD QHV mino de un grfoD SQT squed en tl hsh linelD RIV squed seueniD ISR!ISS gmino ms ortoD PII fellmnEpord mino ms ortoD PIH minos mnimosD TWH!UHS minos de umentoD UIV BinHeap<Key> lulo deD UPQ tulizin de un elementoD PWW minos mnimosD TUP!UHT lgoritmo de fellmnEpordD TWH!UHS elimininD PWV eliminin de ulquier elementoD PWW lgoritmo de hijkstrD TUQ!TVQ eliminin de todos los elementosD QHH lgoritmo de ploydErshllD TVQ!TWH snserinD PWU disusinD UHS intermio entre nodosD PWT nelin de ilos negtivos BinNode<Key> lgoritmo genrio deD UWR onversin Tree_Node D PUQ piddD UHT BinTree<Key>D QIW pidd de un orteD UIT BitArrayD SQ!SV rdinlidd its de ontrolD SSQ de un rolD PPV uleD SQT identiddD PUV

854

NDICE DE TRMINOS

del nivelD PUU rdinlidd de un rol inrioD PRW sting Dlink estrutur ontenidD VH Slink estrutur ontenidD TV gtln nmero deD QHU!QII ilos squed de negtivosD UHI deteinD SWH prue de iliiddD SWI uso de lgoritmo de fellmnEpord pr su deteinD UHI ilos negtivos lgoritmo de fellmnEpordD TWU squedD UHI irulionesD UVI lgoritmo de desomposiin de )ujoD UVP desomposiin de un red enD UVP lse gestorD RW intermediriD RW proxyD RW lusur trnsitivD SWSD TQQ lique de un grfoD SQU digo de vuksiewizD QHPD QHT digo de un rol inrioD QHP ols pliionesD IPQ medinte rreglosD IPR medinte lists enlzdsD IPV medinte lists enlzds dinmisD IQH representiones en memoriD IPQ ols de prioriddD PVV tulizin de un elementoD PVW omprin de roles inriosD PSH gompre y DlinkD ISP omplemento de un grfoD SQU omponentes onexos de los puntos de orteD TPH omponentes fuertemente onexos de un diE grfoD TQU!TSI gomponentes inonexos de un grfoD THV

omprensin de dtosD QRS!QSV ontenin de roles letorizdosD RSV ondiin rojD RWH ondiin negrD RWH onetividdD UVQ entre digrfosD TQT entre grfosD SVU onetividd de ros lgoritmoD UVR luloD UVR implntin del lgoritmo de luloD UVS onetividd entre grfosD TQQ onjuntoD PH onjunto pre(joD QHQ onjuntos representin de rolesD PPV ontrin de tl hsh linelD RIQ onversin Dlink estrutur ontenidD VH Slink estrutur ontenidD TV onversin de un rol rdor un Tree_Node D THT orretitud squedD IWR deteinD IWR plntemiento del prolemD IWQ orrespondeni entre roles inrios y mE riosD PTH orrespondeni entre BinNode<Key> y Tree_Node D PUQ orrespondeni entre Tree_Node y BinNode<Key>D PUQ orte pidd deD UIT vlor de )ujoD UIS orte de un redD UIR orte mnimoD UIT lulo deD UTR ortes de redD UIR oste en espio de lgoritmos dividir omE inrD IUU oste mnimo del )ujo mximoD UWI ostumres de orretitud delogo de roltzmnnD IWT

NDICE DE TRMINOS

855

regunts titudinris de n glekD IWW rti de lgoritmosD IRU rti de los roles inrios de squedD @QPWD QQP rti del mergesortD IUI rti del quiksortD IUT LhashTable<Key>D QVR umpleosD QVI heqD TSI dddD PIH dedlokD PHP hifqD PHR delogo de roltzmnnD IWT deduinD PP deleteD QQ depurdoresD PIH desomposiin de )ujoD UVP desempeo de los roles inrios extendiE dosD QRQ destroyeD PSH destruin de Tree_Node D PUH destruin de un rol inrioD PSH detein de ilos negtivosD TWU hewy squed en Tree_Node D PUI notin pr rolesD PQI df D TII dimetro de un grfoD UHT higrm wv vists dolemente enlzdsD VR diolsD IPQ digrfoD SQT omponentes fuertemente onexosD TQU! TSI digrfosD TQS!TSV onetividdD TQT inversinD TQT ordenmiento topolgioD TSQ!TSV plni(inD TSP digrfos liosD TSI hijkstr minos mnimosD TUQ!TVQ riple prtiin del quiksortD IVR dipolosD IPQ

dispersin de dens de rteresD RPW dispersin por divisinD RPS dispersin por multipliinD RPT dispersin universlD RQH dividir ominrD ITV oste en espioD IUU dmlloD PHW DynArray<T> el prolem fundmentlD ISS hynetreeD QQP edd de un nodoD PPU el prolem del estionmientoD QUW eliminin en effD QPR rol inrio de squedD QPR eliminin de ilos negtivosD UWT eliminin de l reursinD IIT eliminin de l reursin olD IIT eliminin de l reursin por emulin de los registros de tivinD IIU eliminin en tl hsh linelD RIV eliminin por lve en roles inrios exE tendidosD QRP eliminin por posiin en roles inrios extendidosD QRQ eliminin totl de l reursinD IPI eliminin en rol rol rojoEnegroD @RWTD SHP eliminin en rol letorizdoD RSU eliminin en trepD RTV emprejmientoD UUS iprtidoD UUS de rdinlidd mximD UUS mximoD UUS perfetoD UUS emprejmiento iprtido )ujo mximoD UUT inglerD PHI enle doleD UP enle simpleD TS ensenz etimologD i enumerin de rolesD QHP equilirio perfeto de irthD RSP equivleni de roles inriosD PSI

856

NDICE DE TRMINOS

equivleni entre red y orteD UIS error de ompilinD PHH errores de memori eso fuer de loqueD PHV fugD PHU espio glol de estdoD PHI estilidd en ordenmientoD IUP mergesortD IUP estionmientoD QUW istrutur de dtos prolem fundmentlD IU!PH etimolog mortizrD IWP nlisisD IRS lnzD RSI rditoD IWP rtiD IRS equilirioD RSI genrioD IU genelogD PPQ generlD IU grfoD SQQ mtodoD V ojetoD S polimorfoD IQ reurreniD P reursinD P sntesisD IRS sujetoD S evluin de expresiones in(jsD IHT evluin de expresin su(jD IHU exeso de )ujoD UQR expnsin de tl hsh linelD RIQ extensiones los roles inriosD QQS lulo de l posiin in(jD QQV extensiones los roles inrios smolos desempeoD QRQ extensiones los rol inrio smolos inserin por lveD QQV extensiones los eff seleinD QQU pioniD IIT (nD PP )w(nderD PHI ploydErshll

minos mnimosD TVQ!TWH )ujo teorem de desomposiinD UVP vlor deD UHU )ujo ftileD UHU )ujo mximo lgoritmo genrio de empuje de preE )ujoD UQS lgoritmo genrio de pre)ujoD UQS vlores iniiles de lturD URH lgoritmo por empuje de pre)ujo genrio por ros selein letoriD UTQ selein por prioriddD UTQ selein por profundiddD UTP lgoritmo por empuje de pre)ujo genrio por rosD USV selein por mplitudD UTQ lgoritmos de empuje y pre)ujoD UQR lgoritmos de pre)ujo ltur de nodoD UQS ltur de nodoD UQS nlisis del lgoritmo genrio de preE )ujoD URR lulo del orte mnimoD UTR on piddes en los nodosD UUP de oste mnimoD UWI emprejmiento iprtidoD UUT empuje de pre)ujo on ol letoriD USQ empuje de pre)ujo on ol de prioriE ddD URW empuje de pre)ujo on ol pspyD URT empuje de pre)ujo on myor distniD URW implntin del lgoritmo genrio de pre)ujoD URP nodo tivoD UQR provisin de )ujoD UUP reduin desde un red no dirigidD UUI )ujo mximo oste mnimo signinD VHU dens de produinD VPR el prolem de signinD VHU prolem del trnsporteD VHP prolem del trsordoD VHS

NDICE DE TRMINOS

857

)ujo mximoGorte mnimoD UITD UTR )ujo relizleD UUP )ujos de oste mnimoD UWH!VPU onversin progrm linelD VPH form estndr de un progrm linelD VIH form holgd de un progrm linelD VIP portrnD SW fuenteD TQUD UHT fugs de memoriD PHU funin de pioniD IIT funin hsh holgur de dispersinD RPQ mtodo de divisinD RPS mtodo de multipliinD RPT funiones hshD RPQ gdD PIH genrioD IU generin de un nodoD PPU generlD IU grdo de un grfoD SQT grfo rol rdorD SQV iprtidoD SQV minoD SQT iloD SQT liqueD SQU omplemento deD SQU ompletmente onexoD SQU ompletoD SQU on pesosD SQS onexoD SQT dirigidoD SQT inonexoD SQU nodos iterdor de rosD SRV iterdor de nodosD SRV sugrfoD SQU totlmente onexoD SQU grfo iprtido lulo deD UUU grfo iprtido red de )ujoD UUT grfos olorinD SQW onetividdD SVU orteD UIR

de(niin formlD SQS dimetroD UHT emprejmientoD UUS Graph_NodeD SRS hep BinHeap<Key>D PWQ pliionesD PWI ols de prioriddD PVV tulizin de un elementoD PVW on rolesD PWQ on lists enlzdsD PWQ elimininD PVS inserinD PVR hep de ros mnimosD TTS hep exlusivoD TTS hepsD PVP on rreglosD PVQ hepsortD PVW reisenergD PHV heisenugD PHV hereniD II tiposD IP hereni mltipleD IP hildo de roles inriosD @PSSD PTH holgur de dispersin de un funin hshD RPQ roltzmnnD IWT ru'mn digosD QRS!QSV odi(in de textoD QSQ deodi(inD QRW ingreso de freuenisD QSP optiminD QSS indentin representin de rolesD PQH induinD PP LhashTable<Key>D QVT inserin en rol inrio de squedD QPH inserin en rz en rol inrio de squedD QPT en effD QPT en effiD QRH en inrio de squed extendidoD QRH inserin en tl hsh on resoluin de oE lisiones por endenmiento sepE

858

NDICE DE TRMINOS

rdoD QVT inserin en tl hsh linelD RIV inserin por lve en rol inrio extenE didoD QQV inserin por posiin de roles inrios extendidosD QRI inserin mtodo de ordenmientoD ITPD ITS inserin en rol letorizdoD RST inserin en rol rol rojoEnegroD @RWPD RWT inserin en trepD RTT interdor (ltro de ros de nodoD SVP de ros de un grfoD SVPD SVQ interfz de l funin hshD RPQ invrintesD PHR sterdor de ros de un grfo implntinD STQ de ros de un nodo de grfoD STV de nodos de un grfo implntinD STQ sore DlinkD VH sore Dnode<T>D VR iterdor de ros de un nodo de grfoD SRV de nodos sore un grfoD SRV list simplemente enlzdD UH sterdor de ros sore un nodo implntinD STV iterdoresD SW!TI iterdores (ltrosD SVH!SVQ itsRD PHI

lzoD SQT lem de l uniidd de un trepD RTS lintD PHI lists dolemente enlzds DlinkD UP Dnode<T>D VQ DynDlist<T>D VR enle doleD UP nodo doleD VQ dolemente enlzds dinmisD VR simplemente enlzds DynSlist<T>D UI enle simpleD TS iterdorD UH nodo simpleD TV SlinkD TSD TV Slist<T>D TW lists de dyeniD SRP en List_GraphD STR lists enlzdsD TI pr representr rolesD PQI List_GraphD SRQ signinD STH onstruinD STH destruinD STH implntin de l opi de grfosD SUR implntin de l eliminin de rosD SUI implntin de l eliminin de noE dosD SUP implntin de l inserin de rosD SUH implntin de l inserin de nodosD Ke (G) STW lgoritmoD UVR implntin de l limpiez de un grfoD luloD UVR SUQ implntin del lgoritmo de lulo implntin del mpeo de nodos y rE de Ke (G)D UVS os de un grfoD SUQ uorjsu livelokD PHP lgoritmo de lulo de omponentes lolidd de refereniD PIPD PIR fuertemente onexosD TQV espilD PIPD PIR urusklD TSW temporlD PIPD PIR nlisisD TTI longitud orretitudD TTP del mino en rolesD PPT

NDICE DE TRMINOS

859

multipopD IHP longitud del mino de(niinD PUU multisetD PH externo frmul en funin del mino inE nmero de gtlnD QHU!QII xmero de hewy ternoD PUW luloD PUP identiddesD PUV nmeros de pioniD IIS interno nnD PHR!PHU lmitesD PVH longitud del mino intern ponderdD QSV Net_GraphD UHV newD PWD QQ vuksiewizD QHP nivel de un nodo en un rolD PPU mximo emprejmiento iprtidoD UUS!UVI Node_Arc_IteratorD STV mtodo de divisin omo funin hshD RPS nodo mtodo de multipliin omo funin edd deD PPU hshD RPT generin deD PPU mtodos virtulD IQ grdo de un nodo en rolD PPU mnimo oste de )ujo mximoD UWI nodo inidenteD SQT mros pr grfosD SSW nodo tivoD UQR mpD PH nodo dyenteD SQT mpeoD PH xodo de un grfoD SRS rosD SSV nodo externo nodosD SSV ntidd en un rolD PUU mpeo de omponentes onexosD TPR de(niinD PUU mppingD PH nodo simpleD TV mthingD UUS notin mtemtis sore rolesD @PUSD QII de hewyD PQI mtriesD SV notin OD ISU!ITV mtriz O lulo de direinD SW de(niinD ISU en portrnD SW oD ISV wtriz de dyeniD SRH D ISV mtriz de dyeniD TPT D ISV memory leksD PHU D ISW mergesort notin in(jD IHT nlisisD IUI notin pre(jD IHT rtiD IUI notin su(jD IHT metEompilinD PHI nmero df D TII metompilinD PHI OD ISU!ITV mezl lger de OD ISW!ITH mtodo de ordenmientoD ITW!IUQ nlisis de lgoritmos medinte OD ITH! mezl de rreglosD IUH ITS modi(dorD W erroresD ITT!ITU multionjuntoD PH oD ISV multigrfoD SQU oservdorD W multihereniD IP oultmiento de informinD PQ multilistsD IQI D ISV multimpD PH

860

NDICE DE TRMINOS

D ISV operdor deleteD QQ newD PWD QQ orden de un rolD PPU ordenmiento estiliddD IUP inserinD ITPD ITS mezlD ITW!IUQ seleinD ISH!ISQ ordenmiento de ros sore un grfoD SUS yrdenmiento de lists enlzdsD ISP ordenmiento topolgioD TSQ!TSV orientin hi el oneptoD PI hi el )ujoD PI hi los dtosD PI

de hereniD IR de sorergD IQ polinomios implntin on lists enlzdsD WI sumD WS regunts de n glekD IWW rimD TTR nlisisD TUH orretitudD TUP prinipio de retoD PIP del VHEPHD PIP prinipio (nEE(nD PP prioriddes implits en trepsD RUI prolem del trnsporteD VHP prolem del trsordoD VHS prolem del vendedor vijeroD PIP prolem fundmentl de estruturs de dtosD IU prdoj pro(lingD PIR umpleosD QVI progrmin linelD VHV!VPH reto ilfredoD PIP onversin desde un red pitdD prtiin de roles inriosD QPI VPH prtiin de effD QPI form estndrD VIH prtiin de effiD QQW form holgdD VIP prtiin del quiksortD IUR form slkD VIP prtiin por lve de roles inrios exE simplexD VIQ tendidosD QQW promelGspinD PHQ prtiin por posiin de roles inriosD propieddes mtemtis de los rolesD QRH @PUSD QII pso de ejeuinD IRV proxyD RW per(ljeD PIR prue de iliiddD SWI perlD PIS prue de onetividdD SVUD TQT pil prue de existeni de minoD SWRD TQQ representiones en memoriD WW punteros y rregloD PW pils punto de rtiulinD TII on rreglosD IHI punto de orteD TII on lists enlzdsD IHQ pintdo de omponentes onexosD TPP on lists enlzds dinmisD IHS puntos de orte llmds proedimientosD IIP omponentes onexosD TPH reursinD IIP mpeo de omponentes onexosD TPR pintdo de omponentes onexosD TPP pythonD PIS pivote selein en el quiksortD IUW quiksortD IUQ!IVU plntillsD IS nlisisD IUT plegdo de lve en funin hshD RPR lves repetidsD IVQ polimor(smoD IQ on lists enlzdsD IVI

NDICE DE TRMINOS

861

en red pitd on ostesD UWP red pitd lulo de mino de umentoD UPQ red pitd on ostesD UWH red on piddes en los nodosD UUP red residulD UIW redes inEurp mino de umento squed de sudensD RQI inremento de )ujoD UPQ rpido piddD UHT mtodo de ordenmientoD IVU fuenteD UHT reallocD QR pre)ujoD UQR reorrido sumideroD UHT in(jo vlor de )ujoD UIS sore rol inrioD PQS redes pitds por niveles lgoritmo de pordEpulkersonD UPR sore rol inrioD PQSD PSI lgoritmo de idmondsEurpD UPW pre(jo minos de umentoD UIV sore roreseniD PTP on piddes en los nodosD UUP sore rol inrioD PQS on grfos no dirigidosD UUI su(jo orte mnimoD UIT sore rol inrioD PQS ortesD UIR sore roreseniD PTP de(niionesD UHT reorrido en mplitudD SVU )ujo mximoD UIT reorrido en profundiddD SVQ inremento de )ujo por mino de reorrido enordenD see reorrido in(jo umentoD UPQ reorrido postordenD see reorrido su(jo mnejo de vrios fuentes o sumiderosD reorrido preordenD see reorrido pre(jo UHW reorridos operiones topolgisD UII sore roresenisD PTPD PUH red residulD UPI reorridos pseudoEhildos sore roles iE redes pitds on provisin de )ujoD UUP nriosD PSV redes pitds generlizdsD VPI reorridos sore roles inriosD PQR edes on restriiones lterlesD VPP reorridos sore grfosD SUW!TPT redes de )ujoD UHT!UUI reursin irulionesD UVI onsejosD IIS redes de proesmientoD VPQ elimininD IIT edes multiE)ujoD VPQ emulin de los registros de tiE reduiones l )ujo mnimoD UUI!UWH vinD IIU registro de tivinD IIR eliminin totlD IPI regl pilsD IIP de retoD PIP reursin ol del VHEPHD PIP elimininD IIT relin redD UHT simtriD SQS orte deD UIR reljin de roD TWQ residulD UPI removellnddelete@AD VP red residul rtiD IUT selein del pivoteD IUW sin reursinD IVH triple prtiin de hijkstrD IVR quiksort onurrenteD IVR quiksort prleloD IVR

862

NDICE DE TRMINOS

representin de roles onjuntos niddosD PPV indentinD PQH seueni prentizdD PPW representin de roles on rreglosD PQP representin de roles on lists enE lzdsD PQI epresentin de un rol rdor en un rregloD THR representiones en memori de un olD IPQ rotin en rol inriosD QRR rotin en roles inrios extendidosD QRS ruyD PIS

supresin en rol letorizdoD RSU supresin en trepD RTV

tl hsh holgur de dispersinD RPQ interfz de l funin hshD RPQ plegdo de lve en funin hshD RPR tls hsh dispersin de dens de rteresD RPW dispersin universlD RQH funionesD RPQ funiones hshD RPQ mnejo de olisionesD QVI direionmiento iertoD QWQ endenmientoD QVQ seueni prentizd pr representr rE endenmiento seprdoD QVQ olesD PPW mnejo de olisiones por direionmiento edgewikD TTS ierto y sondeo linel selein nlisisD QWW mtodo de ordenmientoD ISH!ISQ reEdimensionmientoD RHW por posiin en rol inrioD QQU rejuste de dimensinD RHW selein supertrzD RQR por posiin en rregloD IVT tls hsh linelesD RIP!RPP sore rreglosD IVT squedD RIV setD PH elimininD RIV siftdownD PVS expnsinD RIQD RIU siftupD PVR inserinD RIV similridd de roles inriosD PSI tls hsh perfetsD RQI simplexD VIQ!VPH eh sistem de tiposD PHH Ady_MatD TPU!TQI Bit_Mat_Graph<GT>D TQI!TQQ kienD PIH kienD tevenD PIH DynMapTreeD QQP!QQS slk List_GraphD SRQ en mino de umentoD UIV ArrayStack<T>D IHI!IHQ progrm linelD VIP ArrayQueue<T>D IPR!IPV SlinkD TS Avl_Tree<Key>D RUP!RVQ BinNode<Key>D @PQVD PRP sondeo linelD QWU BinNodeXt<Key>D @QQTD QRS sondeo idel BinTree<Key>D @QIWD QPW nlisisD QWQ DlinkD UP!VQ spinGpromelD PHQ Dnode<T>D VQ!VR sugrfo de un grfoD SQU DynArray<T>D QR!SQ sum de polinomiosD WS DynDlist<T>D VR!WI sumideroD TQUD UHT DynListQueue<T>D IQH!IQI supertrzD PHQD RQR DynListStack<T>D IHS!IHT supresin en rol inrio de squedD DynSlist<T>D UI!UP @QPRD QPT ListQueue<T>D IPV!IQH

NDICE DE TRMINOS

863

ListStack<T>D IHQ!IHS Rand_Tree<Key>D RSS!RTH Rb_Tree<Key>D RWI!SHP SlinkD TS!TV Slist<T>D TW!UI Snode<T>D TV!TW Splay_Tree<Key>D SHV!SIQ Treap<Key>D RTS!RUH Tree_Node D @PTRD PUS rjn lgoritmo pr lulo de omponentes fuertemente onexosD TRH templtesD IS teorem de desomposiin de )ujoD UVP teorem del )ujo mximoGorte mnimoD UIU test de iliiddD SWI D ISW thrshingD RRR tipos de estrutur de dtosD PI tipos de erroresD IWR om n glekD IWW rep de(niinD RTR trepsD RTR!RUI nlisisD RUH!RUI elimininD RTV inserinD RTT prioriddes implitsD RUI Tree_Node squed por nmero de hewyD PUI onversin BinNode<Key>D PUQ destruinD PUH modi(doresD PTU oservdoresD PTT oservdores de roresenisD PTW reorridosD PUH
wvD IH unin de roles inriosD QPU unin de effD QPU unin exlusiv de roles inriosD QPQ unin exlusiv de roles inrios extendiE dosD QRP unin exlusiv de effD QPQ unidd de ejeuinD IRV

unin exlusiv de roles inrios letoriE zdosD RSV vlgrindD PHW vlor de )ujoD UHUD UIS vendedor vijeroD PIP virtualD IQ rshllD SWS lgoritmo pr l lusur trnsitivD TQQ irth equilirio perfetoD RSP

ndice de identicadores
Activation_RecordX IIVD IIVe ARC_DISTX TUWD TVHD TVI ArcHeapX TTVD TUHD TUID TUWD TUWd Arc_NodeX STUD STVD STVD STWD SUHD SUPD SUQD SUR ArrayQueueX IPSD IPTD PSI ArrayStackX IHID IHID IIHD IIHD IIVeD PRTD PRUD PRVD PRVD SHW AvlNodeX RUPD RUQ binary_searchX QHD QID QP BinNodeX PRHD QIWD QRUD QRVD QRVD QRWdD QSHD QSID QSID QSPD SHW BinNodeVtlX PRH BitArrayX SRD SSD STD STD SUD QIID QIPD QIPD QIQD QRWD QRWdD QSID QSID QSQD QSRD TQQ Bit_FieldsX SSTD SSUD SSUD SSUD SSUf Cache_EntryX RQUD RQVD RRHD RRHD RRHD RRID RRID RRID RRQD RRQD RRQD RRQdD RRRD RRRD RRS cache_sizeX RQWD RRHD RRR call_hash_fctX RISD RIVD RIV chunk_listX RRHD RRHD RRR Compare_DnodeX ISQD ISQD ITS contractX RIUD RIV copy_list_graphX TQRD TQR Cross_ArcX TPQD TPRD TPS DECLARE_BINNODEX PRHD PWSD RUP DECLARE_BINNODE_SENTINELX QQTD RSTD RTSD RWI Dijkstra_Arc_InfoX TUVD TUVD TUW Distance_CompareX TTID TTPD TTVD TTVD TTW dlink_lruX RQUeD RQVD RQV DLINK_TO_TYPEX DnodeX VQD VQD VRD VSD VSdD VTD VUD VVD VVD VVdD VWD VWD VWD VWdD WHD WHD WID ISQD ISQD ISRD ISSD ITSD IVSD QVRD QVSD RRH do_mruX RRID RRID RRQ doubleRotateLeftX RUU doubleRotateRightX RUU DynArrayX QRD RPD RQD RSD RWD RWD SHD SRD ISSD PSQD QISD QTID QTIdD QTPD QTQD THUD TQHD TQQD TRID TWQD UHRD UST DynDlistX VSD VSD VSeD VUD VUD VUdD VVD VVdD VWD WHD WHD WID WID WID WRD WSdD WVD WVD ISSD PHUD PSRD PSSD SUWD SVHD SVID TIHD TIID TISD TIUD TIUD TPTD
VTS

866

. ndice de identicadores

TPVD TRRD TRSD TRTD TRUD TRUD TRVD TSTD TSUD TSUD TSWD UHTD UIPD UTWD UVHD UVID UVPD UVVD UVWD UWI DynListStackX IHSD IHTD IVVD TRSD TRUD TRWD TRWD TSHD TSPD UTR expandX RIUD RIVD RRR FigureX VD VD WD IPD IS Filter_IteratorX SVPD SVQD SVRD SVRD SVS find_succ_and_swapX RWU fix_black_conditionX RWUD RWW FixedStackX IHID IVHD RUQD RWP fix_red_conditionX RWQD RWR get_lru_entryX RRID RRQ get_min_arcX TTWD TUID TVI inconnected_componentsX TIHD TII insert_entry_to_lru_listX RRHD RRHD RRQdD RRR insert_in_binary_search_treeX QPID QPID QPU insert_rootX QPTD QPU insert_sortedX ITRD ITR inside_listX RQWD RRQD RRS is_red_black_treeX RWQ join_exclusiveX QPRD QPSD SIQ join_exclusive_xtX QRPD QRPD QRQ List_DigraphX SRUD STPdD UII List_GraphX SRTD SRUD SSHD SSSD STID STPD STPD STPD STPdD STRdD STSD STSD STTD STTdD SUID SUID SUPD SUQD SURD SUTD SUU ListQueueX IPVhD IPWD IQHD IQI lru_listX RQVD RRHD RRID RRID RRID RRR mapped_nodeX STHD THSD THUD TIPD TPTD TPVD TQVD TRTD TTQD TTQD TVQD UHID UHRD UVID UVUD UWHD UWI mergeX ITWD IUI mergesortX ITWD IUQD SUU Null_ValueX TQHD TQHD TQHdD TQI partitionX IUQD IUSD IUUD IVHD IVPD IVRD IVT PathX SUVD SUWD SWUD SWVD SWVD SWWD THHD THHD THHdD THID THPD TSHD TVPD TVQD TVQD TVUD TVUD TWPD UHRD UHSD UHTD UPTD UPUD UUHD UUID UUID UWVD VHI Path_DescX SUWD SUWD SUWdD SVHD SVHD SVI POTX TUWD TUWD TVHD TVI Prim_Heap_InfoX TUHD TUI push_in_splay_stackX SHWD SIHD SIID SIP put_arcX TTWD TUID TUID TVHD TVI random_insertX RSTfD RSU random_join_exclusiveX RSVD RSV random_removeX RSVD RSW RbNodeX RWID RWP remove_entry_from_hash_tableX RRID RRR remove_entry_from_lru_listX RRHD RRQ remove_from_search_binary_treeX QPSD QPTD QPU

867

rotateLeftX RUU rotateRightX RUU search_and_push_in_splay_stackX SIHD SIPD SIPD SIQ search_and_stack_rbX RWPD RWQD RWU searchInBinTreeX QITD QPH search_minX ISID ISPD IST sequential_searchX ISD QID ISRD ISRD ISSD ISS SlinkX TSD TSD TSD TTD TTD TVD TVD TWdD TWeD UP SnodeX TVD TWD TWdD TWeD TWfD TWgD UID IHQhD IHRD IITD IITD IPW splayX SIID SIPD SIPD SIQ split_key_recX QPPD QPQD QPT split_key_rec_xtX QQWD QRH split_pos_recX QRHD QRI TerminoX WQD WRD WRD WRD WRdD WReD WRfD WSdD WTD WTD WUD WVD WV TREEARCX TUWD TVI zig_typeX SIID SII

Potrebbero piacerti anche