Random tree with specific branching factor in Mathematica - graph

Do you know if it's possible to somehow generate a random tree graph with a specific branching factor? I don't want it to be a k-ary tree.
It would be also great if I could define both the branching factor and the maximum depth. I want to randomly generate a bunch of trees that would differ in branching factor and depth.
TreePlot with random integer input returns something that's almost what I want:
TreePlot[RandomInteger[#] -> # + 1 & /# Range[0, 100]]
but I can't figure out a way to get a tree with a specific branching factor.
Thanks!

I guess I'm a bit late, but I like the question. Instead of creating a tree in the form
{0 -> 1, 0 -> 5, 1 -> 2, 1 -> 3, 1 -> 4}
I will use the following form of nested calls, where every argument is a child, which represents another node
0[1[2, 3, 4], 5]
Both forms are equivalent and can be transformed into each other.
Row[{
TreeForm[0[1[2, 3, 4], 5]],
TreePlot[{0 -> 1, 0 -> 5, 1 -> 2, 1 -> 3, 1 -> 4}]
}]
Here is how the algorithm works: As arguments we need a function f which gives a random number of children and is called when we create a node. Additionally, we have a depth d which defines the maximum depth a (sub-)tree can have.
[Choose branching] Define a branching function f which can be called like f[] and returns a random number of children. If you want a tree with either 2 or 4 children, you could use e.g. f[] := RandomChoice[{2, 4}]. This function will be called for each created node in the tree.
[Choose tree-depth] Choose a maximum depth d of the tree. At this point, I'm not sure what you want the randomness to be incorporated into the generation of the tree. What I do here is that when a new node is created, the depth of the tree below it is randomly chosen between the depth of its parent minus one and zero.
[Create ID Counter] Create a unique counter variable count and set it to zero. This will give us increasing node ID's. When creating a new node, it is increased by 1.
[Create a node] Increase count and use it as node-ID. If the current depth d is zero, give back a leaf with ID count, otherwise call f to decide how many children the node should get. For every new child chose randomly the depth of its sub-tree which can be 0,...,d-1 and call 4. for each new child. When all recursive calls have returned, the tree is built.
Fortunately, in Mathematica-code this procedure is not so verbose and consists only of a few lines. I hope you can find in the code what I have described above
With[{counter = Unique[]},
generateTree[f_, d_] := (counter = 0; builder[f, d]);
builder[f_, d_] := Block[
{nodeID = counter++, childs = builder[f, #] & /# RandomInteger[d - 1, f[]]},
nodeID ## childs
];
builder[f_, 0] := (counter++);
]
Now you can create a random tree like follows
branching[] := RandomChoice[{2, 4}];
t = generateTree[branching, 6];
TreeForm[t]
Or if you like you can use the next function to convert the tree into what is accepted by TreePlot
transformTree[tree_] := Module[{transform},
transform[(n_Integer)[childs__]] := (Sow[
n -> # & /# ({childs} /. h_Integer[__] :> h)];
transform /# {childs});
Flatten#Last#Reap[transform[tree]
]
and use it to create many random trees
trees = Table[generateTree[branching, depth], {depth, 3, 7}, {5}];
GraphicsGrid[Map[TreePlot[transformTree[#]] &, trees, {2}]]

Related

How do I check if the path from a node to another has a depth equal to a given one in a graph in OCaml?

First of all, I'm sorry for how I wrote my question.
Anyway, I'm trying to write a function in OCaml that, given a graph, a max depth, a starting node, and another node, returns the list of the nodes that make the path but only if the depth of it is equal to the given one. However, I can't implement the depth part.
This is what I did:
let m = [(1, 2, "A"); (2, 3, "A");
(3, 1, "A"); (2, 4, "B");
(4, 5, "B"); (4, 6, "C");
(6, 3, "C"); (5, 7, "D");
(6, 7, "D")]
let rec vicini n = function
[] -> []
| (x, y, _)::rest ->
if x = n then y :: vicini n rest
else if y = n then x :: vicini n rest
else vicini n rest
exception NotFound
let raggiungi m maxc start goal =
let rec from_node visited n =
if List.mem n visited then raise NotFound
else if n = goal then [n]
else n :: from_list (n :: visited) (vicini n m)
and from_list visited = function
[] -> raise NotFound
| n::rest ->
try from_node visited n
with NotFound -> from_list visited rest
in start :: from_list [] (vicini start m)
I know I have to add another parameter that increases with every recursion and then check if its the same as the given one, but I don't know where
I am not going to solve your homework, but I will try to teach you how to use recursion.
In programming, especially functional programming, we use recursion to express iteration. In an iterative procedure, there are things that change with each step and things that remain the same on each step. An iteration is well-founded if it has an end, i.e., at some point in time, the thing that changes reaches its foundation and stops. The thing that changes on each step, is usually called an induction variable as the tribute to the mathematical induction. In mathematical induction, we take a complex construct and deconstruct it step by step. For example, consider how we induct over a list to understand its length,
let rec length xs = match xs with
| [] -> 0
| _ :: xs -> 1 + length xs
Since the list is defined inductively, i.e., a list is either an empty list [] or a pair of an element x and a list, x :: list called a cons. So to discover how many elements in the list we follow its recursive definition, and deconstruct it step by step until we reach the foundation, which is, in our case, the empty list.
In the example above, our inductive variable was the list and we didn't introduce any variable that will represent the length itself. We used the program stack to store the length of the list, which resulted in an algorithm that consumes memory equivalent to the size of the list to compute its length. Doesn't sound very efficient, so we can try to devise another version that will use a variable passed to the function, which will track the length of the list, let's call it cnt,
let rec length cnt xs = match xs with
| [] -> cnt
| _ :: xs -> length (cnt+1) xs
Notice, how on each step we deconstruct the list and increment the cnt variable. Here, call to the length (cnt+1) xs is the same as you would see in an English-language explanation of an algorithm that will state something like, increment cnt by one, set xs to the tail xs and goto step 1. The only difference with the imperative implementation is that we use arguments of a function and change them on each call, instead of changing them in place.
As the final example, let's devise a function that checks that there's a letter in the first n letters in the word, which is represented as a list of characters. In this function, we have two parameters, both are inductive (note that a natural number is also an inductive type that is defined much like a list, i.e., a number is zero or the successor of a number). Our recursion is also well-founded, in fact, it even has two foundations, the 0 length and the empty list, whatever comes first. It also has a parameter that doesn't change.
let rec has_letter_in_prefix letter length input =
length > 0 && match input with
| [] -> false
| char :: input ->
char = letter || has_letter_in_prefix letter (length-1) input
I hope that this will help you in understanding how to encode iterations with recursion.

Detecting cycles in Topological sort using Kahn's algorithm (in degree / out degree)

I have been practicing graph questions lately.
https://leetcode.com/problems/course-schedule-ii/
https://leetcode.com/problems/alien-dictionary/
The current way I detect cycles is to use two hashsets. One for visiting nodes, and one for fully visited nodes. And I push the result onto a stack with DFS traversal.
If I ever visit a node that is currently in the visiting set, then it is a cycle.
The code is pretty verbose and the length is long.
Can anyone please explain how I can use a more standard top-sort algorithm (Kahn's) to detect cycles and generate the top sort sequence?
I just want my method to exit or set some global variable which flags that a cycle has been detected.
Many thanks.
Khan's algorithm with cycle detection (summary)
Step 1: Compute In-degree: First we create compute a lookup for the in-degrees of every node. In this particular Leetcode problem, each node has a unique integer identifier, so we can simply store all the in-degrees values using a list where indegree[i] tells us the in-degree of node i.
Step 2: Keep track of all nodes with in-degree of zero: If a node has an in-degree of zero it means it is a course that we can take right now. There are no other courses that it depends on. We create a queue q of all these nodes that have in-degree of zero. At any step of Khan's algorithm, if a node is in q then it is guaranteed that it's "safe to take this course" because it does not depend on any courses that "we have not taken yet".
Step 3: Delete node and edges, then repeat: We take one of these special safe courses x from the queue q and conceptually treat everything as if we have deleted the node x and all its outgoing edges from the graph g. In practice, we don't need to update the graph g, for Khan's algorithm it is sufficient to just update the in-degree value of its neighbours to reflect that this node no longer exists.
This step is basically as if a person took and passed the exam for
course x, and now we want to update the other courses dependencies
to show that they don't need to worry about x anymore.
Step 4: Repeat: When we removing these edges from x, we are decreasing the in-degree of x's neighbours; this can introduce more nodes with an in-degree of zero. During this step, if any more nodes have their in-degree become zero then they are added to q. We repeat step 3 to process these nodes. Each time we remove a node from q we add it to the final topological sort list result.
Step 5. Detecting Cycle with Khan's Algorithm: If there is a cycle in the graph then result will not include all the nodes in the graph, result will return only some of the nodes. To check if there is a cycle, you just need to check whether the length of result is equal to the number of nodes in the graph, n.
Why does this work?:
Suppose there is a cycle in the graph: x1 -> x2 -> ... -> xn -> x1, then none of these nodes will appear in the list because their in-degree will not reach 0 during Khan's algorithm. Each node xi in the cycle can't be put into the queue q because there is always some other predecessor node x_(i-1) with an edge going from x_(i-1) to xi preventing this from happening.
Full solution to Leetcode course-schedule-ii in Python 3:
from collections import defaultdict
def build_graph(edges, n):
g = defaultdict(list)
for i in range(n):
g[i] = []
for a, b in edges:
g[b].append(a)
return g
def topsort(g, n):
# -- Step 1 --
indeg = [0] * n
for u in g:
for v in g[u]:
indeg[v] += 1
# -- Step 2 --
q = []
for i in range(n):
if indeg[i] == 0:
q.append(i)
# -- Step 3 and 4 --
result = []
while q:
x = q.pop()
result.append(x)
for y in g[x]:
indeg[y] -= 1
if indeg[y] == 0:
q.append(y)
return result
def courses(n, edges):
g = build_graph(edges, n)
ordering = topsort(g, n)
# -- Step 5 --
has_cycle = len(ordering) < n
return [] if has_cycle else ordering

How to check equality of two FStar.Set's

How can you check whether two sets are equal in FStar? The following expression is of type Type0 not Tot Prims.bool so I'm not sure how to use it to determine if the sets are equal (for example in a conditional). Is there a different function that should be used instead of Set.equal?
Set.equal (Set.as_set [1; 2; 3]) Set.empty
The sets defined in FStar.Set are using functions as representation.
Therefore, a set s of integers for instance, is nothing else than a function mapping integers to booleans.
For instance, the set {1, 2} is represented as the following function:
// {1, 2}
fun x -> if x = 1 then true
else (
if x = 2 then true
else false
)
You can add/remove value (that is, crafting a new lambda), or asks for a value being a member (that is, applying the function).
However, when it comes to comparing two sets of type T, you're out of luck : for s1 and s2 two sets, s1 = s2 means that for any value x : T, s1 x = s2 x. When the set of T's inhabitants is inifinite, this is not computable.
Solution The function representation is not suitable for you. You should have a representation whose comparaison is computable. FStar.OrdSet.fst defines sets as lists: you should use that one instead.
Note that this OrdSet module requires a total order on the values held in the set. (If you want have set of non-ordered values, I implemented that a while ago, but it's a bit hacky...)

Get all childs of a particular node till a particular depth

I have this relationship in my neo4j:
Parent -> Childs
F -> D,E
D -> A,B,C
A -> X
Use case: I am trying to get all child of a particular node using this query till a particular depth let's say depth = 2
Query to get All child of node F
MATCH (p:Person)-[:REPORTS_TO *]->(c:Person) WHERE p.name="F"
WITH COLLECT (c) + p AS all
UNWIND all as p MATCH (p)-[:REPORTS_TO]-(c)
RETURN p,c;
This returns me this: (which is all child's node of F without limit)
But when I try to get all childs till depth 2 :
Query to get All child of node F with depth = 2
MATCH (p:Person)-[:REPORTS_TO *2]->(c:Person) WHERE p.name="F"
WITH COLLECT (c) + p AS all
UNWIND all as p MATCH (p)-[:REPORTS_TO]->(c)
RETURN p,c;
Which returns
When I put depth = 2, it didn't return all child's of D' (only returned A and notB`, 'C')
Expected response was:
All child's of 'F', child's of all child's of `F' (i.e level 1) and child's of all childs of nodes of level 1 (i.e level 2)
Am I missing something in my query or any another way to get a response as I expected above?
Adding dataset
CREATE (f:Person {name: "F"})
CREATE (e:Person {name: "E"})
CREATE (d:Person {name: "D"})
CREATE (c:Person {name: "C"})
CREATE (b:Person {name: "B"})
CREATE (a:Person {name: "A"})
CREATE (x:Person {name: "X"})
CREATE (a)-[:REPORTS_TO]->(x)
CREATE (d)-[:REPORTS_TO]->(a)
CREATE (d)-[:REPORTS_TO]->(b)
CREATE (d)-[:REPORTS_TO]->(c)
CREATE (f)-[:REPORTS_TO]->(d)
CREATE (f)-[:REPORTS_TO]->(e)
The problem is you're not querying for what you think you're querying for.
[:REPORTS_TO *2]
doesn't query up to depth 2, it queries nodes at exactly depth 2. The result is nodes B, C, A, and F (since you added it in).
Of those nodes, only nodes A and F have an outgoing :REPORTS_TO relationship, so your match eliminates B and C from the result set. The nodes returned are A and F and the nodes reachable by an outgoing :REPORTS_TO relationship (E, D, and X).
If you want to alter your query so it's up to depth 2 instead of exactly depth 2, use a range on the variable-length relationship (omitting the lower-bound makes it default to 1):
[:REPORTS_TO *..2]
And if you want this to include F in the match itself (instead of manually adding it when you collect the nodes), use a lower bound of 0:
[:REPORTS_TO *0..2]

Recursion on staircase

I'm trying to understand the solution provided in a book to the following question:
"A child is running up a staircase with n steps and can hop either 1 step, 2 steps or 3 steps at a time. Implement a method to count how many possible ways the child can run up the stairs."
The book's solution is as follows, stemming from the fact that "the last move may be a single step hop from n - 1, a double step hop from step n - 2 or a triple step hop from step n - 3"
public static int countWaysDP(int n, int[] map) {
if (n < 0)
return 0;
else if (n == 0)
return 1;
else if (map[n] > -1)
return map[n];
else {
map[n] = countWaysDP(n - 1, map) + countWaysDP(n - 2, map) + countWaysDP(n - 3, map);
return map[n]; }
}
My confusion is:
Why should the program return 1 if the number of steps is zero? The way I think about it, if the number of steps is zero, then there are zero ways to traverse the staircase. Wouldn't a better solution be something like "if (n <= 0) return 0; else if (n == 1) return 1"?
I'm not sure I understand the rationale behind making this a static method? Google says that a static method is one that is called by the entire class, and not by an object of the class. So the book's intention seems to be something like:
.
class Staircase {
static int n;
public:
static int countWaysDP(int n, int[] map); }
instead of:
class Staircase {
int n;
public:
int countWaysDP(int n, int[] map); }
Why? What's the problem with there being multiple staircases instantiated by the class?
Thanks.
(Note: Book is Cracking the Coding Interview)
To answer your first question, it turns it is the beauty of mathematics: if there is 1 step for the staircase, there is 1 way to solve it. If there is 0 steps, there is also 1 way to solve it, which is to do nothing.
It is like, for an n-step staircase, for m times, you can either walk 1, 2, or 3 steps to finish it. So if n is 1, then m is 1, and there is 1 way. If n is 0, m is 0, and there is also 1 way -- the way of not taking any step at all.
If you write out all the ways for a 2-step staircase, it is [[1, 1], [2]], and for 1-step staircase, it is [[1]], and for 0-staircase, it is [[]], not []. The number of elements inside of the array [[]] is 1, not 0.
This will become the fibonacci series if the problem is that you can walk 1 step or 2 steps. Note that fib(0) = 1 and fib(1) = 1, and it corresponds to the same thing: when staircase is 1 step, there is 1 way to solve it. When there is 0 steps, there is 1 way to solve it, and it is by doing nothing. It turns out the number of ways to walk a 2-step staircase is fib(2) is 2 and it equals fib(1) + fib(0) = 1 + 1 = 2, and it wouldn't have worked if fib(0) were equal to 0.
Answer 2:
A Static method means the function doesn't need any information from the object.
The function just takes an input (in the parameters), processes it and returns something.
When you don't see any "this" in a function, you can set it as static.
Non-static methods usually read some properties (this-variables) and/or store values in some properties.
Answer 1:
I converted this to javascript, just to show what happens.
http://jsbin.com/linake/1/edit?html,js,output
I guess this is the point. Recursion often works opposite to what you could expect. It often returns values in the opposite order.
For 5 staircases:
First it returns n=1; then n=2, ... up to n=5;
n=5 has to wait until n=4 is ready, n=4 has to wait until n=3 is ready, ...
So here is your n=0 and n<0:
The first return of the function has n=1; that calls this
map[n] = countWaysDP(n - 1, map) + countWaysDP(n - 2, map) + countWaysDP(n - 3, map)
So that is
map[n] = countWaysDP(0, map) + countWaysDP(-1, map) + countWaysDP(-2, map)
There countWaysDP(0, map) returns 1; the other terms are meaningless, so they return 0. That's why there are these clauses for n==0 and n<0
notice, you can add
+ countWaysDP(n - 4, map)
if you want to see what happens when the child can also jump 4 cases
Also notice:
As I said in answer 2, you see this function doesn't require any object. It just processes data and returns something.
So, in your case, having this function in your class is useful because your functions are grouped (they 're not just loose functions scattered around your script), but making it static means the compiler doesn't have to carry around the memory of the object (especially the properties of the object).
I hope this makes sense. There are surely people that can give more accurate answers; I'm a bit out of my element answering this (I mostly do javascript).
To try and answer your first question, why it returns 1 instead of 0, say you're looking at a stair with 2 steps in total, the recursive call then becomes:
countWaysDP(2 - 1, map) + countWaysDP(2 - 2, map) + countWaysDP(2 - 3, map);
The second recursive call is the one where n becomes zero, that's when we have found a successful path, because from 2 steps, there's obviously a path of taking 2 steps. Now, if you write as you suggested:
n == 1: return 1
you would not accept taking two steps from the two stepped stair! What the statement means is that you only count the path if it ends with a single step!
You need to think about it has a tree with 3 possible options on each node.
If the size of the staircase is 4
we will have something like this:
(4)--1-->(3)--..(Choose a step and keep branching)...
|__2-->(2)--..(Until you get size of zero)............
|__3-->(1)--1-->(0) # <--Like this <--
At the end if you count all the leafs with size of zero you will get all the possible ways.
So you can think it like this, what if you take a step and then consider update the size of the stair like this size-step, where your steps can be (1,2,3)
Doing that you can code something like this:
choices = (1, 2, 3)
counter = 0
def test(size):
global counter
if size == 0:
counter += 1
for choice in choices:
if size - choice >= 0:
test(size - choice)
return counter

Resources