¿Cómo podemos detectar si un gráfico dirigido es cíclico? Pensé en usar la primera búsqueda de amplitud, pero no estoy seguro. ¿Algunas ideas?¿Cómo detectar si un gráfico dirigido es cíclico?
Respuesta
Por lo general, se utiliza la búsqueda de profundidad en primer lugar. No sé si BFS se aplica fácilmente.
En DFS, se construye un árbol de expansión por orden de visita. Si se visita un ancestro de un nodo en el árbol (es decir, se crea un borde posterior), detectamos un ciclo.
Consulte http://www.cs.nyu.edu/courses/summer04/G22.1170-001/6a-Graphs-More.pdf para una explicación más detallada.
BFS o DFS tiene la misma complejidad (tiempo de ejecución) y aplicabilidad (mismo resultado) en este problema. La única diferencia está en el orden de visita de los nodos. – darlinton
La última declaración en la página indicada en el enlace es una declaración topológico basado en el número de aristas y vértices: "El número máximo de posibles aristas en el grafo G si no tiene ciclo es | V | - 1. " Esto es válido para los gráficos * no dirigidos *, pero no para los gráficos * dirigidos *, como se indicó en la pregunta original. Para los gráficos dirigidos, el diagrama "herencia de diamantes" proporciona un contraejemplo (4 nodos y 4 aristas forman un "bucle", pero no un "ciclo" que puede recorrerse siguiendo las flechas). – Peter
En caso de que el último comentario no fuera claro, estoy diciendo que la respuesta aceptada es suficiente para los gráficos no dirigidos, pero * incorrecta * para los gráficos dirigidos (como se especifica en la pregunta). – Peter
Otra solución simple sería un enfoque de marcaje y barrido. Básicamente, para cada nodo en el árbol lo marcas como "visitado" y luego pasas a sus hijos. Si alguna vez ves un nodo con la bandera "visted" establecida, sabes que hay un ciclo.
Si no es posible modificar el gráfico para incluir un bit "visitado", en su lugar se puede usar un conjunto de punteros de nodo. Para marcar un nodo como visitado, coloque un puntero en el conjunto. Si el puntero ya está en el conjunto, hay un ciclo.
esta solución es similar a la proporcionada por KennyTM, pero es mejor para el problema. El problema es identificar los ciclos, por lo que marcar y barrido es un buen enfoque. La construcción del árbol de expansión, como lo sugirió KennyTM, es una forma más compleja de resolver el problema, porque está utilizando el concepto de árbol de expansión. Al final, es casi todo lo mismo. – darlinton
@Rakis: ¿Identificará incorrectamente http://en.wikipedia.org/wiki/File:Diamond_inheritance.svg como un ciclo? – kennytm
@KennyTM: Sí, lo hará. Y no importa si usa DFS o BFS para explorar los nodos en el gráfico; obtendrá la misma respuesta incorrecta de cualquier manera. No es suficiente hacer un seguimiento de qué nodos se han visitado para identificar los ciclos. Así que deduzco un punto por la respuesta de Rakis (pero mi reputación es muy escasa para hacerlo). – Peter
Lo que realmente necesita, creo, es un algoritmo de clasificación topológica como el que se describe aquí:
http://en.wikipedia.org/wiki/Topological_sorting
Si el gráfico dirigido tiene un ciclo entonces el algoritmo se producirá un error.
Los comentarios/respuestas que he visto hasta ahora parecen estar perdiendo el hecho de que en un dirigido gráfico puede haber más de una manera de llegar del nodo X al nodo Y sin que haya (dirigido) ciclos en el gráfico.
aproximación: 1
cómo sobre un nivel no asignación para detectar un ciclo. Ej .: considere el siguiente gráfico. A -> (B, C) B-> D D -> (E, F) E, F -> (G) E-> D A medida que realiza un inicio DFS asignando un nivel no al nodo que visita (raíz A = 0). nivel no de nodo = padre + 1. Entonces A = 0, B = 1, D = 2, F = 3, G = 4 entonces, la recursión llega a D, entonces E = 3. No marque el nivel para G (G ya tiene un nivel no asignado que es más grande que E) Ahora E también tiene una ventaja a D. Así que la nivelación diría que D debería obtener un nivel no de 4. Pero D ya tiene asignado un "nivel inferior" a ella de 2. de este modo cualquier momento se intenta asignar un número de nivel a un nodo mientras se hace DFS que ya tiene un número menor nivel fijado a él, que conoce el gráfico dirigido tiene un ciclo ..
Approach2:
usa 3 colores blanco, gris, negro. coloree únicamente nodos blancos, nodos blancos a gris a medida que baja por el DFS, coloque los nodos grises en negro cuando se desarrolle la recursión (se procesan todos los elementos secundarios). si no todos los niños aún procesados y golpeas un nodo gris, eso es un ciclo. por ej .: todo blanco para comenzar en el gráfico directo de arriba. color A, B, D, F, G son de color blanco grisáceo. G es hoja, por lo que todos los niños procesados lo colorean de gris a negro. la recursividad se desarrolla en F (todos los niños procesados) lo colorean en negro. ahora llegas a D, D tiene niños no procesados, por lo que el color E es gris, G ya es de color negro, así que no vayas más abajo. E también tiene borde a D, por lo tanto, mientras procesa D (D sigue siendo gris), encuentra un borde hacia atrás a D (un nodo gris), se detecta un ciclo.
Las pruebas de clasificación topológica sobre el gráfico dado le llevarán a la solución. Si el algoritmo de topsort, es decir, los bordes siempre deben dirigirse de una manera, falla, significa que el gráfico contiene ciclos.
Uso DFS para buscar si cualquier camino es cíclico
class Node<T> { T value; List<Node<T>> adjacent; }
class Graph<T>{
List<Node<T>> nodes;
public boolean isCyclicRec()
{
for (Node<T> node : nodes)
{
Set<Node<T>> initPath = new HashSet<>();
if (isCyclicRec(node, initPath))
{
return true;
}
}
return false;
}
private boolean isCyclicRec(Node<T> currNode, Set<Node<T>> path)
{
if (path.contains(currNode))
{
return true;
}
else
{
path.add(currNode);
for (Node<T> node : currNode.adjacent)
{
if (isCyclicRec(node, path))
{
return true;
}
else
{
path.remove(node);
}
}
}
return false;
}
No ha definido la función isCyclic en absoluto. –
este código falla en esta entrada: 4 -> 1-> 2-> 3. falla si comienza a explorar desde el nodo 1. –
encontró cómo solucionarlo: Set
- 1. Recorrido de gráfico cíclico dirigido
- 2. ¿Cómo transformo un gráfico no dirigido y muy cíclico en un gráfico acíclico dirigido?
- 3. ¿Cómo puedo verificar si un gráfico dirigido es acíclico?
- 4. Todos los posibles caminos en un grafo no dirigido cíclico
- 5. Estructura de datos y algoritmos para un gráfico cíclico dirigido (F #)
- 6. Encontrar un ciclo en un gráfico no dirigido versus encontrar uno en un gráfico dirigido
- 7. Django gráfico no dirigido
- 8. El mejor algoritmo para determinar si un gráfico no dirigido es un árbol
- 9. Redis: implementar gráfico dirigido ponderado
- 10. Implementando un gráfico dirigido en python
- 11. ¿Modelar un gráfico no dirigido en Rails?
- 12. ¿Cómo se almacena un gráfico acíclico dirigido (DAG) como JSON?
- 13. Cómo comprobar si un gráfico no dirigido tiene un ciclo de longitud impar
- 14. Implementación simple para detectar ciclos en un gráfico dirigido en C#
- 15. Detectando ciclos de un gráfico (tal vez dirigido o no dirigido) en Haskell
- 16. ¿Cómo implementar un gráfico no dirigido en Ruby on Rails?
- 17. Visualizar gráfico no dirigido que es demasiado grande para GraphViz?
- 18. ¿Cómo detectar si al romper un borde se descompone un gráfico?
- 19. Flujo máximo - Ford-Fulkerson: gráfico no dirigido
- 20. Un árbol de expansión mínimo bidireccional de un gráfico dirigido
- 21. Encontrar todas las rutas en un gráfico dirigido con ciclos
- 22. Almacenar un gráfico dirigido en google appengine datastore
- 23. Algoritmo de propósito general para triangular un gráfico no dirigido?
- 24. Cómo convertir el gráfico acíclico dirigido (DAG) al árbol
- 25. algoritmo de gráfico para detectar ciclos pares
- 26. implementando un UITableView cíclico
- 27. ¿Encontrando las "mejores raíces" en un gráfico de árbol dirigido?
- 28. Ruta acíclica más larga en un gráfico no ponderado dirigido
- 29. ¿Cómo detectar si un número dado es un número entero?
- 30. cómo detectar si un tipo es un iterador o const_iterator
posible duplicado de [¿Cómo puedo comprobar si un grafo dirigido acíclico es?] (Http://stackoverflow.com/questions/583876/how- do-i-check-si-a-dirigida-gráfico-is-acíclico) –
me acaba de publicar una solución FP genérico para Scala en una relacionada hilo StackOverflow: http://stackoverflow.com/a/36144158/501113 – chaotic3quilibrium