how to implement multi tree data-structures? - data-structures

I have those nodes:
[1,1]
[2,1]
[3,2]
[4,2]
[5,3]
where the first proparty in the Id and the secund is the id of paret node
my goal is to make them as multi trees intities and each item has its list of children

Related

Find the number of possible combinations in a graph

This is the problems I am trying to solve:
Given an undirected graph, find the number of different unordered combinations of nodes that can be obtained by traversing a path between any two nodes and keeping track of what nodes that we went to (without going to any node twice).
Say for example that the adjacency matrix is:
1: 2,3
2: 1,3,4
3: 1,2,4
4: 2,3,5
5: 4
One unordered combination would be [1,2,3,4] which could be obtained by going in the path 1>3>4>2 or 1>3>2>4
The answer would be 17 with the following unordered sets:
[1,2] [1,3] [2,3] [2,4] [3,4] [4,5]
[1,2,3] [1,2,4] [1,3,4] [2,3,4] [2,4,5] [3,4,5]
[1,2,3,4] [1,2,4,5] [1,3,4,5] [2,3,4,5]
[1,2,3,4,5]
Currently, what my function does in my program is just brute force all of the possibilities, but I was wondering if there was any faster ways to do it if the graph had 10,000+ nodes? Brute forcing would be way too slow.
You can user this algorithm :
sort the nodes by name for example N_0,...,N_k
define an `result` set which is empty at beginning
for `i` from `0` to `k` do the following
set node `n_i` as root
step 1: list of all 'n_i` neighbors like `n_j` which `j>i`
add all of these pairs to `result` set
set `n_j` as root
go to step 1
end

Prolog exercise 2-3-4 tree

My prof gave me an exercise to do with prolog. Given this goal i have to build the corrispondent 234 tree:
write(tree(1,tree(11,tree(111,n,n),tree(112,tree(1121,n,n),n)),tree(12,tree(121,n,n),tree(122,n,n),
tree(123,n,n),tree(124,tree(1241,n,n),tree(1242,n,n)))))
The result should be something like this:
Are you asking what is my problem ?
I studied what is a 234 tree, but i dont understand why the tree i represented can be considered a 234 tree, what i see are numbers that range from 1 to 1242. Should a 234 tree be something like this ?
Here's your given term, pretty printed for clarity:
tree(1, % has 2 child nodes
tree(11, % has 2 child nodes
tree(111,n,n), % a leaf
tree(112, % has 2 child nodes
tree(1121,n,n), % a leaf
n)), % empty
tree(12, % has 4 child nodes
tree(121,n,n), % a leaf
tree(122,n,n), % a leaf
tree(123,n,n), % a leaf
tree(124, % has two child nodes
tree(1241,n,n), % a leaf
tree(1242,n,n)))) % a leaf
It is clear that the "numbers" 1, 11, 12, ..., 1242 aren't used for their numeric value, but just as stand-ins. In other words, the values are unimportant. A valid tree has already been built.
This tree's nodes each have either 2 or 4 child nodes (possibly empty, signified by n). That is why it is considered to be a 2-3-4 tree, where each node is allowed to have 2, 3, or 4 child nodes (possibly empty).
Your question then becomes, given a 2-3-4 tree represented by a Prolog compound term like the one above, print the tree in the nice visual fashion as shown in your attached image.
This is achieved simply by swapping the printing of nested sub-trees with the printing of the node's value:
print_tree( n ).
print_tree( tree(A,B,C) ) :- print_tree(B),
print_node_value(A),
print_tree(C).
print_tree( tree(A,B,C,D) ) :- print_tree(B),
print_node_value(A),
print_tree(C),
print_tree(D).
print_tree( tree(A,B,C,D,E) ) :- print_tree(B),
print_tree(C),
print_node_value(A),
print_tree(D),
print_tree(E).
You will have to augment this by passing in the desired indentation level, and incrementing it, by the same amount, when printing the child nodes.

Count the height of a binary tree

I want to caculate the height of a binary tree wihout using the algorithme that takes the maximum of the depths of each leaf.
This is the structure that I have on eache node
[content, left_son, right_son, father_node]
a list of arrays of size 4 that represents every node. the left_son, right_son, and father are respectively the indexes of the the left son node, the right son node and the father node in the list
This is indeed possible, but you have to rework your data structure a bit:
You can store a binary Tree in an array like this:
Store the value of the root node at index 0.
Store the left child of
a node at index 2*i+1, where i is the index of the current node;
right child goes at index 2*i+2.
If you do it like this
a node's parent is saved at index (i-1)/2.
your array needs the length 2^(h+1)-1, where h is the height of the tree.
So all you have to do ist keep track of the last "used" index in your array and use the above formula to calculate the height.
2^(h+1)-1 = l => h = ceil(ld(l+1))-1
whith l being the length of your array you effictively use and ld the logarithm with base 2.

Crossover algorithms for permutation matrices

I'm developing a genetic algorithm to find the optimal connections between points (minimizing distance).
Let's assume we have two lists of points:
sources = {s1, s2, s3}
targets = {t1, t2, t3, t4}
I decided to represent the genome as a 2D binary array, where:
rows represent source points
columns represent target points
1s represent the connection between source and target
This representation implies that each column and each row in the matrix can have at most one 1s.
Now I'm struggling to find a crossover operator which preserves the integrity of the solution.
example:
parent1 :
[0][1][0][0]
[0][0][1][0]
[1][0][0][0]
parent2 :
[0][0][1][0]
[1][0][0][0]
[0][0][0][1]
offspring : ???
Any suggestions?
Keeping your representation and assuming that there are more targets than sources, you could use a row-swapping crossover operator with a built-in repair algorithm.
Randomly select a row (i)
Swap parents' i-th row
Repair children (if required) moving the conflicting 1 to a free (random or near) column
E.g.
Row 0 randomly selected
PARENT 1 PARENT 2
ROW 0 [0][1][0][0] <-crossover-> [0][0][1][0]
ROW 1 [0][0][1][0] [1][0][0][0]
ROW 2 [1][0][0][0] [0][0][0][1]
Offspring before repair
CHILD 1 CHILD 2
[0][0][1][0] [0][1][0][0]
[0][0][1][0] and [1][0][0][0]
[1][0][0][0] [0][0][0][1]
CHILD2 is ok (for a column-swapping operator this doesn't happen); CHILD1 needs the repair operator
CHILD 1
[0][0][X][0]
[0][0][X][0]
[1][0][0][0]
Keep the swapped row (row 0) and change the other conflicting row (row 1). Move the 1 to a free column (column 1 or 3)
CHILD 1
[0][0][1][0]
[0][1][0][0]
[1][0][0][0]
Offspring
CHILD 1 CHILD 2
[0][0][1][0] [0][1][0][0]
[0][1][0][0] and [1][0][0][0]
[1][0][0][0] [0][0][0][1]
You can generalize BFS to this situation. (if I correctly understand task)
In simple graph traversing task you need to find shortest path from start node to finish node, so you need to store for every node distance from start node and predecessor for this node (from what cell you came). Before BFS iterative algorithm you need to add start node to queue. Take one item in each iteration, check if this node is finish node and add neighbors nodes for this node to queue, etc. So, how we can generalize this algorithm to several start and finish nodes. Very simple.
You need to add to queue all start nodes.
You need to compare every node that you take from queue with every finish nodes. You can use hashset to O(1) lookup.
Time complexity of this generalization doesn't depend on count of start and finish nodes and the same as simple BFS algorithm: O(V+E)

Optimal way to create a tree with the following conditions

Expected tree for given array Given an array of n elements , create a tree such that all path labels from root to leaf represent all combinations of array elements of length 'n'.
for ex if array = {1,2,3} then the tree should be such that there are 6 paths from root to leaf with each of them as follows {{123},{132},{213},{231},{312},{321}} 1<= n <= 10^9 and there can be duplicates too.
Since the list might contain duplicates you need to dedupe them and keep count. To keep it less confusing let us use letters instead of numbers.
Now, let us say {a, a, b, b, b} is your input.
Convert it into a data structure that looks like {a:2, b:3} (you can do this by using a map or using tuples)
Algorithm:
Initialization: Create a root node
Input: data = {a:2, b:3} and node
For node create k = size(data) children.
Assign each key in data to each new edge (in this case a and b).
For each child call this function recursively with the corresponding edge value removed. Example: for the function call corresponding to a, you will pass on data = {a:1, b:3} and for b, data = {a:2, b:3}
Whenever a value becomes 0, remove the corresponding key from data.

Resources