2012-02-06 10 views
6

Supongamos que tenemos un DAG con una fuente. Me gustaría encontrar los nodos n de modo que cualquier ruta completa desde la fuente se ejecute a través de n (es decir, n domina todos los receptores). En otras palabras: si eliminamos todos los sucesivos de n, todas las rutas terminarían en n. El problema es que los nodos se marcan incrementalmente como eliminados en el DAG. Como los nodos están marcados como eliminados, otros nodos pueden comenzar a satisfacer la propiedad anterior. ¿Cómo puedo detectar esto de manera eficiente cuando sucede?Dominadores de detección incremental en los DAG

puntos de bonificación si la estructura de datos puede hacer esto con múltiples fuentes de una manera más eficiente que ejecutar el algoritmo para una sola fuente por separado en cada una de las fuentes.

+1

Eso significa que quiere determinar incrementalmente el corte en un gráfico cambiante? ¿Y necesitas todos esos nodos (todos los cortes) o es suficiente? – jpalecek

+0

Sí, esa es otra forma de decirlo: detectar un corte justo antes de que ocurra (es decir, justo antes de que se elimine el último nodo que daría lugar a un corte). – Jules

+0

Re: editar: preferiblemente todos esos cortes, pero un corte sería lo suficientemente bueno también. Los cortes deben ocurrir con relativa poca frecuencia, por lo que si sucede no es demasiado importante ejecutar un algoritmo lento para encontrar los otros cortes. – Jules

Respuesta

3

Topológicamente clasifique este DAG para establecer un orden para sus nodos. Para cada nodo, su valor sería el número de bordes salientes de todos los nodos precedentes menos el número de bordes entrantes para todos los nodos precedentes y el nodo actual. El valor para el nodo "dominador" siempre es cero.

Después de que un nodo esté marcado como "eliminado", ponga sus predecesores y sucesores en la cola de prioridad. La prioridad está determinada por el orden de clasificación topológica. Actualice los valores para todos los nodos, siguiendo el nodo "eliminado" (agregue el número de nodos entrantes y reste la cantidad de nodos salientes para este nodo). Al mismo tiempo (en el mismo orden) el valor de decremento para cada nodo entre el nodo predecesor en la cola de prioridad y el nodo "eliminado" y el valor de incremento para cada nodo, comenzando desde el nodo sucesor en la cola de prioridad. Deténgase cuando el valor de algún nodo se reduzca a cero. Este es un nuevo nodo "dominador". Si se necesitan todos los nodos "dominator", continúe hasta el final del gráfico.

delete(delNode): 
    for each predecessor in delNode.predecessors: queue.add(predecessor) 
    for each successor in delNode.successors: queue.add(successor) 
    for each node in DAG: 
    if queue.top.priority == node.priority > delNode.priority: 
     ++accumulator 

    node.value += accumulator 
    if node.value == 0: dominatorDetected(node) 

    if node.priority == delNode.priority: 
     accumulator += (delNode.predecessors.size - delNode.successors.size) 
     node.value = -1 

    if queue.top.priority == node.priority: 
     queue.pop() 
     if node.priority < delNode.priority: 
     --accumulator 

    if queue.empty: stop 

Para el caso de múltiples fuentes, es posible utilizar el mismo algoritmo, pero mantener una lista de "valores" para cada nodo, un valor para cada fuente. La complejidad del algoritmo es O(Nodes * Sources), lo mismo que para la búsqueda independiente en cada una de las fuentes. Pero el programa puede hacerse más eficiente si se utiliza la vectorización. Los "valores" pueden procesarse en paralelo con las instrucciones SIMD. Los compiladores modernos pueden hacer una vectorización automática para lograr esto.

+0

¿Puedes dar una referencia/prueba de que el valor para un vértice es 0 si y solo si es un dominador? No estoy seguro de entender por qué es cierto [o no entiendo la definición de 'valor' correctamente]. – amit

+1

Amit: los nodos que estoy buscando son nodos donde pasan todos los caminos. Entonces 0 bordes deberían ir paralelos a ese nodo. Bordes entrantes: los bordes salientes antes de que un nodo sea igual al número de bordes paralelos. – Jules

+0

¡Muchas gracias por esta respuesta! Le daré a otras personas un poco de tiempo para escribir respuestas y respuestas a favor, luego lo aceptaré :) ¡Gracias de nuevo! – Jules

Cuestiones relacionadas