How is the space complexity of below algorithm come out to be O(log n) - space-complexity

int[] findMinMax(int A[], int start, int end)
{
int max;
int min;
if ( start == end )
{
max = A[start]
min = A[start]
}
else if ( start + 1 == end )
{
if ( A[start] < A[end] )
{
max = A[end]
min = A[start]
}
else
{
max = A[start]
min = A[end]
}
}
else
{
int mid = start + (end - start)/2
int left[] = findMinMax(A, start, mid)
int right[] = findMinMax(A, mid+1, end)
if ( left[0] > right[0] )
max = left[0]
else
max = right[0]
if ( left[1] < right[1] )
min = left[1]
else
min = right[1]
}
// By convention, we assume ans[0] as max and ans[1] as min
int ans[2] = {max, min}
return ans
}
On analysing the time complexity comes out to be O(n) using the master theorem for recursion. On looking through the pseudocode it's much clear that Divide & Conquer Algorithmic Paradigm is used. I'm facing difficulty with the space complexity part. Any help would be appreciated ?

Your arrays left and right get populated by the recursive calls to your function. Since the input to these calls keeps getting halved in size with each call, you will only need log n number of calls before you get to the base case where you do not need to populate them at all. The bound on auxiliary space used is therefore O(log n).

Related

How to stop the search in CP Optimizer if the upper bound doesn't get better after x seconds

I'm wondering if there exists a way in CP Optimizer 12.10 to stop the search if the upper bound (of a minimization problem) doesn't get better after "x" seconds. This would be especially helpful when trying to solve a difficult instance of an NP-Hard problem and the search is stuck in one incumbent solution.
I know there exist some parameters to control the search as cp.param.TimeLimit (I'm using that) or cp.param.FailLimit but that is not that I need for my problem.
Any help would be highly appreciated.
what you can do is use a main block (flow control) if you rely on the OPL API and in this main block you give a time limit of x seconds, then you get the bound and the current objective, you save them if you think you should go further or stop if you're ok with the solution.
Let me share a full example out of the lifegame example in the OPL product. And remember John Conway once again.
using CP;
int n=20;
int Half=n div 2;
range FirstHalf = 1..Half;
range LastHalf = n-Half+1..n;
range States = 0..1;
range Bord = 0..(n+1);
range Interior = 1..n;
range obj = 0..(n*n);
tuple neighbors {
int row;
int col;
}
{neighbors} Neighbor =
{<(-1),(-1)>,<(-1),0>,<(-1),1>,<0,(-1)>,<0,1>,<1,(-1)>,<1,0>,<1,1>};
dvar int Life[Bord][Bord] in States;
dvar int Obj in obj;
dvar int x[0..(n+2)*(n+2)-1];
maximize Obj;
subject to {
forall(i,j in Bord) Life[i][j]==x[i*(n+2)+j];
//ct1:
Obj == sum( i , j in Bord )
Life[i][j];
forall( i , j in Interior ) {
ct21:
2*Life[i][j] - sum( nb in Neighbor )
Life[i+nb.row][j+nb.col] <= 0;
ct22:
3*Life[i][j] + sum( nb in Neighbor )
Life[i+nb.row][j+nb.col] <= 6;
forall( ordered n1 , n2 , n3 in Neighbor ) {
ct23:
-Life[i][j]+Life[i+n1.row][j+n1.col]
+Life[i+n2.row][j+n2.col]
+Life[i+n3.row][j+n3.col]
-sum( nb in Neighbor : nb!=n1 && nb!=n2 && nb!=n3 )
Life[i+nb.row][j+nb.col] <= 2;
}
}
forall( j in Bord ) {
ct31:
Life[0][j] == 0;
ct32:
Life[j][0] == 0;
ct33:
Life[j][n+1] == 0;
ct34:
Life[n+1][j] == 0;
}
forall( i in Bord : i<n ) {
ct41:
Life[i][1]+Life[i+1][1]+Life[i+2][1] <= 2;
ct42:
Life[1][i]+Life[1][i+1]+Life[1][i+2] <= 2;
ct43:
Life[i][n]+Life[i+1][n]+Life[i+2][n] <= 2;
ct44:
Life[n][i]+Life[n][i+1]+Life[n][i+2] <= 2;
}
ct5:
sum( i in FirstHalf , j in Bord )
Life[i][j] >=
sum( i in LastHalf , j in Bord )
Life[i][j];
ct6:
sum( i in Bord , j in FirstHalf )
Life[i][j] >=
sum( i in Bord , j in LastHalf )
Life[i][j];
}
main
{
thisOplModel.generate();
cp.param.timelimit=10;
var obj=0;
var bound=0;
var oldobj=0;
var oldbound=0;
while (1==1)
{
cp.solve();
obj=cp.getObjValue();
bound=cp.getObjBound();
writeln("bound and obj =",bound," ",obj);
if (Opl.abs((oldobj-oldbound-obj+bound))<=0) break;
oldobj=obj;
oldbound=bound;
}
}
which gives
bound and obj =398 181
bound and obj =398 180
bound and obj =398 180
// Script execution finished with status 1.

Binary search to solve 'Kth Smallest Element in a Sorted Matrix'. How can one ensure the correctness of the algorithm,

I'm referring to the leetcode question: Kth Smallest Element in a Sorted Matrix
There are two well-known solutions to the problem. One using Heap/PriorityQueue and other is using Binary Search. The Binary Search solution goes like this (top post):
public class Solution {
public int kthSmallest(int[][] matrix, int k) {
int lo = matrix[0][0], hi = matrix[matrix.length - 1][matrix[0].length - 1] + 1;//[lo, hi)
while(lo < hi) {
int mid = lo + (hi - lo) / 2;
int count = 0, j = matrix[0].length - 1;
for(int i = 0; i < matrix.length; i++) {
while(j >= 0 && matrix[i][j] > mid) j--;
count += (j + 1);
}
if(count < k) lo = mid + 1;
else hi = mid;
}
return lo;
}
}
While I understand how this works, I have trouble figuring out one issue.
How can we be sure that the returned lo is always in the matrix?
Since the search space is min and max value of the array, the mid need NOT be a value that is in the array. However, the returned lo always is.
Why is this happening?
For the sake of argument, we can move the calculation of count to a separate function like the following:
bool valid(int mid, int[][] matrix, int k) {
int count = 0, m = matrix.length;
for (int i = 0; i < m; i++) {
int j = 0;
while (j < m && matrix[i][j] <= mid) j++;
count += j;
}
return (count < k);
}
This predicate will do exactly same as your specified operation. Here, the loop invariant is that, the range [lo, hi] always contains the kth smallest number of the 2D array.
In other words, lo <= solution <= hi
Now, when the loop terminates, it is evident that lo >= hi
Merging those two properties, we get, lo = solution = hi, since solution is a member of array, it can be said that, lo is always in the array after loop termination and will rightly point to the kth smallest element.
Because We are finding the lower_bound using binary search and there cannot be any number smaller than the number(lo) in the array which could be the kth smallest element.

Cyclomatic Complexity edges

So I'm trying to figure out if that blue line is in the right place, I know that I should have 9 edges but not sure if it's correct.
The code
public int getResult(int p1, int p2) {
int result = 0; // 1
if (p1 == 0) { // 2
result += 1; //3
} else {
result += 2; //4
}
if (p2 == 0) { //5
result += 3; //6
} else {
result += 4; //7
}
return result; //8 exit node
}
so 8 nodes and it should have 9 edges, right? Did I do the right thing?
Yes, the blue line is placed correctly because after the 3rd line, your program is going to jump to the 5th line.
The easiest way to compute cyclomatic complexity without drawing any flow diagram is as follows:
Count all the loops in the program for, while, do-while, if. Assign a value of 1 to each loop. Else should not be counted here.
Assign a value of 1 to each switch case. Default case should not be counted here.
Cyclomatic complexity = Total number of loops + 1
In your program, there are 2 if loops, so the cyclomatic complexity would be 3(2+1)
You can cross-check it with the standard formulae available as well which are as below:
C = E-N+2 (9-8+2=3)
OR
C = Number of closed regions + 1 (2+1=3)
According to wikipedia:
M = E − N + 2P,
where
E = the number of edges of the graph.
N = the number of nodes of the graph.
P = the number of connected components.
so:
9 - 8 + 2*1 = 3

how much time will fibonacci series will take to compute?

i have created the recursive call tree by applying brute force technique but when i give this algorithm 100 values it takes trillion of years to compute..
what you guys suggest me to do that it runs fast by giving 100 values
here is what i have done so far
function fib(n) {
if (n =< 1) {
return n;
} else {
return fib(n - 1) + fib(n - 2);
}
}
You can do it also with a loop:
int a = 1;
int b = 1;
for(int i = 2; i < 100; i++){
int temp = a + b;
a = b;
b = temp;
}
System.out.println("Fib 100 is: "+b);
The runtime is linear and avoids the overhead caused by the recursive calls.
EDIT: Please note that the result is wrong. Since Fib(100) is bigger than Integer.MAX_VALUE you have to use BigInteger or similar to get the correct output but the "logic" will stay the same.
You could have a "cache", where you save already computed Fibonacci numbers. Every time you try to compute
fib(n-1) /* or */ fib(n-2) ;
You would first look into your array of already computed numbers. If it's there, you save a whole lot of time.
So every time you do compute a fibonacci number, save it into your array or list, at the corresponding index.
function fib(n)
{
if (n =< 1)
{
return n;
}
if(fiboList[n] != defaultValue)
{
return fiboList[n];
}
else
{
int fibo = fib(n-1) + fib(n-2);
fiboList[n] = fibo;
return fibo;
}
}
You can also do it by dynamic programming:
def fibo(n):
dp = [0,1] + ([0]*n)
def dpfib(n):
return dp[n-1] + dp[n-2]
for i in range(2,n+2):
dp[i] = dpfib(i)
return dp[n]

Number of possible combinations

How many possible combinations of the variables a,b,c,d,e are possible if I know that:
a+b+c+d+e = 500
and that they are all integers and >= 0, so I know they are finite.
#Torlack, #Jason Cohen: Recursion is a bad idea here, because there are "overlapping subproblems." I.e., If you choose a as 1 and b as 2, then you have 3 variables left that should add up to 497; you arrive at the same subproblem by choosing a as 2 and b as 1. (The number of such coincidences explodes as the numbers grow.)
The traditional way to attack such a problem is dynamic programming: build a table bottom-up of the solutions to the sub-problems (starting with "how many combinations of 1 variable add up to 0?") then building up through iteration (the solution to "how many combinations of n variables add up to k?" is the sum of the solutions to "how many combinations of n-1 variables add up to j?" with 0 <= j <= k).
public static long getCombos( int n, int sum ) {
// tab[i][j] is how many combinations of (i+1) vars add up to j
long[][] tab = new long[n][sum+1];
// # of combos of 1 var for any sum is 1
for( int j=0; j < tab[0].length; ++j ) {
tab[0][j] = 1;
}
for( int i=1; i < tab.length; ++i ) {
for( int j=0; j < tab[i].length; ++j ) {
// # combos of (i+1) vars adding up to j is the sum of the #
// of combos of i vars adding up to k, for all 0 <= k <= j
// (choosing i vars forces the choice of the (i+1)st).
tab[i][j] = 0;
for( int k=0; k <= j; ++k ) {
tab[i][j] += tab[i-1][k];
}
}
}
return tab[n-1][sum];
}
$ time java Combos
2656615626
real 0m0.151s
user 0m0.120s
sys 0m0.012s
The answer to your question is 2656615626.
Here's the code that generates the answer:
public static long getNumCombinations( int summands, int sum )
{
if ( summands <= 1 )
return 1;
long combos = 0;
for ( int a = 0 ; a <= sum ; a++ )
combos += getNumCombinations( summands-1, sum-a );
return combos;
}
In your case, summands is 5 and sum is 500.
Note that this code is slow. If you need speed, cache the results from summand,sum pairs.
I'm assuming you want numbers >=0. If you want >0, replace the loop initialization with a = 1 and the loop condition with a < sum. I'm also assuming you want permutations (e.g. 1+2+3+4+5 plus 2+1+3+4+5 etc). You could change the for-loop if you wanted a >= b >= c >= d >= e.
I solved this problem for my dad a couple months ago...extend for your use. These tend to be one time problems so I didn't go for the most reusable...
a+b+c+d = sum
i = number of combinations
for (a=0;a<=sum;a++)
{
for (b = 0; b <= (sum - a); b++)
{
for (c = 0; c <= (sum - a - b); c++)
{
//d = sum - a - b - c;
i++
}
}
}
This would actually be a good question to ask on an interview as it is simple enough that you could write up on a white board, but complex enough that it might trip someone up if they don't think carefully enough about it. Also, you can also for two different answers which cause the implementation to be quite different.
Order Matters
If the order matters then any solution needs to allow for zero to appear for any of the variables; thus, the most straight forward solution would be as follows:
public class Combos {
public static void main() {
long counter = 0;
for (int a = 0; a <= 500; a++) {
for (int b = 0; b <= (500 - a); b++) {
for (int c = 0; c <= (500 - a - b); c++) {
for (int d = 0; d <= (500 - a - b - c); d++) {
counter++;
}
}
}
}
System.out.println(counter);
}
}
Which returns 2656615626.
Order Does Not Matter
If the order does not matter then the solution is not that much harder as you just need to make sure that zero isn't possible unless sum has already been found.
public class Combos {
public static void main() {
long counter = 0;
for (int a = 1; a <= 500; a++) {
for (int b = (a != 500) ? 1 : 0; b <= (500 - a); b++) {
for (int c = (a + b != 500) ? 1 : 0; c <= (500 - a - b); c++) {
for (int d = (a + b + c != 500) ? 1 : 0; d <= (500 - a - b - c); d++) {
counter++;
}
}
}
}
System.out.println(counter);
}
}
Which returns 2573155876.
One way of looking at the problem is as follows:
First, a can be any value from 0 to 500. Then if follows that b+c+d+e = 500-a. This reduces the problem by one variable. Recurse until done.
For example, if a is 500, then b+c+d+e=0 which means that for the case of a = 500, there is only one combination of values for b,c,d and e.
If a is 300, then b+c+d+e=200, which is in fact the same problem as the original problem, just reduced by one variable.
Note: As Chris points out, this is a horrible way of actually trying to solve the problem.
link text
If they are a real numbers then infinite ... otherwise it is a bit trickier.
(OK, for any computer representation of a real number there would be a finite count ... but it would be big!)
It has general formulae, if
a + b + c + d = N
Then number of non-negative integral solution will be C(N + number_of_variable - 1, N)
#Chris Conway answer is correct. I have tested with a simple code that is suitable for smaller sums.
long counter = 0;
int sum=25;
for (int a = 0; a <= sum; a++) {
for (int b = 0; b <= sum ; b++) {
for (int c = 0; c <= sum; c++) {
for (int d = 0; d <= sum; d++) {
for (int e = 0; e <= sum; e++) {
if ((a+b+c+d+e)==sum) counter=counter+1L;
}
}
}
}
}
System.out.println("counter e "+counter);
The answer in math is 504!/(500! * 4!).
Formally, for x1+x2+...xk=n, the number of combination of nonnegative number x1,...xk is the binomial coefficient: (k-1)-combination out of a set containing (n+k-1) elements.
The intuition is to choose (k-1) points from (n+k-1) points and use the number of points between two chosen points to represent a number in x1,..xk.
Sorry about the poor math edition for my fist time answering Stack Overflow.
Just a test for code block
Just a test for code block
Just a test for code block
Including negatives? Infinite.
Including only positives? In this case they wouldn't be called "integers", but "naturals", instead. In this case... I can't really solve this, I wish I could, but my math is too rusty. There is probably some crazy integral way to solve this. I can give some pointers for the math skilled around.
being x the end result,
the range of a would be from 0 to x,
the range of b would be from 0 to (x - a),
the range of c would be from 0 to (x - a - b),
and so forth until the e.
The answer is the sum of all those possibilities.
I am trying to find some more direct formula on Google, but I am really low on my Google-Fu today...