I'm doing a breadth-first search on a digraph. I'm lost at nodes c and f, and I'm not sure if and how they should be in the BF-tree or if you only go as far as reachable from the source node and don't start at another node in order to get all the vertices.
Here's what I'm getting so far. As you can see, letters mark the nodes. Distance and predecessor are marked by d and pi:
This was helpful BFS traversal of directed graph from a given node but I'm not familiar with graphs enough to understand how that applies to this situation. From what I'm getting from that question, it seems like in this case I would not include c and f at all.
In fact, it seems like I have the maximal number of nodes included already, just because I started at i. I think that the d=4 at the g node (also at k but that doesn't even connect to any other nodes), this is the greatest distance and max-depth possible in BFS in this graph.
Related
Heyo!
So I've got this directed and/or undirected graph with a bunch of vertices and edges. In this graph there is a start vertex and an end vertex. There's also a subset of vertices which are coloured red (this subset can include the start and end vertices). Also, no pair of vertices can have more than one edge between them.
What I have to do is to find:
A) The shortest path that passes no red vertices
B) If there is a path that passes at least one red vertex
C) The path with the greatest amount of red vertices
D) The path with the fewest amount of red vertices
For A I use a breadth first search ignoring red branches. For B I simply brute force it with a depth first search of the graph. And for C and D I use dynamic programming, memoizing the number of red vertices I find in all paths, using the same DFS as in B.
I am moderately happy with all the solutions and I would very much appreciate any suggestions! Thanks!!
For A I use a breadth first search ignoring red branches
A) is a Typical pathfinding problem happening in the sub-graph that contains no red edges. So your solution is good (could be improved with heuristics if you can come up with one, then use A*)
For B I simply brute force it with a depth first search of the graph
Well here's the thing. Every optimal path A->C can be split at an arbitrary intermediate point B. A Nice property of optimal paths, is that every sub-path is optimal. So A->B and B->C are optimal.
This means if you know you must travel from some start to some end through an intermediary red vertex, you can do the following:
Perform a BFS from the start vertex
Perform a BFS from the endvertex backwards (If your edges are directed - as I think - you'll have to take them in reverse, here)
Alternate expanding both BFS so that both their 'edge' (or open lists, as they are called) have the same distance to their respective start.
Stop when:
One BFS hits a red vertex encountered by (or in the 'closed' list of) the other one. In this case, Each BFS can construct the optimal path to that commen vertex. Stitch both semi-paths, and you have your optimal path with at least a red vertex.
One BFS is stuck ('open' list is empty). In this case, there is no solution.
C) The path with the greatest amount of red vertices
This is a combinatorial problem. the first thing I would do is make a matrix of reachability of [start node + red nodes + end nodes] where:
reachability[i, j] = 1 iff there is a path from node i to node j
To compute this matrix, simply perform one BFS search starting at the start node and at every red node. If the BFS reaches a red node, put a 1 in the corresponding line/column.
This will abstract away the underlying complexity of the graph, and make an order of magnitude speedup on the combinatorial search.
The problem is now a longest path problem through that connectivity matrix. dynamic programming would be the way to go indeed.
D) The path with the fewest amount of red vertices
Simply perform a Dijkstra search, but use the following metric when sorting the nodes in the 'open' list:
dist(start, a) < dist(start, b) if:
numRedNodesInPath(start -> a) < numRedNodesInPath(start -> b)
OR (
numRedNodesInPath(start -> a) == numRedNodesInPath(start -> b)
AND
numNodesInPath(start -> a) < numNodesInPath(start -> a)
)
For this, when discovering new vertices, you'll have to store the path leading up to them (well, just the nb of nodes in the path, as well as the nb of red nodes, separately) in a dedicated map to be fetched. I mention this because usually, the length of the path is stored implicitly as the position of the verrtex in the array. You'll have to enforce it explicitely in your case.
Note on length optimality:
Even though you stated you did not care about length optimality outside of problem A), the algorithm I provided will produce shortest-length solutions. In many cases (like in D) it helps Dijkstra converge better I believe.
I am not asking an algorithm, I am asking definitions.
There is this question: given a graph to detect if it is a tree or not in directed and undirected graphs? According to the selected answer, I came up with the following:
For a directed graph to be a valid tree, it must satisfy all the facts:
The graph must have only 1 vertex that has purely outgoing edges.
The graph is connected.
The undirected version of this graph has no cycles.
I searched online for this and seems like most people agree with these points.
However I am still confused. For example, are the following graphs valid trees?:
G1:
G2:
If yes, why? If no, why?
Any help is appreciated! Thanks!
In case Directed graph, we start from vertex which has outgoing edge. When we have done traversal and is there any unvisited vertex then it is not tree.
For graph G1,
We can start from A, B or C.
If we start from A, then there is no chance to visit B. A->C, C->D or C->E.
If we start from B, then there is no chance to visit A. B->C, C->D or C->E.
And same for C, no chance to visit A and B.
It means there is no way to visit each vertex, so it's not a tree - graph is not connected.
For graph G2,
We can start from A or B.
If we start from A, then there is no chance to visit B and D.
Same case for B.
Therefore, this graph is also not connected.
I'm trying to solve the following problem:
I have an directed graph G = (E,V) which has a low number of edges. Now I try to find all subgraphs in it which are transitive closured and maximal which means there should be no subgraph which ist part of another subgraph.
The first idea I had was to start at every Node doing a DFS and on every step look if all edges for the closure exists but the performance is horrible. So I wonder if there is any faster algorithm
I came across this posting from a while back:
Best algorithm to determine if an undirected graph is a tree
It says that to determine if an undirected graph is a tree, you just have to check if it has a cycle. However, don't you have to make sure the graph is connected? I was taught that a tree is connected and acyclic. How is checking only for acyclicity sufficient?
Thanks.
You're right. If the graph is acyclic, then it's a forest. In addition, if it only has one component, then it's a tree.
What the algorithm mentioned does is look for back edges. If it finds one, then the graph is not a tree. If it doesn't find one and the algorithm visited n-1 edges before running out of edges, then it IS a tree, because having visited n-1 edges means that the graph is indeed connected (a tree with n vertices has n-1 edges). If the algorithm ran out of edges but didn't reach n-1 visited edges, then it means the graph is not connected, hence it is not a tree.
I have a directed graph, and a set U of nodes of that graph.
I want to find out if there is a path(not necessarily a simple path) that includes all nodes in the set U. What is the most efficient way of doing this?
Hint: Create a graph G'=(U,E') with e \in E' iff e's target can be reached from e's source in the original graph G. (The exact computation of reachability depends on if you allow nodes to be visited twice.)
Now, what do you have to check for G' in order to solve your problem?