Graph - Algorithm to position nodes - graph

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.

Related

Build the highest tower of N colored, weighed cubes

I'm stuck trying to solve this problem where, in basic terms, you are given as an input a set of N cubes ordered by weight (first one is the lightest, the Nth cube is the heaviest), each with all their sides assigned a color represented by an integer m so that 1 <= m <= 100 (cubes can have the same color on multiple sides); and you have to show the tallest possible tower that you can build with the given cubes following 2 conditions
Any cube can't have a heavier cube on top of it
For any pair of cubes stacked on top of each other, the faces of the cubes that touch must be the same color
The problem must be solved by modelling it as a graph, I've derived from condition 1 that the graph modelling the connections between cubes can be represented as a DAG and can therefore be seen as a longest path problem within a DAG, however, I'm having a hard time figuring out how to determine what the longest path will be when how the path goes forward depends on what cube I used and on which orientation I placed it. Would the solution just be to try all possible paths and output the longest one or could there be a more efficient approach?

Break up graph into smallest sub-components of 2-nodes or greater

I wish to be able to separate my graph into subcomponent such that the removal of any single node would create no further sub-components (excluding single nodes). As an example see the two images below.
The first image shows the complete graph. The second image shows the sub-components of the graph when it has been split into the smallest possible subcomponents. As can be seen from the second image, the vertex names have been maintained. I don't need the new structure to be a single graph it can be a list of graphs, or even a list of the nodes in each component.
The component of nodes 4-5-6 remains as removing any of the three nodes will not create a new component as the node that was broken off will only be a single node.
At the moment I am trying to put together an iterative process, that removes nodes sequentially in ascending degree order and recurses into the resultant new components. However, it is difficult and I imagine someone else has done it better before.
You say you want the "smallest subcomponents of 2 nodes of greater", and that your example has the "smallest possible subcomponents". But what you actually meant is the largest possible subcomponents such that the removal of any single node would create no further sub-components, right? Otherwise you could just separate the graph into a collection of all of the 2-graphs.
I believe, then, that your problem can be described as finding all "biconnected components" (aka maximal biconnected subgraphs of a graph): https://en.wikipedia.org/wiki/Biconnected_component
As you said in the comments, igraph has the function biconnected_components(g), which will solve your problem. :)

Number of triangles with N points inside

Given some points in plane (upto 500 points), no 3 collinear. We have to determine the number of triangles whose vertices are from the given points and that contain exactly N points inside them. How to efficiently solve this problem? The naive O(n^4) algorithm is too slow. Any better approach?
You could try thinking of the triangle as the intersection of three half-spaces. To find the number of points inside a triangle A, B, C first consider the set of points on one side of the infinite line in direction AB. Let these sets L(AB) and R(AB) for points of the left and right. Similarly you the same with other two edges and build sets L(AC) and R(AC) and sets L(BC) and R(BC).
So the number of points in ABC will be the number of points in the intersection of L(AB), L(AC) and L(BC). (You might want to consider R(AB) instead depending on the orientation of the triangle).
Now if we want to consider the full set of 500 points. First take all pairs of points AB and construct the sets L(AB) and R(AB). This will take O(n^3) operations.
Next we test all triangles and find the intersections of the three sets. If we use some hash table structure for the sets then to find the intersection points is like a hashtable lookups. If L(AB) has l elements, L(AC) has m elements and L(BC) n elements. Say l > m > n. For each point in L(BC) we need to do a lookup in L(AC) and L(BC) so thats a maximum of 2n hashtable lookups.
It might be faster to consider a geometric lookup table.
Divide your whole domain into a coarse grid say a 10 by 10 grid. We can then put each point into a set G(i,j). We can then split the sets L(AB) into each grid cell. Say call these sets L(AB,i,j) and R(AB,i,j). In testing for intersections first workout which grid cells lie in the intersection. This dramatically reduces the search space and as each set L(AB,i,j) contain fewer members there will be fewer hashtable lookups.
Actually I happened to encounter similar problem recently but the only difference was that there were around 300 pts and I solved it using bitset (C++ STL). For every pair of points, say (x[i],y[i]) and (x[j],y[j]), I formed a bitset<302>B[i][j] and B[i][j][k] stores 1 if k-th point is above line segment from point i to point j else I would store 0.
Now in a brute force manner I get three points so as to form a triangle, lets say (x[i],y[i]), (x[j],y[j]) and (x[k],y[k]), then a point,say z-th point ,would be inside triangle if B[i][j][z]==B[i][j][k] && B[j][k][z]==B[j][k][i] && B[k][i][z]==B[k][i][j] because a point inside triangle would show similar sign w.r.t. a side of triangle as the third point of triangle(one which is not on this side).
So i get three bitset variables P=B[i][j], Q=B[j][k] and R=B[k][i] and there taking there bitwise AND then applying count() function to give me the active number of bits and hence the number of points within the triangle. But make sure you change variable P such that it gives B[i][j][k]=1 if not then take bitwise not (~) of this variable.
Though the above solution is problem specific, i hope it helps. This is the problem link: http://usaco.org/current/index.php?page=viewproblem&cpid=660

sum graph from bottom to top

given the following graph modeled in neo4j
goal:
calculate the sum of all nodes multiplied by the edge percentage from the bottom up.
e.g.
(((30*.6)+(50*.1)+100)*.5)+10)=71,5
status:
I found the REDUCE function (http://neo4j.com/docs/stable/query-functions-collection.html#functions-reduce)
but in my opinion it sums from top to the bottom, instead of bootom up.
Is this a commen problem with a well known name, and I dont know it?
Is there any solution in neo4j or in another (graph)database/language?
This was a really interesting one :
I assumed 2 things, first all nodes have the :A label, second the property on nodes and relationship has the key p
Here is a working query :
MATCH p=(:A)-[r]->(pike)
WITH pike, collect(p) as paths
OPTIONAL MATCH (pike)-[r]->()
WITH
CASE r WHEN null THEN 1 ELSE r.p END as multiplier,
CASE r WHEN null THEN last(nodes(paths[0])).p
ELSE reduce(x=0, path in paths | x + (head(nodes(path)).p * head(rels(path)).p)) + last(nodes(paths[0])).p END as total
RETURN sum(total*multiplier) as total
The logic behind :
Find one depths paths, agreggate the children by the pike (first WITH)
In case the optional match doesn't pass, the multiplier will be 1 instead of a possible float value on the relationship property
The second case, do the math logic, if this is the top of the pikes (hence here node A) it will just add the value of the top node, otherwise it will take the value of the children
Then it sum the score + the multiplication
You can test it here : http://console.neo4j.org/r/ih8obf

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:

Resources