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.
Related
Note: no need for formal proof or anything, just the general idea of the algorithm and I will go deeper myself.
Given a directed graph: G(V,E), I want to find the smallest set of vertices T, such that for each vertex t in T the following edges don't exist: {(t,v) | for every v outside t} in O(V+E)
In other words, it's allowed for t to get edges from vertices outside T, but not to send.
(You can demonstrate it as phone call, where I am allowed to be called from outside and it's free but it's not allowed to call them from my side)
I saw this problem to be so close or similar to finding all strongly connected components (scc) in a directed graph which its time complexity is O(V+E) and I'm thinking of building a new graph and running this algorithm but not totally sure about that.
The main idea is to contract each strongly connected component (SCC) of G into a single vertex while keeping a score on how many vertices were contracted to create each vertex in the contracted graph (condensation of G). The resulting graph is a directed acyclic graph. The answer is the vertex with lower score among the ones with out-degree equal 0.
The answer structure is an union of strongly connected components because of the restriction over edges and you can prove that there is only a SCC involved in the answer because of the min restriction.
First of all, I have to admit I'm not good at graph theory.
I have a weakly connected directed graph G=(V,E) where V is about 16 millions and E is about 180 millions.
For a given set S, which is a subset of V (size of S will be around 30), is it possible to find a weakly connected sub-graph G'=(V',E') where S is a subset of V' but try to keep the number of V' and E' as small as possible?
The graph G may change and I hope there's a way to find the sub-graph in real time. (When a process is writing into G, G will be locked, so don't worry about G get changed when your sub-graph calculation is still running.)
My current solution is find the shortest path for each pair of vertex in S and merge those paths to get the sub-graph. The result is OK but the running time is pretty expensive.
Is there a better way to solve this problem?
If you're happy with the results from your current approach, then it's certainly possible to do at least as well a lot faster:
Assign each vertex in S to a set in a disjoint set data structure: https://en.wikipedia.org/wiki/Disjoint-set_data_structure. Then:
Do a breadth-first-search of the graph, starting with S as the root set.
When you the search discovers a new vertex, remember its predecessor and assign it to the same set as its predecessor.
When you discover an edge that connects two sets, merge the sets and follow the predecessor links to add the connecting path to G'
Another way to think about doing exactly the same thing:
Sort all the edges in E according to their distance from S. You can use BFS discovery order for this
Use Kruskal's algorithm to generate a spanning tree for G, processing the edges in that order (https://en.wikipedia.org/wiki/Kruskal%27s_algorithm)
Pick a root in S, and remove any subtrees that don't contain a member of S. When you're done, every leaf will be in S.
This will not necessarily find the smallest possible subgraph, but it will minimize its maximum distance from S.
Although we can check a if a graph is bipartite using BFS and DFS (2 coloring ) on any given undirected graph, Same implementation may not work for the directed graph.
So for testing same on directed graph , Am building a new undirected graph G2 using my source graph G1, such that for every edge E[u -> v] am adding an edge [u,v] in G2.
So by applying a 2 coloring BFS I can now find if G2 is bipartite or not.
and same applies for the G1 since these two are structurally same. But this method is costly as am using extra space for graph. Though this will suffice my purpose as of now, I'd like know if there any better implementations for the same.
Thanks In advance.
You can execute the algorithm to find the 2-partition of an undirected graph on a directed graph as well, you just need a little twist. (BTW, in the algorithm below I assume that you will eventually find a 2-coloring. If not, then you will run into a node that is already colored and you find you need to color it to the other color. Then you just exit saying it's not bipartite.)
Start from any node and do the 2-coloring by traversing the edges. If you have traversed every edge and every node in the graph then you have your partition. If not, then you have a component that is 2-colored and there are no edges leaving the component. Pick any node not in the component and repeat. If you get into a situation when you have a few components that are all 2-colored, and there are no edges leaving any of them, and you encounter an edge that originates in a node in the component you are currently building and goes into a node in one of the previous components then you just merge the current component with the older one (and possibly need to flip the color of every node in one of the components -- flip it in the smaller component). After merging just continue. You can do the merge, because at the time of the merge you have scanned only one edge between the two components, so flipping the coloring of one of the components leaves you in a valid state.
The time complexity is still O(max(|N|,|E|)), and all you need is an extra field for every node indicating which component that node is in.
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.
I have a disconnected bipartite undirected graph. I want to completely disconnect the graph. Only operation that I can perform is to remove a node. Removing a node will automatically delete its edges. Task is to minimize the number of nodes to be removed. Each node in the graph has atmost 4 edges.
By completely disconnecting a graph, I mean that no two nodes should be connected through a link. Basically an empty edge set.
I think, you cannot prove your algorithm is optimal because, in fact, it is not optimal.
To completely disconnect your graph minimizing the number of nodes to be removed, you have to remove all the nodes belonging to the minimal vertex cover of your graph. Searching the minimal vertex cover is usually NP-complete, but for bipartite graphs there is a polynomial-time solution.
Find maximum matching in the graph (probably with Hopcroft–Karp algorithm). Then use König's theorem to get the minimal vertex cover:
Consider a bipartite graph where the vertices are partitioned into left (L) and right (R) sets. Suppose there is a maximum matching which partitions the edges into those used in the matching (E_m) and those not (E_0). Let T consist of all unmatched vertices from L, as well as all vertices reachable from those by going left-to-right along edges from E_0 and right-to-left along edges from E_m. This essentially means that for each unmatched vertex in L, we add into T all vertices that occur in a path alternating between edges from E_0 and E_m.
Then (L \ T) OR (R AND T) is a minimum vertex cover.
Here's a counter-example to your suggested algorithm.
The best solution is to remove both nodes A and B, even though they are different colors.
Since all the edges are from one set to another, find these two sets using say BFS and coloring using 2 colours. Then remove the nodes in smaller set.
Since there are no edges among themselves the rest of the nodes are disconnected as well.
[As a pre-processing step you can leave out nodes with 0 edges first.]
I have thought of an algorithm for it but am not able to prove if its optimal.
My algorithm: On each disconnected subgraph, I run a BFS and color it accordingly. Then I identify the number of nodes colored with each color and take the minimum of the two and store. I repeat the procedure for each subgraph and add up to get the required minimum. Help me prove the algorithm if it's correct.
EDIT: The above algorithm is not optimal. The accepted answer has been verified to be correct.