Adjacency list indegree - graph

I was solving this CLRS problem, which asked to find out the indegree of every vertex of a graph G(V,E). I found out the solution to be O(|E|) as we only have to scan through all the edges to find out the degrees of all vertices.
But most of the solutions, I found online, say that it is O(|V|+|E|). How come? How are the vertices accounting for the time taken?

If we suppose that the implementation of the digraph uses objects for vertices and each vertex has an associated list of successors and no additional data structures, then it will be impossible to iterate the edges directly.
If the digraph is connected, then each vertext has at least one associated edge. This means that iteration over the edges via iteration over the vertices takes O(|E|) time - the iteration over the vertices does not increase the running time, which is dominated by the number of edges.
If the digraph is not connected, then the iteration over the vertices is not necessarily dominated by the number of edges; even isolated vertices have to be processed just to find out that they have no associated outgoing arcs, which can be done in O(|V|+|E|) time.
In total, the runtime bound of O(|V|+|E|) is correct in either case; however, for a connected digraph (or an implementation which permits direct iteration over the edges regardless of the number of vertices) one can obtain a tighter runtime bound of O(|E|).

Related

Explanation of network indices normalization

Could someone explain in pretty simple words why the normalization of many network analysis indicies (graph theory) is n(n - 1), where n – the graph size? Why do we need to take into account (n - 1)?
Most network measures that focus on counting edges (e.g. clustering coefficient) are normalized by the total number of possible edges. Since every edge connects a pair of vertices, we need to know how many possible pairs of vertices we can make. There are n possible vertices we could choose as the source of our edge, and therefore there are n-1 possible vertices that could be the target of our edge (assuming no self-loops, and if undirected divide by 2 bc source and target are exchangeable). Hence, you frequently encounter $n(n-1)$ or $\binomal{n}{2}$.

Pathfinding through graph with special vertices

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.

Finding all maximal transitive closured subgraphs in given graph

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

What is the most amount of edges a directed graph can have without having a cycle?

Working on a graph, and this information would be useful, but it is hard to calculate. Thanks!
Attempted solution: Run a BFS and for each subsequent layer add an edge from all vertices of one BFS layer to all vertices of the next BFS layer.
Your attempt would give the maximum number of edges. Another way to look at it is to number the vertices 1 through n, and have an edge connecting each vertex to all higher numbered vertices, for a total of n(n-1)/2 edges.
To see that you can’t have any more edges, you just have to realize that once you have more than n(n-1)/2 edges, there must be some pair of vertices connected to each other in each direction, forming a cycle.

Determine if undirected graph is connected

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.

Resources