Remove duplicate edge in directed graph - algorithm

Given a directed graph, remove the edge between two nodes if there is an alternate path between them. Ex: given a->b, b->c, a->c, remove a->c. Is there an efficient algorithm to count the number of those removed edges?

From wiki Strongly connected component:
A directed graph is acyclic if and only if it has no strongly connected subgraphs with more than one vertex, because a directed cycle is strongly connected and every nontrivial strongly connected component contains at least one directed cycle.
You can use Tarjan's strongly connected components algorithm to find SCC. And then delete one edge from every component.
Next you need iterate the whole process as every nontrivial strongly connected component contains at least one directed cycle.
In general counting number of cycles is NP-hard as if you can count all cycles in polynomial time then you can detect the existence of Hamiltonian cycle as well. But Hamiltonian path is NP-hard.

Related

Directed Graph walk - visit every node at least once

I’m familiar with the Hamilton path for a directed graph - visit every node exactly once.
I’m looking for an algorithm to walk the graph so that I visit every node at least once. I can’t find the standard name for this problem, if any.
This graph is walkable - root-a-d-b-c
This graph is not walkable - because in my walk, if I reach c, I have no directed edge to reach a & d and conversely, if I walk to a, d; there’s no directed edge that takes me to b & c
Hope that clarifies the question? Is there a standard name for this type of graph walk and an algorithm to solve it?
Hamiltonian path
Finding at most 2 leafs in the graph
I don't know if there's a name for a directed "walkable" graph, but it's not too hard to determine of a graph is walkable or not:
Find all the strongly connected components using Tarjan's algorithn, for example
Make a new directed graph of the connections between SCCs. This will be a DAG, and your original graph is walkable if and only if this DAG is walkable.
To determine whether or not a DAG is walkable, do a topological sort. Then check that each vertex has an edge to the next.
Each of these steps takes linear time, so you get O(|V|+|E|) complexity for the whole algorithm.
Theorem: a directed graph is walkable if and only if its strongly connected components are totally ordered by reachability.
Proof sketch: (walkable implies condition) The existence of a walk implies that, for each two strongly connected components, a vertex from one or the other appears first in the walk. That component can reach the other. (condition implies walkable) Since there is full connectivity inside a strongly connected component, each is walkable on its own. We just have to concatenate the walks according to the total order, adding the necessary transitions.
The proof is constructive, so we can extract an algorithm.
Algorithm
Compute the strongly connected components.
Concatenate the strongly connected components in topological order. Actually Tarjan's algorithm will list them in reverse topological order, so this doesn't need to be a separate step.
For each adjacent pair in the previous list, use breadth-first search to find a shortest path.
In general, this algorithm does not find the shortest walk (that's NP-hard by reduction from Hamiltonian path).

Finding strongly connected subgraph that contains no negative cycles

Is there an algorithm that solves the following decision problem:
Given a strongly connected weighted directed graph G, defined by its transition matrix, is there a strongly connected spanning subgraph of G that has no negative cycles?
A strongly connected spanning subgraph of G is a strongly connected subgraph of G that shares the same vertexes with G. You can look to this paper for the definition of strongly connected spanning subgraph. In this paper they present an approximation for the minimum strongly connected subgraph problem.
A naive approach to this problem is to find a negative cycle of the graph using the Ford-Bellman or Floyd-Warshall algorithm, deleting an edge from this cycle, and repeating while the graph is still strongly connected. But this naive approach has poor time complexity because we will potentially run the Ford-bellman algorithm and check for strong connectivity many times -- moreover I am unable to prove if this algorithm is correct in all instances.
I'm hoping to find experts here who can tell me if this decision problem can be solved in a polynomial time and what algorithm does so. Many thanks in advance.
Here is a naive solution that has a reasonable chance of finding a strongly connecting spanning subgraph with no negative cycles in polynomial time. But is emphatically not guaranteed to find one.
Turn all weights to their negatives. Now use Ford-Bellman or Floyd-Warshall to find a negative cycle. This is actually a positive cycle in the original graph.
Now we pick one vertex in the cycle, and contract the other vertices to it.
Edges that connect to/from removed vertices are replaced by ones representing traveling along that edge and around the cycle to the one we keep. If you wind up with multiple edges between two vertices, only keep the best one.
Repeat the exercise on the new, smaller, graph.
This algorithm runs in guaranteed polynomial time (each iteration runs in polynomial time and removes at least one vertex). If it manages to reduce your graph to a point, then you just walk the process backwards and find that you have in fact found a strongly connected spanning graph with no negative cycles.
However if it fails to do so, there is no guarantee that there isn't one. You just didn't find it.
(I suspect that a guaranteed algorithm will be NP-complete.)
This problem is NP hard in general, this can be proven by reducing Hamiltonian cycle into it.

Efficient algorithm that decides if an edge belongs to some cycle

I'm trying to struct an efficient algorithm gets undirected graph, and edge e(u,v), and decides if the edge belongs to some cycle in the graph ,but not all of the cycles!
My approach is to take out the edge (u,v) from the graph, and run BFS to see if v is still reachable from u. If yes then the original graph has a cycle containing e, otherwise there isn't.
But i'm not so sure how to tweak the algorithm that it will decide if the edge doesn't belong to all the cycles of the graph.
An undirected graph can contain an edge which belongs to all of its cycles graph only if this graph has a single cycle.
Let's look at an example. Edge (2,3) belongs to two cycles, but you always can find a third cycle to which such an edge doesn't belong.
After you have checked that the edge belongs to some cycle, you can check if this is the only cycle in the graph by removing this edge and checking if the reduced graph has any cycles at all. Thanks to #nomanpouigt for pointing that out.

Minimize set of edges in a directed graph keeping connected components

Here is the full question:
Assume we have a directed graph G = (V,E), we want to find a graph G' = (V,E') that has the following properties:
G' has same connected components as G
G' has same component graph as G
E' is minimized. That is, E' is as small as possible.
Here is what I got:
First, run the strongly connected components algorithm. Now we have the strongly connected components. Now go to each strong connected component and within that SCC make a simple cycle; that is, a cycle where the only nodes that are repeated are the start/finish nodes. This will minimize the edges within each SCC.
Now, we need to minimize the edges between the SCCs. Alas, I can't think of a way of doing this.
My 2 questions are: (1) Does the algorithm prior to the part about minimizing edges between SCCs sound right? (2) How does one go about minimizing the edges between SCCs.
For (2), I know that this is equivalent to minimizing the number of edges in a DAG. (Think of the SCCs as the vertices). But this doesn't seem to help me.
The algorithm seems right, as long as you allow for closed walks (i.e. repeating vertices.) Proper cycles might not exist (e.g. in an "8" shaped component) and finding them is NP-hard.
It seems that it is sufficient to group the inter-component edges by ordered pairs of components they connect and leave only one edge in each group.
Regarding the step 2,minimize the edges between the SCCs, you could randomly select a vertex, and run DFS, only keeping the longest path for each pair of (root, end), while removing other paths. Store all the vertices searched in a list L.
Choose another vertex, if it exists in L, skip to the next vertex; if not, repeat the procedure above.

Minimal addition to strongly connected graph

I have a set of nodes and set of directed edges between them. The edges have no weight.
How can I found minimal number of edges which has to be added to make the graph strongly connected (ie. there should be a path from every node to all others)? Does this problem have a name?
It's a really classical graph problem.
Run algorithm like Tarjan-SCC algorithm to find all SCCs. Consider
each SCC as a new vertice, link a edge between these new
vertices according to the origin graph, we can get a new graph.
Obviously, the new graph is a Directed Acyclic Graph(DAG).
In the DAG, find all vertices whose in-degree is 0, we define them
{X}; find all vertices whose out-degree is 0, we define
them {Y}.
If DAG has only one vertice, the answer is 0; otherwise, the answer
is max(|X|, |Y|).
Off the top of my head, it seems the simplest (fewest edges) way to make a directed graph strongly connected would be to just have a cycle involving all nodes; so the minimum number of edges would just be N where N is the number of nodes. If there are already edges, just do something like connect longest existing directed path to the next longest path that doesn't overlap with your current path, until you form a complete cycle (once your path contains all nodes, connect the ends to form the cycle.)
Not sure if there is a more formal definition of any of this, but is seems logical to me.
I would find all weakly connected components, and tie them up in a cycle.
EDIT:
To be more explicit, the idea is if you have WCCs W(1),...,W(n),
make all of W(i%n + 1) reachable from any node in W(i), for i=1 to n.

Resources