how to compute the compound probability of multiple independent events? - probability

for example, I have 7 customer bookings in a day, each with an independent probability of show up. So what is the probability of only 1 customer show up? only 2 customers show up? only 3 customers show up? etc. How to compute this type of problem, is there any generalized equation or formula ?
Customer
Probability of show up
Probability of not show up
A
0.3
0.7
B
0.4
0.6
C
0.5
0.5
D
0.6
0.4
E
0.7
0.3
F
0.8
0.2

I don't know of any formula, but you can calculate the probabilities of n customers turning up like this:
Let p[i] be the probability of customer i turning up.
Let Q( N, n) be the probability that, if we consider just customers 0,..N-1, then n of them turn up.
We have
Q( 1, 0) = 1.0-p[0]
Q( 1, 1) = p[0]
And
Q( N+1, 0) = (1.0-p[N])*Q(N, 0)
for i=1..N
Q( N+1, i) = (1.0-p[N])*Q(N, i) + p[N]*Q(N, i-1)
Q( N+1, N+1) = p[N]*Q(N, N)
For example, there are two mutually exclusive ways that i of customers 0..N can turn up: either customer N doesn't turn up and i of 0..N-1 do, or N does turn up and i-1 of 0..N-1 do

Related

Get all the possible permutations and combinations given min and max number

I have suppose two places: -,- .Each of these place has a max limit. Such as first place has max limit of 3 and 2nd place has max limit of 7.
I have other 2 numbers which is totalmaxlimit and other is totalminlimit.
Ex; totalmaxlimit = 6
totalminlimit = 3
I want to write a code where I can fill above two places with all possible permutation and combinations such that the sum of three places is greater than equal to 3 and less than equal to 6.
Example:
3 0
3 1
2 0
2 1
2 4
Also,
2 6 will be wrong result because sum is greater than totalmaxlimit.
4 2 is also wrong as first place has max limit of 3.
Code in any language is fine. Thanks in advance.
Let's assume that:
1) The place is given by A, B coordinates
2) You have a totalMin (m) and a totalMax (M)
3) The rules are that A, B, and A+B should be >= m and <=M
4) The amount of values is given by the equation M-m. (e.g, if M =10 and m=0, we will have 10 valid values).
You can get a permutation by using the formula P = n! / (n-k)! where N is you number of values, and k is the valid numbers you can have.
So, for example, if m = 0, M = 6:
Permutations = (0,6) , (1,5), (2,4), etc...
Basically you have the sum of (X_n, X_M) where, when n grows, M decreases. M = M - n
I hope this helps for now, but I can provide a more 'profissional' formula if you like. The language could be python because I think it would be easier. But first you need to get the algorithm, passing it to code is trivial.
Here's the code:
def permutations(min, max):
# init variables
m = min
M = max
results = []
# main loop
for i in range(min, max):
for j in range(min, max):
if ((i + j) >= min and (i+j) <= max ):
results.append([i, j])
print(results)

Need help in solving the following efficiently in terms of time complexity

I am trying to solve the problem below for the last two days. I can't think of any solution for it other than brute force. Any kind of hints or references will be appreciated. TIA.
"Given N distinct prime integers i.e p1, p2,..., pN and an interval [L,R]. Calculate the number of integers in this interval that are divisible by at least one of the given primes."
N is very small (1<=N<=10) and L,R are very big (1<=L<=R<=10^10)
First note, it's easier to restrict the problem, and ignore the lower bound (ie: treat L=1). If we can count numbers divisible by the primes <= N for any N, we can also count them on an interval, by subtracting the count of numbers <= L-1 from the count <= R.
Given any number x, the count of numbers <= R divisible by x is floor(R / x).
Now, we can apply the inclusion-exclusion principle to get the result. First, I'll show the results by hand for 3 primes p1, p2 and p3, and then give the general result.
The count of numbers <= R divisible by p1, p2 or p3 is:
R / p1 + R / p2 + R / p3
- R / (p1p2) - R / (p1p3) - R / (p2p3)
+ R / (p1p2p3)
(Here / is assumed to be rounding-down integer division).
The general case is as follows:
sum((-1)^(|S|+1) * R / prod(S) for S a non-empty subset of {p1, p2, .., pN}).
Here S ranges over all subsets of your primes, prod(S) is the product of the primes in the subset, and the initial term varies between -1 and +1 depending on the size of the subset.
For your problem, N<=10, so there's 1023 non-empty subsets which a small number of things to iterate over.
Here's some example Python code:
from itertools import *
def powerset(iterable):
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
def prod(ns):
r = 1
for n in ns:
r *= n
return r
def divs(primes, N):
r = 0
for S in powerset(primes):
if not S: continue
sign = 1 if len(S) % 2 else -1
r += sign * (N // prod(S))
return r
def divs_in_range(primes, L, R):
return divs(primes, R) - divs(primes, L-1)
Note, that the running time of this code is more-or-less only dependent on the number of primes, and not so much on the magnitudes of L and R.
Assuming n is the interval size and N is const.
For each prime p, there should be roughly (R-L) / p numbers in the interval divisible by the prime.
Finding the first number divisible by p in interval: L' = L + (p - L % p).
Now if L' > R, there is none; otherwise there are 1 + floor((R-L') / p).
Example: 3, [10, 20]:
L' = 10 + 3 - 10 % 3 = 12.
Numbers divisible by 3 in the interval: 1 + floor((20 - 12) / 3) = 3
Note: So far we haven't used the fact that p1..pN are primes.
Remaining problem seems to be: How to avoid counting a number divisible by multiple primes multiple times? Example: Assuming we have 3,5 and [10, 20], we need to avoid counting 15 twice...
Maybe we can just count divisibility by (p1*p2) etc. using the counting algorithm above, and reduce the total accordingly? If N ist const, this should still be const time. Because p1...pN are prime, all their products need to be different (as any number can't have more than one prime factorizations).

Pyramids dynamic programming

I encountered this question in an interview and could not figure it out. I believe it has a dynamic programming solution but it eludes me.
Given a number of bricks, output the total number of 2d pyramids possible, where a pyramid is defined as any structure where a row of bricks has strictly less bricks than the row below it. You do not have to use all the bricks.
A brick is simply a square, the number of bricks in a row is the only important bit of information.
Really stuck with this one, I thought it would be easy to solve each problem 1...n iteratively and sum. But coming up with the number of pyramids possible with exactly i bricks is evading me.
example, n = 6
X
XX
X
XX XXX
X
XXX XXXX
XX X
XXX XXXX XXXXX
X
XX XX X
XXX XXXX XXXXX XXXXXX
So the answer is 13 possible pyramids from 6 bricks.
edit
I am positive this is a dynamic programming problem, because it makes sense to (once you've determined the first row) simply look to the index in your memorized array of your remainder of bricks to see how many pyramids fit atop.
It also makes sense to consider bottom rows of width at least n/2 because we can't have more bricks atop than on the bottom row EXCEPT and this is where I lose it and my mind falls apart, in certain (few cases) you can I.e. N = 10
X
XX
XXX
XXXX
Now the bottom row has 4 but there are 6 left to place on top
But with n = 11 we cannot have a bottom row with less than n/2 bricks. There is another wierd inconsistency like that with n = 4 where we cannot have a bottom row of n/2 = 2 bricks.
Let's choose a suitable definition:
f(n, m) = # pyramids out of n bricks with base of size < m
The answer you are looking for now is (given that N is your input number of bricks):
f(N, N+1) - 1
Let's break that down:
The first N is obvious: that's your number of bricks.
Your bottom row will contain at most N bricks (because that's all you have), so N+1 is a sufficient lower bound.
Finally, the - 1 is there because technically the empty pyramid is also a pyramid (and will thus be counted) but you exclude that from your solutions.
The base cases are simple:
f(n, 0) = 1 for any n >= 0
f(0, m) = 1 for any m >= 0
In both cases, it's the empty pyramid that we are counting here.
Now, all we need still is a recursive formula for the general case.
Let's assume we are given n and m and choose to have i bricks on the bottom layer. What can we place on top of this layer? A smaller pyramid, for which we have n - i bricks left and whose base has size < i. This is exactly f(n - i, i).
What is the range for i? We can choose an empty row so i >= 0. Obviously, i <= n because we have only n bricks. But also, i <= m - 1, by definition of m.
This leads to the recursive expression:
f(n, m) = sum f(n - i, i) for 0 <= i <= min(n, m - 1)
You can compute f recursively, but using dynamic programming it will be faster of course. Storing the results matrix is straightforward though, so I leave that up to you.
Coming back to the original claim that f(N, N+1)-1 is the answer you are looking for, it doesn't really matter which value to choose for m as long as it is > N. Based on the recursive formula it's easy to show that f(N, N + 1) = f(N, N + k) for every k >= 1:
f(N, N + k) = sum f(N - i, i) for 0 <= i <= min(N, N + k - 1)
= sum f(N - i, i) for 0 <= i <= N
= sum f(N - i, i) for 0 <= i <= min(N, N + 1 - 1)
In how many ways can you build a pyramid of width n? By putting any pyramid of width n-1 or less anywhere atop the layer of n bricks. So if p(n) is the number of pyramids of width n, then p(n) = sum [m=1 to n-1] (p(m) * c(n, m)), where c(n, m) is the number of ways you can place a layer of width m atop a layer of width n (I trust that you can work that one out yourself).
This, however, doesn't place a limitation on the number of bricks. Generally, in DP, any resource limitation must be modeled as a separate dimension. So your problem is now p(n, b): "How many pyramids can you build of width n with a total of b bricks"? In the recursive formula, for each possible way of building a smaller pyramid atop your current one, you need to refer to the correct amount of remaining bricks. I leave it as a challenge for you to work out the recursive formula; let me know if you need any hints.
You can think of your recursion as: given x bricks left where you used n bricks on last row, how many pyramids can you build. Now you can fill up rows from either top to bottom row or bottom to top row. I will explain the former case.
Here the recursion might look something like this (left is number of bricks left and last is number of bricks used on last row)
f(left,last)=sum (1+f(left-i,i)) for i in range [last+1,left] inclusive.
Since when you use i bricks on current row you will have left-i bricks left and i will be number of bricks used on this row.
Code:
int calc(int left, int last) {
int total=0;
if(left<=0) return 0; // terminal case, no pyramid with no brick
for(int i=last+1; i<=left; i++) {
total+=1+calc(left-i,i);
}
return total;
}
I will leave it to you to implement memoized or bottom-up dp version. Also you may want to start from bottom row and fill up upper rows in pyramid.
Since we are asked to count pyramids of any cardinality less than or equal to n, we may consider each cardinality in turn (pyramids of 1 element, 2 elements, 3...etc.) and sum them up. But in how many different ways can we compose a pyramid from k elements? The same number as the count of distinct partitions of k (for example, for k = 6, we can have (6), (1,5), (2,4), and (1,2,3)). A generating function/recurrence for the count of distinct partitions is described in Wikipedia and a sequence at OEIS.
Recurrence, based on the Pentagonal number Theorem:
q(k) = ak + q(k − 1) + q(k − 2) − q(k − 5) − q(k − 7) + q(k − 12) + q(k − 15) − q(k − 22)...
where ak is (−1)^(abs(m)) if k = 3*m^2 − m for some integer m and is 0 otherwise.
(The subtracted coefficients are generalized pentagonal numbers.)
Since the recurrence described in Wikipedia obliges the calculation of all preceding q(n)'s to arrive at a larger q(n), we can simply sum the results along the way to obtain our result.
JavaScript code:
function numPyramids(n){
var distinctPartitions = [1,1],
pentagonals = {},
m = _m = 1,
pentagonal_m = 2,
result = 1;
while (pentagonal_m / 2 <= n){
pentagonals[pentagonal_m] = Math.abs(_m);
m++;
_m = m % 2 == 0 ? -m / 2 : Math.ceil(m / 2);
pentagonal_m = _m * (3 * _m - 1);
}
for (var k=2; k<=n; k++){
distinctPartitions[k] = pentagonals[k] ? Math.pow(-1,pentagonals[k]) : 0;
var cs = [1,1,-1,-1],
c = 0;
for (var i in pentagonals){
if (i / 2 > k)
break;
distinctPartitions[k] += cs[c]*distinctPartitions[k - i / 2];
c = c == 3 ? 0 : c + 1;
}
result += distinctPartitions[k];
}
return result;
}
console.log(numPyramids(6)); // 13

Algorithm for calculating total cost in groups of N

I have a limited supply of objects and as the objects are purchased, the price goes up accordingly in groups of N (every time N objects are bought, price increases). When trying to purchase a number of objects, what is the easiest way to calculate total cost?
Example:
I have 24 foo. For every N(example using 3) that are purchased, the price increases by 1.
So if I buy 1 at the prices of 1 then there are 23 left and 2 left at the price of 1.
After 1 has been purchased, someone wishes to buy 6. Well the total cost would be = (2*1)+(3*2)+(1*3)
Borrowing RBarryYoung's notation, the first N items cost B each, the second N items cost B + I each, the third N items cost B + 2*I each, etc.
To buy X items: Q := X div N (floor division) whole groups are bought, plus R := X mod N extra items. The former cost Q * N * (B + (B + (Q - 1) * I)) / 2, since, with linearly increasing item costs, the average item cost is equal to the average of first item cost, B, and the last item cost, B + (Q - 1) * I. The latter items cost R * (B + Q*I), so the resulting function f(X) is
f(X) := (Q * N * (B + (B + (Q - 1) * I))) div 2 + R * (B + Q*I).
To compute the cost of the items (zero-)indexed from X inclusive to X' exclusive, use f(X') - f(X).
OK, I think that this is correct now...
Given:
X = Total Number of Items Bought
N = Number of Items per Price Increment
B = Base Item Price, before any Increments
I = Price Increment per [N]
Set:
J = FLOOR((X-1)/N)+1
Then:
TotalCost = X*(B-I) + I*(X*J - N*J*(J-1)/2)

Algorithm to partition a number

Given a positive integer X, how can one partition it into N parts, each between A and B where A <= B are also positive integers? That is, write
X = X_1 + X_2 + ... + X_N
where A <= X_i <= B and the order of the X_is doesn't matter?
If you want to know the number of ways to do this, then you can use generating functions.
Essentially, you are interested in integer partitions. An integer partition of X is a way to write X as a sum of positive integers. Let p(n) be the number of integer partitions of n. For example, if n=5 then p(n)=7 corresponding to the partitions:
5
4,1
3,2
3,1,1
2,2,1
2,1,1,1
1,1,1,1,1
The the generating function for p(n) is
sum_{n >= 0} p(n) z^n = Prod_{i >= 1} ( 1 / (1 - z^i) )
What does this do for you? By expanding the right hand side and taking the coefficient of z^n you can recover p(n). Don't worry that the product is infinite since you'll only ever be taking finitely many terms to compute p(n). In fact, if that's all you want, then just truncate the product and stop at i=n.
Why does this work? Remember that
1 / (1 - z^i) = 1 + z^i + z^{2i} + z^{3i} + ...
So the coefficient of z^n is the number of ways to write
n = 1*a_1 + 2*a_2 + 3*a_3 +...
where now I'm thinking of a_i as the number of times i appears in the partition of n.
How does this generalize? Easily, as it turns out. From the description above, if you only want the parts of the partition to be in a given set A, then instead of taking the product over all i >= 1, take the product over only i in A. Let p_A(n) be the number of integer partitions of n whose parts come from the set A. Then
sum_{n >= 0} p_A(n) z^n = Prod_{i in A} ( 1 / (1 - z^i) )
Again, taking the coefficient of z^n in this expansion solves your problem. But we can go further and track the number of parts of the partition. To do this, add in another place holder q to keep track of how many parts we're using. Let p_A(n,k) be the number of integer partitions of n into k parts where the parts come from the set A. Then
sum_{n >= 0} sum_{k >= 0} p_A(n,k) q^k z^n = Prod_{i in A} ( 1 / (1 - q*z^i) )
so taking the coefficient of q^k z^n gives the number of integer partitions of n into k parts where the parts come from the set A.
How can you code this? The generating function approach actually gives you an algorithm for generating all of the solutions to the problem as well as a way to uniformly sample from the set of solutions. Once n and k are chosen, the product on the right is finite.
Here is a python solution to this problem, This is quite un-optimised but I have tried to keep it as simple as I can to demonstrate an iterative method of solving this problem.
The results of this method will commonly be a list of max values and min values with maybe 1 or 2 values inbetween. Because of this, there is a slight optimisation in there, (using abs) which will prevent the iterator constantly trying to find min values counting down from max and vice versa.
There are recursive ways of doing this that look far more elegant, but this will get the job done and hopefully give you an insite into a better solution.
SCRIPT:
# iterative approach in-case the number of partitians is particularly large
def splitter(value, partitians, min_range, max_range, part_values):
# lower bound used to determine if the solution is within reach
lower_bound = 0
# upper bound used to determine if the solution is within reach
upper_bound = 0
# upper_range used as upper limit for the iterator
upper_range = 0
# lower range used as lower limit for the iterator
lower_range = 0
# interval will be + or -
interval = 0
while value > 0:
partitians -= 1
lower_bound = min_range*(partitians)
upper_bound = max_range*(partitians)
# if the value is more likely at the upper bound start from there
if abs(lower_bound - value) < abs(upper_bound - value):
upper_range = max_range
lower_range = min_range-1
interval = -1
# if the value is more likely at the lower bound start from there
else:
upper_range = min_range
lower_range = max_range+1
interval = 1
for i in range(upper_range, lower_range, interval):
# make sure what we are doing won't break solution
if lower_bound <= value-i and upper_bound >= value-i:
part_values.append(i)
value -= i
break
return part_values
def partitioner(value, partitians, min_range, max_range):
if min_range*partitians <= value and max_range*partitians >= value:
return splitter(value, partitians, min_range, max_range, [])
else:
print ("this is impossible to solve")
def main():
print(partitioner(9800, 1000, 2, 100))
The basic idea behind this script is that the value needs to fall between min*parts and max*parts, for each step of the solution, if we always achieve this goal, we will eventually end up at min < value < max for parts == 1, so if we constantly take away from the value, and keep it within this min < value < max range we will always find the result if it is possable.
For this code's example, it will basically always take away either max or min depending on which bound the value is closer to, untill some non min or max value is left over as remainder.
A simple realization you can make is that the average of the X_i must be between A and B, so we can simply divide X by N and then do some small adjustments to distribute the remainder evenly to get a valid partition.
Here's one way to do it:
X_i = ceil (X / N) if i <= X mod N,
floor (X / N) otherwise.
This gives a valid solution if A <= floor (X / N) and ceil (X / N) <= B. Otherwise, there is no solution. See proofs below.
sum(X_i) == X
Proof:
Use the division algorithm to write X = q*N + r with 0 <= r < N.
If r == 0, then ceil (X / N) == floor (X / N) == q so the algorithm sets all X_i = q. Their sum is q*N == X.
If r > 0, then floor (X / N) == q and ceil (X / N) == q+1. The algorithm sets X_i = q+1 for 1 <= i <= r (i.e. r copies), and X_i = q for the remaining N - r pieces. The sum is therefore (q+1)*r + (N-r)*q == q*r + r + N*q - r*q == q*N + r == X.
If floor (X / N) < A or ceil (X / N) > B, then there is no solution.
Proof:
If floor (X / N) < A, then floor (X / N) * N < A * N, and since floor(X / N) * N <= X, this means that X < A*N, so even using only the smallest pieces possible, the sum would be larger than X.
Similarly, if ceil (X / N) > B, then ceil (X / N) * N > B * N, and since ceil(X / N) * N >= X, this means that X > B*N, so even using only the largest pieces possible, the sum would be smaller than X.

Resources