Algoritmo eficiente para recuperar el cierre transitivo de un gráfico acíclico dirigido


14

Estoy tratando de resolver un problema gráfico (no es para la tarea, solo para practicar mis habilidades). Se da un DAG , donde es el conjunto de vértices y los bordes. El gráfico se representa como una lista de adyacencia, por lo que A v es un conjunto que contiene todas las conexiones de . Mi tarea es encontrar el que los vértices son accesibles desde cada vértice . La solución que uso tiene una complejidad de , con cierre transitivo, pero leí que en un blog puede ser más rápido, aunque no reveló cómo. ¿Alguien podría decirme otra forma (con mayor complejidad) para resolver el problema de cierre transitivo en un DAG?V Esol(V,mi)VmiUNvv V O ( V 3 )vvVO(V3)




Sin embargo, mi sugerencia es mantener el . pero solo intenta disminuir el número de comparaciones en promedio. Es decir, adivine y agregue reglas simples a su algoritmo. Puede usar la multiplicación de matrices, pero si la está usando para gráficos pequeños, entonces es un desastre y, de hecho, en la práctica, su método es mejor. O(|V|3)
AJed

@AJed En este problema particular, excederá el límite de tiempo. O(V3)
Rontogiannis Aristofanis

2
@RondogiannisAristophanes Cuando dice límite de tiempo, ¿quiere decir que esto es un problema en algunos desafíos de programación / algoritmos como topcoder, etc.? Si es así, y si está seguro de que ha implementado correctamente una solución , es posible que desee ver el problema nuevamente. Puede haber alguna otra propiedad oculta que pueda simplificar las cosas, o puede haber una mejor manera de expresar el problema para que no se necesite un cierre transitivo. Porque el cierre transitivo es tan difícil como la multiplicación de matrices. Lea student.cs.uwaterloo.ca/~cs466/Old_courses/F08/…O(V3)
Paresh el

Respuestas:


8

El hecho de que nuestro gráfico sea acíclico hace que este problema sea mucho más simple.

La ordenación topológica puede darnos una ordenación de los vértices manera que, si i < j , entonces no hay un borde de v j a v i . Hemos enumerado los vértices de modo que todos los bordes en "avance" en nuestra lista.v1,v2,...,vnorteyo<jvjvyo

(editado para corregir el análisis y dar un algoritmo ligeramente más rápido)

Ahora solo retrocedemos por esta lista, comenzando en el último vértice . El cierre transitivo de v n es solo en sí mismo. Agregue también v n al cierre transitivo de cada vértice con un borde para v n .vnortevnortevnortevn

Para cada vértice , yendo desde el extremo hacia atrás, primero agregue v i a su propio cierre transitivo, luego agregue todo en el cierre transitivo de v i al cierre transitivo de todos los vértices con un borde a v i .vivivivi

El tiempo de ejecución es en el peor de los casos, con n el número de vértices y m O ( n 2 ) el número de aristas. La ordenación topológica lleva tiempo O ( n + m ) . Luego hacemos otro trabajo O ( m n ) en el paso hacia atrás: a medida que avanzamos hacia atrás en la lista, para cada borde, tenemos que sumar nO(n+m+nm)=O(n3)nmO(n2)O(n+m)O(mn)n vértices al cierre transitivo de alguien.

n=64iiijcjci

n>64

OO(n3)


1
Probablemente podría usar una representación de lista vinculada para los conjuntos y terminarían compartiendo colas comunes.
Kyle Butt
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.