Best algorithm for detecting cycles in a directed graph - Stack Overflow
Finally we will understand four different types of Graphs - Cyclic, Acyclic, Spare In directed graphs there exists a one way relationship between two nodes and . A control flow graph (CFG) in computer science is a representation, using graph notation, of all 1 Definition; 2 Example; 3 Reachability; 4 Domination relationship; 5 Special edges; 6 Loop management; 7 Reducibility; 8 Loop . Forward edges form a directed acyclic graph with all nodes reachable from the entry node. I think it is likely that it is therefore more efficient to detect cycles at the same time as The simplest way to do it is to do a depth first traversal (DFT) of the graph.
However, the smallest such set is NP-hard to find. Transitive closure and transitive reduction[ edit ] The transitive closure of a given DAG, with n vertices and m edges, may be constructed in time O mn by using either breadth-first search or depth-first search to test reachability from each vertex. The transitive reduction consists of the edges that form length-one paths that are the only paths connecting their endpoints.
Therefore, the transitive reduction can be constructed in the same asymptotic time bounds as the transitive closure. Closure problem The closure problem takes as input a directed acyclic graph with weights on its vertices and seeks the minimum or maximum weight of a closure, a set of vertices with no outgoing edges. The problem may be formulated for directed graphs without the assumption of acyclicity, but with no greater generality, because in this case it is equivalent to the same problem on the condensation of the graph.
It may be solved in polynomial time using a reduction to the maximum flow problem.
- Control flow graph
- Cycle detection
- Directed acyclic graph
For example, it is possible to find shortest paths and longest paths from a given starting vertex in DAGs in linear time by processing the vertices in a topological order, and calculating the path length for each vertex to be the minimum or maximum length obtained via any of its incoming edges.
In this context, a dependency graph is a graph that has a vertex for each object to be updated, and an edge connecting two objects whenever one of them needs to be updated earlier than the other. A cycle in this graph is called a circular dependencyand is generally not allowed, because there would be no way to consistently schedule the tasks involved in the cycle.
Dependency graphs without circular dependencies form DAGs. For this problem, the tasks to be scheduled are the recalculations of the values of individual cells of the spreadsheet. Dependencies arise when an expression in one cell uses a value from another cell. In such a case, the value that is used must be recalculated earlier than the expression that uses it. Topologically ordering the dependency graph, and using this topological order to schedule the cell updates, allows the whole spreadsheet to be updated with only a single evaluation per cell.
A somewhat different DAG-based formulation of scheduling constraints is used by the program evaluation and review technique PERTa method for management of large human projects that was one of the first applications of DAGs. In this method, the vertices of a DAG represent milestones of a project rather than specific tasks to be performed. Instead, a task or activity is represented by an edge of a DAG, connecting two milestones that mark the beginning and completion of the task.
Each such edge is labeled with an estimate for the amount of time that it will take a team of workers to perform the task. The longest path in this DAG represents the critical path of the project, the one that controls the total time for the project. Individual milestones can be scheduled according to the lengths of the longest paths ending at their vertices.
Directed acyclic graph - Wikipedia
In this representation, data enters a processing element through its incoming edges and leaves the element through its outgoing edges. For instance, in electronic circuit design, static combinational logic blocks can be represented as an acyclic system of logic gates that computes a function of an input, where the input and output of the function are represented as individual bits.
The following Python code shows how this idea may be implemented as an algorithm.
Main phase of algorithm: The hare moves twice as quickly as the tortoise and the distance between them increases by 1 at each step. So hare moving in circle one step at a time, and tortoise reset to x0 moving towards the circle, will intersect at the beginning of the circle.
Brent described an alternative cycle detection algorithm that, like the tortoise and hare algorithm, requires only two pointers into the sequence. It has two advantages compared to the tortoise and hare algorithm: Next, the hare and tortoise move at same speed until they agree while tortoise!
Control flow graph - Wikipedia
It is not difficult to show that the number of function evaluations can never be higher than for Floyd's algorithm. He also performs an average case analysis for a randomized version of the algorithm in which the sequence of indices traced by the slower of the two pointers is not the powers of two themselves, but rather a randomized multiple of the powers of two.
Although his main intended application was in integer factorization algorithms, Brent also discusses applications in testing pseudorandom number generators. Gosper's algorithm   finds the period but not the starting point of the first cycle. Its main feature is that it never backs up to reevaluate the generator function, and is economical in both space and time.
For example, if it is known a priori that the generator function has a period of then 33 words is sufficient.
Several algorithms based on depth first search compute strongly connected components in linear time. Kosaraju's algorithm uses two passes of depth first search.
Strongly Connected Components
The first, in the original graph, is used to choose the order in which the outer loop of the second depth first search tests vertices for having been visited already and recursively explores them if not. The second depth first search is on the transpose graph of the original graph, and each recursive exploration finds a single new strongly connected component. Rao Kosarajuwho described it but did not publish his results in ; Micha Sharir later published it in It maintains a stack of vertices that have been explored by the search but not yet assigned to a component, and calculates "low numbers" of each vertex an index number of the highest ancestor reachable in one step from a descendant of the vertex which it uses to determine when a set of vertices should be popped off the stack into a new component.
The path-based strong component algorithm uses a depth first search, like Tarjan's algorithm, but with two stacks.