Articulo de referencia

Cola ancha

En informática , la cola de Brodal es una estructura de cola de prioridad / montículo con límites de tiempo en el peor de los casos muy bajos : O ( 1 ) {\displaystyle O(1)} para...

En informática , la cola de Brodal es una estructura de cola de prioridad / montículo con límites de tiempo en el peor de los casos muy bajos :O(1){\displaystyle O(1)}para inserción, find-minimum, fusionar (combinar dos colas) y decrease-key yO(logramo(norte)){\displaystyle O(\mathrm {log} (n))}para eliminación mínima y eliminación general. Son la primera variante de montón que logra estos límites sin recurrir a la amortización de los costos operativos. Las colas de Brodal reciben su nombre de su inventor, Gerth Stølting Brodal. [ 1 ]

Aunque tienen mejores límites asintóticos que otras estructuras de colas de prioridad, son, en palabras del propio Brodal, "bastante complicadas" y "[no] aplicables en la práctica". [ 1 ] Brodal y Okasaki describen una versión persistente ( puramente funcional ) de las colas de Brodal. [ 2 ]

Definición

Una cola de Brodal es un conjunto de dos árboles.T1{\displaystyle T_{1}}yT2{\displaystyle T_{2}}y 5 guías . La definición de la estructura de datos de la guía se puede encontrar en la siguiente sección. Para ambos árboles, cada nodo tiene un rango , este rango es útil para operaciones posteriores y corresponde intuitivamente al logaritmo del tamaño del subárbol con raíz en el nodo. Observamosaridadi(incógnita){\displaystyle {\text{aridad}}_{i}(x)}el número de hijos del nodoincógnita{\displaystyle x}con rangoi{\displaystyle i}También utilizaremost1{\displaystyle t_{1}}para la raíz del árbolT1{\displaystyle T_{1}}yt2{\displaystyle t_{2}}para la raíz del árbolT2{\displaystyle T_{2}}En cada momento dado, cada subárbol con raíz en un nodo debe cumplir con estos 5 invariantes (que luego se llamaránRANGO{\displaystyle {\text{RANGO}}}invariantes):

  • RANGO DE HOJA{\displaystyle {\text{RANGO DE HOJAS}}} : Siincógnita{\displaystyle x}es una hoja, entoncesrango(incógnita)=0{\displaystyle {\text{rank}}(x)=0},
  • RANGO DE PADRES{\displaystyle {\text{RANGO PADRE}}} :rango(incógnita)<rango(padre(incógnita)){\displaystyle {\text{rank}}(x)<{\text{rank}}({\text{parent}}(x))},
  • SIGUIENTE RANGO{\displaystyle {\text{NEXT-RANK-ARITY}}} : Sirango(incógnita)>0{\displaystyle {\text{rank}}(x)>0}, entoncesaridadrango(incógnita)1(incógnita)2{\displaystyle {\text{arity}}_{{\text{rank}}(x)-1}(x)\geqslant 2},
  • ARITY-RUMBO{\displaystyle {\text{ARITY-BOUND}}}:aridadi(incógnita){0,2,3,,7}{\displaystyle {\text{arity}}_{i}(x)\in \{0,2,3,\dots ,7\}}destacamos quearidadi(incógnita)1{\displaystyle {\text{arity}}_{i}(x)\neq 1},
  • RANGO RAÍZ{\displaystyle {\text{RANGO RAÍZ}}} :T2={\displaystyle T_{2}=\emptyset }orango(t1)rango(t2){\displaystyle {\text{rank}}(t_{1})\leqslant {\text{rank}}(t_{2})}.

AquíSIGUIENTE RANGO{\displaystyle {\text{NEXT-RANK-ARITY}}}nos garantiza que el tamaño del subárbol enraizado en un nodo es al menos exponencial al rango de ese nodo. Además,ARITY-RUMBO{\displaystyle {\text{ARITY-BOUND}}}limita el número de hijos de cada rango para un nodo dado, esto implica que todos los nodos tienen rango y grados enO(registronorte){\displaystyle O(\log n)}.

En una cola de Brodal, no todos los nodos tendrán un valor mayor que su padre; los nodos que incumplan esta condición se denominarán nodos violadores . Sin embargo, queremos mantener el número de nodos violadores relativamente pequeño. Para realizar un seguimiento de los nodos violadores, creamos para cada nodo dos conjuntos.V(incógnita){\displaystyle V(x)}yW(incógnita){\displaystyle W(x)}de nodos más grandes queincógnita{\displaystyle x}Intuitivamente,V(incógnita){\displaystyle V(x)}son los nodos más grandes deincógnita{\displaystyle x}con alto rango (de tal manera queyV(incógnita){\displaystyle y\in V(x)}sirango(y)rango(t1){\displaystyle {\text{rank}}(y)\geqslant {\text{rank}}(t_{1})}), yW(incógnita){\displaystyle W(x)}son los nodos con rango pequeño (rango(y)<rango(t1){\displaystyle {\text{rank}}(y)<{\text{rank}}(t_{1})}). Estos conjuntos se implementan utilizando listas doblemente enlazadas, lo que significa que tienen un orden . En particular, todos los nodos que violan se agregan aV(incógnita){\displaystyle V(x)}se agregan al principio de la lista y todos los nodos que violan se agregan aW(incógnita){\displaystyle W(x)}se insertan junto a un nodo del mismo rango. Dejamoswi(incógnita){\displaystyle w_{i}(x)}denota el número de nodos enW(incógnita){\displaystyle W(x)}de rangoi{\displaystyle i}ElV(incógnita){\displaystyle V(x)}yW(incógnita){\displaystyle W(x)}Las listas cumplen con estos 5 invariantes (llamaremos lasCONJUNTOS{\displaystyle {\text{CONJUNTOS}}}invariantes):

  • NODO MÍNIMO{\displaystyle {\text{NODO MÍNIMO}}} :t1=min(T1T2){\displaystyle t_{1}=\min(T_{1}\cup T_{2})}
  • VIOLACIÓN DE LA CONDICIÓN{\displaystyle {\text{VIOLACIÓN DE LA CONDICIÓN}}} : SiyV(incógnita)W(incógnita){\displaystyle y\in V(x)\cup W(x)}entoncesyincógnita{\displaystyle y\geqslant x}
  • VIOLACIÓN DE LOS DERECHOS DE LOS PADRES{\displaystyle {\text{VIOLACIÓN DE LOS PADRES}}}: Siy<padre(y){\displaystyle y<{\text{padre}}(y)}entonces existe un nodoincógnitay{\displaystyle x\neq y}de tal manera queyV(incógnita)W(incógnita){\displaystyle y\in V(x)\cup W(x)}
  • W-RANK-RUUND{\displaystyle {\text{W-RANK-BOUND}}}:wi(incógnita)6{\displaystyle w_{i}(x)\leqslant 6}
  • V-RANK-RUUND{\displaystyle {\text{V-RANK-BOUND}}}: Al denotarV(incógnita)=(v|V(incógnita)|,,v2,v1){\displaystyle V(x)=(v_{|V(x)|},\dots,v_{2},v_{1})}, tenemos:rango(vi)i1α{\displaystyle {\text{rank}}(v_{i})\geqslant \left\lfloor {\frac {i-1}{\alpha }}\right\rfloor }para una cierta constanteα{\displaystyle \alpha }.

Dado que todos los nodos tienen rango enO(registronorte){\displaystyle O(\log n)}elW-RANK-RUUND{\displaystyle {\text{W-RANK-BOUND}}}yV-RANK-RUUND{\displaystyle {\text{V-RANK-BOUND}}}, todoV(incógnita){\displaystyle V(x)}yW(incógnita){\displaystyle W(x)}son de tamañoO(registronorte){\displaystyle O(\log n)}.

También tenemos algunas invariantes de las raíces de los árboles.T1{\displaystyle T_{1}}yT2{\displaystyle T_{2}}:t1{\displaystyle t_{1}}yt2{\displaystyle t_{2}}(llamado elRAÍCES{\displaystyle {\text{RAÍCES}}}invariantes).

  • RAÍZ{\displaystyle {\text{RAÍZ-ARIDAD}}} :ti{2,3,,7} para i{0,1,,rango(ti)1}{\displaystyle t_{i}\in \{2,3,\dots ,7\}{\text{ para }}i\in \{0,1,\dots ,{\text{rank}}(t_{i})-1\}},
  • ENCUADERNACIÓN DE TAMAÑO V{\displaystyle {\text{V-SIZE-BOUND}}}:|V(incógnita)|α rango(t1){\displaystyle |V(x)|\leqslant \alpha {\text{ rango}}(t_{1})},
  • RANGO DE ELEMENTOS W{\displaystyle {\text{W-ELEMENTS-RANK}}}: siyW(t1){\displaystyle y\in W(t_{1})}, entoncesrango(y)<rango(t1){\displaystyle {\text{rank}}(y)<{\text{rank}}(t_{1})}.

ElENCUADERNACIÓN DE TAMAÑO V{\displaystyle {\text{V-SIZE-BOUND}}}invariante esencialmente nos dice que si aumentamos el rango det1{\displaystyle t_{1}}por uno, tenemos como máximoα{\displaystyle \alpha }nuevas violaciones "grandes" (aquí grande significa tener un rango alto) sin violar laV-RANK-RUUND{\displaystyle {\text{V-RANK-BOUND}}}invariante. Por otro lado, elRANGO DE ELEMENTOS W{\displaystyle {\text{W-ELEMENTS-RANK}}}invariante nos dice que todas las violaciones enW(incógnita){\displaystyle W(x)}son "pequeños", este invariante es verdadero según la definición deW{\displaystyle W}. Mantener las invariantesW-RANK-RUUND{\displaystyle {\text{W-RANK-BOUND}}}yRAÍZ{\displaystyle {\text{RAÍZ-ARIDAD}}}no es trivial, para mantener estos utilizaremos elDisminuirTecla{\displaystyle {\text{Tecla de disminución}}}operación que se puede implementar utilizando una guía como se define en la siguiente sección. Cada vez que llamemos a laDisminuirTecla{\displaystyle {\text{Tecla de disminución}}}En esta operación, esencialmente haremos lo siguiente  :

  1. Agregue la nueva infracción aV(t1){\displaystyle V(t_{1})}oW(t1){\displaystyle W(t_{1})}dependiendo de la gravedad de dicha infracción.
  2. Para evitarV(t1){\displaystyle V(t_{1})}yW(t1){\displaystyle W(t_{1})}Para evitar que se vuelva demasiado grande, realizamos de forma incremental dos tipos de transformaciones:
    1. Trasladando a los hijos det2{\displaystyle t_{2}}at1{\displaystyle t_{1}}para aumentar el rango det1{\displaystyle t_{1}}
    2. Reducir el número de infracciones enW(t1){\displaystyle W(t_{1})}reemplazando dos violaciones de rangok{\displaystyle k}por una violación de rangok+1{\displaystyle k+1}

La estructura de datos de la guía

Esta definición se basa en la definición del artículo de Brodal. [ 3 ]

Suponemos que tenemos una secuencia de variablesincógnitak,,incógnita1{\displaystyle x_{k},\dots ,x_{1}}y queremos asegurarnos de queik,incógnitaiT{\displaystyle \forall i\leqslant k,x_{i}\leqslant T}para algún umbralT{\displaystyle T}. La única operación permitida esREDUCIR(i){\displaystyle {\text{REDUCIR}}(i)}lo cual disminuyeincógnitai{\displaystyle x_{i}}por al menos 2 y aumentaincógnitai+1{\displaystyle x_{i+1}}por como máximo 1. Podemos suponer sin pérdida de generalidad queREDUCIR(i){\displaystyle {\text{REDUCIR}}(i)}reduceincógnitai{\displaystyle x_{i}}por 2 y aumentaincógnitai+1{\displaystyle x_{i+1}}por 1.

Si unincógnitaj{\displaystyle x_{j}}se incrementa en uno, el objetivo de la guía es decirnos en qué índicesi{\displaystyle i}para solicitarREDUCIR(i){\displaystyle {\text{REDUCIR}}(i)}para respetar el umbral. El guía solo está autorizado a hacerO(1){\displaystyle O(1)}llamadas a laREDUCIR{\displaystyle {\text{REDUCIR}}}función para cada incremento.

El guía tiene acceso a otra secuenciaincógnitak,,incógnita1{\displaystyle x'_{k},\dots ,x'_{1}}de tal manera queincógnitaiincógnitai{\displaystyle x_{i}\leqslant x'_{i}}yincógnitai{T2,T1,T}{\displaystyle x'_{i}\in \{T-2,T-1,T\}}. Siempre y cuando después del aumento deincógnitaj{\displaystyle x_{j}}tenemosincógnitajincógnitaj{\displaystyle x_{j}\leqslant x'_{j}}no necesitamos pedir ayuda a nuestro guía ya queincógnitaj{\displaystyle x_{j}}está "muy" abajoT{\displaystyle T}. Sin embargo, siincógnitaj=incógnitaj{\displaystyle x_{j}=x'_{j}}antes del aumento, entonces tenemosincógnitaj+1>incógnitaj{\displaystyle x_{j}+1>x'_{j}}después del cambio.

Para simplificar la explicación, podemos suponer queT=2{\displaystyle T=2}, de modo queincógnitai{0,1,2}{\displaystyle x'_{i}\in \{0,1,2\}}. La guía creará bloques en la secuencia deincógnitai{\displaystyle x'_{i}}de forma2,1,1,,1,0{\displaystyle 2,1,1,\dots ,1,0}donde permitimos que no haya1{\displaystyle 1}. La guía mantiene la invariante de que cada elemento que no está en un bloque es o bien un1{\displaystyle 1}o un0{\displaystyle 0}. Por ejemplo, aquí están los bloques para una secuencia deincógnitai{\displaystyle x'_{i}}.

1,2,1,1,0_,1,1,2,0_,2,0_,1,0,2,1,0_{\textstyle 1,{\underline {2,1,1,0}},1,1,{\underline {2,0}},{\underline {2,0}},1,0,{\underline {2,1,0}}}

La guía se compone de 3 matrices  :

  • incógnita{\displaystyle x}la gama deincógnitak,,incógnita1{\displaystyle x_{k},\dots ,x_{1}}
  • incógnita{\displaystyle x'}la gama deincógnitak,,incógnita1{\displaystyle x'_{k},\dots ,x'_{1}}
  • pag{\displaystyle p}una matriz de punteros donde todos lospagi{\displaystyle p_{i}}para quéincógnitai{\displaystyle x'_{i}}están en el mismo bloque apuntarán a la misma celda de memoria que contiene un valor. Si unincógnitai{\displaystyle x'_{i}}no está en un bloque, entoncespagi{\displaystyle p_{i}}apunta a una celda de memoria que contiene{\displaystyle \bot }.

Con esta definición, una guía tiene dos propiedades importantes  :

  1. Para cada elemento de un bloque, podemos encontrar el elemento más a la izquierda del bloque en el tiempoO(1){\displaystyle O(1)}.
  2. Podemos destruir un bloque a tiempoO(1){\displaystyle O(1)}asignando{\displaystyle \bot }a la celda de memoria a la que apunta cada elemento del bloque.

De esta forma, el guía puede decidir qué índices utilizar.REDUCIR{\displaystyle {\text{REDUCE}}}a tiempoO(1){\displaystyle O(1)}Aquí tienes un ejemplo  :

2,1,1,0_,2,1,1,1,0_2,1,1,0_,2,2,1,1,0_Incremento incógnitai2,1,1,1_,0,2,1,1,0_REDUCIR2,1,1,1_,1,0,1,1,0_REDUCIR2,1,1,1,1,0_,1,1,0restablecer bloques{\displaystyle {\begin{array}{ll}{\underline {2,1,1,0}},{\underline {2,1,1,1,0}}&\\{\underline {2,1,1,0}},{\underline {2,{\color {red}2},1,1,0}}&{\text{Increment }}x'_{i}\\{\underline {2,1,1,{\color {green}1}}},{\underline {{\color {blue}0},2,1,1,0}}&{\text{REDUCE}}\\{\underline {2,1,1,1}},{\underline {{\color {green}1},{\color {blue}0},1,1,0}}&{\text{REDUCE}}\\{\underline {2,1,1,1,1,0}},1,1,0&{\text{reestablish blocks}}\\\end{array}}}

Para restablecer los bloques, los punteros del 1 y el 0 agregados al primer bloque ahora apuntan a la misma celda que todos los demás elementos del primer bloque, y el valor de la celda del segundo bloque se cambia a{\displaystyle \bot }En el ejemplo anterior, solo dosREDUCIR{\displaystyle {\text{REDUCE}}}Se necesitaban operaciones, este es el caso para todas las instancias. Por lo tanto, la cola solo necesitaO(1){\displaystyle O(1)}operaciones para restablecer la propiedad.

Funcionamiento de una cola ancha

Para implementar las diferentes operaciones de la cola de prioridad , primero necesitamos describir algunas transformaciones esenciales para los árboles.

Transformaciones

Árboles de enlace

Para enlazar árboles, necesitamos tres nodos.incógnita1,incógnita2 y incógnita3{\displaystyle x_{1},x_{2}{\text{ and }}x_{3}}de igual rango. Podemos calcular el mínimo de estos tres nodos con dos comparaciones. Aquí asumimos queincógnita1{\displaystyle x_{1}}es el mínimo pero el proceso es similar para todosincógnitai{\displaystyle x_{i}}. Ahora podemos hacer los nodosincógnita2{\displaystyle x_{2}}yincógnita3{\displaystyle x_{3}}los dos hijos más a la izquierda deincógnita1{\displaystyle x_{1}}y aumentar el rango deincógnita1{\displaystyle x_{1}}por uno. Esto conserva todo elRANGO{\displaystyle {\text{RANK}}}yCONJUNTOS{\displaystyle {\text{SETS}}}invariantes.

Desvinculación de árboles

Siincógnita{\displaystyle x}tiene exactamente dos o tres hijos de rangorango(incógnita)1{\displaystyle {\text{rank}}(x)-1}, podemos eliminar a estos hijos yincógnita{\displaystyle x}obtiene el rango de su nuevo hijo mayor más uno. Desde elARITY-RUMBO{\displaystyle {\text{ARITY-BOUND}}}condición, sabemos que laSIGUIENTE RANGO{\displaystyle {\text{NEXT-RANK-ARITY}}}El invariante se conservará. Entonces, todos losRANGO{\displaystyle {\text{RANK}}}yCONJUNTOS{\displaystyle {\text{SETS}}}Los invariantes siguen satisfechas. Siincógnita{\displaystyle x}tiene 4 o más hijos, podemos simplemente cortar dos de ellos y todas las invariantes permanecen verdaderas. Por lo tanto, la desvinculación de un árbol de rangok{\displaystyle k}siempre dará como resultado dos o tres árboles de rangok1{\displaystyle k-1}(de los 2 o 3 hijos excluidos) y un árbol adicional de rango como máximok{\displaystyle k}.

Manteniendo a los hijos de una raíz

Cuando agregamos y eliminamos hijos de una raíz, queremos mantener laRANGO RAÍZ{\displaystyle {\text{ROOT-RANK}}}invariante verdadero. Para ello, utilizamos 4 guías, dos para cada raíz.t1{\displaystyle t_{1}}yt2{\displaystyle t_{2}}. Tener acceso constante al tiempo del hijo det1{\displaystyle t_{1}}creamos una matriz extensible de punteros que tiene para cada rangoi{0,,rango(t1)1}{\displaystyle i\in \{0,\dots ,{\text{rank}}(t_{1})-1\}}un puntero a un hijo det1{\displaystyle t_{1}}de rangoi{\displaystyle i}. Un guía mantendrá la condición de quearidadi(t1)7{\displaystyle {\text{arity}}_{i}(t_{1})\leqslant 7}y el otro sostienearidadi(t1)2{\displaystyle {\text{arity}}_{i}(t_{1})\geqslant 2}ambos parai{0,,rango(t1)3}{\displaystyle i\in \{0,\dots ,{\text{rank}}(t_{1})-3\}}. Los hijos det1{\displaystyle t_{1}}de rangorango(t1)1{\displaystyle {\text{rank}}(t_{1})-1}yrango(t1)2{\displaystyle {\text{rank}}(t_{1})-2}se tratan por separado de una manera sencilla para mantener su número entre 2 y 7. El equivalente a laincógnitai{\displaystyle x'_{i}}La variable en la definición de la guía tendrá los valores{5,6,7}{\displaystyle \{5,6,7\}}para la guía de límites superiores y{4,3,2}{\displaystyle \{4,3,2\}}para el límite inferior.

En este contexto, cuando agregamos un hijo de rangoi{\displaystyle i}hasta la raíz, aumentamosincógnitai{\displaystyle x'_{i}}por uno, y aplicar elREDUCIR{\displaystyle {\text{REDUCE}}}operaciones. ElRECUPERACIÓN(i){\displaystyle {\text{RECUCE}}(i)}La operación aquí consiste en vincular tres árboles de rangoi{\displaystyle i}lo que crea un nuevo niño de rangoi+1{\displaystyle i+1}Por lo tanto, disminuimosaridadi(t1){\displaystyle {\text{arity}}_{i}(t_{1})}por tres y aumentararidadi+1(t1){\displaystyle {\text{arity}}_{i+1}(t_{1})}por uno. Si este aumento resulta en demasiados hijos de rangorango(t1)2{\displaystyle {\text{rank}}(t_{1})-2}orango(t1)1{\displaystyle {\text{rank}}(t_{1})-1}unimos a algunos de estos hijos y posiblemente aumentamos el rango det1{\displaystyle t_{1}}. Si aumentamos el rango det1{\displaystyle t_{1}}, tenemos que aumentar la longitud del array extensible gestionado por las guías.

Cortarle la relación a un hijot1{\displaystyle t_{1}}es muy similar, excepto que aquí elREDUCIR{\displaystyle {\text{REDUCE}}}Esta operación corresponde a la eliminación de enlaces en un árbol.

Para la raízt2{\displaystyle t_{2}}La situación es casi la misma. Sin embargo, dado queNODO MÍNIMO{\displaystyle {\text{MINIMUM-NODE}}}nos garantiza quet1{\displaystyle t_{1}}es el elemento mínimo, sabemos que no crearemos ninguna violación al vincular o desvincular hijos det1{\displaystyle t_{1}}No se puede decir lo mismo det2{\displaystyle t_{2}}. Vincular hijos nunca creará nuevas violaciones, pero desvincular hijos puede crear hasta tres nuevas violaciones. El árbol que queda después de una desvinculación se convierte en un hijo det1{\displaystyle t_{1}}si tiene un rango menor querango(t1){\displaystyle {\text{rank}}(t_{1})}y de lo contrario se convierte en hijo det2{\displaystyle t_{2}}. Las nuevas violaciones que tienen un rango mayor querango(t1){\displaystyle {\text{rank}}(t_{1})}se añaden aV(t1){\displaystyle V(t_{1})}. Para mantener los invariantes en elV(t1){\displaystyle V(t_{1})}conjunto (es decirV-RANK-RUUND{\displaystyle {\text{V-RANK-BOUND}}}yENCUADERNACIÓN DE TAMAÑO V{\displaystyle {\text{V-SIZE-BOUND}}}), tenemos que garantizar que el rango det1{\displaystyle t_{1}}se incrementará y queα{\displaystyle \alpha }en esos invariantes se elige suficientemente grande.

Reducción de violaciones

El objetivo de esta transformación es reducir la cantidad total de posibles violaciones, lo que significa reducir|incógnitaT1T2V(incógnita)W(incógnita)|{\displaystyle \left|\bigcup _{x\in T_{1}\cup T_{2}}V(x)\cup W(x)\right|}.

Suponemos que tenemos dos posibles violaciones.incógnita1{\displaystyle x_{1}}yincógnita2{\displaystyle x_{2}}de igual rangok{\displaystyle k}. Entonces tenemos varios casos:

  1. Si resulta que uno de los nodos no constituye una infracción, simplemente lo eliminamos de su conjunto de infracciones correspondiente.
  2. De lo contrario, ambos nodos son violaciones. Debido aARITY-RUMBO{\displaystyle {\text{ARITY-BOUND}}}, sabemos que ambosincógnita1{\displaystyle x_{1}}yincógnita2{\displaystyle x_{2}}tener al menos un hermano. Entonces:
    1. Siincógnita1{\displaystyle x_{1}}yincógnita2{\displaystyle x_{2}}si no son hermanos, entonces podemos asumir sin perder generalidad quepadre(incógnita1)padre(incógnita2){\displaystyle {\text{parent}}(x_{1})\leqslant {\text{parent}}(x_{2})}, entonces podemos intercambiar los subárboles enraizados enincógnita1{\displaystyle x_{1}}yincógnita2{\displaystyle x_{2}}El número de infracciones solo puede disminuir durante ese intercambio.
    2. Demás,incógnita1{\displaystyle x_{1}}yincógnita2{\displaystyle x_{2}}son hermanos de un nodo que llamaremosy{\displaystyle y}.
      1. Siincógnita1{\displaystyle x_{1}}tiene más de un hermano de rangok{\displaystyle k}, podemos simplemente cortarincógnita1{\displaystyle x_{1}}y convertirlo en un nodo que no violet1{\displaystyle t_{1}}como se describe en la subsección anterior.
      2. Demás,incógnita1{\displaystyle x_{1}}yincógnita2{\displaystyle x_{2}}son los únicos hijos de rangok{\displaystyle k}dey{\displaystyle y}...
        1. Sirango(y)>k+1{\displaystyle {\text{rank}}(y)>k+1}, podemos cortar ambosincógnita1{\displaystyle x_{1}}yincógnita2{\displaystyle x_{2}}nodos dey{\displaystyle y}y convertirlos en nodos que no violent1{\displaystyle t_{1}}como se describe en la subsección anterior
        2. Demás,rango(y)=k+1{\displaystyle {\text{rank}}(y)=k+1}Vamos a cortarincógnita1,incógnita2 y y{\displaystyle x_{1},x_{2}{\text{ and }}y}, el nuevo rango dey{\displaystyle y}será uno más el rango de su hijo más a la izquierda, Reemplazamosy{\displaystyle y}por un hijo ent1{\displaystyle t_{1}}de rangok+1{\displaystyle k+1}, que se puede cortar como se describe en la subsección anterior. Si el reemplazo dey{\displaystyle y}se convierte en un nodo violador de rangok+1{\displaystyle k+1}, lo añadimos aW(t1){\displaystyle W(t_{1})}. Finalmente hacemosincógnita1,incógnita2 y y{\displaystyle x_{1},x_{2}{\text{ and }}y}nuevos hijos det1{\displaystyle t_{1}}como se describió anteriormente.

Evitar demasiadas infracciones

Los únicos conjuntos de violaciones en los que agregaremos violaciones sonV(t1){\displaystyle V(t_{1})}yW(t1){\displaystyle W(t_{1})}Como se describió anteriormente, los invariantes en esos conjuntos se mantienen usando guías. Cuando agregamos una violación aW(t1){\displaystyle W(t_{1})}Tenemos dos casos:

  1. Si hay exactamente 6 violaciones del rango dado y hay al menos dos nodos violadores que no son hijos det2{\displaystyle t_{2}}, aplicamos elREDUCIR{\displaystyle {\text{REDUCE}}}operaciones indicadas por el guía.
  2. Si hay más de 4 violaciones que son hijos det2{\displaystyle t_{2}}Hemos eliminado las infracciones adicionales y las enlazamos a continuación.t1{\displaystyle t_{1}}. Esto elimina la violación creada por estos nodos y no afecta la guía que mantiene los hijos det2{\displaystyle t_{2}}.

Por cada operación de cola de prioridad que se realiza, aumentamos el rango det1{\displaystyle t_{1}}por al menos uno moviendo un número constante de hijos det2{\displaystyle t_{2}}at1{\displaystyle t_{1}}(siempre queT2{\displaystyle T_{2}\neq \emptyset }). Aumentando el rango det1{\displaystyle t_{1}}nos permite agregar infracciones aV(t1){\displaystyle V(t_{1})}sin dejar de mantener todas nuestras invariantes. SiT2{\displaystyle T_{2}\neq \emptyset }yrango(t2)rango(t1)+2{\displaystyle {\text{rank}}(t_{2})\leqslant {\text{rank}}(t_{1})+2}podemos cortar los hijos más grandes det2{\displaystyle t_{2}}, vincularlos at1{\displaystyle t_{1}}y luego hacert2{\displaystyle t_{2}}un hijo det1{\displaystyle t_{1}}. Esto satisface todas las invariantes. De lo contrario, cortamos un hijo det2{\displaystyle t_{2}}de rangorango(t1)+2{\displaystyle {\text{rank}}(t_{1})+2}, desvincule este hijo y agregue los árboles resultantes at1{\displaystyle t_{1}}. SiT2={\displaystyle T_{2}=\emptyset }, sabemos quet1{\displaystyle t_{1}}es el nodo de mayor rango, por lo tanto sabemos que no se pueden crear grandes violaciones.

Operaciones de cola de prioridad

Cola de creación

Cola de creación(){\displaystyle {\text{MakeQueue}}()}simplemente devuelve un par de árboles vacíos.

FindMin

FindMin(Q){\displaystyle {\text{FindMin}}(Q)}devolucionest1{\displaystyle t_{1}}.

Insertar

Insertar(Q,mi){\displaystyle {\text{Insert}}(Q,e)}es solo un caso especial deFusión(Q1,Q2){\displaystyle {\text{Meld}}(Q_{1},Q_{2})}dóndeQ2{\displaystyle Q_{2}}es una cola que solo contienemi{\displaystyle e}yQ1=Q{\displaystyle Q_{1}=Q}.

Fusión

Fusión(Q1,Q2){\displaystyle {\text{Meld}}(Q_{1},Q_{2})}implica cuatro árboles (dos para cada cola). El árbol con la raíz mínima se convierte en el nuevoT1{\displaystyle T_{1}}árbol. Si este árbol es también el árbol de rango máximo, podemos agregar todos los demás árboles a continuación como se describió anteriormente. En este caso, no se crea ningún nodo violatorio, por lo que no se realiza ninguna transformación en los nodos violatorios. De lo contrario, el árbol de rango máximo se convierte en el nuevoT2{\displaystyle T_{2}}El árbol y los demás árboles se agregan a continuación como se describe en la sección "Mantenimiento de los hijos de una raíz". Si algunos árboles tienen el mismo rango que este nuevoT2{\displaystyle T_{2}}Podemos desvincularlos antes de agregarlos. Las infracciones creadas se manejan como se explica en la sección  : "Evitar demasiadas infracciones".

DisminuirTecla

DisminuirTecla(Q,mi,mi){\displaystyle {\text{DecreaseKey}}(Q,e,e')}reemplaza el elemento demi{\displaystyle e}pormi{\displaystyle e'}(conmimi{\displaystyle e'\leqslant e}). Simi<t1{\displaystyle e'<t_{1}}, intercambiamos los dos nodos; de lo contrario, manejamos la posible nueva violación como se explica en la sección "Evitar demasiadas violaciones".

Eliminar mínimo

Eliminar mínimo(Q){\displaystyle {\text{DeleteMin}}(Q)}se permite tomar el peor de los casos tiempoO(registronorte){\displaystyle O(\log n)}Primero, vaciamos completamenteT2{\displaystyle T_{2}}moviendo a todos los hijos det2{\displaystyle t_{2}}at1{\displaystyle t_{1}}luego haciendot2{\displaystyle t_{2}}un hijo de rango 0 det1{\displaystyle t_{1}}. Entonces,t1{\displaystyle t_{1}}se elimina, esto nos deja con como máximoO(registronorte){\displaystyle O(\log n)}árboles independientes. El nuevo mínimo se encuentra entonces observando los conjuntos violatorios de la raíz antigua y observando todas las raíces de los nuevos árboles. Si el elemento mínimo no es una raíz, podemos intercambiar una raíz de un árbol de igual rango con él. Esto crea como máximo una violación. Luego, hacemos que los árboles independientes sean hijos del nuevo elemento mínimo realizandoO(registronorte){\displaystyle O(\log n)}operaciones de vinculación y desvinculación. Esto restablece elRANGO{\displaystyle {\text{RANK}}}yRAÍCES{\displaystyle {\text{ROOTS}}}invariantes. Al fusionar losV{\displaystyle V}yW{\displaystyle W}conjuntos de la nueva raíz junto con elV{\displaystyle V}yW{\displaystyle W}conjuntos de la raíz antigua juntos, obtenemos un nuevo conjunto de violación de tamañoO(registronorte){\displaystyle O(\log n)}. Haciendo como máximoO(registronorte){\displaystyle O(\log n)}transformaciones que reducen la violación podemos hacer que el conjunto de violación contenga como máximo un elemento de cada rango. Este conjunto será nuestro nuevoW{\displaystyle W}conjunto y el nuevoV{\displaystyle V}El conjunto está vacío. Esto restablece elCONJUNTOS{\displaystyle {\text{SETS}}}invariantes. También tenemos que inicializar una nueva guía para la nueva raíz.t1{\displaystyle t_{1}}.

Borrar

Aquí,{\displaystyle -\infty }denota el elemento más pequeño posible.Borrar(Q,mi){\displaystyle {\text{Delete}}(Q,e)}puede implementarse simplemente llamandoDisminuirTecla(Q,mi,){\displaystyle {\text{DecreaseKey}}(Q,e,-\infty )}seguido deEliminar mínimo(Q){\displaystyle {\text{DeleteMin}}(Q)}.

Detalles de implementación

En esta sección, resumimos algunos detalles de implementación de la estructura de datos de cola de Brodal.

En cada árbol, cada nodo es un registro que tiene los siguientes campos:

  • El elemento asociado al nodo (su valor),
  • El rango del nodo,
  • punteros a los hermanos izquierdo y derecho del nodo,
  • un puntero al nodo padre,
  • un puntero al hijo de más a la izquierda,
  • punteros al primer elemento del nodoV{\displaystyle V}yW{\displaystyle W}conjuntos,
  • Punteros al elemento siguiente y anterior en el conjunto de violaciones al que pertenece el nodo. Si este nodo es el primer nodo del conjunto de violacionesV(incógnita){\displaystyle V(x)}oW(incógnita){\displaystyle W(x)}pertenece a, el puntero anterior apunta aincógnita{\displaystyle x}.
  • una serie de indicadores para los hijos det1{\displaystyle t_{1}}de rangoi{\displaystyle i}(coni{0,,rango(t1)1}{\displaystyle i\in \{0,\dots ,{\text{rank}}(t_{1})-1\}}),
  • una matriz similar parat2{\displaystyle t_{2}},
  • una matriz de punteros a nodos enW(t1){\displaystyle W(t_{1})}de rangoi{\displaystyle i}(coni{0,,rango(t1)1}{\displaystyle i\in \{0,\dots ,{\text{rank}}(t_{1})-1\}}).

Finalmente, tenemos 5 guías: tres para mantener los límites superiores enaridadi(t1){\displaystyle {\text{arity}}_{i}(t_{1})},aridadi(t2){\displaystyle {\text{arity}}_{i}(t_{2})}ywi(t1){\displaystyle w_{i}(t_{1})}y dos para mantener los límites inferiores enaridadi(t1){\displaystyle {\text{arity}}_{i}(t_{1})}yaridadi(t2){\displaystyle {\text{arity}}_{i}(t_{2})}.

Debido a la gran cantidad de punteros y conjuntos que debe gestionar, la cola de Brodal es extremadamente difícil de implementar. Por esta razón, se describe mejor como un objeto puramente teórico para reducir la complejidad temporal de algoritmos como el de Dijkstra . Sin embargo, la cola de Brodal se ha implementado en Scala (el repositorio de GitHub se puede encontrar aquí: https://github.com/ruippeixotog/functional-brodal-queues ). En su artículo, Gerth Stølting Brodal menciona que: "Un aspecto importante para futuros trabajos es simplificar la construcción para que sea aplicable en la práctica". [ 3 ]

Resumen de los tiempos de carrera

Aquí se muestran las complejidades temporales [ 4 ] de diversas estructuras de datos de montículo. La abreviatura am. indica que la complejidad dada está amortizada; de lo contrario, se trata de la complejidad en el peor de los casos. Para conocer el significado de " O ( f )" y " Θ ( f )", consulte la notación Big O. Los nombres de las operaciones presuponen un montículo mínimo.

  1. make-heap es la operación de construir un montón a partir de una secuencia de n elementos no ordenados. Se puede realizar entiempo Θ ( n ) siempre que meld se ejecute en tiempo O (log n ) (donde ambas complejidades se pueden amortizar). [ 5 ] [ 6 ] Otro algoritmo alcanza Θ ( n ) para montones binarios. [ 7 ] 
  2. 1 2 3 Paramontículos persistentes (que no admiten decrease-key ), una transformación genérica reduce el costo de meld al de insert , mientras que el nuevo costo de delete-min es la suma de los costos antiguos de delete-min y meld . [ 10 ] Aquí, hace que meld se ejecute en tiempo Θ (1) (amortizado, si el costo de insert lo es) mientras que delete-min todavía se ejecuta en O (log n ). Aplicado a montículos binomiales asimétricos, produce colas de Brodal-Okasaki, montículos persistentes con complejidades óptimas en el peor de los casos. [ 9 ] 
  3. Límite inferior deΩ(registroregistronorte),{\displaystyle \Omega (\log \log n),}[ 13 ] límite superior deO(22registroregistronorte).{\displaystyle O(2^{2{\sqrt {\log \log n}}}).}[ 14 ]
  4. Las colas de Brodal y los montículos de Fibonacci estrictos alcanzan complejidades óptimas en el peor de los casos para los montículos. Inicialmente se describieron como estructuras de datos imperativas. La cola de Brodal-Okasaki es una estructura de datos persistente que alcanza el mismo óptimo, excepto queno admite la decreción de clave .

Gerth Stølting Brodal

Gerth Stølting Brodal es profesor de la Universidad de Aarhus , Dinamarca . [ 20 ] Es mejor conocido por la cola de Brodal.

Referencias

  1. 1 2 Gerth Stølting Brodal (1996). Colas de prioridad eficientes en el peor de los casos. Actas del 7.º Simposio ACM-SIAM sobre Algoritmos Discretos, págs. 52-58
  2. Gerth Stølting Brodal y Chris Okasaki (1996). Colas de prioridad puramente funcionales óptimas . Journal of Functional Programming.
  3. ^ Brodal , Gerth Stølting (1996). "Colas de prioridad eficientes en el peor de los casos" (PDF) .{{cite web}}: CS1 mantenimiento: estado de la URL ( enlace )
  4. 1 2 3 4 Cormen, Thomas H .; Leiserson, Charles E .; Rivest, Ronald L. (1990). Introducción a los algoritmos (1ª ed.). MIT Press y McGraw-Hill. ISBN  0-262-03141-8.
  5. 1 2 3 Sleator, Daniel Dominic ; Tarjan, Robert Endre (febrero de 1986). "Montículos autoajustables" . SIAM Journal on Computing . 15 (1): 52– 69. CiteSeerX 10.1.1.93.6678 . doi : 10.1137/0215004 . ISSN 0097-5397 .  
  6. 1 2 Tarjan, Robert (1983). "3.3. Montones izquierdistas". Estructuras de datos y algoritmos de red . págs. 38–42 . doi : 10.1137/1.9781611970265 . ISBN  978-0-89871-187-5.
  7. Hayward, Ryan; McDiarmid, Colin (1991). "Análisis del caso promedio de la construcción de montículos mediante inserción repetida" (PDF) . J. Algorithms . 12 : 126–153 . CiteSeerX 10.1.1.353.7888 . doi : 10.1016/0196-6774(91)90027-v . Archivado del original (PDF) el 5 de febrero de 2016. Recuperado el 28 de enero de 2016 . 
  8. "Montículo binomial | Brilliant Math & Science Wiki" . brilliant.org . Consultado el 30 de septiembre de 2019 .
  9. 1 2 Brodal, Gerth Stølting; Okasaki, Chris (noviembre de 1996), "Colas de prioridad puramente funcionales óptimas", Journal of Functional Programming , 6 (6): 839– 857, doi : 10.1017/s095679680000201x
  10. Okasaki, Chris (1998). "10.2. Abstracción estructural". Estructuras de datos puramente funcionales (1.ª ed.). págs. 158–162 . ISBN   9780521631242.
  11. Takaoka, Tadao (1999), Teoría de los montículos 2-3 (PDF) , pág. 12 
  12. Iacono, John (2000), "Improved upper bounds for pairing heaps", Proc. 7th Scandinavian Workshop on Algorithm Theory (PDF) , Lecture Notes in Computer Science, vol. 1851, Springer-Verlag, pp. 63–77 , arXiv : 1110.4428 , CiteSeerX 10.1.1.748.7812 , doi : 10.1007/3-540-44985-X_5 , ISBN    3-540-67690-2
  13. Fredman, Michael Lawrence (julio de 1999). "Sobre la eficiencia de los montículos de emparejamiento y estructuras de datos relacionadas" (PDF) . Journal of the Association for Computing Machinery . 46 (4): 473– 501. doi : 10.1145/320211.320214 .
  14. Pettie, Seth (2005). Hacia un análisis final de los montículos de emparejamiento (PDF) . Actas de FOCS '05 del 46.º Simposio Anual IEEE sobre Fundamentos de la Informática. págs. 174–183 . CiteSeerX 10.1.1.549.471 . doi : 10.1109/SFCS.2005.75 . ISBN   0-7695-2468-0.
  15. Haeupler, Bernhard; Sen, Siddhartha; Tarjan, Robert E. (noviembre de 2011). "Montones de emparejamiento de rangos" (PDF) . SIAM J. Informática . 40 (6): 1463–1485.doi : 10.1137 / 100785351 .
  16. Fredman, Michael Lawrence ; Tarjan, Robert E. (julio de 1987). "Montículos de Fibonacci y sus usos en algoritmos mejorados de optimización de redes" (PDF) . Journal of the Association for Computing Machinery . 34 (3): 596– 615. CiteSeerX 10.1.1.309.8927 . doi : 10.1145/28869.28874 . 
  17. Brodal, Gerth Stølting ; Lagogiannis, George; Tarjan, Robert E. (2012). Montículos estrictos de Fibonacci (PDF) . Actas del 44.º simposio sobre Teoría de la Computación - STOC '12. págs. 1177–1184 . CiteSeerX 10.1.1.233.1740 . doi : 10.1145/2213977.2214082 . ISBN   978-1-4503-1245-5.
  18. Brodal, Gerth S. ( 1996), "Colas de prioridad eficientes en el peor de los casos" (PDF) , Actas del 7.º Simposio Anual ACM-SIAM sobre Algoritmos Discretos , págs. 52–58 
  19. Goodrich, Michael T .; Tamassia, Roberto (2004). "7.3.6. Construcción de montículos ascendentes". Estructuras de datos y algoritmos en Java (3.ª ed.). págs. 338–341 . ISBN   0-471-46983-1.
  20. «Sitio web de Gerth Stølting Brodal, en la Universidad de Aarhus» . Consultado el 18 de febrero de 2016 .