Let's assume that a graph in question is a DAG (directed acyclic graph).
Question: can I conclude that such graph will have a unique topological sort if, and only if, only one of its vertices has no incoming edges?
In other words, is having only one vertex with no incoming edges necessary (but not sufficient) to generate a unique topological sort?
A topological sort will be unique if and only if there is a directed edge between each pair of consecutive vertices in the topological order (i.e., the digraph has a Hamiltonian path). Source
A Hamiltonian path just means that a path between two vertices will only visit each vertex once, it does not mean though that one vertex must have no incoming edges. You can have a Hamiltonian path that is in fact a cycle. This would still generate a unique topological sort (of course it would be a cycle as well if that is important to you).
Hope this helps
Haaaaa, ok. sorry for the misunderstanding.
In this case I assume that you are right, here is a sketch of proof:
We have a unique topological sort => We have only one vertex that it is legal to put in the first place => For every vertex, except one, it is not legal to put in the first place => For every vertex, except one, we have incoming edges.
Hope that now I answered your question....
No! The graph below has only one vertex with no incoming edges, and have 2 possible solutions.
1 -> 2
3 -> 4
3 -> 1
4 -> 2
Two solutions are:
2 0 3 1
2 3 0 1
Yes you can say that as a necessary condition as if there are multiple nodes with in-degree =0 then there will not be a Hamiltonian Path hence no unique topological order. Only for the starting node of graphs (in-degree=0) will have no incoming edge, rest all vertices MUST have an incoming edge from their topological ancestor, that means node just before the current node in topological ordering. If every consecutive node in topological ordering does not have an edge the DAG will NOT Have unique order.
Someone has given the answer. Here I just want to give you a counter example: G = {(1,2), (1,3)}. In this case there are 2 valid topological sort: 1,2,3 and 1,3,2
Related
I have weighted undirected graph. I need to find spanning tree with minimal possible cost, so that distance between point A and B will be as low as possible.
For example, I have this graph: graph.
Minimal distance between A and B is 2.
Minimal spanning tree would look like this. But that would make distance between A and B = 3.
Right now I am doing this:
Find distance between AB in graph, using BFS.
Find all paths between AB with length from step 1 using DFS.
Generate spanning tree from every path from step 2.
Compare them and get minimal one.
Everything is OK until I got graph with A-B distance = 12.
Second step then take too much time. Is there any faster way of doing this? Thanks.
The fastest/most efficient way to solve this problem is to use Dijkstra's Shortest Path algorithm. This is a greedy algorithm that has the following basic structure:
1-all nodes on the graph start "infinity" distance apart
2-start with your first node (node A in your example) and keep track of each edge weight to get from this node A to each of its neighbors.
3-Choose the shortest current edge and follow it to your next node, let's call it node C for now
4-Now, for each of C's neighbors, compare the current distance (including infinity if applicable) with the sum of A's edge to C and C's shortest edge to the current neighbor. If it is shorter than the current distance, update it to the new distance.
5-Continue this process until all nodes have been visited and you reach the node you were looking for the shortest path to (i.e. B in your example)
This is a pretty efficient way of finding the shortest path between two nodes, with a running time of O(V^2), not O(nlogn) as mentioned above. As you can see, by making this a greedy algorithm, we are constantly choosing the optimal solution based on the available local information, and therefore we will never have to go back and change our decisions.
This also eliminates the need for a BFS and a DFS like in your example. Hope this helps!
While your step two is correct, I think that the problem is that you are doing too many operations.
You are doing both a BFS and a DFS which is going to be very costly. Instead, what I would recommend doing is using one of several different traversal techniques that will minimize in the computational costs.
This is a common problem to find the shortest path, and one of the popular solutions is Dijkstra's algorithm. Here is an article that expounds on this topic. https://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-greedy-algo-7/
In short, what this algorithm does, is it takes the starting point A, and then it generates the minimal spanning tree until point B is hit, then there is a single path in which A can get to B, and that is the shortest path.
Both this and your algorithm both run in O(nlogn), but in practice this solution can be thought of as running a single BFS instead of both a BFS and a DFS.
Hi I am trying to match a subgraph that may have a path of Extends edges.
The known parts are the Vertices with ids 1,2,3 and 6 and their edges.. What is not known is the number of vertices and their ids between 1 and 6. Match starts from vertex with id=1. The match traversal needs to match the whole subgraph with a limit of let's say 10 steps between 4 and 6. In the trivial case vertex with id 6 is directly connected with vertex having id = 1 through edge ContainsB.
Any help is appreciated!
I think this seems to work the way I wanted:
g.V().match(
__.as("s").hasId("1").outE("ContainsB").inV().until(hasId("6")).repeat(out("Extends")).limit(10),
__.as("s").hasId("1").outE("ContainsA").inV().hasId("2"),
__.as("s").hasId("1").outE("ContainsC").inV().hasId("3")
)
I got an undirected graph with such that all the edges with same weight and all the vertices are connected. I want to find path between any given pair of vertices.
A less efficient solution is:
To perform BFS starting with one of the vertices, keep track of the visited vertices till the destination vertex is reached. This would perform in O(V + E). But this will have to be done for every pair of vertices given. Hence if there are M number of queries to find path, complexity would be O(M *(E+V)).
Can we do it better? Is it possible to leverage the output a BFS and solve the rest?
As you state that the graph is connected, it is not necessary to call a searching algorithm for the graph more than once. It is sufficient to use a single call to BFS (or DFS, this should make no major difference) to generate a spanning tree for the input. As from your problem statement it is apparently not necessary to find a shortest path between the vertices, any pair (a,b) of vertices is connected via the path from a to the root r of the spanning tree and the path from r to b.
The runtime would be O(V+E), namely the runtime of te searching algorithm; an additional computational cost might be necessary for the generation of the actual paths themselves.
I was wondering, that if there is a weighted graph G(V,E), and I need to find a single shortest path between any two vertices S and T in it then I could have used the Dijkstras algorithm. but I am not sure how this can be done when we need to find all the distinct shortest paths from S to T. Is it solvable on O(n) time? I had one more question like if we assume that the weights of the edges in the graph can assume values only in certain range lets say 1 <=w(e)<=2 will this effect the time complexity?
You can do it using Dijkstra. In Dijkstra's algorithm, you assign labels to each node based on the distance it has from your source and settle nodes according to this distance (smallest first). Once the target node is settled, you have the length of the shortest path. To retrieve the path (=the sequence of edges), you can keep track of the parent of each node you settle. To retrieve all possible paths, you have to account for multiple parents of each node.
A small example:
Suppose you have a graph which looks like this (all edges weight 1 for simplicity):
B
/ \
A C - D
\ /
E
When you do dijkstra to find the distance A->D, you would get 3. You would first settle node A with distance 0, then nodes B and E with distance 1, node C with distance 2 and finally node D with distance 3. To get the paths, you would remember the parents of the nodes when you settle them. In this case you would first set the parents of B and C =node A. You then need to set the parents of node C to B and E as they both supply the same length. Node D would get node C as a parent.
When you need the paths, you could just follow the parent pointers, starting at D and branching each time a node has multiple parents. This would give you a branch at node C.
The post mentioned in the comment above uses the same principles, although it does not allow you to actually extract the paths, it only gives you the count.
One final remark: Dijkstra is not a linear time algorithm as you need to do a lot of operations to maintain you queue and node sets.
(a) Using BFS from s to mark nodes visited as usual, in the meantime, changing following things:
(b) for each node v, it has a record L(v) representing the layer that v is on and a record f(v)
representing the number of incoming paths:
(c) everytime a node v1 is found in another node's v2 neighbors:
(d) if v1 is not in the queue, add it into queue, L(v1) = L(v2) + 1,f(v1)+ = f(v2)
(d) if v1 is already in the queue and L(v1) equals L(v2), do nothing.
(e) if v1 is already in the queue but L(v1) doe not equal to L(v2), f(v1)+ = f(v2)
(f) until in this modied BFS, t pop from the queue for the rst time, we have f(t)
(g) and this f(t) represents the number of dierent shortest paths from s to t
This might solve your problem.
I am looking for a Dijkstra's algorithm implementation, that also takes into consideration the number of nodes traversed.
What I mean is, a typical Dijkstra's algorithm, takes into consideration the weight of the edges connecting the nodes, while calculating the shortest route from node A to node B. I want to insert another parameter into this. I want the algorithm to give some weightage to the number of nodes traversed, as well.
So that the shortest route computed from A to B, under certain values, may not necessarily be the Shortest Route, but the route with the least number of nodes traversed.
Any thoughts on this?
Cheers,
RD
Edit :
My apologies. I should have explained better. So, lets say, the shortest route from
(A, B) is A -> C -> D -> E -> F -> B covering a total of 10 units
But I want the algorithm to come up with the route A -> M -> N -> B covering a total of 12 units.
So, what I want, is to be able to give some weightage to the number of nodes as well, not just the distance of the connected nodes.
Let me demonstrate that adding a constant value to all edges can change which route is "shortest" (least total weight of edges).
Here's the original graph (a triangle):
A-------B
\ 5 /
2 \ / 2
\ /
C
Shortest path from A to B is via C. Now add constant 2 to all edges. The shortest path becomes instead the single step from A directly to B (owing to "penalty" we've introduced for using additional edges).
Note that the number of edges used is (excluding the node you start from) the same as the number of nodes visited.
The way you can do that is adapt the weights of the edges to always be 1, so that you traverse 5 nodes, and you've gone a distance of "5". The algorithm would be the same at that point, optimizing for number of nodes traversed rather than distance traveled.
If you want some sort of hybrid, you need to determine how much importance to give to traversing a node and the distance. The weight used in calculations should look something like:
weight = node_importance * 1 + (1 - node_importance) * distance
Where node_importance would be a percentage which gauges how much distance is a factor and how much minimum node traversal is important. Though you may have to normalize the distances to be an average of 1.
I'm going to go out on a limb here, but have you tried the A* algorithm? I may have understood your question wrong, but it seems like A* would be a good starting point for what you want to do.
Check out: http://en.wikipedia.org/wiki/A*_search_algorithm
Some pseudo code there to help you out too :)
If i understood the question correctly then its best analogy would be that used to find the best network path.
In network communication a path may not only be selected because it is shortest but has many hop counts(node), thus may lead to distortion, interference and noise due to node connection.
So the best path calculation contains the minimizing the function of variables as in your case Distance and Hop Count(nodes).
You have to derive a functional equation that could relate the distance and node counts with quality.
so something as suppose
1 hop count change = 5 unit distance (which means the impact is same for 5unit distace or 1 node change)
so to minimize the loss you can use it in the linear equation.
minimize(distance + hopcount);
where hopcount can be expressed as distance.