Is toposort of reverse edges same as reversing toposort result? - topological-sort

Does reversing the result of a topological sort on a graph where all edges are in the wrong direction result in a valid topological order, as if the edges were reversed before the sort?
a -> b
a -> c
b -> d
c -> d
could give a toposort of a b c d. Reversing this list gives d c b a. Reversing all edges in the graph before toposorting could also give d c b a. Is this true in the general case? I'm guessing no, but I can't find an example that fails.

It obviously is, if you look at it from the right angle.
After a topo-sort, if we store all nodes in a list, all arrows out from any edge point in the same direction. If we reverse the list, all arrows now point in the opposite direction. Since all arrows point the same way, it's a valid topological sort.
And the other approach, first flipping all edges and then performing a toposort obviously yields a valid toposort, or the toposort algorithm is broken.
The exact total order produced by the two approaches might differ, but they're both valid.

Related

Find group of friends with no mutual spies and maximum value by dynamic programming

In a group of friends, each except one friend spies exactly one other friend. Every friend has some valuables, which is a positive integer. Find a group of friends with the biggest sum of valuables such that no friend spies any other friend within this group.
Example: We have the following graph for one of the possible test cases. The value above each vertex is the positive number of valuables owned by them.
The best possible group is [A,F,D,J,H] = 92 value
Looks like we can achieve the solution by ignoring the traversal through the graph and calculating the combinations of all possible groups.
Unfortunately not able to think of a dynamic programming approach or how to get started.
Give the constraints on your graph, you will always have:
one disjoint connected sub-graph that is a tree consisting of zero-or-more simple paths all branching off the friend who is not spying on anyone; and
zero-or-more disjoint connected sub-graphs where each sub-graph contains exactly one cycle and zero-or-more simple paths branching off the cycle.
To get the best sum of valuables:
Within each branching path, there can be at most two non-selected vertices between each selected vertex. (If there were three non-selected vertices then you would get a better result if the middle vertex of those three were selected; i.e. (A)->B->C->D->(E) where () is a selected vertex will always give a better result as (A)->B->(C)->D->(E)).
Within each cycle, unless blocked by a selected adjacent vertex in a branching path, there can be at most two non-selected vertices between each selected vertex. (for similar reasons to branching paths).
If you have the connected sub-graph (similar to the bottom of your example but E spies I, rather than spying nothing):
-----------
V |
C -> D -> E -> I -> J <- H
Then you can either start with the cycle and work outwards to the branching paths or from the branching paths inwards. If you consider the cycle-outwards then:
if E is selected then D, I and J cannot be and given that the minimum separation of 1 is achieved, then C and H must be selected.
if I is selected then E and J cannot be selected and H and either C or D can be selected.
if J is selected then E, I and H cannot be selected and either C or D can be selected.
if none of the vertices on the cycle are selected then H and either C or D can be selected (which, in this case, is always a strictly worse option that selecting J as well, since it does not block selection from the branching paths).
This gives possible solutions for that connected sub-graph of:
C, E, H
C, I, H
D, I, H
C, J
D, J
You can perform a similar operation for each disjoint subgraph and, for the one disjoint sub-graph containing the friend who is not spying on anyone then that friend can either be selected or not selected and each branching simple path can be evaluated independently choosing to either skip one-or-two vertices between selected vertices and finding the optimum total.
Find the solution with the highest value for the sub-graph and move on to the next sub-graph.

Converting a DAG to Binary Tree

I am trying to convert a DAG to a binary tree. Consider the following graph
I want to have the following output for above tree.
Since A,B,C,E forms a diamond, to convert it into a tree, I need to move B and C into a line.
I have tried following:
Topological Sort : Output is A -> D -> B -> C -> E -> F .
Topological Sort with order : A -> [B,C,D] -> E -> F
Topological Path gives us a straight path. But, I want to preserve the sequence if possible i.e. A -> D. However, if there is a diamond, I want a node to only have one parent and sequence these parents as well.
Is there a way to generate a tree from a DAG for above cases?
Algorithm in pseudo-code
Run a topological sort on the graph
For every node B, in reverse order of the topological sort:
If B has more than one parent:
Order its parents A1, A2, ..., An in the order of the topological sort
For every i in 1..n-1:
Add an arc from Ai to A(i+1)
Remove the arc from Ai to B
Proof of correctness
The algorithm always terminates, since it is a loop of fixed length; its time complexity is O(N^2) where N is the number of nodes
Immediately after the step on a given node B, B has no more than one parent
If the step on a given node C has already been executed, then executing the step on a node B that comes before C in the topological order only adds arcs to nodes that come before C in the topological order; hence once a node's step has been executed, they never gain new parents.
This proves that the algorithm terminates and that every node has at most one parent after executing the algorithm. Since we only remove parents from nodes which had more than one parent, I think it also satisfies your question.

Need assistance in resolving this variation of shortest path algorithm

The below picture is the representation from the question which was asked to me during samsung interview. I had to write the program to find the minimum distance between I and M. There was an additional constraint that we can change one of the edges. For example, The edge FM can be moved to join edge L and M and the edge value will still be 4.
If you notice, the distance between I and M via I-> E -> F -> G -> M is 20. However, if we change one of the edges such that L to M edge value is 4 now. We have to move edge FM to join L and M now. By this method, the distance between I and M is 20.
An arbitrary edge u, v can be changed to u, t or t,v. It can not be changed to x,y. So one of the vertices in the edge has to be same.
Please find the picture below to illustrate the scenario -
So my problem is that I had to write the program for this. To find the minimum distance between two vertices, I thought of using Djikstra's algorithm. However , I as not sure how to take care of the additional constraint where I had the option of changing one of the vertices. If I could get some help to solve this, I would really appreciate it.
If we move an edge (A, B), the new end should be either the start S or the target T vertex (otherwise, the answer is not optimal).
Let's assume that we move the edge (A, B) and the new end is T (the case when it's S is handled similarly). We need to know the shortest path from S to A that doesn't use this edge (once we know it, we can update the answer with the S->A->T path).
Let's compute the shortest path from S to all other vertices using Dijkstra's algorithm.
Let's fix a vertex A and compute the two minimums of dist[B] + weight(A, B) for all B adjacent to A. Let's iterate over all edges adjacent to A. Let the current edge be (A, B). If dist[B] + weight(A, B) is equal to the first minimum, let d be the second minimum. Otherwise, let d be the first minimum. We need to update the answer with d + weight(A, B) (it means that (A, B) becomes (A, T) now).
This solution is linear in the size of the graph (not counting the Dijkstra's algorithm run time).
To avoid code duplication, we can handle the case when the edge is redirected to S by swapping S and T and running the same algorithm (the final answer is the minimum of the results of these two runs).
In the graph you've shown, the shortest path I see is I -> E -> F -> M with a length of 13.
Moving the edge F -> M so that it connects L -> M just makes things worse. The new shortest path is I -> E-> F -> L -> M with a length of 18.
The obvious answer is to move edge F -> M so that it connects I directly to M, giving a length of 4.
In other words, find the shortest edge that's connected to I or M and use it to connect I directly to M.
For future reference, it's highly unlikely that you'll be asked to implement Djikstra's algorithm from memory in an interview. So you need to look for something simpler.

Algorithm to convert directed acyclic graphs to sequences

If D depends on B and C which each depend on A, I want ABCD (or ACBD) as the result; that is generate a flat sequence from the graph such that all nodes appear before any of their descendants. For example, we may need to install dependencies for X before installing X.
What is a good algorithm for this?
In questions like this, terminology is crucial in order to find the correct links.
The dependencies you describe form a partially ordered set (poset). Simply put, that is a set with an order operator, for which the comparison of some pairs might be undefined. In your example B and C are incomparible (neither B depends on C, nor C depends on B).
An extension of the order operator is one that respects the original partial order and adds some extra comparisons to previously incomparable elements. In the extreme: a linear extension leads to a total ordering. For every partial ordering such an extension exists.
Algorithms to obtain a linear extension from a poset are called topological sorting. Wikipedia provides the following very simple algorithm:
L ← Empty list that will contain the sorted elements
S ← Set of all nodes with no incoming edges
while S is non-empty do
remove a node n from S
add n to tail of L
for each node m with an edge e from n to m do
remove edge e from the graph
if m has no other incoming edges then
insert m into S
if graph has edges then
return error (graph has at least one cycle)
else
return L (a topologically sorted order)

Is Topological Sorting trying to sort vertices or edges?

Happy easters, everyone.
I am currently learning topological sort and having a question about what topological sort tries to really sort.
The Algorithm Design Manual describes topological sort in this way:
Topological sorting is the most important operation on directed acyclic graphs (DAGs). It orders the vertices on a line such that all directed edges go from left to right.
This bold part confuses me. So does the topological sorting sort vertices or all directed edges?
Let's take an example which is also in the book.
So for the above DAG, we can get a topological sort (G, A, B, C, F, E, D).
I can understand this sort. Not only the vertices are sorted, but the edges are also sorted, i.e., G->A->B->C->F->E->D, this matches the above ADM book description: all directed edges go from left to right
But what if I remove the edge of B->C? The resulting graph is still a DAG, but will the topological sort is still (G, A, B, C, F, E, D)?
If it is Yes, then I think the edges are not sorted, as A->B->C does not exist any more, instead, it is A->B and A->C. So, it this case still a valid topological sort? Can we still
think (G, A, B, C, F, E, D) is a valid sort even if A is the parent of B and C?
Thanks
You can think of it as orderring of elements.
let v1,v2,...,vn be elements. and let an edge (vi,vj) denote that vi<vj. topological sort guarantees that after the sorting: for every vi, and for every vj such that i < j, vj is not greater then vi
Or in other notations: assume (vi,vj) indicate that vj is dependent on vi, topological sorts guarantees that each element "does not depend" on any elements that appears after it in the sort.
So does the topological sorting sort vertices or all directed edges?
topological sort sorts vertices, not edges. It uses edges as constraints for sorting the vertices.
But what if I remove the edge of B->C?
yes, every edge you add, just add a constraint. Note that there could be more then one feasible solution for topological sort [for example, for a graph without edges, any permutation is a feasible solution]. removing a constraint, makes any previous solution, which "solves a harder problem" still feasible.
Can we still think (G, A, B, C, F, E, D) is a valid sort even if A is
the parent of B and C?
There is no problem with that! A appears before B,C in the topological sort, so there is no problem it is their father.
Hope that makes it a bit more clear.

Resources