En teoría de redes , el algoritmo de Brandes es un algoritmo para calcular la centralidad de intermediación de los vértices de un grafo . El algoritmo fue publicado por primera vez en 2001 por Ulrik Brandes . [1] La centralidad de intermediación, junto con otras medidas de centralidad , es una medida importante en muchas redes del mundo real, como las redes sociales y las redes de computadoras . [2] [3] [4]
Existen varias métricas para la centralidad de un nodo, una de ellas es la centralidad de intermediación . [5] Para un nodo en un gráfico conectado , la centralidad de intermediación se define como: [6] [7]
donde es el número total de caminos más cortos de nodo a nodo y es el número de estos caminos que pasan por . Para un gráfico no ponderado, se considera que la longitud de un camino es el número de aristas que contiene.
Por convención, siempre que , ya que el único camino es el camino vacío. Además, si es o , ya que los caminos más cortos no pasan por sus puntos finales.
La cantidad
se conoce como la dependencia de pares de , y representa la proporción de los caminos más cortos que pasan por . La centralidad de intermediación es simplemente la suma de las dependencias de pares sobre todos los pares. Además de la dependencia de pares, también es útil definir la dependencia (única) de , con respecto a un vértice en particular :
,
con lo cual podemos obtener la formulación concisa
.
El algoritmo de Brandes calcula la centralidad de intermediación de todos los nodos de un grafo. Para cada vértice , hay dos etapas.
El número de caminos más cortos entre y cada vértice se calcula mediante una búsqueda en amplitud . La búsqueda en amplitud comienza en y se registra la distancia más corta de cada vértice desde , dividiendo el gráfico en capas discretas. Además, cada vértice lleva un registro del conjunto de vértices que en la capa anterior apuntan a él, . Descrito en la notación de constructor de conjuntos , se puede escribir como:
.
Esto se presta a una fórmula iterativa simple para :
,
que esencialmente establece que, si está en la profundidad , entonces cualquier camino más corto en la profundidad extendido por un solo borde a se convierte en un camino más corto a .
Brandes demostró la siguiente fórmula recursiva para las dependencias de vértices: [1]
,
donde la suma se toma sobre todos los vértices que están a una arista más alejada que . Este lema elimina la necesidad de sumar explícitamente todas las dependencias de pares. Usando esta fórmula, la dependencia única de en un vértice en profundidad está determinada por la capa en profundidad . Además, el orden de suma es irrelevante, lo que permite un enfoque de abajo hacia arriba comenzando en la capa más profunda.
Resulta que las dependencias de de todos los demás vértices se pueden calcular en el tiempo. Durante la búsqueda en amplitud, el orden en el que se visitan los vértices se registra en una estructura de datos de pila . Luego, el paso de retropropagación extrae repetidamente los vértices, que se ordenan naturalmente por su distancia desde , en orden descendente.
Para cada nodo emergente , iteramos sobre sus predecesores : se suma la contribución de hacia , es decir,
.
Fundamentalmente, cada capa propaga sus dependencias por completo, antes de pasar a la capa con menor profundidad, debido a la naturaleza de la búsqueda en amplitud. Una vez que la propagación llega de nuevo a , cada vértice ahora contiene . Estos simplemente se pueden agregar a , ya que
.
Después de iteraciones de ruta más corta de fuente única y retropropagación , cada una contiene la centralidad de intermediación para .
El siguiente pseudocódigo ilustra el algoritmo de Brandes en un gráfico dirigido no ponderado. [8]
El algoritmo Brandes( Graph ) es para cada u en Graph.Los vértices hacen CB[ u ] ← 0 para cada s en Graph.Vertices , haga para cada v en Graph.Vertices , haga δ[ v ] ← 0 // Dependencia única de s en v prev[ v ] ← lista vacía // Predecesores inmediatos de v durante BFS σ[ v ] ← 0 // Número de caminos más cortos de s a v (s implícito) dist[ v ] ← null // No se conocen rutas inicialmente, σ[ s ] ← 1 // excepto el vértice inicial distribución[ s ] ← 0 Q ← cola que contiene solo s // Búsqueda en amplitud S ← pila vacía // Registra el orden en el que se visitan los vértices // Rutas más cortas de una sola fuente mientras Q no esté vacío , haga u ← Q .dequeue() S .push( u ) para cada v en Graph.Neighbours [ u ] hacer si dist[ v ] = null entonces dist[ v ] ← dist[ u ] + 1 Q .enqueue( v ) si dist[ v ] = dist[ u ] + 1 entonces σ[ v ] ← σ[ v ] + σ[ u ] prev[ v ].append( u ) // Propagación hacia atrás de dependencias mientras S no esté vacío, haga v ← S .pop() para cada u en prev[ v ] haga δ[ u ] ← δ[ u ] + σ[ u ] / σ[ v ] * (1 + δ[ v ]) si u ≠ s entonces CB[ v ] ← CB[ v ] + δ[ v ] // Reducido a la mitad para grafos no dirigidos devolver CB
El tiempo de ejecución del algoritmo se expresa en términos del número de vértices y el número de aristas .
Para cada vértice , realizamos una búsqueda en amplitud, que lleva tiempo. Como el gráfico está conectado, el componente subsume el término, ya que el número de aristas es al menos .
En la etapa de retropropagación, cada vértice se extrae de la pila y se itera sobre sus predecesores. Sin embargo, dado que cada entrada predecesora corresponde a una arista en el gráfico, esta etapa también está limitada por .
Por lo tanto, el tiempo de ejecución total del algoritmo es , una mejora en los límites de tiempo alcanzados por algoritmos anteriores. [1] Además, el algoritmo de Brandes mejora la complejidad espacial de los algoritmos ingenuos, que normalmente requieren espacio. El algoritmo de Brandes solo almacena como máximo predecesores, junto con datos para cada vértice, lo que hace que su complejidad espacial adicional sea
El algoritmo se puede generalizar a grafos ponderados utilizando el algoritmo de Dijkstra en lugar de la búsqueda en amplitud. Cuando se opera en grafos no dirigidos, la centralidad de intermediación se puede dividir por 2, para evitar el doble conteo de la contraparte invertida de cada camino. También existen variantes para calcular diferentes medidas de centralidad, incluyendo la intermediación con caminos en longitud máxima , la intermediación de aristas , la intermediación de carga y la intermediación de tensión . [8]