possible number of rectangle in a matrix - algorithm

I am going through a algorithm of calculating the sum of a region of matrix. And I read a solution to pre-compute the sum to get better result.I want to calculate the possible number of rectangle(sub Maxtix) in a 2d-matrix of size mXn.
Can anybody explain solution using permutation and combination.

Start form the simplest case first:
Start with m x n, thats 1 rectangle.
Reduce n by 1, that gives another 2.
Reduce n by 1, that gives another 3.
Reduce n by 1, that gives another 4.
Do you see the pattern?
When n gets down to 1, subtract 1 from m, and start over:
Start with m-1 x n, thats 2 rectangles.
Reduce n by 1, that gives another 4.
Reduce n by 1, that gives another 6.
Reduce n by 1, that gives another 8.
Are you seeing the pattern yet..?
Now you extrapolate to m-2, m-3, m-4, ..., 1.
Now start form the beginning reducing n first, then n (or simply double all results, except mxn).
And the sum of all those results is your answer.

You can count all rectangles a*b with a,b>=2 by simply choosing which rows and which columns to include (see picture):
C(m,2)*C(n,2)
You can count a*1 rectangles with a>=2 via
C(m,2)*n
and 1*b rectangles with b>=2 via
m*C(n,2)
and 1*1 matrices via:
m*n
so add these for the final answer:
C(m,2)*C(n,2) + C(m,2)*n + m*C(n,2) + m*n

Number of possible Rectangles of any size in an m x n matrix
mn + (m-1)(n-1) + (m-2)(n-1) + .. + (m-m+1)(n-1) + (m-1)(m-2) + .. + (m-m)(n-n)
Sum { i * j } for i in [0,m]; j in [0,n]

It is not an algorithm it is a counting problem.
try to count the amount of rectangulars in a 1X1 matrix and 1X2 2X1 3X2 etc. and then you will see
num_of_rect(mXn) = sum(i*j) for 0<i<m+1; 0<j<n+1
in python:
def countRect(n,m):
return sum([i*j for i in xrange(n+1) for j in xrange(m+1)])
if __name__ == "__main__":
print countRect(2,3)
gives 18

Related

Finding the combination of N numbers that their sum give number R

How it would be possible to find/guess the combination of N numbers such as 5 or 7 or whatever that gives a final number R?
For example, determine N = 5 and R = 15
The one possible result/guess that the 5 numbers in which their summation give 15 would be {1,2,3,4,5}
To get n floating point numbers that total a target r:
Fill an array of size n with random numbers in (0,1).
Find the total of the array. Call this T.
Multiply every element in the array by r/T.
-edit (thanks #ruakh) -
To account for floating point error, total the array again, calculate the delta from target, and update the array to correct for it however you like. This will be a very small number. It's probably fine to update the first element of the array, but if you want you could spread it across the full array.
This can be solved by backtracking, this is really slow, because it looks for all combinations, but if you only want one combination use K-1 0' and N, this sum = N
n = 15
k = 2
array = [0] * k
def comb (len, sum):
if len == k - 1:
array[len] = sum
print(array)
return
for i in range(0, n + 1):
if sum - i >= 0:
array[len] = i
comb(len + 1, sum - i)
comb(0, n)
Python code
import random
N = 5
R = 7
result = random.sample(range(0, int(R)), N-1)
result.append(R - sum(result))

Maximize sum of two numbers plus distance between them

We are given square matrix of numbers, e.g.
1 9 2
3 8 3
2 1 1
The distance between adjacent numbers is 2. We want to find such two numbers, in the same row or in the same column, that their sum plus the distance between them is maximal. For example, in the example above, such numbers are 9 and 8 and the max result is 9+8+1*2 = 19. We want to find just the maximal result, we don't need which specific numbers sum to it.
That looks like a DP problem for me, but I can't think of any elegant solution.
One can solve the 1D problem (that is, given a list of numbers, find the pair which maximizes sum+distance) using dynamic programming.
bi = 0
best = -10**9 # anything large and negative
for i in range(1, n+1):
best = max(best, a[i] + a[bi] + (i - bi)*2)
if a[i] - i*2 > a[bi] - bi*2:
bi = i
After this code finishes, best will store the maximum sum + distance of any pair of numbers in the list. It works because at any given loop iteration of i, bi stores the index of the value at index less than i that maximizes its value minus twice its index. One can observe that the number at this index is the best number (to the left of i) to pair the number at i with.
Once you have this, the 2D problem is straightforward: go through each row and column and apply the 1D algorithm, and return the maximum pair found. Overall for an n by n matrix, this runs in O(n^2) time, which is clearly asymptotically optimal since every element in the matrix needs to be read at least once.
Here is working Python3 code:
def max_sum_dist_1D(a):
bi = 0
best = -10**9
for i in range(1, len(a)):
best = max(best, a[i] + a[bi] + (i - bi)*2)
if a[i] - i*2 > a[bi] - bi*2:
bi = i
return best
def max_sum_dist_2D(M):
best_row = max(max_sum_dist_1D(row) for row in M)
best_col = max(max_sum_dist_1D(col) for col in zip(*M))
return max(best_row, best_col)
M = [[1, 9, 2], [3, 8, 3], [2, 1, 1]]
print(max_sum_dist_2D(M))

Ruby calculate How many different squares are there in a grid of NxN squares?

I worked on ruby exercice to create a method for calculate the square in a grid NxN
like If n = 1, there is one 1-by-1 square = 1.
If n = 3, there is one 3-by-3 square, four 2-by-2 squares and nine 1-by-1 squares = 14.
If we continued the above sequence for an arbitrary n, then we would have one n-by-n square, four (n - 1)-by-(n - 1) squares, nine (n - 2)-by-(n - 2) squares, ... , and n2 1-by-1 squares.
i would like to know how can i do to get this in ruby
Generally for an n x n square grid, the total number of squares is defined by
n² + (n-1)² + (n-2)² + ... + 1.
In Ruby you could do something like this:
class Number
def squares_counter(n)
(1..n).map {|e| e*e }.inject(:+)
end
end
map creates an array of square numbers from 1 to n then inject sums them up. Using this we can calculate the number of squares on a chessboard:
num = Number.new
puts num.squares_counter(8) #=> 204

Algorithm-Find sum in matrix

We are given 2D matrix array (let's say length i and wide j) and integer k
We have to find size of smallest rectangle, that contains this or greater sum
F.e k=7
4 1
1 1
1 1
4 4
Anwser is 2, because 4+4=8 >= 7, if there wasn't last line, anwser would be 4, 4+1+1+1 = 7 >= 7
My idea is to count prefix sums Pref[k,l]=Tab[k,l]+Pref[k-1,l]+Pref[k,l-1]
And then compare every single rectangle
Is this possible to make it faster? My idea is T(n)=O(n^2) (Where n is number of elements in matrix)
I would like to do this in time n or n * log n
I would be really glad if someone would give me any tip how to do this :)
First, create an auxillary matrix: sums, where:
sums[i,j] = A[0,0] + A[0,1] + .... + A[0,j] + A[1,0] + ... + A[1,j] + ... + A[i,j]
I think this is what you meant when you said "prefix matrix".
This can be calculated in linear time with dynamic programming:
sums[0,j] = A[0,0] + ... + A[0,j]
sums[i,0] = A[0,0] + ... + A[i,0]
sums[i,j] = sums[i-1,j] + sums[i,j-1] - sums[i-1,j-1] + A[i,j]
^
elements counted twice
Now, assuming all elements are non negative, this is non decreasing, matrix, where each column and each row are sorted.
So, iterating the matrix again, for each pair of indices i,j, find the value closest yet smaller than sum[i,j]-k.
This can be done in O(sqrt(n)).
Do it for each such (i,j) pair, and you get O(n*sqrt(n)) solution.

Algorithm to find smallest N such that N! is divisible by a prime raised to a power

Is there an efficient algorithm to compute the smallest integer N such that N! is divisible by p^k where p is a relatively small prime number and k, a very large integer. In other words,
factorial(N) mod p^k == 0
If, given N and p, I wanted to find how many times p divides into N!, I would use the well-known formula
k = Sum(floor(N/p^i) for i=1,2,...
I've done brute force searches for small values of k but that approach breaks down very quickly as k increases and there doesn't appear to be a pattern that I can extrapolate to larger values.
Edited 6/13/2011
Using suggestions proposed by Fiver and Hammar, I used a quasi-binary search to solve the problem but not quite in the manner they suggested. Using a truncated version of the second formula above, I computed an upper bound on N as the product of k and p (using just the first term). I used 1 as the lower bound. Using the classic binary search algorithm, I computed the midpoint between these two values and calculated what k would be using this midpoint value as N in the second formula, this time with all the terms being used.
If the computed k was too small, I adjusted the lower bound and repeated. Too big, I first tested to see if k computed at midpoint-1 was smaller than the desired k. If so, midpoint was returned as the closest N. Otherwise, I adjusted the highpoint and repeated.
If the computed k were equal, I tested whether the value at midpoint-1 was equal to the value at midpoint. If so, I adjusted the highpoint to be the midpoint and repeated. If midpoint-1 was less than the desired k, the midpoint was returned as the desired answer.
Even with very large values for k (10 or more digits), this approach works O(n log(n)) speeds.
OK this is kind of fun.
Define f(i) = (p^i - 1) / (p - 1)
Write k in a kind of funny "base" where the value of position i is this f(i).
You do this from most-significant to least-significant digit. So first, find the largest j such that f(j) <= k. Then compute the quotient and remainder of k / f(j). Store the quotient as q_j and the remainder as r. Now compute the quotient and remainder of r / f(j-1). Store the quotient as q_{j-1} and the remainder as r again. Now compute the quotient and remainder of r / f(j-2). And so on.
This generates a sequence q_j, q_{j-1}, q_{j-2}, ..., q_1. (Note that the sequence ends at 1, not 0.) Then compute q_j*p^j + q_{j-1}*p^(j-1) + ... q_1*p. That's your N.
Example: k = 9, p = 3. So f(i) = (3^i - 1) / 2. f(1) = 1, f(2) = 4, f(3) = 13. So the largest j with f(j) <= 9 is i = 2 with f(2) = 4. Take the quotient and remainder of 9 / 4. That's a quotient of 2 (which is the digit in our 2's place) and remainder of 1.
For that remainder of 1, find the quotient and remainder of 1 / f(1). Quotient is 1, remainder is zero, so we are done.
So q_2 = 2, q_1 = 1. 2*3^2 + 1*3^1 = 21, which is the right N.
I have an explanation on paper for why this works, but I am not sure how to communicate it in text... Note that f(i) answers the question, "how many factors of p are there in (p^i)!". Once you find the largest i,j such that j*f(i) is less than k, and realize what you are really doing is finding the largest j*p^i less than N, the rest kind of falls out of the wash. In our p=3 example, for instance, we get 4 p's contributed by the product of 1-9, 4 more contributed by the product of 10-18, and one more contributed by 21. Those first two are just multiples of p^2; f(2) = 4 is telling us that each multiple of p^2 contributes 4 more p's to the product.
[update]
Code always helps to clarify. Save the following perl script as foo.pl and run it as foo.pl <p> <k>. Note that ** is Perl's exponentiation operator, bdiv computes a quotient and remainder for BigInts (unlimited-precision integers), and use bigint tells Perl to use BigInts everywhere.
#!/usr/bin/env perl
use warnings;
use strict;
use bigint;
#ARGV == 2
or die "Usage: $0 <p> <k>\n";
my ($p, $k) = map { Math::BigInt->new($_) } #ARGV;
sub f {
my $i = shift;
return ($p ** $i - 1) / ($p - 1);
}
my $j = 0;
while (f($j) <= $k) {
$j++;
}
$j--;
my $N = 0;
my $r = $k;
while ($r > 0) {
my $val = f($j);
my ($q, $new_r) = $r->bdiv($val);
$N += $q * ($p ** $j);
$r = $new_r;
$j--;
}
print "Result: $N\n";
exit 0;
Using the formula you mentioned, the sequence of k values given fixed p and N = 1,2... is non-decreasing. This means you can use a variant of binary search to find N given the desired k.
Start with N = 1, and calculate k.
Double N until k is greater or equal than your desired k to get an upper bound.
Do a binary search on the remaining interval to find your k.
Why don't you try binary search for the answer, using the second formula you mentioned?
You only need to consider values for N, for which p divides N, because if it doesn't, then N! and (N-1)! are divided by the same power of p, so N can't be the smallest one.
Consider
I = (pn)!
and ignore prime factors other than p. The result looks like
I = pn * pn-1 * pn-2 * ... * p * 1
I = pn + (n-1) + (n-2) + ... 2 + 1
I = p(n2 +n)/2
So we're trying to find the smallest n such that
(n2 +n)/2 >= k
which if I remember the quadratic equation right gives us
N = pn, where n >= (sqrt(1+8k) -1)/2
(P.S. Does anyone know how to show the radical symbol in markdown?)
EDIT:
This is wrong. Let me see if I can salvage it...

Resources