Find equation based on known x and answers - algorithm

So basically I have something like this
[always 8 numbers]
5-->10
2-->4
9-->18
7-->14
I know four x and the answers for that four x. I need to find equation so it fits for all of those x and their answers. I know there is infinite number of equations possible, but I would like to solve for shortest ones if possible.
For this example
x*2 or x+x fits the best
of course something like this x*3-x and infinite number of other equations works also but they're not most optimal ones like x*2
Any ideas, theories or algorithms that solve similar problem?

Using the numbers you provided:
5-->10
2-->4
9-->18
7-->14
You want to find a, b, c and d that solve the system defined by:
ax^3 + bx^2 + cx + d = f(x)
So, in your case it is:
125a + 25b + 5c + d = 10
8a + 4b + 2c + d = 4
729a + 81b + 9c + d = 18
343a + 49b + 7c + d = 14
If you solve the system you'll find that (a,b,c,d) must be (0, 0, 2, 0). So, the minimum polynomial is 2x.
I made a website some time ago that solves this:
http://juanlopes.net/actually42/#5%2010%202%204%209%2018%207%2014/true/true

If your goal is to fit the data to a polynomial function, i.e. something like:
f(x) = a_0 + a_1*x + a_2*x^2 + ... + a_n*x^n where each a_i is a real (or complex) number,
then there is some theory available as to when it is possible to put all those points on a single curve. What you can do is pick a degree (the highest power of x) and then write down a system of equations and solve the system (or try to solve it). For example, if the degree is 2, then your data become:
10 = a_0 + a_1*5 + a_2*5^2
4 = a_0 + a_1*2 + a_2*2^2
etc
If you are able to solve the system, then great. If not, you need a larger degree. Solving the system can be done (built in) in many languages via matrix multiplication. You may want to start out by saying: can my data all fit on a polynomial of degree 1? if yes, done. If not, does it fit on degree 2 polynomial? if yes, done. If not, degree 3, etc. Be careful though, because in general you may have data that you cannot fit "exactly" to a polynomial (or any function for that matter). If you just want a low degree polynomial that is very close, then you want to look into polynomial regression (which will give you a best fit polynomial), see: http://en.wikipedia.org/wiki/Polynomial_regression

Related

0-1 Knapsack with penalty for under and overweight cases

Assume a classic 0-1 knapsack problem but you are allowed to overflow/underflow the sack with some penalty. X profit is deducted for every unit overflow (weight above max capacity) and Y profit is deducted for every unit underflow (weight below max capacity).
I thought of sorting all items by the ratio of profit to weight and then try to fill the sack like a normal knapsack problem then for remaining weight and items I calculate extra profit by taking the underflow, overflow in consideration.
This solution fails in some cases like when there are 3 items with weight 30,20,10 and profit 30, 25, 20 respectively. Max weight allowed is 39, underflow penalty is 5 and overflow penalty is 10.
My solution was to solve it like normal knapsack then considering penalties so it gives the solution of selecting items of weight 20,10 but then it does not add the item of weight 30 as its penalty is higher than profit. The optimal solution should be selection items of weight 30 and 10. The only thing I can think of now is to brute force which should be avoided if possible. If anyone could think of any other solution, that'd be great!
You can break it into two subproblems, one with an underweight penalty and one with an overweight penalty. More specifically, you can solve the problem by solving two different integer linear programming problems, and taking the best of the two solutions:
Say that you have n items of weights w1,w2,...,wn and values v1, v2, ..., vn. Say that the weight capacity is C, the penalty for undeweight is A and the penality for overweight is B (per unit).
In both problems, let the binary decision variable be x1, ..., xn indicating whether or not the corresponding item is selected.
Problem 1)
max v1*x1 + v2*x2 + ... + vn*xn - A*(C - w1*x1 - w2*x2 - ... - wn*xn)
subject to
w1*x1 + w2*x2 + ... + wn*xn <= C
Note that via algebra the objective function is the same as the affine expression
(v1 + A*w1)*x1 + ... + (vn + A*wn)*xn - A*C
and is maximized at the same values x1, ..., xn which maximize the purely linear function
(v1 + A*w1)*x1 + ... + (vn + A*wn)*xn
This subproblem can be solved using any ILP solver, or just as an ordinary knapsack problem.
Problem 2)
max v1*x1 + v2*x2 + ... + vn*xn - B*(w1*x1 + w2*x2 + ... + wn*xn - C)
subject to
w1*x1 + w2*x2 + ... + wn*xn >= C
which can be solved by maximizing the linear objective function
(v1 - B*w1)*x1 + ... + (vn - B*wn)*xn
Again, that can be solved with any ILP solver. This problem isn't a knapsack problem since the inequality in the main constraint points in the wrong direction, though there might be some way of reducing it to a knapsack problem.
On Edit. The second problem can also be solved as a knapsack problem -- one in which you decide which items to not include. Start with the solution in which you include everything. If this isn't feasible (if the sum of all weights doesn't exceed the capacity) then you are done. The solution of problem 1 is the global solution. Otherwise. Define the surplus, S, to be
S = w1 + w2 + ... + wn - C
Now, solve the following knapsack problem:
weights: w1, w2, ..., wn //same as before
values: Bw1 - v1, Bw2 - v2, ..., BWn - vn
capacity: S
A word on the values: Bwi - vi is a measure of how much removing the ith object helps (under the assumption that removing it keeps you above the original capacity so that you don't need to consider the underweight penalties). On the one hand, it removes part of the penalty, Bwi, but on the other hand it takes some value away, vi.
After you solve this knapsack problem -- remove these items. The remaining items are the solution for problem 2.
Lets see how this plays out for your toy problem:
weights: 30, 20, 10
values: 20, 25, 20
C: 39
A: 5 //per-unit underflow penalty
B: 10 //per-unit overflow penalty
For problem 1, solve the following knapsack problem:
weights: 30, 20, 10
values: 170, 125, 70 // = 20 + 5*30, 25 + 5*20, 20 + 5*10
C: 39
This has solution: include 20, 10 with value of 195. In terms of the original problem this has value 195 - 5*39 = 0. That seems a bit weird, but in terms of the original problem the value of using the last two items is 25 + 20 = 45 but it leaves you 9 units under with a penalty of 5*9 = 45 and 45 - 45 = 0
Second problem:
weights: 30, 20, 10
values: 280, 175, 80 // = 10*30 - 20, 10*20 - 25, 10*10 - 20
S: 26 // = 30 + 20 + 10 - 39
The solution of this problem is clearly to select 20. This means that 20 is selected for non-inclusion. This means that for the second problem I want to include the objects of weights 30 and 10.
The value of doing so is (in terms of the original problem)
20 + 20 - 10*1 = 30
Since 30 > 0 (the value of solution 1), this is the overall optimal solution.
To sum up: you can solve your version of the knapsack problem by solving two ordinary knapsack problems to find two candidate solutions and then taking the better of the two. If you already have a function to solve knapsack problems, it shouldn't be too hard to write another function which calls it twice, interprets the outputs, and returns the best solution.
You can still use standard dynamic programming.
Let's compute whether the sum s is reachable for all s from 0 to the sum of all elements of the array. That's exactly what a standard dynamic programming solution does. We don't care about penalty here.
Let's iterate over all reachable sums and choose the best one taking into account the penalty for over(or under)flow.

Math function with three variables (correlation)

I want to analyse some data in order to program a pricing algorithm.
Following dates are available:
I need a function/correlationfactor of the three variables/dimension which show the change of the Median (price) while the three dimensions (pers_capacity, amount of bedrooms, amount of bathrooms) grow.
e.g. Y(#pers_capacity,bedroom,bathroom) = ..
note:
- in the screenshot below are not all the data available (just a part of it)
- median => price per night
- yellow => #bathroom
e.g. For 2 persons, 2 bedrooms and 1 bathroom is the median price 187$ per night
Do you have some ideas how I can calculate the correlation/equation (f(..)=...) in order to get a reliable factor?
Kind regards
One typical approach would be formulating this as a linear model. Given three variables x, y and z which explain your observed values v, you assume v ≈ ax + by + cz + d and try to find a, b, c and d which match this as closely as possible, minimizing the squared error. This is called a linear least squares approximation. You can also refer to this Math SE post for one example of a specific linear least squares approximation.
If your your dataset is sufficiently large, you may consider more complicated formulas. Things like
v ≈
a1x2 +
a2y2 +
a3z2 +
a4xy +
a5xz +
a6yz +
a7x +
a8y +
a9z +
a10
The above is non-linear in the variables but still linear in the coefficients ai so it's still a linear least squares problem.
Or you could apply transformations to your variables, e.g.
v ≈
a1x +
a2y +
a3z +
a4exp(x) +
a5exp(y) +
a6exp(z) +
a7
Looking at the residual errors (i.e. difference between predicted and observed values) in any of these may indicate terms worth adding.
Personally I'd try all this in R, since computing linear models is just one line in that language, and visualizing data is fairly easy as well.

convert real number to radicals

Suppose I have a real number. I want to approximate it with something of the form a+sqrt(b) for integers a and b. But I don't know the values of a and b. Of course I would prefer to get a good approximation with small values of a and b. Let's leave it undefined for now what is meant by "good" and "small". Any sensible definitions of those terms will do.
Is there a sane way to find them? Something like the continued fraction algorithm for finding fractional approximations of decimals. For more on the fractions problem, see here.
EDIT: To clarify, it is an arbitrary real number. All I have are a bunch of its digits. So depending on how good of an approximation we want, a and b might or might not exist. Brute force is naturally not a particularly good algorithm. The best I can think of would be to start adding integers to my real, squaring the result, and seeing if I come close to an integer. Pretty much brute force, and not a particularly good algorithm. But if nothing better exists, that would itself be interesting to know.
EDIT: Obviously b has to be zero or positive. But a could be any integer.
No need for continued fractions; just calculate the square-root of all "small" values of b (up to whatever value you feel is still "small" enough), remove everything before the decimal point, and sort/store them all (along with the b that generated it).
Then when you need to approximate a real number, find the radical whose decimal-portion is closet to the real number's decimal-portion. This gives you b - choosing the correct a is then a simple matter of subtraction.
This is actually more of a math problem than a computer problem, but to answer the question I think you are right that you can use continued fractions. What you do is first represent the target number as a continued fraction. For example, if you want to approximate pi (3.14159265) then the CF is:
3: 7, 15, 1, 288, 1, 2, 1, 3, 1, 7, 4 ...
The next step is create a table of CFs for square roots, then you compare the values in the table to the fractional part of the target value (here: 7, 15, 1, 288, 1, 2, 1, 3, 1, 7, 4...). For example, let's say your table had square roots for 1-99 only. Then you would find the closest match would be sqrt(51) which has a CF of 7: 7,14 repeating. The 7,14 is the closest to pi's 7,15. Thus your answer would be:
sqrt(51)-4
As the closest approximation given a b < 100 which is off by 0.00016. If you allow larger b's then you could get a better approximation.
The advantage of using CFs is that it is faster than working in, say, doubles or using floating point. For example, in the above case you only have to compare two integers (7 and 15), and you can also use indexing to make finding the closest entry in the table very fast.
This can be done using mixed integer quadratic programming very efficiently (though there are no run-time guarantees as MIQP is NP-complete.)
Define:
d := the real number you wish to approximate
b, a := two integers such that a + sqrt(b) is as "close" to d as possible
r := (d - a)^2 - b, is the residual of the approximation
The goal is to minimize r. Setup your quadratic program as:
x := [ s b t ]
D := | 1 0 0 |
| 0 0 0 |
| 0 0 0 |
c := [0 -1 0]^T
with the constraint that s - t = f (where f is the fractional part of d)
and b,t are integers (s is not)
This is a convex (therefore optimally solvable) mixed integer quadratic program since D is positive semi-definite.
Once s,b,t are computed, simply derive the answer using b=b, s=d-a and t can be ignored.
Your problem may be NP-complete, it would be interesting to prove if so.
Some of the previous answers use methods that are of time or space complexity O(n), where n is the largest “small number” that will be accepted. By contrast, the following method is O(sqrt(n)) in time, and O(1) in space.
Suppose that positive real number r = x + y, where x=floor(r) and 0 ≤ y < 1. We want to approximate r by a number of the form a + √b. If x+y ≈ a+√b then x+y-a ≈ √b, so √b ≈ h+y for some integer offset h, and b ≈ (h+y)^2. To make b an integer, we want to minimize the fractional part of (h+y)^2 over all eligible h. There are at most √n eligible values of h. See following python code and sample output.
import math, random
def findb(y, rhi):
bestb = loerror = 1;
for r in range(2,rhi):
v = (r+y)**2
u = round(v)
err = abs(v-u)
if round(math.sqrt(u))**2 == u: continue
if err < loerror:
bestb, loerror = u, err
return bestb
#random.seed(123456) # set a seed if testing repetitively
f = [math.pi-3] + sorted([random.random() for i in range(24)])
print (' frac sqrt(b) error b')
for frac in f:
b = findb(frac, 12)
r = math.sqrt(b)
t = math.modf(r)[0] # Get fractional part of sqrt(b)
print ('{:9.5f} {:9.5f} {:11.7f} {:5.0f}'.format(frac, r, t-frac, b))
(Note 1: This code is in demo form; the parameters to findb() are y, the fractional part of r, and rhi, the square root of the largest small number. You may wish to change usage of parameters. Note 2: The
if round(math.sqrt(u))**2 == u: continue
line of code prevents findb() from returning perfect-square values of b, except for the value b=1, because no perfect square can improve upon the accuracy offered by b=1.)
Sample output follows. About a dozen lines have been elided in the middle. The first output line shows that this procedure yields b=51 to represent the fractional part of pi, which is the same value reported in some other answers.
frac sqrt(b) error b
0.14159 7.14143 -0.0001642 51
0.11975 4.12311 0.0033593 17
0.12230 4.12311 0.0008085 17
0.22150 9.21954 -0.0019586 85
0.22681 11.22497 -0.0018377 126
0.25946 2.23607 -0.0233893 5
0.30024 5.29150 -0.0087362 28
0.36772 8.36660 -0.0011170 70
0.42452 8.42615 0.0016309 71
...
0.93086 6.92820 -0.0026609 48
0.94677 8.94427 -0.0024960 80
0.96549 11.95826 -0.0072333 143
0.97693 11.95826 -0.0186723 143
With the following code added at the end of the program, the output shown below also appears. This shows closer approximations for the fractional part of pi.
frac, rhi = math.pi-3, 16
print (' frac sqrt(b) error b bMax')
while rhi < 1000:
b = findb(frac, rhi)
r = math.sqrt(b)
t = math.modf(r)[0] # Get fractional part of sqrt(b)
print ('{:11.7f} {:11.7f} {:13.9f} {:7.0f} {:7.0f}'.format(frac, r, t-frac, b,rhi**2))
rhi = 3*rhi/2
frac sqrt(b) error b bMax
0.1415927 7.1414284 -0.000164225 51 256
0.1415927 7.1414284 -0.000164225 51 576
0.1415927 7.1414284 -0.000164225 51 1296
0.1415927 7.1414284 -0.000164225 51 2916
0.1415927 7.1414284 -0.000164225 51 6561
0.1415927 120.1415831 -0.000009511 14434 14641
0.1415927 120.1415831 -0.000009511 14434 32761
0.1415927 233.1415879 -0.000004772 54355 73441
0.1415927 346.1415895 -0.000003127 119814 164836
0.1415927 572.1415909 -0.000001786 327346 370881
0.1415927 911.1415916 -0.000001023 830179 833569
I do not know if there is any kind of standard algorithm for this kind of problem, but it does intrigue me, so here is my attempt at developing an algorithm that finds the needed approximation.
Call the real number in question r. Then, first I assume that a can be negative, in that case we can reduce the problem and now only have to find a b such that the decimal part of sqrt(b) is a good approximation of the decimal part of r. Let us now write r as r = x.y with x being the integer and y the decimal part.
Now:
b = r^2
= (x.y)^2
= (x + .y)^2
= x^2 + 2 * x * .y + .y^2
= 2 * x * .y + .y^2 (mod 1)
We now only have to find an x such that 0 = .y^2 + 2 * x * .y (mod 1) (approximately).
Filling that x into the formulas above we get b and can then calculate a as a = r - b. (All of these calculations have to be carefully rounded of course.)
Now, for the time being I am not sure if there is a way to find this x without brute forcing it. But even then, one can simple use a simple loop to find an x good enough.
I am thinking of something like this(semi pseudo code):
max_diff_low = 0.01 // arbitrary accuracy
max_diff_high = 1 - max_diff_low
y = r % 1
v = y^2
addend = 2 * y
x = 0
while (v < max_diff_high && v > max_diff_low)
x++;
v = (v + addend) % 1
c = (x + y) ^ 2
b = round(c)
a = round(r - c)
Now, I think this algorithm is fairly efficient, while even allowing you to specify the wished accuracy of the approximation. One thing that could be done that would turn it into an O(1) algorithm is calculating all the x and putting them into a lookup table. If one only cares about the first three decimal digits of r(for example), the lookup table would only have 1000 values, which is only 4kb of memory(assuming that 32bit integers are used).
Hope this is helpful at all. If anyone finds anything wrong with the algorithm, please let me know in a comment and I will fix it.
EDIT:
Upon reflection I retract my claim of efficiency. There is in fact as far as I can tell no guarantee that the algorithm as outlined above will ever terminate, and even if it does, it might take a long time to find a very large x that solves the equation adequately.
One could maybe keep track of the best x found so far and relax the accuracy bounds over time to make sure the algorithm terminates quickly, at the possible cost of accuracy.
These problems are of course non-existent, if one simply pre-calculates a lookup table.

Find the formula of this binary recurrence equation? f(m,n) = f(m-1,n) + f(m,n-1)

SORRY GUYS! MY MISTAKE! Thanks for your reminder, I found out f(0,k) == f(k,0) == 1. This question is about how to count the number of shortest paths from grid (0,0) to (m,n).
I have to solve the following equation now, find out exactly what f(m,n) equal to.
1) f(m,n) = 0 : when (m,n) = (0,0)
**2) f(m,n) = 1 : when f(0,k) or f(k,0)**
3) f(m,n) = f(m-1,n) + f(m,n-1) : when else
for example:
1) f(0,0) = 0;
2) f(0,1) = 1; f(2,0) = 1;
3) f(2,1) = f(1,1) + f(2,0) = f(0, 1) + f(1, 0) + f(2, 0) = 1 + 1 + 1 = 3
I remember there is a standard way to solve such kinds of binary recurrence equation as I learned in my algorithm class several years ago, but I just cannot remember for now.
Could anyone give any hint? Or a keyword how to find the answer?
Ugh, I was just having fun going through my old textbooks on generating functions, and you went and changed the question again!
This question is about how to count the number of shortest path from grid (0,0) to (m,n).
This is a basic combinatorics question - it doesn't require knowing anything about generating functions, or even recurrence relations.
To solve, imagine the paths being written out as a sequence of U's (for "up") and R's (for "right"). If we are moving from (0,0) to, say, (5, 8), there must be 5 R's and 8 U's. Just one example:
RRUURURUUURUU
There will always be, in this example, 8 U's and 5 R's; different paths will just have them in different orders. So we can just choose 8 positions for our U's, and the rest must be R's. Thus, the answer is
(8+5) choose (8)
Or, in general,
(m+n) choose (m)
This is simply the binomial coefficient
f(m,n) = (m+n choose m) = (m+n choose n)
You can prove this by noting that they satisfy the same recurrence relation.
To derive the formula (if you couldn't just guess and then check), use generating functions as Chris Nash correctly suggests.
Try looking up "generating functions" in the literature. One approach would be to imagine a function P(x,y) where the coefficient of x^m y^n is f(m,n). The recurrence line (line 3) tells you that P(x,y) - x.P(x,y) - y.P(x,y) = (1-x-y) P(x,y) should be pretty simple except for those pesky edge values. Then solve for P(x,y).
Are you sure f(k,0) = f(0,k) = k, and not 1, maybe? If it were, I'd say the best bet would be to write some values out, guess what they are, then prove it.

Algorithm for multidimensional optimization / root-finding / something

I have five values, A, B, C, D and E.
Given the constraint A + B + C + D + E = 1, and five functions F(A), F(B), F(C), F(D), F(E), I need to solve for A through E such that F(A) = F(B) = F(C) = F(D) = F(E).
What's the best algorithm/approach to use for this? I don't care if I have to write it myself, I would just like to know where to look.
EDIT: These are nonlinear functions. Beyond that, they can't be characterized. Some of them may eventually be interpolated from a table of data.
There is no general answer to this question. A solver finding the solution to any equation does not exist. As Lance Roberts already says, you have to know more about the functions. Just a few examples
If the functions are twice differentiable, and you can compute the first derivative, you might try a variant of Newton-Raphson
Have a look at the Lagrange Multiplier Method for implementing the constraint.
If the function F is continuous (which it probably is, if it is an interpolant), you could also try the Bisection Method, which is a lot like binary search.
Before you can solve the problem, you really need to know more about the function you're studying.
As others have already posted, we do need some more information on the functions. However, given that, we can still try to solve the following relaxation with a standard non-linear programming toolbox.
min k
st.
A + B + C + D + E = 1
F1(A) - k = 0
F2(B) - k = 0
F3(C) -k = 0
F4(D) - k = 0
F5(E) -k = 0
Now we can solve this in any manner we wish, such as penalty method
min k + mu*sum(Fi(x_i) - k)^2
st
A+B+C+D+E = 1
or a straightforward SQP or interior-point method.
More details and I can help advise as to a good method.
m
The functions are all monotonically increasing with their argument. Beyond that, they can't be characterized. The approach that worked turned out to be:
1) Start with A = B = C = D = E = 1/5
2) Compute F1(A) through F5(E), and recalculate A through E such that each function equals that sum divided by 5 (the average).
3) Rescale the new A through E so that they all sum to 1, and recompute F1 through F5.
4) Repeat until satisfied.
It converges surprisingly fast - just a few iterations. Of course, each iteration requires 5 root finds for step 2.
One solution of the equations
A + B + C + D + E = 1
F(A) = F(B) = F(C) = F(D) = F(E)
is to take A, B, C, D and E all equal to 1/5. Not sure though whether that is what you want ...
Added after John's comment (thanks!)
Assuming the second equation should read F1(A) = F2(B) = F3(C) = F4(D) = F5(E), I'd use the Newton-Raphson method (see Martijn's answer). You can eliminate one variable by setting E = 1 - A - B - C - D. At every step of the iteration you need to solve a 4x4 system. The biggest problem is probably where to start the iteration. One possibility is to start at a random point, do some iterations, and if you're not getting anywhere, pick another random point and start again.
Keep in mind that if you really don't know anything about the function then there need not be a solution.
ALGENCAN (part of TANGO) is really nice. There are Python bindings, too.
http://www.ime.usp.br/~egbirgin/tango/codes.php - " general nonlinear programming that does not use matrix manipulations at all and, so, is able to solve extremely large problems with moderate computer time. The general algorithm is of Augmented Lagrangian type ... "
http://pypi.python.org/pypi/TANGO%20Project%20-%20ALGENCAN/1.0
Google OPTIF9 or ALLUNC. We use these for general optimization.
You could use standard search technic as the others mentioned. There are a few optimization you could make use of it while doing the search.
First of all, you only need to solve A,B,C,D because 1-E = A+B+C+D.
Second, you have F(A) = F(B) = F(C) = F(D), then you can search for A. Once you get F(A), you could solve B, C, D if that is possible. If it is not possible to solve the functions, you need to continue search each variable, but now you have a limited range to search for because A+B+C+D <= 1.
If your search is discrete and finite, the above optimizations should work reasonable well.
I would try Particle Swarm Optimization first. It is very easy to implement and tweak. See the Wiki page for it.

Resources