Solve multi-objective optimization problem with R package rmoo - r

The documentation to this packages is available here, but for me it is impossible to transfer my real-valued 3 objective function to a form that it works.
I'm trying to solve it with the nsga2 function - and I think nsga3 should work the same way?!
My objective functions, which I want to minimize, are:
f1 <- 1640.2823 + 2.3573285*x[1] + 2.3220035*x[2] +4.5688768*x[3] + 7.7213633*x[4] + 4.4559504*x[5]
f2 <- 6.5856 + 1.15*x[1] - 1.0427*x[2] + 0.9738*x[3] + 0.8364*x[4] - 0.3695*x[1]*x[4] + 0.0861*x[1]*x[5] + 0.3628*x[2]*x[4] - 0.1106*x[1]^2 - 0.3437*x[3]^2 + 0.1764*x[4]^2
f3 <- -0.0551 + 0.0181*x[1] + 0.1024*x[2] + 0.0421*x[3] - 0.0073*x[1]*x[2] + 0.024*x[2]*x[3] - 0.0118*x[2]*x[4] - 0.0204*x[3]*x[4] - 0.008*x[3]*x[5] - 0.0241*x[2]^2 + 0.0109*x[4]^2
And x has to be between one and three (these are the constraints)
1 <= x[i] <= 3
I appreciate any hints... so many thanks in advance!

Related

Solving of a linear system with parameters

I have a linear system of four equations with four variables $a,b,c,d$ and two parameters $i,h$ where equations are roughly of the form
$$a h^3 i^3 + b h^2 i^2 +c h i +d=0$$
I want to get $a,b,c,d$ in terms of $i,h$.
Is this possible in SymPy? If not, can someone recomend how to do it on some other way?
For completeness, the answer is yes, solve in Sympy solves systems of equations with parameters. An example using the equation you stated:
from sympy import *
var('a b c d i h')
eqns = [a*h**3*i**3 + b*h**2*i**2 + c*h*i + d, a+b+c+d, a-b*h*i**2 -c - d, a+b+c-h**2 - i**2]
solve(eqns, [a,b,c,d])
The first argument of solve is a list of equations, the second the list of variables to solve for. The output is a solution, presented as a dictionary:
{c: (h**2 + i**2)*(-h**4*i**5 + h**3*i**3 - 2*h**2*i**2 + h*i**2 + 1)/(h*i*(-h**3*i**4 + h**2*i**2 + h*i**2 - 2*h*i + 1)),
b: -(2*h**2 + 2*i**2)/(h*i*(h**2*i**3 + h*i**2 - h*i + 1)),
a: (-h**3*i**2 + h**2 - h*i**4 + i**2)/(h*i*(h**2*i**3 + h*i**2 - h*i + 1)),
d: -h**2 - i**2}

Avoid round off error in exponential calculation

Due to rounding error cannot get ratio between two numbers:
Ratio=exp(x)/(exp(x)+exp(y)) such that x=-1.11e4 and y=-1.12e4.
Any mathematical or computational trick to do?
You can simplify it like this:
R = exp(x) / (exp(x) + exp(y))
= exp(x) / (exp(x) * (1 + exp(y) / exp(x)))
= 1 / (1 + exp(y) / exp(x))
= 1 / (1 + exp(y - x))
(This is the same result as derived by DiltihiumMatrix, but obtained without going into the log domain and back again.)
How about some mathematical manipulation in log-space...
R = exp(x)/[exp(x)+exp(y)]
log(R) = log[exp(x)] - log[exp(x)+exp(y)]
= log[exp(x)] - log[exp(x)*(1+exp(y)/exp(x))]
= log[exp(x)] - log[exp(x)*(1+exp(y-x)]
= log[exp(x)] - log[exp(x)] - log[(1+exp(y-x))]
= - log[(1+exp(y-x))]
Now, exp(y-x) should be a reasonable number, so you can calculate that easily. Then convert back to normal space using R = exp(log(R)).
If that still doesn't work, you can actually taylor expand the last line:
log[(1+z)] ~ 1 + z^2/2 - z^3/3 ...
for small z, in this case z = exp(y-x).

Simplify expression

I have an expressions like:
a*b*c + d*e + f - g*h*h + i*a
In other words: terms can be either added or subtracted, and each term is a product of some of the symbols.
Is there a way to come up with a minimal/simpler expression, basically the reverse of expand? I tried simplify and factor but I cannot get them to work. For example:
a**4 - 4*a**3*b + 6*a**2*b**2 - 4*a*b**3 - a + b**4
should turn into:
(a - b)**4 - a
but it stays unchanged when using the said commands.
PS: If this is something what SymPy simply cannot do, could you please suggest an alternative which does this?
See sympy factor simple relationship. SymPy's factor only knows how to factor the entire expression, but if you know the term you want to rewrite things in terms of, you can use a trick with subs, like:
>>> expr = a**4 - 4*a**3*b + 6*a**2*b**2 - 4*a*b**3 - a + b**4
>>> expr.subs(a, x + b).expand()
-b + x**4 - x
>>> expr.subs(a, x + b).expand().subs(x, a - b)
-a + (a - b)**4
Basically, let x = a - b, so that a = x + b. Then replace a with x + b, expand things out, and replace it back.
For your more complicated example, SymPy is actually smart enough to replace a*b in an expression correctly:
>>> expr = (a*b - c*d)**2 - a
>>> expr = expr.expand()
>>> expr
a**2*b**2 - 2*a*b*c*d - a + c**2*d**2
>>> expr.subs(a*b, x + c*d)
-a + c**2*d**2 - 2*c*d*(c*d + x) + (c*d + x)**2
>>> expr.subs(a*b, x + c*d).expand()
-a + x**2
>>> expr.subs(a*b, x + c*d).expand().subs(x, a*b - c*d)
-a + (a*b - c*d)**2
Another possible approach to this problem would be to try using factor on subsets of the terms in an expression (itertools.combinations could be useful here). For instance, to try factoring all combinations of all terms but one from your original expression:
>>> args = Add.make_args(expr)
>>> for comb in combinations(args, len(args) - 1):
... print(factor(Add(*comb)) + Add(*(set(args) - set(comb))))
...
a**4 - 4*a**3*b + 6*a**2*b**2 - 4*a*b**3 - a + b**4
a**4 - 4*a**3*b + 6*a**2*b**2 - 4*a*b**3 - a + b**4
a**4 - 4*a**3*b + 6*a**2*b**2 - 4*a*b**3 - a + b**4
a**4 - 4*a**3*b + 6*a**2*b**2 - 4*a*b**3 - a + b**4
-a + (a - b)**4
a*(a**3 - 4*a**2*b + 6*a*b**2 - 4*b**3 - 1) + b**4
You could check not isinstance(factored_expr, Add) to filter out the ones that aren't factored.
If you know the function in advance, then you can use more powerful software packages such as Maple to reduce the expression before putting it into your computer code. There is a optimization package in Maple, which reduces the expression into sub-expressions such that it takes advantage of repeated operations in the expression. Also you can factorize very complicated expressions in a much reliable way.
In addition such software also can create programming code as output, which you can directly paste in your program. If you do not have access to Maple or Mathematica software, you can also use a free (but powerful) software called maxima. http://maxima.sourceforge.net/

Recursive cumulative function

I need to write a cumulative summation function in R but I've been hitting a brick wall. The function has the following structure:
a*x1
a*x2 + a^2*x1
a*x3 + a^2*x2 + a^3*x1
a*x4 + a^2*x3 + a^3*x2 + a^4*x1
And so on. cumsum doesn't seem to work for this type of function. Is there any way this could be implemented in R?
Since your recursion is
u[n+1] = a * ( x[n+1] + u[n] )
i.e.,
u[n+1]/a = x[n+1] + a * u[n]/a,
you can use filter:
x <- 1:5
a <- 2
a*filter(1:5, a, method="recursive")
# Compare with the expected values
a*x[1]
a*x[2] + a^2*x[1]
a*x[3] + a^2*x[2] + a^3*x[1]
a*x[4] + a^2*x[3] + a^3*x[2] + a^4*x[1]

WolframAlpha: Solve Multiple Functions

I'm trying to use WolframAlpha to solve for a variable.
I have
u(k, r) = (900-3k)r^(k-1)
and
s(n, r) = sum u(k, r), k=1 to n
and I want to solve for r with
s(5000, r) = -600000000000
I've tried various incantations, but can't seem to get it working. I can't even get s defined to evaluate it.
If you care, it is to solve this problem : http://projecteuler.net/index.php?section=problems&id=235
WARNING: Spoiler below!
You should ask WA to FullSimplify the expression of s(n,r) after you substitute u(k,r) into it. It should give
(3 (299 - 300 r + r^n (-299 + n + 300 r - n r)))/(-1 + r)^2
Solving the final equality is then just finding the root of a (high degree) polynomial:
299 + 200000000000 (-1 + r)^2 + (4701 - 4700 r) r^5000 == 300 r
where r != 1 since that was a pole of the original expression. Note that r must be positive so that the positive quadratic gets negated by the high-degree term. Plotting the function shows that It is positive for r < 1, and negative for r >~ 1, so the solution is somewhere past r=1. Now change variables so that x = r-1 and look near x=0:
200000000000 x^2 + (1 + x)^5000 (1 - 4700 x) - 1 - 300 x == 0
This should be enlightnening:
Plot[200000000000 x^2 + (1 + x)^5000 (1 - 4700 x) - 1 - 300 x, {x, 0, 0.003}]
Using FindRoot with a good guess gives x=0.002322108633 or r=1.002322108633.
The WA commands follow.
First I used
FullSimplify[Sum[(900-3k)r^(k-1),{k,1,n]]
Then you would have to retype the expression it spits out:
Plot[(3 (299 - 300 r + r^5000 (-299 + 5000 + 300 r - 5000 r)))/(-1 + r)^2 + 6000000000,{r,-2,2}]
At this point I manually replaced r with x+1:
Plot[200000000000 x^2 + (1 + x)^5000 (1 - 4700 x) - 1 - 300 x, {x, 0, 0.003}]
And solving for the root:
FindRoot[200000000000 x^2 + (1 + x)^5000 (1 - 4700 x) - 1 - 300 x, {x, 0.0023}]
Which doesn't give enough precision, and this is as far as you can go using only WA. You can try to subtract off the first few digits that WA gives you, and do another substitution with y = x + 0.00232211 to get the next few digits, but that is too tedious for me to try.

Resources