calculating the height of a Minimum spannning tree - java

I need a JAVA code that could help me find the height of the Minimum spanning tree.
Basically i m looking for an extension of the
Prim's/Kruskal's algo that not only gives the height of the MST but also gives its height.
Thanks in advance.

Take as the root vertex one of the tree's centers and calculate the maximal distance from the chosen center to the leaf nodes.
The height can the be calculated in the following way:
set the height to 0
while there are at least 3 remaining vertices:
delete all leaf vertices
height := height+1
if 2 vertices remain:
height := height+1
the remaining vertices are the centers of the tree.
The time complexity is O(n).
A practical way of calculating the height would be to combine all leaf nodes int a single node that serves as a root, then calculate the MST of that modification and the height as the maximum distance from generated root node to the newly generated leaf nodes.

I am not writing the code here, just giving you a hint.
In every node keep a variable that stores the height/depth of that node.
So, depth for starting node will be 0. Now, whenever you add a edge to the MST, increase the depth of the new node by 1.
Currently you have the following discovered nodes with the following depth.
a 0
b 1
c 1Now suppose you want to add the edge from c to d, so the depth of node d will be depth(c)+1, i.e 1+1=2.
Also, you can keep a track of the maximum depth among all nodes at each step of the algorithm.
So, finally answer will be the maximum depth among all the nodes of the tree.

Related

How do I find the median in O(h) time?

This is for a homework problem -
I need to find the median of a Binary Search Tree in O(h) time - meaning, I cant go through the whole tree to find it. I need to find the median by going through the left or right side of the tree, in a recursion solution.
I've placed an index into each node of the BST, using inorder traversal.
So if a BST has 99 nodes, the smallest node has an index of 1, the next smallest has index of 2 etc etc...while the largest node has index of 99. THis indexing is also required of the assignment.
So whichever side is heavier, has the median.
So here's what I was thinking:
if the left side has more nodes median is on the left. if right side has more nodes, median is on the right. if the left and right sides have equal num of nodes, median is the main root of the whole tree.
But I can't think of how the nodes' indexes would play a role in any of this. I was thinking of using the difference of 2 nodes' indexes to see if 1 side is heavier, but this would require me to go through the whole tree I think, so this would be O(n).
Please set me on a clearer path or a hint or 2.

Dijkstra - find destinations within budget

I was given a graph, including a start vertex, other vertices, and edges represent the costs going from one vertex to another. I need to find the set of destination vertices that I can travel to from the start vertex. The budget is a certain amount of dollars and the travel total cost should be within the budget. How can i implement the Dijkstra's algorithm to this problem? I think we usually use Dijkstra to find the shortest path between two fixed vertices before. But I am not sure how to implement Dijkstra on this budget problem. If someone can give some ideas, that really helps!
To my undersatanding, Dijkstra's algorithm solves the single-source shortest path problem. This means that the resulting data structure is a tree rooted at the starting node. Typically, an implementation would store the minimum cost to reach each node from the starting node. In total, the set of vertices that can be reached within the budget are the ones to which the cost of the shortest path does not exceed the budget. The algorithm itself does not need to be modified; in an additional step, the nodes which can be reached within budged has to be returned as the output.
If you use Dijkstra algorithm, you may end up with the below scenarios:
Assuming budget of 50 and the graph of 4 nodes (start, node 1, node 2, node 3)
Start Node -> node 1 (15) -> node 2 (10): so total cost is 25
Start Node -> node 3 (15): total cost is 15
So now what is your expected result? You should go to node 1 then node 2 and ignore node 3 (since you cannot return back to start then go to node 3, the return will cost 30 too). Or you should go to node 1, back to start, then go to node 3 (total cost of 45, the largest cost you can utilise)
What you need is not the shortest path covering all destinations which is Floyd-Warshall algorithm https://en.wikipedia.org/wiki/Floyd–Warshall_algorithm

Strongly connected component

Given total number of V vertices and total number of E edges of a graph G, how can I compute largest strongly connected component with minimum number of vertices & edges in strongly connected component of graph.
Eg. for graph with 5 vertices and 7 edges, the minimum size of connected component is 3. This graph can be modeled so that there are more connected components but minimum is 3.
The problem I am facing is that edge information is not given to me. Only the total number of edges are given. I wanted to use Tarjan's algorithm using depth first search but I need edge information.
Is it possible to find the size of strongly connected component with minimum vertices and edges just total number of vertices and total number of edges.
Simplest way I can think of is to consider trying to utilise the edges to form components that are Complete Graphs of size 1, then 2, etc until you find one that works.
A complete graph of size n has (n2 - n) / 2 edges. So to split into components of size n will look something like
numFullComponents := V/n //integer division
numEdgesUsed := numFullComponents * n * (n-1) / 2 //This is edges from full components
+ (V%n) * (V%n - 1)/2 //a complete graph on the remainder nodes
You can then compare that number of edges used with the number of edges in the graph. The smallest n that uses at least E edges is the solution.

Best algorthm to get all combination pair of nodes in an undirected graph (need to improve time complexity)

I have an undirected graph A that has : no multiple-links between any two nodes , no self-connected node, there can be some isolated nodes (nodes with degree 0).
I need to go through all the possible combinations of pair of nodes in graph A to assign some kind of score for non-existence links (Let say if my graph has k nodes and n links, then the number of combination should be (k*(k-1)/2 - n) of combinations). The way that I assign score is based on the common neighbor nodes between the 2 nodes of combination.
Ex: score between A-D should be 1, score between G-D should be 0 ...
The biggest problem is that my graph has more than 100.000 nodes and it was too slow to handle almost 10^10 combinations which is my first attempt to approach the solution.
My second thought is since the algorithm is based on common neighbors of the node, I might only need to look at the neighbors so that I can assign score which is different from 0. The rest can be determined as 0 and no need to compute. But this could possibly repeat a combination.
Any idea to approach this solution is appreciated. Please keep in mind that the actual network has more than 100.000 nodes.
If you represent your graph as an adjacency list (rather than an adjacency matrix), you can make use of the fact that your graph has only 600,000 edges to hopefully reduce the computation time.
Let's take a node V[j] with neighbors V[i] and V[k]:
V[i] ---- V[j] ---- V[k]
To find all such pairs of neighbors you can take the list of nodes adjacent to V[j] and find all combinations of those nodes. To avoid duplicates you will have to generate the combinations rather than the permutations of the end nodes V[i] and V[k] by requiring that i < k.
Alternatively, you can start with node V[i] and find all of the nodes that have a distance of 2 from V[i]. Let S be the set of all the nodes adjacent to V[i]. For each node V[j] in S, create a path V[i]-V[j]-V[k] where:
V[k] is adjacent to V[j]
V[k] is not an element of S (to avoid directly connected nodes)
k != i (to avoid cycles)
k > i (to avoid duplications)
I personally like this approach better because it completes the adjacency list for one node before moving on to the next.
Given that you have ~600,000 edges in a graph with ~100,000 nodes, assuming an even distribution of edges across all of the nodes each node would have an average degree of 12. The number of possible paths for each node is then on the order of 102. Over 105 nodes that gives on the order of 107 total paths rather than the theoretical limit of 1010 for a complete graph. Still a large number, but a thousand times faster than before.

Height of a binary tree

Consider the following code:
public int heightOfBinaryTree(Node node)
{
if (node == null)
{
return 0;
}
else
{
return 1 +
Math.max(heightOfBinaryTree(node.left),
heightOfBinaryTree(node.right));
}
}
I want to know the logical reasoning behind this code. How did people come up with it? Does some have an inductive proof?
Moreover, I thought of just doing a BFS with the root of the binary tree as the argument to get the height of the binary tree. Is the previous approach better than mine?Why?
if (node == null)
{
return 0;
}
The children of leaf nodes are null. Therefore this is saying that once we've gone past the leaves, there are no further nodes.
If we are not past the leaf nodes, we have to calculate the height and this code does so recursively.
return 1 +
The current node adds a height of 1 to the height of the subtree currently being calculated.
Math.max(heightOfBinaryTree(node.left),
heightOfBinaryTree(node.right));
We recursively calculate the height of the left subtree (node.left) and right subtree (node.right). Since we're calculating the maximum depth, we take the maximum of these two depths.
I've shown above that the recursive function is correct. So calling the function on the parent node will calculate the depth of the entire tree.
Here's a graphical representation of the height of a tree from this document. h is the height of the tree, hl and hr are the heights of the left and right subtrees respectively.
Moreover, I thought of just doing a
BFS with the root of the binary tree
as the argument to get the height of
the binary tree. Is the previous
approach better than mine?Why?
The code you provided is a form of DFS. Since you have to process all nodes to find the height of the tree, there will be no runtime difference between DFS and BFS, although BFS will use O(N) memory while DFS will use O(logN) memory. BFS is also slightly more complex to code, since it requires a queue while DFS makes use of the "built-in" recursive stack.
The logic behind that code is:
since a node will have two children, the height of the Tree will be maximum of the heights of tree whose roots are the left child and right child, and of course +1 for the walk to the children.
As you can see, the description above is recursive and so is the code.
BFS should also do, but it would be an overkill as both implementation and space/time complexity.
There is a say, recursive functions though hard to understand, but are very elegant to implement.
The height of a tree is the length of longest downward path from it's root.
This function is a recursive way to count the levels of a binary tree. It just increments counters as it descends the tree, returning the maximum counter (the counter on the lowest node).
I hope I have helped.
It's a recursive function. It's saying the height of a tree is 1 + the height of its tallest branch.
Is BFS a breadth first search? I'm not sure what difference there would be in efficiency, but I like the simplicity of the recursive function.
To extend more on the answers and elaborate more on recursion plus recursive call stack.
Suppose the tree
2
/\
5 9
/
0
lets suppose the left sub-tree first, root(2) called the heightOfBinaryTree method on the left sub-tree
The call stack of the method in question will be as follows
node(5) calls node(0)
node(0) calls node(null)
node(null) breaks the recursive loop
consider that fact these calls are made before the method returned anything.
iterating back on the recursive call stack, this is where each node return its output.
node(null) returned 0 -> 0
node(0) returned (return from node(null) + 1) -> 1
node(5) returned (return from node(0) + 1) -> 2
Same goes for the right sub-tree. If we compare the output from both left and right sub-tree we will have the height.

Categories

Resources