Recurrence: T(n/4) + T(n/2) + n^2 with tree methods - algorithm

I'm trying to solve this exercise with tree method but I've a doubt about two parts:
1) In the T(?) column, is it correct using (n^2/2^i) instead of (n/2^i)? I'm asking because this is the part which cause me the error;
2) Is the last multiplication correct (it's between the number of nodes and the time)? After finding the i value I have to create a serie which starts from 0 to the result of the multiplication, right? And as variable of the serie have I to use 2^i (the number of nodes)?

The column for the number of nodes is misleading.
Each node has a cost of (m/k)^2 where k is whatever the denominator of the node is. With the structure you have using, the nodes in each level will have a variety of denominators. For example, your level 2 should contain the nodes [(m/16), (m/8)], [(m/8), (m/4)].
The cost for a level is the sum of the cost of each node in that level. Since each node has a different cost, you cannot multiply the number of nodes by a value to find the cost of a level, you have to add them up individually.
The total cost is the sum of the cost of each level. The result of this calculation may result in a logarithm, or it may not. It depends on the cost of each level and the number of levels.
Hint: Pascal's Triangle

Related

Number of walks from source to sink with exactly h hops

Given an un-directed graph, a starting vertex and ending vertex. Find the number of walks (so a vertex can be visited more than once) from the source to the sink that involve exactly h hops. For example, if the graph is a triangle, the number of such paths with h hops is given by the h-th Jakobstahl number. This can be extended to a fully connected k-node graph, producing the recurrence (and closed form solution) here.
When the graph is an n-sided polygon, the accepted answer here expresses the number of walks as a sum of binomial terms.
I assume there might be an efficient algorithm for finding this number for any given graph? We can assume the graph is provided in adjacency matrix or adjacency list or any other convenient notation.
A solution to this would be to use a modified BFS with two alternating queues and a per-node counter for paths to this node of a certain length:
paths(start, end, n):
q = set(start)
q_next = set()
path_ct = map()
path_ct_next = map()
path_ct[start] = 1
for i in [0, n): # counting loop
for node in q: # queue loop
for a in adjacent(node): # neighbor-loop
path_ct_next[a] += path_ct[node]
q_next.add(a)
q = q_next
q_next = set()
path_ct = path_ct_next
path_ct_next = map()
return path_ct_next[end]
The basic assumption here is that map() produces a dictionary that returns zero, if the entry doesn't yet exist. Otherwise it returns the previously set value. The counting-loop simply takes care of doing exactly as many iterations as hops as required. The queue loop iterates over all nodes that can be reached using exactly i hops. In the neighbor-loop finally all nodes that can be reached in i + 1 hops are found. In this loop the adjacent nodes will be stored into a queue for the next iteration of counting-loop. The number of possible paths to reach such a node is the sum of the number of paths to reach it's predecessors. Once this is done for each node of the current iteration of counting-loop, the queues and tables are swapped/replaced by empty instances and the algorithm can start over.
If you take the adjacency matrix of a graph and raise it to the nth power, the resulting matrix counts the number of paths from each node to each other that uses exactly n edges. That would provide one way of computing the number you want - plus many others you aren’t all that interested in. :-)
Assuming the number of paths is “small” (say, something that fits into a 64-bit integer), you could use exponentiation by squaring to compute the matrix in O(log n) multiplies for a total cost of O(|V|ω log n), where ω is the exponent of the fastest matrix multiplication algorithm. However, if the quantity you’re looking for doesn’t fit into a machine word, then the cost of this approach will depend on how big the answer is as the multiplies will take variable amounts of time. For most graphs and small n this won’t be an issue, but if n is large and there are other parts of the graph that are densely connected this will slow down a bit.
Hope this helps!
You can make an algorithm that keep searching all possible paths , but with a variable that will contain your number of hops
For each possible path , each hop will decrement that variable and when arriving to zero your algorithm goes to trying another path , and if ever a path arrives to the target before making variable reachs zero , this path will be added to the list of your desired paths

How to prove Average height of Binary Search Tree is O(logn)?

I had thought of a proof but unable to sketch things up on paper.
I had though of the Recurrence relation for the height of a binary search tree would be
T(n)=T(k)+T(n-k-1)+1
Where k is the Number of elements in the left subtree if root and n-k-1 are on right subtree of root (and n= total nodes)
(Correct me if the thing above is wrong)
Now what I thought, because we have to calculate for average case..
So there would be half of the cases possible...
(Now this is the point from where I am starting messing up things plz correct here..)
My claim: I would have approx half cases out of all possible..
Example
Root
(0,N-1) OR
(1, N-2) OR
.
.
(N-1,0)
Where N is total nodes.
Now I am considering half of above cases for average case calculation...
(I don't know whether I am doing this right or not..comment on it would be most appreciated)
So I get :
T(n)=T(n/2)+T(n/2)+1
T(n)=2T(n/2)+1
Now when I apply master method for getting approx answer over the obtained recurrence relation..
I get O(n).
Now how should I proceed...?
(My expectation was instead of n I should have got logn)
But that didn't work out..
So plz suggest how should I proceed further.
(Is my approach even at all correct..from start, also tell me about that?)
From "Algorithms" by Robert Sedgewick and Kevin Wayne
Definition. A binary search tree (BST) is a binary tree where each node has a
Comparable key (and an associated value) and satisfies the restriction that the key
in any node is larger than the keys in all nodes in that node’s left subtree and smaller than the keys in all nodes in that node’s right subtree.
Proposition C. Search hits in a BST built from N random keys require ~ 2 ln N
(about 1.39 lg N) compares, on the average.
Proof: The number of compares used for a search hit ending at a given node is
1 plus the depth. Adding the depths of all nodes, we get a quantity known as the
internal path length of the tree. Thus, the desired quantity is 1 plus the average internal path length of the BST, which we can analyze with the same argument that
we used for Proposition K in Section 2.3: Let CN be the total internal path length
of a BST built from inserting N randomly ordered distinct keys, so that the average
cost of a search hit is 1 CN / N. We have C0= C1= 0 and for N > 1 we can write a
recurrence relationship that directly mirrors the recursive BST structure:
CN = N 1 (C0 CN1) / N + (C1 CN2)/N . . . (CN1 C0 )/N
The N 1 term takes into account that the root contributes 1 to the path length
of each of the other N 1 nodes in the tree; the rest of the expression accounts
for the subtrees, which are equally likely to be any of the N sizes. After rearranging
terms, this recurrence is nearly identical to the one that we solved in Section 2.3
for quicksort, and we can derive the approximation CN ~ 2N ln N
I also reccommend you to check this Mit lecture Binary Search Trees, BST Sort
Also check the chapter 3.2 from Algorithms books, it explains binary search trees in depth

Intitutive idea behind the build heap function

I want to know about the following statement in build heap function
for i=A.length/2 downto 1
As this step was deduced by hit & trial to find out the parent of leaves or there was something else in the mind of the person who developed this algorithmBelow is build heap function-
Build_Max_Heap(A)
A.heap_size=A.length
for i=A.length/2 downto 1
Max_Heapify(A,i)
The nodes of the second half of the array are leaves(explanation follows in next paragraph) and are thus trivially 1-node max heaps already, and hence Max_Heapify need not be done for them.
Even if you call Max_Heapify for those nodes, no harm in terms of time complexity as the leaf nodes have no nodes below and Max_Heapify would return immediately anyway.
Mathematically it's easy to establish that the second half of the array are leaves by the way summation of a Geometric Progression works. Recall that a heap is a complete binary tree, which means it will have all nodes filled in each level, except possibly the last level, in which it will be filled partially from left to right. For sake of simplicity, let's assume the number of nodes in our heap as 2^N. Clearly this tree has N levels with all levels filled.
First level has 2^0 node
Second level has 2^1 nodes
Third level has 2^2 nodes
N-1 level has 2^N-2 nodes
Nth level has 2^N-1 nodes
Sum of the count of nodes in all levels except last = 2^0 + 2^1...+ 2^N-2
= 2^N-1 - 1
This is the number of nodes in the last level off by one. That is, the the total number of nodes in all levels except the last is almost same as the number of nodes in just the last level, which directly implies that the last level must have half the total number of all nodes in the heap in it. By this observation, we get A.length/2.

Partition a set into k groups with minimum number of moves

You have a set of n objects for which integer positions are given. A group of objects is a set of objects at the same position (not necessarily all the objects at that position: there might be multiple groups at a single position). The objects can be moved to the left or right, and the goal is to move these objects so as to form k groups, and to do so with the minimum distance moved.
For example:
With initial positions at [4,4,7], and k = 3: the minimum cost is 0.
[4,4,7] and k = 2: minimum cost is 0
[1,2,5,7] and k = 2: minimum cost is 1 + 2 = 3
I've been trying to use a greedy approach (by calculating which move would be shortest) but that wouldn't work because every move involves two elements which could be moved either way. I haven't been able to formulate a dynamic programming approach as yet but I'm working on it.
This problem is a one-dimensional instance of the k-medians problem, which can be stated as follows. Given a set of points x_1...x_n, partition these points into k sets S_1...S_k and choose k locations y_1...y_k in a way that minimizes the sum over all x_i of |x_i - y_f(i)|, where y_f(i) is the location corresponding of the set to which x_i is assigned.
Due to the fact that the median is the population minimizer for absolute distance (i.e. L_1 norm), it follows that each location y_j will be the median of the elements x in the corresponding set S_j (hence the name k-medians). Since you are looking at integer values, there is the technicality that if S_j contains an even number of elements, the median might not be an integer, but in such cases choosing either the next integer above or below the median will give the same sum of absolute distances.
The standard heuristic for solving k-medians (and the related and more common k-means problem) is iterative, but this is not guaranteed to produce an optimal or even good solution. Solving the k-medians problem for general metric spaces is NP-hard, and finding efficient approximations for k-medians is an open research problem. Googling "k-medians approximation", for example, will lead to a bunch of papers giving approximation schemes.
http://www.cis.upenn.edu/~sudipto/mypapers/kmedian_jcss.pdf
http://graphics.stanford.edu/courses/cs468-06-winter/Papers/arr-clustering.pdf
In one dimension things become easier, and you can use a dynamic programming approach. A DP solution to the related one-dimensional k-means problem is described in this paper, and the source code in R is available here. See the paper for details, but the idea is essentially the same as what #SajalJain proposed, and can easily be adapted to solve the k-medians problem rather than k-means. For j<=k and m<=n let D(j,m) denote the cost of an optimal j-medians solution to x_1...x_m, where the x_i are assumed to be in sorted order. We have the recurrence
D(j,m) = min (D(j-1,q) + Cost(x_{q+1},...,x_m)
where q ranges from j-1 to m-1 and Cost is equal to the sum of absolute distances from the median. With a naive O(n) implementation of Cost, this would yield an O(n^3k) DP solution to the whole problem. However, this can be improved to O(n^2k) due to the fact that the Cost can be updated in constant time rather than computed from scratch every time, using the fact that, for a sorted sequence:
Cost(x_1,...,x_h) = Cost(x_2,...,x_h) + median(x_1...x_h)-x_1 if h is odd
Cost(x_1,...,x_h) = Cost(x_2,...,x_h) + median(x_2...x_h)-x_1 if h is even
See the writeup for more details. Except for the fact that the update of the Cost function is different, the implementation will be the same for k-medians as for k-means.
http://journal.r-project.org/archive/2011-2/RJournal_2011-2_Wang+Song.pdf
as I understand, the problems is:
we have n points on a line.
we want to place k position on the line. I call them destinations.
move each of n points to one of the k destinations so the sum of distances is minimum. I call this sum, total cost.
destinations can overlap.
An obvious fact is that for each point we should look for the nearest destinations on the left and the nearest destinations on the right and choose the nearest.
Another important fact is all destinations should be on the points. because we can move them on the line to right or to left to reach a point without increasing total distance.
By these facts consider following DP solution:
DP[i][j] means the minimum total cost needed for the first i point, when we can use only j destinations, and have to put a destination on the i-th point.
to calculate DP[i][j] fix the destination before the i-th point (we have i choice), and for each choice (for example k-th point) calculate the distance needed for points between the i-th point and the new point added (k-th point). add this with DP[k][j - 1] and find the minimum for all k.
the calculation of initial states (e.g. j = 1) and final answer is left as an exercise!
Task 0 - sort the position of the objects in non-decreasing order
Let us define 'center' as the position of the object where it is shifted to.
Now we have two observations;
For N positions the 'center' would be the position which is nearest to the mean of these N positions. Example, let 1,3,6,10 be the positions. Then mean = 5. Nearest position is 6. Hence the center for these elements is 6. This gives us the position with minimum cost of moving when all elements need to be grouped into 1 group.
Let N positions be grouped into K groups "optimally". When N+1 th object is added, then it will disturb only the K th group, i.e, first K-1 groups will remain unchanged.
From these observations, we build a dynamic programming approach.
Let Cost[i][k] and Center[i][k] be two 2D arrays.
Cost[i][k] = minimum cost when first 'i' objects are partitioned into 'k' groups
Center[i][k] stores the center of the 'i-th' object when Cost[i][k] is computed.
Let {L} be the elements from i-L,i-L+1,..i-1 which have the same center.
(Center[i-L][k] = Center[i-L+1][k] = ... = Center[i-1][k]) These are the only objects that need to be considered in the computation for i-th element (from observation 2)
Now
Cost[i][k] will be
min(Cost[i-1][k-1] , Cost[i-L-1][k-1] + computecost(i-L, i-L+1, ... ,i))
Update Center[i-L ... i][k]
computecost() can be found trivially by finding the center (from observation 1)
Time Complexity:
Sorting O(NlogN)
Total Cost Computation Matrix = Total elements * Computecost = O(NK * N)
Total = O(NlogN + N*NK) = O(N*NK)
Let's look at k=1.
For k=1 and n odd, all points should move to the center point. For k=1 and n even, all points should move to either of the center points or any spot between them. By 'center' I mean in terms of number of points to either side, i.e. the median.
You can see this because if you select a target spot, x, with more points to its right than it's left, then a new target 1 to the right of x would result in a cost reduction (unless there is exactly one more point to the right than the left and the target spot is a point, in which case n is even and the target is on/between the two center points).
If your points are already sorted, this is an O(1) operation. If not, I believe it's O(n) (via an order statistic algorithm).
Once you've found the spot that all points are moving to, it's O(n) to find the cost.
Thus regardless of whether the points are sorted or not, this is O(n).

Is this a linear programming problem?

I have been pulling my hair out on one problem... The overall problem is complicated... but let me try my best to explain the part that really matters...
I have a graph where each edge represents the correlation between the connected two nodes. Each node is a time course (TC) (i.e., 400 time points), where events will occur at different time points. The correlation between two nodes is defined as the percentage of overlapped events. For the simplicity of this example, let us assume that the total number of events happening on each node is the same as $tn$. And if two TCs (nodes) have $on$ overlapped events (i.e., events that happened at exactly the same time point). Then, the correlation can be defined simply as $on$/$tn$.
Now, I have a network of 11 nodes; and I know the correlation between every two nodes. How do I generate the TCs for all 11 nodes that meet the correlation constraints???
It is easy to do this for two nodes when you know the correlation between the two. Assume TC_1 and TC_2 have a correlation value of 0.6, which means there are 60 percent overlapped events in two TCs. Also, assume that the total number of events are the same for both TC_1 and TC_2 as $tn$. A simple algorithm to place the events in the two TCs is first randomly pick 0.6*$tn$ time points, and consider those as time slots where overlapped events happened in both TCs. Next, randomly pick (1-0.6)*$tn$ time points in TC_1 to place the rest of the events for TC_1. Finally, randomly pick (1-0.6)*$tn$ time points in TC_2 where no events happened in correspondent time points in TC_1.
However, it starts to get harder, when you consider a 3-node network, where the generated three TCs need to meet all three correlation constraints (i.e., 3 edges)... It's hardly possible to do this for a 11-node network...
Does this make any sense to you? Please let me know if it's not...
I was thinking that this is just a trick computer science programing issue... but the more I think about it, it's more like a linear programing problem, isn't it?
Anyone has a reasonable solution? I am doing this in R, but any code is ok...
I think there is a simpleminded linear programming approach. Represent a solution as a matrix, where each column is a node, and each row is an event. The cells are either 0 or 1 to say that an event is or is not associated with a given node. Your correlation constraint is then a constraint fixing the number of 11s in a pair of columns, relative to the number of 1s in each of those columns, which you have in fact fixed ahead of time.
Given this framework, if you treat each possible row as a particular item, occuring X_i times, then you will have constraints of the form SUM_i X_i * P_ij = K_j, where P_ij is 0 or one depending on whether possible row i has 11 in the pair of columns counted by j. Of course this is a bit of a disaster for large numbers of nodes, but with 11 nodes there are 2048 possible rows, which is not completely unmanageable. The X_i may not be linear, but I guess they should be rational, so if you are prepared to use astounding numbers of rows/events you should be OK.
Unfortunately, you may also have to try different total column counts, because there are inequalities lurking around. If there are N rows and two columns have m and n 1s in them there must be at least m + n - N 11s in that column pair. You could in fact make the common number of 1s in each column come out as a solution variable as well - this would give you a new set of constraints in which the Q_ij are 0 and one depending on whether column row i has a 1 in column j.
There may be a better answer lurking out there. In particular, generating normally distributed random variables to particular correlations is easy (when feasible) - http://en.wikipedia.org/wiki/Cholesky_decomposition#Monte_Carlo_simulation and (according to Google R mvrnorm). Consider a matrix with 2^N rows and 2^N-1 columns filled with entries which are +/-1. Label the rows with all combinations of N bits and the columns with all non-zero columns of N bits. Fill each cell with -1^(parity of row label AND column label). Each column has equal numbers of +1 and -1 entries. If you multiple two columns together element by element you get a different column, which has equal numbers of +1 and -1 entries - so they are mutually uncorrelated. If your Cholesky decomposition provides you with matrices whose elements are in the range [-1, 1] you may be able to use it to combine columns, where you combine them by picking at random from the columns or from the negated columns according to a particular probability.
This also suggests that you might possibly get by in the original linear programming approach with for example 15 columns by choosing from amongst not the 2^15 different rows that are all possibilities, but from amongst the 16 different rows that have the same pattern as a matrix with 2^4 rows and 2^4-1 columns as described above.
If there exist solution (you can have problem whit no solution) you can represent this as system of linear equtions.
x1/x2 = b =>
x1 - b*x2 = 0
or just
a*x1 + b*x2 = 0
You should be able to transform this into solving system of linear equations or more precisely homogeneous system of linear equations since b in Ax=b is equal 0.
Problem is that since you have n nodes and n*(n-1)/2 relations (equations) you have to many relations and there will be no solution.
You might represent this problem as
Minimize Ax where x > 0 and x.x == konstant
You can represent this as a mixed integer program.
Suppose we have N nodes, and that each node has T total time slots. You want to find an assignment of events to these time slots. Each node has tn <= T events. There are M total edges in your graph. Between any pair of nodes i and j that share an edge, you have a coefficent
c_ij = overlap_ij/tn
where overlap_ij is the number of overlapping events.
Let x[i,t] be a binary variable defined as
x[i,t] = { 1 if an event occurs at time t in node i
= { 0 otherwise.
Then the constraint that tn events occur at node i can be written as:
sum_{t=1}^T x[i,t] == tn
Let e[i,j,t] be a binary variable defined as
e[i,j,t] = { 1 if node i and node j share an event a time t
= { 0 otherwise
Let N(i) denote the neighbors of node i. Then we have that at each time t
sum_{j in N(i)} e[i,j,t] <= x[i,t]
This says that if a shared event occurs in a neighbor of node i at time t, then node i must have an event at time t. Furthermore, if nodei has two neighbors u and v, we can't have e[i,u,t] + e[i,v,t] > 1 (meaning that two events would share the same time slot), because the sum over all neighbors is less than x[i,t] <= 1.
We also know that there must be overlap_ij = tn*c_ij overlapping events between node i and node j. This means that we have
sum_{t=1}^T e[i,j,t] == overlap_ij
Putting this all together you get the following MIP
minimize 0
e, x
subject to sum_{t=1}^T x[i,t] == tn, for all nodes i=1,...,N
sum_{j in N(i)} e[i,j,t] <= x[i,t],
for all nodes i=1,...,N and all time t=1,...,T
sum_{t=1}^T e[i,j,t] == overlap_ij for all edges (i,j)
between nodes
x[i,t] binary for i=1,...,N and t=1,...,T
e[i,j,t] binary for all edges (i,j) and t=1,...,T
Here the objective is zero, since your model is a pure feasibility problem. This model has a total of T*N + M*T variables and N + N*T + M constraints.
A MIP solver like Gurobi can solve the above problem, or prove that it is infeasible (i.e. no solution exists). Gurobi has an interface to R.
You can extract the final time series of events for the ith node by looking at the solution vector x[i,1], x[i,2], ..., x[i,T].

Resources