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 :para inserción, find-minimum, fusionar (combinar dos colas) y decrease-key ypara 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.yy 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. Observamosel número de hijos del nodocon rangoTambién utilizaremospara la raíz del árbolypara la raíz del árbolEn cada momento dado, cada subárbol con raíz en un nodo debe cumplir con estos 5 invariantes (que luego se llamaráninvariantes):
- : Sies una hoja, entonces,
- :,
- : Si, entonces,
- :destacamos que,
- :o.
Aquínos garantiza que el tamaño del subárbol enraizado en un nodo es al menos exponencial al rango de ese nodo. Además,limita el número de hijos de cada rango para un nodo dado, esto implica que todos los nodos tienen rango y grados en.
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.yde nodos más grandes queIntuitivamente,son los nodos más grandes decon alto rango (de tal manera quesi), yson los nodos con rango pequeño (). Estos conjuntos se implementan utilizando listas doblemente enlazadas, lo que significa que tienen un orden . En particular, todos los nodos que violan se agregan ase agregan al principio de la lista y todos los nodos que violan se agregan ase insertan junto a un nodo del mismo rango. Dejamosdenota el número de nodos ende rangoElyLas listas cumplen con estos 5 invariantes (llamaremos lasinvariantes):
- :
- : Sientonces
- : Sientonces existe un nodode tal manera que
- :
- : Al denotar, tenemos:para una cierta constante.
Dado que todos los nodos tienen rango enely, todoyson de tamaño.
También tenemos algunas invariantes de las raíces de los árboles.y:y(llamado elinvariantes).
- :,
- :,
- : si, entonces.
Elinvariante esencialmente nos dice que si aumentamos el rango depor uno, tenemos como máximonuevas violaciones "grandes" (aquí grande significa tener un rango alto) sin violar lainvariante. Por otro lado, elinvariante nos dice que todas las violaciones enson "pequeños", este invariante es verdadero según la definición de. Mantener las invariantesyno es trivial, para mantener estos utilizaremos eloperación que se puede implementar utilizando una guía como se define en la siguiente sección. Cada vez que llamemos a laEn esta operación, esencialmente haremos lo siguiente :
- Agregue la nueva infracción aodependiendo de la gravedad de dicha infracción.
- Para evitaryPara evitar que se vuelva demasiado grande, realizamos de forma incremental dos tipos de transformaciones:
- Trasladando a los hijos deapara aumentar el rango de
- Reducir el número de infracciones enreemplazando dos violaciones de rangopor una violación de rango
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 variablesy queremos asegurarnos de quepara algún umbral. La única operación permitida eslo cual disminuyepor al menos 2 y aumentapor como máximo 1. Podemos suponer sin pérdida de generalidad quereducepor 2 y aumentapor 1.
Si unse incrementa en uno, el objetivo de la guía es decirnos en qué índicespara solicitarpara respetar el umbral. El guía solo está autorizado a hacerllamadas a lafunción para cada incremento.
El guía tiene acceso a otra secuenciade tal manera quey. Siempre y cuando después del aumento detenemosno necesitamos pedir ayuda a nuestro guía ya queestá "muy" abajo. Sin embargo, siantes del aumento, entonces tenemosdespués del cambio.
Para simplificar la explicación, podemos suponer que, de modo que. La guía creará bloques en la secuencia dede formadonde permitimos que no haya. La guía mantiene la invariante de que cada elemento que no está en un bloque es o bien uno un. Por ejemplo, aquí están los bloques para una secuencia de.
La guía se compone de 3 matrices :
- la gama de
- la gama de
- una matriz de punteros donde todos lospara quéestán en el mismo bloque apuntarán a la misma celda de memoria que contiene un valor. Si unno está en un bloque, entoncesapunta a una celda de memoria que contiene.
Con esta definición, una guía tiene dos propiedades importantes :
- Para cada elemento de un bloque, podemos encontrar el elemento más a la izquierda del bloque en el tiempo.
- Podemos destruir un bloque a tiempoasignandoa la celda de memoria a la que apunta cada elemento del bloque.
De esta forma, el guía puede decidir qué índices utilizar.a tiempoAquí tienes un ejemplo :
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 aEn el ejemplo anterior, solo dosSe necesitaban operaciones, este es el caso para todas las instancias. Por lo tanto, la cola solo necesitaoperaciones 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.de igual rango. Podemos calcular el mínimo de estos tres nodos con dos comparaciones. Aquí asumimos quees el mínimo pero el proceso es similar para todos. Ahora podemos hacer los nodosylos dos hijos más a la izquierda dey aumentar el rango depor uno. Esto conserva todo elyinvariantes.
Desvinculación de árboles
Sitiene exactamente dos o tres hijos de rango, podemos eliminar a estos hijos yobtiene el rango de su nuevo hijo mayor más uno. Desde elcondición, sabemos que laEl invariante se conservará. Entonces, todos losyLos invariantes siguen satisfechas. Sitiene 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 rangosiempre dará como resultado dos o tres árboles de rango(de los 2 o 3 hijos excluidos) y un árbol adicional de rango como máximo.
Manteniendo a los hijos de una raíz
Cuando agregamos y eliminamos hijos de una raíz, queremos mantener lainvariante verdadero. Para ello, utilizamos 4 guías, dos para cada raíz.y. Tener acceso constante al tiempo del hijo decreamos una matriz extensible de punteros que tiene para cada rangoun puntero a un hijo dede rango. Un guía mantendrá la condición de quey el otro sostieneambos para. Los hijos dede rangoyse tratan por separado de una manera sencilla para mantener su número entre 2 y 7. El equivalente a laLa variable en la definición de la guía tendrá los valorespara la guía de límites superiores ypara el límite inferior.
En este contexto, cuando agregamos un hijo de rangohasta la raíz, aumentamospor uno, y aplicar eloperaciones. ElLa operación aquí consiste en vincular tres árboles de rangolo que crea un nuevo niño de rangoPor lo tanto, disminuimospor tres y aumentarpor uno. Si este aumento resulta en demasiados hijos de rangoounimos a algunos de estos hijos y posiblemente aumentamos el rango de. Si aumentamos el rango de, tenemos que aumentar la longitud del array extensible gestionado por las guías.
Cortarle la relación a un hijoes muy similar, excepto que aquí elEsta operación corresponde a la eliminación de enlaces en un árbol.
Para la raízLa situación es casi la misma. Sin embargo, dado quenos garantiza quees el elemento mínimo, sabemos que no crearemos ninguna violación al vincular o desvincular hijos deNo se puede decir lo mismo de. 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 desi tiene un rango menor quey de lo contrario se convierte en hijo de. Las nuevas violaciones que tienen un rango mayor quese añaden a. Para mantener los invariantes en elconjunto (es deciry), tenemos que garantizar que el rango dese incrementará y queen 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.
Suponemos que tenemos dos posibles violaciones.yde igual rango. Entonces tenemos varios casos:
- Si resulta que uno de los nodos no constituye una infracción, simplemente lo eliminamos de su conjunto de infracciones correspondiente.
- De lo contrario, ambos nodos son violaciones. Debido a, sabemos que ambosytener al menos un hermano. Entonces:
- Siysi no son hermanos, entonces podemos asumir sin perder generalidad que, entonces podemos intercambiar los subárboles enraizados enyEl número de infracciones solo puede disminuir durante ese intercambio.
- Demás,yson hermanos de un nodo que llamaremos.
- Sitiene más de un hermano de rango, podemos simplemente cortary convertirlo en un nodo que no violecomo se describe en la subsección anterior.
- Demás,yson los únicos hijos de rangode...
- Si, podemos cortar ambosynodos dey convertirlos en nodos que no violencomo se describe en la subsección anterior
- Demás,Vamos a cortar, el nuevo rango deserá uno más el rango de su hijo más a la izquierda, Reemplazamospor un hijo ende rango, que se puede cortar como se describe en la subsección anterior. Si el reemplazo dese convierte en un nodo violador de rango, lo añadimos a. Finalmente hacemosnuevos hijos decomo se describió anteriormente.
Evitar demasiadas infracciones
Los únicos conjuntos de violaciones en los que agregaremos violaciones sonyComo se describió anteriormente, los invariantes en esos conjuntos se mantienen usando guías. Cuando agregamos una violación aTenemos dos casos:
- Si hay exactamente 6 violaciones del rango dado y hay al menos dos nodos violadores que no son hijos de, aplicamos eloperaciones indicadas por el guía.
- Si hay más de 4 violaciones que son hijos deHemos eliminado las infracciones adicionales y las enlazamos a continuación.. Esto elimina la violación creada por estos nodos y no afecta la guía que mantiene los hijos de.
Por cada operación de cola de prioridad que se realiza, aumentamos el rango depor al menos uno moviendo un número constante de hijos dea(siempre que). Aumentando el rango denos permite agregar infracciones asin dejar de mantener todas nuestras invariantes. Siypodemos cortar los hijos más grandes de, vincularlos ay luego hacerun hijo de. Esto satisface todas las invariantes. De lo contrario, cortamos un hijo dede rango, desvincule este hijo y agregue los árboles resultantes a. Si, sabemos quees 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
simplemente devuelve un par de árboles vacíos.
FindMin
devoluciones.
Insertar
es solo un caso especial dedóndees una cola que solo contieney.
Fusión
implica cuatro árboles (dos para cada cola). El árbol con la raíz mínima se convierte en el nuevoá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 nuevoEl á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 nuevoPodemos desvincularlos antes de agregarlos. Las infracciones creadas se manejan como se explica en la sección : "Evitar demasiadas infracciones".
DisminuirTecla
reemplaza el elemento depor(con). Si, 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
se permite tomar el peor de los casos tiempoPrimero, vaciamos completamentemoviendo a todos los hijos dealuego haciendoun hijo de rango 0 de. Entonces,se elimina, esto nos deja con como máximoá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 realizandooperaciones de vinculación y desvinculación. Esto restablece elyinvariantes. Al fusionar losyconjuntos de la nueva raíz junto con elyconjuntos de la raíz antigua juntos, obtenemos un nuevo conjunto de violación de tamaño. Haciendo como máximotransformaciones 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 nuevoconjunto y el nuevoEl conjunto está vacío. Esto restablece elinvariantes. También tenemos que inicializar una nueva guía para la nueva raíz..
Borrar
Aquí,denota el elemento más pequeño posible.puede implementarse simplemente llamandoseguido de.
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 nodoyconjuntos,
- 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 violacionesopertenece a, el puntero anterior apunta a.
- una serie de indicadores para los hijos dede rango(con),
- una matriz similar para,
- una matriz de punteros a nodos ende rango(con).
Finalmente, tenemos 5 guías: tres para mantener los límites superiores en,yy dos para mantener los límites inferiores eny.
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.
- ↑ 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 ]
- 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 ]
- ↑ Límite inferior de[ 13 ] límite superior de[ 14 ]
- 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 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
- ↑ Gerth Stølting Brodal y Chris Okasaki (1996). Colas de prioridad puramente funcionales óptimas . Journal of Functional Programming.
- ^ 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 ) - 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.
- 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 .
- 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.
- ↑ 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 .
- ↑ "Montículo binomial | Brilliant Math & Science Wiki" . brilliant.org . Consultado el 30 de septiembre de 2019 .
- 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
- ↑ Okasaki, Chris (1998). "10.2. Abstracción estructural". Estructuras de datos puramente funcionales (1.ª ed.). págs. 158–162 . ISBN 9780521631242.
- ↑ Takaoka, Tadao (1999), Teoría de los montículos 2-3 (PDF) , pág. 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
- ↑ 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 .
- ↑ 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.
- ↑ 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 .
- ↑ 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 .
- ↑ 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.
- ↑ 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
- ↑ 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.
- ↑ «Sitio web de Gerth Stølting Brodal, en la Universidad de Aarhus» . Consultado el 18 de febrero de 2016 .
- Montones (estructuras de datos)