Gaining information from nodes of tree - graph

I am working with the tree data structure and trying to come up with a way to calculate information I can gain from the nodes of the tree.
I am wondering if there are any existing techniques which can assign higher numerical importance to a node which appears less frequently at lower level (Distance from the root of the tree) than the same nodes appearance at higher level and high frequency.
To give an example, I want to give more significance to node Book, at level 2 appearing once,
then at level 3 appearing thrice.
Will appreciate any suggestions/pointers to techniques which achieve something similar.
Thanks,
Prateek

One metric I just thought of is this: for a labelk, let it's "value" be the sum of the levels it appears at. So, if it appears at the root and the root's left child, let it's value be 1.
Then, your most "important" labels are those with the lowest value.
EDIT: This will make the root more important than the label of it's children, even if they are both the same. So, some scaling by occurrence count might be in order.

It depends how much significance you want to give to it at each level.
Just multiply by a number that decreases as you move down the levels of the tree. For example, n_nodes * 1/(3^n), where n is the level of the tree. Thus, a node on level 2 gets a value of 1/4, and 3 nodes on level 3 get a value of 1/9. Thus, the single node on level 2 is more significant.
Adjust the denominator to your liking. As long as it increases with n, it will give more significance to nodes higher in the tree.

Related

Graph - Algorithm to position nodes

I am trying to create a dynamic graph where users can add new nodes using ELK.js
The graph is a tree that has one root node. I am trying to set the position of nodes in a row using (x,y) position (y is not important for now).
Assumptions:
Lower x value brings the node to the left.
Two nodes in one row can't have the same x value.
When we add a new node it should appear on the right of other children if available (the green box in row 2 and 3 for example are a new nodes)
New nodes can be added to every row at any moment (green box in row 2 and row 3)
Max number we can use to set x value is 16 digit long: 9999999999999999
A simple example of how positions behave can be found here (see the position of nodes n2, n3, n4 and change them in JSON)
I am trying not to calculate every position of every node in a row. I tried a lot of different numbers but I stuck and need fresh ideas.
Any help would be appreciated. Thank you
You could approach this as follows:
When a new node is the first one on its level, give it 0 as its x-value.
When it is not the first, find out what its immediate two siblings are on that level (one at the left, one at the right of the node). In some cases you'll need to traverse from the node via one or more of its ancestor(s) to find such immediate sibling.
Get the x-values of these two siblings, and take the average of those two values for the new node's x value.
It might be that there is only a sibling at one side. If there is no sibling at the right side, take the average between the left siblings's x-value and 1016. If it is the left sibling that is missing, take the average between the right siblings's x-value and -1016.
This practically means you use an initial range of -1016...1016 and keep cutting segments in half when a new node must be placed within a segment.

Shortest distance to cover all the (N+1) points. All the N points lie on x- axis. Remaining one point lies anywhere in the coordinate plane

Given (N+1) points. All the N points lie on x- axis. Remaining one point (HEAD point) lies anywhere in the coordinate plane.
Given a START point on x- axis.
Find the shortest distance to cover all the points starting from START point.We can traverse a point multiple times.
Example N+1=4
points on x axis
(0,1),(0,2),(0,3)
HEAD Point
(1,1) //only head point can lie anywhere //Rest all on x axis
START Point
(0,1)
I am looking for a method as of how to approach this problem.
Whether we should visit HEAD point first or HEAD point in between.
I tried to find a way using Graph Theory to simplify this problem and reduce the paths that need to be considered. If there is an elegant way to represent this problem using graphs to identify a solution, I was not able to find it. This approach becomes very inefficient as the n increases - the time and memory is O(2^n).
Looking at this as a tree graph, the root node would be the START point, then each of its child nodes would be the points it is connected to.
Since the START point and the rest of the points aside from the HEAD all lay on the x-axis, all non-HEAD points only need to be connected to adjacent points on the x-axis. This is because the distance of the path between any two points is the sum of the distances between any adjacent points along the path between those two points (the subset of nodes representing points on the x-axis does not need to form a complete graph). This reduces the brute force approach some.
Here's a simple example:
The upper left shows the original problem: points on the x-axis along with the START and HEAD points.
In the upper right, this has been transformed into a graph with each node representing a point from the original problem. The edges represent the paths that can be taken between points. This assumes that the START point only represents the first point in the path. Unlike the other nodes, it is only included in the path once. If that is not the case and the path can return to the START point, this would approximately double the possible paths, but the same approach can be followed.
In the bottom left, the START point, a, is the root of a tree graph, and each node connected to the START point is a child node. This process is repeated for each child node until either:
A path that is obviously not optimal is identified, in which case that node can just be excluded from the graph. See the nodes in red boxes; going back and forth between the same nodes is unnecessary.
All points are included when traversing the tree from the root to that node, producing a potential solution.
Note that when creating the tree graph, each time a node is repeated, its "potential" child nodes are the same as the first time the node was included. By "potential", I mean cases above still need to be checked, because the result might include a nonsensical path, in which case that node would not be included. It is also possible a potential solution results from the path after its child nodes are included.
The last step is to add up the distances for each of the potential solutions to determine which path is shortest.
This requires a careful examination of the different cases.
Assume for now START (S) is on the far left, and HEAD (H) is somewhere in the middle the path maybe something like
H
/ \
S ---- * ----*----* * --- * ----*
Or it might be shorter to from H to and from the one of the other node
H
//
S ---- * --- * -- *----------*---*
If S is not at one end you might have something like
H
/ \
* ---- * ----*----* * --- * ----*
--------S
Or even going direct from S to H on the first step
H
/ |
* ---- * ----*----* |
S
A full analysis of cases would be quite extensive.
Actually solving the problem, might depend on the number of nodes you have. If the number is small < 10, then compete enumeration might be possible. Just work out every possible path, eliminate the ones which are illegal, and choose the smallest. The number of paths is I think in the order of n!, so its computable for small n.
For large n you can break the problem into small segments. I think its enough just to consider a small patch with nodes either side of H and a small patch with nodes either side of S.
This is not really a solution, but a possible way to think about tackling the problem.
(To be pedantic stackoverflow.com is not the right site for this question in the stack exchange network. Computational Science : algorithms might be a better place.
This is a fun problem. First, lets try to find a brute force solution, as Poosh did.
Observations about the Shortest Path
No repeated points
You are in an Euclidean geometry, thus the triangle inequality holds: For all points a,b,c, the distance d(a,b) + d(b,c) <= d(a,c). Thus, whenever you have an optimal path that contains a point that occurs more than once, you can remove one of them, which means it is not an optimal path, which leads to a contradiction and proves that your optimal path contains each point exactly once.
Permutations
Our problem is thus to find the permutation, lets call it M_i, of the numbers 1...n for points P1...Pn (where P0 is the fixed start point and Pn the head point, P1...Pn-1 are ordered by increasing x value) that minimizes the sum of |(P_M_i)-(P_M_(i-1))| for i from 1 to n, || being the vector length sqrt(v_x²+v_y²).
The number of permutations of a set of size n is n!. In this case we have n+1 points, so a brute force approach testing all permutations would have complexity (n+1)!, which is higher than even 2^n and definitely not practical, so we need further observations to improve this.
Next Steps
My next step would now be to see if there are any other sequences that can be proven to be not optimal, leading to a reduction in the number of candidates to be tested.
Paths of non-head points
Lets look at all paths (sequences of indices of points that don't contain a head point and that are parts of the optimal path. If we don't change the start and end point of a path, then any other transpositions have no effect on the outside environment and we can perform purely local optimizations. We can prove that those sequences must have monotonic (increasing or decreasing) x coordinate values and thus monotonic indices (as they are ordered by ascending x coordinate between indices 0 and n-1):
We are in a purely one dimensional subspace and the total distance of the path is thus equal to the sum of the absolute values of the differences in x coordinates between one such point and the next. It is clear that this sum is minimized by ordering by x coordinate in either ascending or descending order and thus ordering the indices in the same way. Note that this is true for maximal such paths as well as for all continuous "subpaths" of them.
Wrapping it up
The only choices we have left are:
where do we place the head node in the optimal path?
which way do we order the two paths to the left and right?
This means we have n values for the index of the head node (1...n, 0 is fixed as the start node) and 2x2 values for sort order. So we have 4n choices which we can all calculate and pick the shortest one. One of the sort orders probably determines the other but I leave that to you.
Anyways, the complexity of this algorithm is O(4n) = O(n). Because reading in the input of the problems is in O(n) and writing the output is as well, I believe that is an algorithm of optimal complexity. However, if we could reformulate the problem somewhat, so that we could read and write the input and output in some compressed form, as in only the parameters that we actually need to solve the problem, then it is possible that we could do better.
P.S.: I'm not a mathematician so I probably used wrong words for some concepts and missed the usual notation for the variables and functions. I would be glad for some expert to check this for any obvious errors.

Layout for a family tree

I have a dataset of DNA relationships (as a percent match) between myself and few hundred relatives, almost all distant relatives. I also have data on DNA relationships between each of them and certain other members in the dataset.
I'm hoping to build a network graph that shows the interrelationships and have Gephi build something that loosely resembles a family tree. But even using a small sample database I can't get the resulting graph to look anything like that.
I want each relationship (i.e. edge) to have a "force" related to the closeness of the relationship, so distant relatives (nodes) are pushed further away. I want the graph to self-assemble based on these "forces" and assume there is a layout for this, but I haven't found one.
I'm currently putting the DNA relationship in the weight column, and not using the interval column at all. But even using just 8 relatives and artificially perfect data I have to manually move nodes around to make it look remotely useful.
What layout should I use for this type of graph, and what other advice can you offer to make this work? Should the weight field increase or decrease as relationship distance increases?
… and have Gephi build something that loosely resembles a family tree. But even using a small sample database I can't get the resulting graph to look anything like that.
A family tree connects descendants (mostly). DNA similarity (as a percentage) does not conform to this structure. Related questions may be answered here.
Setting a Library > Edges > Edge Weight -filter to the DNA similarity attribute may help (but will not produce "something that loosely resembles a family tree").
I want each relationship (i.e. edge) to have a "force" related to the closeness of the relationship, so distant relatives (nodes) are pushed further away. I want the graph to self-assemble based on these "forces" …
All layouts work like that. However, Gephi does not feature hierarchical positioning. 3rd party candidates include EventGraphLayout, Layered Layout and Concentric Layout.
Should the weight field increase or decrease as relationship distance increases?
The greater an edge's weight, the stronger its connection (resulting in less distance between the nodes it connects). To a family tree however this is irrelevant.
I'm hoping to build a network graph that shows the interrelationships between each member …
What layout should I use for this type of graph, and what other advice can you offer to make this work?
Following steps emphasize clustering and modularity:
Calculate modularity.
Color nodes by modularity class: Appearance > Nodes > Partition > Modularity Class
Apply a layout; ForceAtlas 2 for example (with Dissuade Hubs, LinLog mode and Prevent Overlap enabled).
Apply the Contraction layout afterwards if necessary. Optionally set node size according to (for example) Eigenvector Centrality (prior to applying layout).

How is this Huffman Table created?

I have a table that shows the probability of an event happening.
I'm fine with part 1, but part 2 is not clicking with me. I'm trying to get my head around how
the binary numbers are derived in part 2?
I understand 0 is assigned to the largest probability and we work back from there, but how do we work out what the next set of binary numbers is? And what do the circles around the numbers mean/2 shades of grey differentiate?
It's just not clicking. Maybe someone can explain it in a way that will make me understand?
To build huffman codes, one approach is to build a binary tree, using a priority queue, in which the data to be assigned codes are inserted, sorted by frequency.
To start with, you have a queue with only leaf nodes, representing each of your data.
At each step you take the two lowest priority nodes from the queue, make a new node with a frequency equal to the sum of the two removed nodes, and then attach those two nodes as the left and right children. This new node is reinserted into the queue, according to it's frequency.
You repeat this until you only have one node in the queue, which will be the root.
Now you can traverse the tree from the root to any leaf node, and the path you take (whether you go left or right) at each level gives you either a 0 or a 1, and the length of the path (how far down the tree the node is) gives you the length of the code.
In practice you can just build this code as you build the tree, but appending 0 or 1 to the code at each node, according to whether the sub-tree it is part of is being added to the left or the right of some new parent.
In your diagram, the numbers in the circles are indicating the sum of the frequency of the two nodes which have been combined at each stage of building the tree.
You should also see that the two being combined have been assigned different bits (one a 0, the other a 1).
A diagram may help. Apologies for my hand-writing:

How to find total number of minimum spanning trees in a graph?

I don't want to find all the minimum spanning trees but I want to know how many of them are there, here is the method I considered:
Find one minimum spanning tree using prim's or kruskal's algorithm and then find the weights of all the spanning trees and increment the running counter when it is equal to the weight of minimum spanning tree.
I couldn't find any method to find the weights of all the spanning trees and also the number of spanning trees might be very large, so this method might not be suitable for the problem.
As the number of minimum spanning trees is exponential, counting them up wont be a good idea.
All the weights will be positive.
We may also assume that no weight will appear more than three times in the graph.
The number of vertices will be less than or equal to 40,000.
The number of edges will be less than or equal to 100,000.
There is only one minimum spanning tree in the graph where the weights of vertices are different. I think the best way of finding the number of minimum spanning tree must be something using this property.
EDIT:
I found a solution to this problem, but I am not sure, why it works. Can anyone please explain it.
Solution: The problem of finding the length of a minimal spanning tree is fairly well-known; two simplest algorithms for finding a minimum spanning tree are Prim's algorithm and Kruskal's algorithm. Of these two, Kruskal's algorithm processes edges in increasing order of their weights. There is an important key point of Kruskal's algorithm to consider, though: when considering a list of edges sorted by weight, edges can be greedily added into the spanning tree (as long as they do not connect two vertices that are already connected in some way).
Now consider a partially-formed spanning tree using Kruskal's algorithm. We have inserted some number of edges with lengths less than N, and now have to choose several edges of length N. The algorithm states that we must insert these edges, if possible, before any edges with length greater than N. However, we can insert these edges in any order that we want. Also note that, no matter which edges we insert, it does not change the connectivity of the graph at all. (Let us consider two possible graphs, one with an edge from vertex A to vertex B and one without. The second graph must have A and B as part of the same connected component; otherwise the edge from A to B would have been inserted at one point.)
These two facts together imply that our answer will be the product of the number of ways, using Kruskal's algorithm, to insert the edges of length K (for each possible value of K). Since there are at most three edges of any length, the different cases can be brute-forced, and the connected components can be determined after each step as they would be normally.
Looking at Prim's algorithm, it says to repeatedly add the edge with the lowest weight. What happens if there is more than one edge with the lowest weight that can be added? Possibly choosing one may yield a different tree than when choosing another.
If you use prim's algorithm, and run it for every edge as a starting edge, and also exercise all ties you encounter. Then you'll have a Forest containing all minimum spanning trees Prim's algorithm is able to find. I don't know if that equals the forest containing all possible minimum spanning trees.
This does still come down to finding all minimum spanning trees, but I can see no simple way to determine whether a different choice would yield the same tree or not.
MST and their count in a graph are well-studied. See for instance: http://www14.informatik.tu-muenchen.de/konferenzen/Jass08/courses/1/pieper/Pieper_Paper.pdf.

Resources