En computación distribuida , la elección de líder es el proceso de designar un solo proceso como organizador de alguna tarea distribuida entre varias computadoras (nodos). Antes de que comience la tarea, todos los nodos de la red desconocen qué nodo actuará como "líder" (o coordinador ) de la tarea o no pueden comunicarse con el coordinador actual. Sin embargo, después de ejecutar un algoritmo de elección de líder, cada nodo de la red reconoce un nodo particular y único como líder de la tarea.
Los nodos de la red se comunican entre sí para decidir cuál de ellos pasará al estado de "líder". Para eso, necesitan algún método para romper la simetría entre ellos. Por ejemplo, si cada nodo tiene identidades únicas y comparables, entonces los nodos pueden comparar sus identidades y decidir que el nodo con la identidad más alta es el líder.
La definición de este problema a menudo se atribuye a LeLann, quien lo formalizó como un método para crear un nuevo token en una red de token ring en la que el token se ha perdido.
Los algoritmos de elección de líderes están diseñados para ser económicos en términos de bytes totales transmitidos y tiempo. El algoritmo sugerido por Gallager, Humblet y Spira [1] para gráficos generales no dirigidos ha tenido un fuerte impacto en el diseño de algoritmos distribuidos en general, y ganó el Premio Dijkstra por un artículo influyente en computación distribuida.
Se han sugerido muchos otros algoritmos para diferentes tipos de gráficos de red , como anillos no dirigidos, anillos unidireccionales, gráficos completos, cuadrículas, gráficos de Euler dirigidos y otros. Korach, Kutten y Moran sugirieron un método general que desacopla el problema de la familia de gráficos del diseño del algoritmo de elección de líderes . [2]
Definición
El problema de la elección del líder es que cada procesador finalmente decida si es un líder o no, sujeto a la restricción de que exactamente un procesador decide que es el líder. [3] Un algoritmo resuelve el problema de elección de líder si:
- Los estados de procesadores se dividen en estados elegidos y no elegidos. Una vez elegido, permanece como elegido (de manera similar si no es elegido).
- En cada ejecución, se elige exactamente un procesador y el resto determina que no lo son.
Un algoritmo de elección de líder válido debe cumplir las siguientes condiciones: [4]
- Terminación : el algoritmo debe finalizar en un tiempo finito una vez que se selecciona el líder. En los enfoques aleatorios, esta condición a veces se debilita (por ejemplo, requiere la terminación con probabilidad 1).
- Singularidad : hay exactamente un procesador que se considera líder.
- Acuerdo : todos los demás procesadores saben quién es el líder.
Un algoritmo para la elección de líder puede variar en los siguientes aspectos: [5]
- Mecanismo de comunicación: los procesadores son síncronos en los que los procesos se sincronizan mediante una señal de reloj o asíncronos cuando los procesos se ejecutan a velocidades arbitrarias.
- Nombres de procesos: si los procesos tienen una identidad única o son indistinguibles (anónimos).
- Topología de red: por ejemplo, anillo , gráfico acíclico o gráfico completo .
- Tamaño de la red: el algoritmo puede utilizar o no el conocimiento del número de procesos del sistema.
Algoritmos
Elección de líder en anillos
Una red de anillo es una topología de gráfico conectado en la que cada nodo está conectado exactamente a otros dos nodos, es decir, para un gráfico con n nodos, hay exactamente n bordes que conectan los nodos. Un anillo puede ser unidireccional, lo que significa que los procesadores solo se comunican en una dirección (un nodo solo puede enviar mensajes a la izquierda o solo enviar mensajes a la derecha), o bidireccional, lo que significa que los procesadores pueden transmitir y recibir mensajes en ambas direcciones (un nodo puede enviar mensajes a la izquierda y a la derecha).
Anillos anónimos
Se dice que un anillo es anónimo si todos los procesadores son idénticos. Más formalmente, el sistema tiene la misma máquina de estado para cada procesador. [3] No existe un algoritmo determinista para elegir un líder en anillos anónimos, incluso cuando los procesos conocen el tamaño de la red. [3] [6] Esto se debe al hecho de que no hay posibilidad de romper la simetría en un anillo anónimo si todos los procesos se ejecutan a la misma velocidad. El estado de los procesadores después de algunos pasos solo depende del estado inicial de los nodos vecinos. Entonces, debido a que sus estados son idénticos y ejecutan los mismos procedimientos, en cada ronda los mismos mensajes son enviados por cada procesador. Por lo tanto, el estado de cada procesador también cambia de manera idéntica y, como resultado, si un procesador es elegido como líder, también lo harán todos los demás.
Por simplicidad, pruébelo en anillos sincrónicos anónimos. Demuestre por contradicción. Considere un anillo anónimo R con tamaño n> 1. Suponga que existe un algoritmo "A" para resolver la elección del líder en este anillo anónimo R. [3]
- Lema : después de la ronda de la ejecución admisible de A en R, todos los procesos tienen los mismos estados.
Prueba. probar por inducción en.
Caso base: : todos los procesos están en el estado inicial, por lo que todos los procesos son idénticos.
Hipótesis de inducción: suponga que el lema es verdadero para rondas.
Paso inductivo: en redondo, cada proceso envía el mismo mensaje a la derecha y envía el mismo mensaje A la izquierda. Dado que todos los procesos están en el mismo estado después de la ronda, en la ronda k, cada proceso recibirá el mensaje desde el borde izquierdo, y recibirá el mensaje desde el borde derecho. Dado que todos los procesos reciben los mismos mensajes en ronda, están en el mismo estado después de la ronda .
El lema anterior contradice el hecho de que después de un número finito de rondas en una ejecución de A, un proceso ingresó al estado electo y otros procesos ingresaron al estado no electo.
Elección de líder aleatoria (probabilística)
Un enfoque común para resolver el problema de la elección de líderes en anillos anónimos es el uso de algoritmos probabilísticos . En tales enfoques, generalmente los procesadores asumen algunas identidades basadas en una función probabilística y la comunican al resto de la red. Al final, mediante la aplicación de un algoritmo, se selecciona un líder (con alta probabilidad).
Anillo asíncrono [3]
Dado que no existe un algoritmo para anillos anónimos (demostrado anteriormente), los anillos asincrónicos se considerarían anillos no anónimos asincrónicos. En los anillos no anónimos, cada proceso tiene un únicoy no conocen el tamaño del anillo. La elección de líder en anillos asincrónicos se puede resolver mediante algún algoritmo con el uso de mensajes o mensajes.
En el algoritmo, cada proceso envía un mensaje con su al borde izquierdo. Luego espera hasta un mensaje del borde derecho. Si el en el mensaje es mayor que el suyo , luego reenvía el mensaje al borde izquierdo; si no, ignora el mensaje y no hace nada. Si el en el mensaje es igual al suyo , luego envía un mensaje a la izquierda anunciando que soy elegido. Otros procesos adelantan el anuncio a la izquierda y se vuelven no electos. Está claro que el límite superior es para este algoritmo.
En el algoritmo, se ejecuta en fases. Sobre ela fase, un proceso determinará si es el ganador entre el lado izquierdo y el lado derecho vecinos. Si es un ganador, entonces el proceso puede pasar a la siguiente fase. En fase, cada proceso necesita determinar si es un ganador o no enviando un mensaje con su a los vecinos de izquierda y derecha (el vecino no reenvía el mensaje). El vecino responde un solo si el en el mensaje es más grande que el del vecino , de lo contrario responde un . Si recibe dos s, uno de la izquierda, uno de la derecha, luego es el ganador en fase . En fase, los ganadores en fase Necesito enviar un mensaje con su hacia izquierda y vecinos correctos. Si los vecinos del camino reciben la en el mensaje más grande que su , luego reenvíe el mensaje al próximo vecino; de lo contrario, responda un . Si elel vecino recibe el más grande que su , luego envía un , de lo contrario responde un . Si el proceso recibe doss, entonces es el ganador en la fase . En la última fase, el ganador final recibirá su propioen el mensaje, luego termina y envía un mensaje de terminación a los otros procesos. En el peor de los casos, cada fase hay como máximo ganadores, donde es el número de fase. Existenfases en total. Cada ganador envía en el orden demensajes en cada fase. Entonces, la complejidad de los mensajes es.
Anillo sincrónico
En el libro de Computación distribuida de Attiya y Welch, [3] describieron un algoritmo no uniforme utilizando mensajes en anillo sincrónico con tamaño de anillo conocido . El algoritmo está operando en fases, cada fase tienerondas, cada ronda es una unidad de tiempo. En fase, si hay un proceso con , luego procesa envía un mensaje de terminación a los otros procesos (envío de mensajes de terminación costo rondas). De lo contrario, pase a la siguiente fase. El algoritmo comprobará si hay un número de fase igual a un proceso, luego realiza los mismos pasos que la fase . Al final de la ejecución, el mínimoserá elegido como líder. Usó exactamente mensajes y rondas.
Itai y Rodeh [7] introdujeron un algoritmo para un anillo unidireccional con procesos sincronizados. Asumen que el tamaño del anillo (número de nodos) es conocido por los procesos. Para un anillo de tamaño n, están activos a≤n procesadores. Cada procesador decide con probabilidad de a ^ (- 1) si se convierte en candidato. Al final de cada fase, cada procesador calcula el número de candidatos cy si es igual a 1, se convierte en líder. Para determinar el valor de c, cada candidato envía un token (guijarro) al inicio de la fase que se pasa alrededor del anillo, regresando después de exactamente n unidades de tiempo a su remitente. Cada procesador determina c contando el número de guijarros que pasaron. Este algoritmo logra la elección de líder con una complejidad de mensaje esperada de O (nlogn). También se utiliza un enfoque similar en el que se emplea un mecanismo de tiempo de espera para detectar puntos muertos en el sistema. [8] También existen algoritmos para anillos de tamaños especiales como el tamaño principal [9] [10] y el tamaño impar. [11]
Algoritmo uniforme
En los enfoques típicos para la elección de líderes, se supone que los procesos conocen el tamaño del anillo. En el caso de los anillos anónimos, sin utilizar una entidad externa, no es posible elegir un líder. Incluso asumiendo que existe un algoritmo, el líder no pudo estimar el tamaño del anillo. es decir, en cualquier anillo anónimo, existe una probabilidad positiva de que un algoritmo calcule un tamaño de anillo incorrecto. [12] Para superar este problema, Fisher y Jiang utilizaron el llamado oráculo líder Ω? que cada procesador puede preguntar si hay un líder único. Muestran que desde algún punto hacia arriba, está garantizado devolver la misma respuesta a todos los procesos. [13]
Anillos con identificaciones únicas
En uno de los primeros trabajos, Chang y Roberts [14] propusieron un algoritmo uniforme en el que se selecciona un procesador con el ID más alto como líder. Cada procesador envía su ID en el sentido de las agujas del reloj. Un proceso que recibe un mensaje y lo compara con el suyo. Si es más grande, lo pasa, de lo contrario descartará el mensaje. Muestran que este algoritmo utiliza como máximo mensajes y en el caso medio.
Hirschberg y Sinclair [15] mejoraron este algoritmo con complejidad del mensaje mediante la introducción de un esquema de paso de mensajes bidireccional que permite a los procesadores enviar mensajes en ambas direcciones.
Elección de líder en una malla
La malla es otra forma popular de topología de red, especialmente en sistemas paralelos, sistemas de memoria redundantes y redes de interconexión. [16]
En una estructura de malla, los nodos son de esquina (solo dos vecinos), de borde (solo tres vecinos) o interiores (con cuatro vecinos). El número de aristas en una malla de tamaño axb es m = 2ab-ab.
Malla desorientada
Un algoritmo típico para resolver la elección de líder en una malla no orientada es elegir solo uno de los cuatro nodos de esquina como líder. Dado que es posible que los nodos de las esquinas no estén al tanto del estado de otros procesos, el algoritmo primero debe activar los nodos de las esquinas. Se puede elegir un líder de la siguiente manera. [17]
- Proceso de despertar : en el que k nodos inician el proceso de elección. Cada iniciador envía un mensaje de activación a todos sus nodos vecinos. Si un nodo no es un iniciador, simplemente reenvía los mensajes a los otros nodos. En esta etapa se envían como máximo 3n + k mensajes.
- Proceso de elección : la elección en el anillo exterior tiene dos etapas como máximo con 6 (a + b) -16 mensajes.
- Terminación : el líder envía un mensaje de terminación a todos los nodos. Esto requiere como máximo 2n mensajes.
La complejidad del mensaje es como máximo 6 ( a + b ) - 16 , y si la malla tiene forma cuadrada, O ( √ n ).
Malla orientada
Una malla orientada es un caso especial en el que los números de puerto son etiquetas de brújula, es decir, norte, sur, este y oeste. La elección de un líder en una malla orientada es trivial. Solo necesitamos designar una esquina, por ejemplo, "norte" y "este" y asegurarnos de que el nodo sepa que es un líder.
Toro
Un caso especial de arquitectura de malla es un toro que es una malla con "envoltura". En esta estructura, cada nodo tiene exactamente 4 bordes de conexión. Un enfoque para elegir a un líder en tal estructura se conoce como etapas electorales. Similar a los procedimientos en estructuras de anillo, este método en cada etapa elimina candidatos potenciales hasta que finalmente queda un nodo candidato. Este nodo se convierte en el líder y luego notifica a todos los demás procesos de terminación. [16] Este enfoque se puede utilizar para lograr una complejidad de O (n). También se introdujeron enfoques más prácticos para tratar la presencia de enlaces defectuosos en la red. [18] [19]
Elección en hipercubos
Un hipercubo es una red que consta de nodos, cada uno con grado de y bordes. Se pueden utilizar etapas electorales similares a las anteriores para resolver el problema de la elección de líderes. En cada etapa compiten dos nodos (llamados duelistas) y el ganador asciende a la siguiente etapa. Esto significa que en cada etapa solo la mitad de los duelistas ingresan a la siguiente etapa. Este procedimiento continúa hasta que solo queda un duelista y se convierte en el líder. Una vez seleccionado, notifica a todos los demás procesos. Este algoritmo requieremensajes. En el caso de hipercubos no orientados, se puede utilizar un enfoque similar pero con una mayor complejidad de mensaje de. [dieciséis]
Elección en redes completas
Las redes completas son estructuras en las que todos los procesos están conectados entre sí, es decir, el grado de cada nodo es n-1, siendo n el tamaño de la red. Se conoce una solución óptima con mensajes O (n) y complejidad de espacio. [20] En este algoritmo, los procesos tienen los siguientes estados:
- Dummy: nodos que no participan en el algoritmo de elección de líder.
- Pasivo: el estado inicial de los procesos antes del inicio.
- Candidato: el estado de los nodos después de despertarse. Los nodos candidatos se considerarán líderes.
Para elegir un líder, se considera un anillo virtual en la red. Todos los procesadores se inician inicialmente en un estado pasivo hasta que se despiertan. Una vez que los nodos están despiertos, son candidatos para convertirse en líderes. Según un esquema de prioridad, los nodos candidatos colaboran en el anillo virtual. En algún momento, los candidatos toman conciencia de la identidad de los candidatos que los preceden en el ring. Los candidatos de mayor prioridad preguntan a los de menor prioridad sobre sus predecesores. Los candidatos con menor prioridad se vuelven ficticios después de responder a los candidatos con mayor prioridad. Con base en este esquema, el candidato de mayor prioridad eventualmente sabe que todos los nodos del sistema son ficticios excepto él mismo, momento en el que sabe que es el líder.
Técnicas universales de elección de líderes
Como su nombre lo indica, estos algoritmos están diseñados para ser utilizados en todas las formas de redes de procesos sin ningún conocimiento previo de la topología de una red o sus propiedades, como su tamaño. [dieciséis]
Gritar
Shout (protocolo) construye un árbol de expansión en un gráfico genérico y elige su raíz como líder. El algoritmo tiene un costo total lineal en la cardinalidad de los bordes.
Mega-fusión
En esencia, esta técnica es similar a encontrar un árbol de expansión mínimo (MST) en el que la raíz del árbol se convierte en el líder. La idea básica de este método es que los nodos individuales se fusionan entre sí para formar estructuras más grandes. El resultado de este algoritmo es un árbol (un gráfico sin ciclo) cuya raíz es el líder de todo el sistema. El costo del método de megafusión es donde m es el número de aristas y n es el número de nodos.
Yoyó
Yo-yo (algoritmo) es un algoritmo de búsqueda mínima que consta de dos partes: una fase de preprocesamiento y una serie de iteraciones. [16] En la primera fase o configuración , cada nodo intercambia su id con todos sus vecinos y en función del valor orienta sus bordes incidentes. Por ejemplo, si el nodo x tiene un id menor que y, x se orienta hacia y. Si un nodo tiene una identificación más pequeña que todos sus vecinos, se convierte en una fuente . En contraste, un nodo con todos los bordes hacia adentro (es decir, con un id mayor que todos sus vecinos) es un sumidero . Todos los demás nodos son nodos internos .
Una vez que todos los bordes están orientados, comienza la fase de iteración . Cada iteración es una etapa electoral en la que se eliminarán algunos candidatos. Cada iteración tiene dos fases: YO- y –YO . En esta fase las fuentes inician el proceso para propagar a cada sumidero los valores más pequeños de las fuentes conectadas a ese sumidero.
Yo-
- Una fuente (mínimos locales) transmite su valor a todos sus vecinos.
- Un nodo interno espera recibir un valor de todos sus vecinos. Calcula el mínimo y lo envía al vecino.
- Un sumidero (un nodo sin borde de salida) recibe todos los valores y calcula su mínimo.
-yo
- Un sumidero envía SÍ a los vecinos de los que vio el valor más pequeño y NO a los demás
- Un nodo interno envía SÍ a todos los vecinos de los que recibió el valor más pequeño y NO a los demás. Si recibe solo un NO, envía NO a todos.
- Una fuente espera hasta recibir todos los votos. Si todo es SÍ, sobrevive y si no, deja de ser candidato.
- Cuando un nodo x envía NO a un vecino y, la dirección lógica de ese borde se invierte.
- Cuando un nodo y recibe NO de un vecino, cambia la dirección de ese enlace.
Después de la etapa final, cualquier fuente que reciba un NO deja de ser una fuente y se convierte en un sumidero. También se introduce una etapa adicional, la poda , para eliminar los nodos que resultan inútiles, es decir, su existencia no repercute en las próximas iteraciones.
- Si un fregadero es de hoja, entonces es inútil y, por lo tanto, se retira.
- Si, en la fase YO- el mismo valor es recibido por un nodo de más de un vecino, les pedirá a todos menos a uno que eliminen el enlace que los conecta.
Este método tiene un costo total de mensajes O (mlogn). La complejidad de su mensaje real, incluida la poda, es un problema de investigación abierto y se desconoce.
Aplicaciones
Redes de radio
En los protocolos de redes de radio, la elección del líder se usa a menudo como un primer paso para abordar primitivas de comunicación más avanzadas, como la recopilación o transmisión de mensajes. [21] La propia naturaleza de las redes inalámbricas induce colisiones cuando los nodos adyacentes transmiten al mismo tiempo; elegir un líder permite coordinar mejor este proceso. Si bien el diámetro D de una red es un límite inferior natural para el tiempo necesario para elegir un líder, los límites superior e inferior para el problema de elección de líder dependen del modelo de radio específico estudiado.
Modelos y tiempo de ejecución
En las redes de radio, los n nodos pueden elegir en cada ronda entre transmitir o recibir un mensaje. Si no hay detección de colisiones disponible, un nodo no puede distinguir entre silencio o recibir más de un mensaje a la vez. Si la detección de colisiones estuviera disponible, entonces un nodo puede detectar más de un mensaje entrante al mismo tiempo, aunque los mensajes en sí no puedan decodificarse en ese caso. En el modelo de pitidos , los nodos solo pueden distinguir entre silencio o al menos un mensaje a través de la detección de portadora .
Los tiempos de ejecución conocidos para las redes de un solo salto varían desde una constante (esperada con detección de colisión) a O (n log n) rondas (determinista y sin detección de colisión). En las redes de varios saltos , los tiempos de ejecución conocidos difieren de aproximadamente O ((D + log n) (log² log n)) rondas (con alta probabilidad en el modelo de pitido), O (D log n) (determinista en el modelo de pitido), O (n) (determinista con detección de colisión) a O (n log 3/2 n (log log n) 0.5 ) rondas (determinista y sin detección de colisión).
Ver también
- Computación distribuida # Elección
- Algoritmo de bully
- Algoritmo de Chang y Roberts
- Algoritmo HS
- Sistema de votación
Referencias
- ^ RG Gallager , PA Humblet y PM Spira (enero de 1983). "Un algoritmo distribuido para árboles de expansión de peso mínimo" (PDF) . Transacciones ACM sobre lenguajes y sistemas de programación . 5 (1): 66–77. doi : 10.1145 / 357195.357200 . Archivado desde el original (PDF) el 12 de octubre de 2016 . Consultado el 30 de septiembre de 2007 .CS1 maint: varios nombres: lista de autores ( enlace )
- ^ Ephraim Korach, Shay Kutten, Shlomo Moran (1990). "Una técnica modular para el diseño de algoritmos de búsqueda de líderes distribuidos eficientes". Transacciones ACM sobre lenguajes y sistemas de programación . 12 (1): 84–101. CiteSeerX 10.1.1.139.7342 . doi : 10.1145 / 77606.77610 .CS1 maint: varios nombres: lista de autores ( enlace )
- ^ a b c d e f H. Attiya y J. Welch, Computación distribuida: fundamentos, simulaciones y temas avanzados , John Wiley & Sons inc., 2004, cap. 3
- ^ I.Gupta, R. van Renesse y KP Birman, 2000, Un protocolo de elección de líder probablemente correcto para grupos grandes, Informe técnico , Universidad de Cornell
- ^ R. Bakhshi, W. Fokkink, J. pang y J. Van de Pol, c2008 "Elección de líder en anillos anónimos: Franklin se vuelve probabilístico", TCS , vol. 273, págs. 57-72.
- ^ H. Attiya y M. Snir, 1988, "Computación en un anillo anónimo", JACM , vol. 35, número. 4, págs.845-875
- ^ A. Itai y M. Rodeh, 1990, "Simetría que se rompe en redes distribuidas", vol. 88, número 1, págs. 60-87.
- ^ L. Higham y S. Myers, 1998, "Circulación de tokens autoestabilizantes en anillos de paso de mensajes anónimos", Segunda Conferencia Internacional sobre principios de sistemas distribuidos .
- ^ G. Itkis, C. Lin y J. Simon, 1995, "Determinista, constante espacio, elección de líder autoestabilizante en anillos uniformes". En Proc. 9º Taller de Algoritmos Distribuidos , Vol. 972, págs. 288-302.
- ^ J. Burns y J. Pachl, 1989, "Anillos uniformes autoestabilizadores", ACM Trans. Programa. Lang. Systems , vol. 11, número. 2, páginas 330-344
- ^ T. Herman, 1990, "Autoestabilización probabilística", Inf. Proceso. Letón. , Vol. 35, número 2, págs. 63-67.
- ^ G. Tel, Introducción a los algoritmos distribuidos . Cambridge University Press, 2000.2a edición
- ^ M. Fischer y H. Jiang, 2006, "Elección de líder autoestabilizante en redes de agentes anónimos de _nite-state", En Proc. 10ª Conf. sobre Principios de Sistemas Distribuidos , Vol. 4305, págs. 395-409.
- ^ E. Chang y R. Roberts, 1979, "Un algoritmo mejorado para la búsqueda descentralizada de extremos en configuraciones circulares de procesos", ACM , vol. 22, número 5, págs. 281-283.
- ^ DS Hirschberg y JB Sinclair, 1980, "Descubrimiento de extremos descentralizados en configuraciones circulares de procesadores", ACM , vol. 23, número 11, págs. 627-628.
- ^ a b c d e N. Santoro, Diseño y análisis de algoritmos distribuidos , Wiley, 2006.
- ^ H. Kallasjoki, 2007, "Elección en malla, cubo y redes completas", Seminario sobre informática teórica .
- ^ M. Refai, A. Sharieh y. Alsmmari, 2010, "Algoritmo de elección de líder en red Torus 2D con presencia de falla de un enlace", The International Arab Journal of Information Technology , vol. 7, N ° 2.
- ^ M Al Refai, 2014, "Algoritmo de elección de líder dinámico en red Torus 2D con falla de enlaces múltiples", IJCST , Vol. 2, número 5.
- ^ J. Villadangos, A. Córdoba, F. Farina y M. Prieto, 2005, "Elección de líder eficiente en redes completas", PDP , pp.136-143.
- ^ Haeupler, Bernhard; Ghaffari, Mohsen (2013). Elección de líder casi óptima en redes de radio de varios saltos . Actas del vigésimo cuarto simposio anual ACM-SIAM sobre algoritmos discretos . págs. 748–766. arXiv : 1210.8439 . doi : 10.1137 / 1.9781611973105.54 . ISBN 978-1-61197-251-1.