Graph Theory: function for a DAG? - directed-acyclic-graphs

For a directed acyclic graph where vertices have numerical labels what is the best way to return the maximum label on a vertex reachable from vertex u (including u itself)? Ideally it should run in time linear in the size of the graph.

Related

When adding a vertex to a weighted undirected graph, which weight stays?

I'm doing an adjacency list implementation of a graph class in C++ (but that's kinda irrelevant). I have a weighted directionless graph and I am writing the addVertex method. I have basically everything down, but I'm not sure what I should do when I add a vertex in between two others that were already there and had their own corresponding weights.
Should I just throw away the old weight that the vertex stored? Should I use the new one that was passed in? A mix of both? Or does it not matter at all what I pick?
I just wanted to make sure that I was not doing something I shouldn't.
Thanks!
I guess it depends on what you want to achieve. Usually, an adjacency list is a nested list whereby each row i indicates the i-th node's neighbourhood. To be precise, each entry in the i-th node's neighbourhood represents an outgoing connection from node i to j. The adjacency list does not comprise edge or arc weights.
Hence, adding a vertex n should do not affect the existing adjacency list's entries but adds a new empty row n to the adjacency list. However, adding or removing edges alter the adjacency list's entries. Thus, adding a vertex n "between two other [nodes i and j] that were already there and had their own corresponding weights" implies that you remove the existing connection between i and j and eventually add two new connections (i,n) and (n,j). If there are no capacity restrictions on the edges and the sum of distances (i,n) and (n,j) dominates the distance (I,j) this could be fine. However, if the weights represent capacities (e.g. max-flow problem) you should keep both connections.
So your question seems to be incomplete or at least unprecise. I assume that your goal is to calculate the shortest distances between each pair of nodes within an undirected graph. I suggest keeping all the different connections in your graph. Shortest path algorithms can calculate the shortest connections between each node pair after you have finished your graph's creation.

The number of undirected graphs reprezentate în the same matrix

I have in the same adiacence matrix for many undirected graphs. I need a idea to find the number of graphs from the matrix.
I have to dolce this in c/c++.
I have in the same adjacency matrix many undirected graphs. I need an idea to find the number of graphs from the matrix.
This means that you have many unconnected components in the matrix (i.e. graphs that do not connect to each other).
take a random node and follow its edges, marking each node visited. If you cannot continue, you have found one component.
take a random node that has not yet been visited and do the same.
repeat until all nodes are marked.
For the marking, take an integer that you increment with each component marked. That allows you to identify (and list) the components and at the same time tell how many components there are.

Directed Graph - How to count the number of vertices from which each other vertex in graph is reachable?

In a directed graph how to efficiently count the number of vertices from which each other vertex in graph is reachable?
If there is no cycle in the graph, there can be only one such vertex and it has an in-degree zero, and there are no other vertices with an in-degree zero. You then have to run a DFS to check if all other vertices are reachable from it. So the answer is either one or zero, depending on the result of DFS.
If there is a cycle, then all the vertices in the cycle have this property or none of them have it.
If you detect a cycle, replace all the vertices in the cycle with one vertex and keep a label for that vertex of how many vertices it represents. Use the same procedure as above. I.e., check in-degrees and run DFS from the new node. The answer will be zero or the label.
Detecting a cycle can be accomplished using a DFS.
There might be several cycles in the graph. In that case you have to eliminate all of them. You can eliminate all of them in one linear pass of DFS, but that's tricky. You could also use Tarjan's algorithm as suggested by btilly in his answer.
Use Tarjan's strongly connected components algorithm to detect all loops then construct a graph with each strongly connected component collapsed to a single node.
Now in this new graph, it is sufficient to look for a vertex with no in edges. If that vertex connects to every other one (verifiable with a breadth first linear search), then everything in the strongly connected component that it came from is in your set, otherwise no vertex is in your set.

Given a set of vertices, how do you generate a strongly-connected directed graph with a near-minimal amount of edges?

I am trying to perform testing on my graph class's dijkstras algorithm. To do this, I generate a graph with a couple thousand vertices, and then make the graph connected by randomly adding thousands of edges until the graph is connected. I can then run the search between any two random vertices over and over and be sure that there is a path between them. The problem is, I often end-up with a nearly-dense graph, which because I am using an adjacency list representation, causes my search algorithm to be terribly slow.
Question :
Given a set of vertices V, how do you generate a strongly-connected, directed graph, that has significantly less edges than a dense-graph over the same vertices would have?
I was thinking about simply doing the following :
vertex 1 <--> vertex 2, vertex 2 <--> vertex 3, ..., vertex n-1 <--> vertex n
And then randomly adding like n/10 edges throughout the graph, but this doesn't seem like an optimal way of coming up with random graph structures to test my search algorithms on.
One approach would be to maintain a set of strongly connected components (starting with |V| single-vertex components), and in each iteration, merge some random subset of them into a single connected component by connecting a random vertex of each one to a random vertex of the next one, forming a cycle.
This will tend to generate very sparse graphs, so depending on your use case, you might want to toss in some extra random edges as well.
EDIT: Intuitively I think you'd want to use an exponential distribution when deciding how many components to merge in a single iteration. I don't have any real support for that, though.
I don't know if there is a better way of doing it, but at least this seems to work:
I would add E (directed) edges between random vertices. This will generate several clusters of vertices.
Then, I need to connect those clusters to form a chain of clusters, so ensuring that from a cluster I can reach any other cluster. For this I can label a random vertex of each cluster as the "master"vertex, and join the master vertices forming a loop. Thus, you have a strongly-connected directed graph composed of clusters (not vertices yet). The last master should be connected back to the first master, thus creating a loop.
Now, in order to turn it into a strongly-connected digraph composed of vertices I need to make each cluster a strongly-connected digraph by itself. But this is easy if I run a DFS starting at the master node of a cluster and each time I find a leaf I add an edge from that leaf to its master vertex. Note that the DFS must not traverse outside of the cluster.
I think this may work, though the topology will not be truly random, it will loop like a big loop composed of smaller graphs joined together. But depending on the algorithm you need to test, this may come in handy.
EDIT:
If after that you want to have a more random topology, you can add random edges between vertices of different clusters. That doesn't invalidate the rules and creates more complex paths for your algorithm to traverse.

Efficiently expand set of graph edges

I have a set of edges from a graph, and would like to expand it with all edges that share a vertex with any edge. How could I do this efficiently with boost::graphs?
The only way I've been able to come up with is the naive solution of extracting all the source and target vertices, using boost::adjacent_vertices to get all adjacencies and then creating all the new edges with boost::edge. Is there a better way of doing this?
Context: The graph vertices are centroids of a terrain triangulation, the edges connect vertices whose corresponding triangles are adjacent (so sort of a dual graph). The set of edges I'm looking to expand corresponds to inter-triangle paths which are blocked, and the blocked area is expanding. The area is sort-of circular, so most of the edges I'll see using my naive approach above will already be part of the set.
Instead of considering all adjacent vertices in each step to generate the new edges, use a property map to mark edges already encounterd. Thus, you need to consider unmarked edges in each step only. A vertex is marked after adding all edges incident to it to your set.
Given the fact that the internal data structure used by boost::graph is either an adjacency list or an adjacency matrix, I do not think that any further improvement is possible.