Imagine that I'm a bakery trying to maximize the number of pies I can produce with my limited quantities of ingredients.
Each of the following pie recipes A, B, C, and D produce exactly 1 pie:
A = i + j + k
B = t + z
C = 2z
D = 2j + 2k
*The recipes always have linear form, like above.
I have the following ingredients:
4 of i
5 of z
4 of j
2 of k
1 of t
I want an algorithm to maximize my pie production given my limited amount of ingredients.
The optimal solution of these example inputs would yield me the following quantities of pies:
2 x A
1 x B
2 x C
0 x D
= a total of 5 pies
I can solve this easily enough by taking the maximal producer of all combinations, but the number
of combos becomes prohibitive as the quantities of ingredients increases. I feel like there must
be generalizations of this type of optimization problem, I just don't know where to start.
While I can only bake whole pies, I would be still be interested in seeing a method which may produce non integer results.
You can define the linear programming problem. I'll show the usage on the example, but it can of course be generalized to any data.
Denote your pies as your variables (x1 = A, x2 = B, ...) and the LP problem will be as follows:
maximize x1 + x2 + x3 + x4
s.t. x1 <= 4 (needed i's)
x1 + 2x4 <= 4 (needed j's)
x1 + 2x4 <= 2 (needed k's)
x2 <= 1 (needed t's)
x2 + 2x3 <= 5 (needed z's)
and x1,x2,x3,x4 >= 0
The fractional solution to this problem is solveable polynomially, but the integer linear programming is NP-Complete.
The problem is indeed NP-Complete, because given an integer linear programming problem, you can reduce the problem to "maximize the number of pies" using the same approach, where each constraint is an ingredient in the pie and the variables are the number of pies.
For the integers problem - there are a lot of approximation techniques in the literature for the problem if you can do with "close up to a certain bound", (for example local ratio technique or primal-dual are often used) or if you need an exact solution - exponential solution is probably your best shot. (Unless of course, P=NP)
Since all your functions are linear, it sounds like you're looking for either linear programming (if continuous values are acceptable) or integer programming (if you require your variables to be integers).
Linear programming is a standard technique, and is efficiently solvable. A traditional algorithm for doing this is the simplex method.
Integer programming is intractable in general, because adding integral constraints allows it to describe intractable combinatorial problems. There seems to be a large number of approximation techniques (for example, you might try just using regular linear programming to see what that gets you), but of course they depend on the specific nature of your problem.
Related
I am trying to solve a special case of Integer Linear Programming Problem, but I seem to be stack on the algorithm.
Specifically, suppose you have some binary variable x_{1}, ... x_{n} and some inequalities of the form:
i.e. x_{2} + x_{3} + x_{10} <= 2
Note, that the coefficients of the inequalities are all unity and the right hand side is always the number of variables in the left hand side minus 1.
Also, remember that the variables x_{1}, ..., x_{n} can take the values of 0 or 1.
This is a homework (to write a program) but I cannot find an algorithm to start.
I tried with DP and Network Flow, but nothing came out.
The objective function (got lost in the edit) is to maximize the sum:
x_{1} + ... + x_{n}
The problem is equivalent to Set Cover: http://en.wikipedia.org/wiki/Set_cover_problem#Integer_linear_program_formulation. One way to see this easily is to replace x_{i} with 1-y{i}, which gives an equivalent 0-1 linear programming problem, namely
maximize (1-y_{1}) + (1-y_{2}) + ... + (1-y_{n}) = n - (y_{1} + ... + y_{n}),
which is equivalent to minimizing y_{1} + ... + y_{n},
subject to the following family of inequalities indexed by j:
(1-y_{i_{1j}}) + (1-y_{i_{2j}}) + ... + (1-y_{i_{kj}) <= k-1,
which are equivalent to:
y_{i_{1j}} + y_{i_{2j}} + ... + y_{i_kj} >= 1
The equivalent formulation of the problem is the 0-1 integer linear programming formulation of Set Cover.
A greedy algorithm will provide a reasonable approximation in this situation. Determine which of the x_{i} appear most often in constraints, and set it equal to 0. All of the constraints in which x_{i0} appears are now satisfied, so they can be removed from consideration, and the variable x_{i0} can be removed from objective. Repeat with the variable x_{i1} which appears most often in the remaining constraints, etc.
Alternatively, real linear programming will also provide an approximation.
Since Set Cover is NP-hard, the best exact solution you will be able to find will be exponential in time. A simple algorithm would just try all possibilities (run through all binary numbers from x_{n}x_{n-1}...x_{1}x_{0} = 00...00 to x_{n}x_{n-1}...x_{1}x_{0} = 11...11 = 2^(n+1)-1. There are surely faster (but still exponential time) algorithms if you search.
This is part of a bigger question. Its actually a mathematical problem. So it would be really great if someone can direct me to any algorithm to obtain the solution of this problem or a pseudo code will be of help.
The question. Given an equation check if it has an integral solution.
For example:
(26a+5)/32=b
Here a is an integer. Is there an algorithm to predict or find if b can be an integer. I need a general solution not specific to this question. The equation can vary. Thanks
Your problem is an example of a linear Diophantine equation. About that, Wikipedia says:
This Diophantine equation [i.e., a x + b y = c] has a solution (where x and y are integers) if and only if c is a multiple of the greatest common divisor of a and b. Moreover, if (x, y) is a solution, then the other solutions have the form (x + k v, y - k u), where k is an arbitrary integer, and u and v are the quotients of a and b (respectively) by the greatest common divisor of a and b.
In this case, (26 a + 5)/32 = b is equivalent to 26 a - 32 b = -5. The gcd of the coefficients of the unknowns is gcd(26, -32) = 2. Since -5 is not a multiple of 2, there is no solution.
A general Diophantine equation is a polynomial in the unknowns, and can only be solved (if at all) by more complex methods. A web search might turn up specialized software for that problem.
Linear Diophantine equations take the form ax + by = c. If c is the greatest common divisor of a and b this means a=z'c and b=z''c then this is Bézout's identity of the form
with a=z' and b=z'' and the equation has an infinite number of solutions. So instead of trial searching method you can check if c is the greatest common divisor (GCD) of a and b
If indeed a and b are multiples of c then x and y can be computed using extended Euclidean algorithm which finds integers x and y (one of which is typically negative) that satisfy Bézout's identity
(as a side note: this holds also for any other Euclidean domain, i.e. polynomial ring & every Euclidean domain is unique factorization domain). You can use Iterative Method to find these solutions:
Integral solution to equation `a + bx = c + dy`
I came across a question where it was asked to find the number of unique ways of reaching from point 1 to point 2 in a 2D co-ordinate plain.
Note: This can be assumed without loss of generality that x1 < x2 and y1 < y2.
Moreover the motions are constrained int he following manner. One can move only right or up. means a valid move is from (xa, ya) to (xb, yb) if xa < xb and ya < yb.
Mathematically, this can be found by ( [(x2-x1)+(y2-y1)]! ) / [(x2-x1)!] * [(y2-y1)!]. I have thought of code too.
I have approaches where I coded with dynamic programming and my approach takes around O([max(x2,y2)]^2) time and Theta( x2 * y2 ) where I can just manage with the upper or lower triangular matrix.
Can you think of some other approaches where running time is less than this? I am thinking of a recursive solution where the minimum running time is O(max(x2,y2)).
A simple efficient solution is the mathematical one.
Let x2-x1 = n and y2-y1 = m.
You need to take exactly n steps to the right, and m steps up, all is left to determine is their order.
This can be modeled as number of binary vectors with n+m elements with exactly n elements set to 1.
Thus, the total number of possibilities is chose(n,n+m) = (n+m)! / (n! * m!), which is exactly what you got.
Given that the mathematical answer is both proven and both faster to calculate - I see no reason for using a different solution with these restrictions.
If you are eager to use recursion here, the recursive formula for binomial coefficient will probably be a good fit here.
EDIT:
You might be looking for the multiplicative formula to calculate it.
To compute the answer, you can use this formula:
(n+m)!/(n!m!)=(n+1)*(n+2)/2*(n+3)/3*…*(n+m)/m
So the pseudo code is:
let foo(n,m) =
ans=1;
for i = 1 to m do
ans = ans*(n+i)/i;
done;
ans
The order of multiplications and divisions is important, if you modify it you can have an overflow even if the result is not so large.
I finally managed to write the article to describe this question in detail and complete the answer as well. Here is the link for the same. http://techieme.in/dynamic-programming-distinct-paths-between-two-points/
try this formula:
ans = (x2-x1) * (y2-y1) + 1;
I've been trying to solve the codechef problem: http://www.codechef.com/MAY11/problems/TPRODUCT/
They have given the post-contest analysis here: http://www.codechef.com/wiki/may-2011-contest-problem-editorials
I need some help in understanding the logic discussed there:
They are talking about using logarithm in place of the function
Pi=max(Vi*PL, Vi*PR)
Math is not my strong area. [I've been trying to improve by participating in contests like this]. If someone can give a very dumbed down explanation for this problem, it would be helpful for mortals like me. Thanks.
One large problem with multiplication is that numbers get very large very fast, and there are issues with reaching the upper bounds of an int or long, and spilling over to the negatives. The logarithm allows us to keep the computations small, and then get the answer back modulo n.
In retracing the result found via dynamic programming, the naive solution is to multiply all the values together and then mod:
(x0 * x1 * x2 * ... * xk) (mod n)
this is replaced with a series of smaller computations, which avoid bound overflow:
z1 = e^(log(x0) + log(x1)) modulo n
z2 = e^(log(x2) + log(z1)) modulo n
...
zk = e^(log(xk) + log(z{k-1})) modulo n
and then zk contains the result.
Presumably, they are relying on the simple mathematical observation that if:
z = y * x
then:
log(z) = log(y) + log(x)
Thus turning multiplications into additions.
You are given a list of distances between various points on a single line.
For example:
100 between a and b
20 between c and b
90 between c and d
170 between a and d
Return the sorted sequence of points as they appear on the line with distances between them:
For example the above input yields:
a<----80-----> c <----20------> b <----70-----> d or the reverse sequence(doesn't matter)
What is this problem called? I would like to research it.
If anybody knows, also, what are some of the possible asymptotic runtimes achieved for this?
not sure it has a name; more formally stated, it would be:
|a-b| = 100
|c-b| = 20
|c-d| = 90
|a-d| = 170
where |x| stands for the absolute value of x
As far as the generalized system goes, if you have N equations of this type with k unknowns, you have N choices of sign. Without loss of generality (because any solution yields a second solution with reversed ordering) you can choose a sign for the first equation, and a particular value for one of the unknowns (since the whole thing can slide left and right in position). Then you have 2N-1 possibilities for the remaining equations, and all you have to do is go through them to see which ones, if any, have solutions. Because the coefficients are all +/- 1 and each equation has 2 unknowns, you just go through them one by one:
Step 1: Without loss of generality,
choose a sign for one equation
and pick a value for one unknown:
a-b = 100, a = 0
Step 2: Choose signs for the remaining absolute values.
a = 0
a-b = 100
c-b = 20
c-d = 90
a-d = 170
Step 3: go through them one by one to solve / verify there aren't conflicts
(time = N steps).
0-b = 100 => b = -100
c-b = 20 => c = -80
c-d = 90 => d = -170
a-d = 170 => OK => (0,-100,-80,-170) is a solution
Step 4: if this doesn't work, go back through the possible choices of sign
and try again, starting at step 2.
Full set of solutions is (0,-100,-80,-170)
and its negation (0,100,80,170) and any number x<sub>0</sub> added to all terms.
So an upper bound for the runtime is O(N * 2N-1) ≡ O(N * 2N).
I suppose there could be a shortcut but no obvious one comes to mind.
As written, your problem is just a system of non-linear equations (expressed with absolute values or quadratic equations). However, it looks similar to the problems of finding Golomb rulers or perfect rulers.
If you consider your constraints as quadratic equations eg. (a-b)^2=100^2, then you can formulate this as a quadratic programming problem and use some of the well-studied techniques for that class of problem.
Considering the sign of the direction of each segment X[i] -> X[i+1] it becomes a boolean satisfiability problem. I can't see an obvious simplification. The runtime is O(2^N) - specifically 2^(N-2) tests with N values and an O(1) expression to test.
Assuming a = 0 and fixing the direction of a -> b:
a = 0
b = 100
c = b + 20 X[0] = 100 + 20 X[0]
d = c + 90 X[1] = 100 + 20 X[0] + 90 X[1]
test d == 170
where X[i] is either +1 or -1.
Although the expression for d appears to require O(N) operations ( (N-2) multiplications and (N-2) additions ), by using a Gray code or other such mechanism for changing the state of only one X at a time so the cost can be O(1) per test. ( though for N=4 it probably isn't worth it )
Simplifications may arise if you either have more constraints than points - if you were given |b-d| == 70, then you only need tests two cases rather than four - essentially b,c and d become their own fully constrained sub-problem.
Simplifications may also arise from the triangular property
| |a-b| - |b-c| | <= |a-c| <= |a-b| + |b-c| for all a, b and c.
So if you have many points, and you know the total of the distances between the points up to a certain point given the assignments made to X, and that total is further from the target value than the total of the distances between the remaining points, you can then deduce that there is no combination of assignments of the remaining points which will work.
algebra...
or it may be a simplification of the traveling salesman problem
I don't have an algorithms book handy, but this sounds like a graph search problem where the paths are constrained. You could probably use Dijkstra's Algorithm or some variant of it.