Linear programming constraints: multiplication of optimization variables - matlab

Given an optimization problem with two optimization variables (x_in(t), x_out(t)). For any time-step, when x_in is non-zero, x_out must be zero (and vice versa). Written as a constraint:
x_in(t)*x_out(t)=0
How can such a constraint be included in Matlab's linprog function?

Since the problem is not entirely linear, I do not believe you can solve it as-is using the linprog function. However, you should be able to reformulate the problem as a mixed integer linear programming problem. Then you would be able to use for example this extension from Matlab Central to solve the problem.
Assuming that x_in(t) and x_out(t) are non-negative variables with upper bounds x_in_max and x_out_max, respectively, then you can add the variables y_in(t) and y_out(t) to your optimization problem and include the following constraints:
(1) y_in(t) and y_out(t) are binary, i.e. 0 or 1
(2) x_in(t) <= x_in_max * y_in(t)
(3) x_out(t) <= x_out_max * y_out(t)
(4) y_in(t) + y_out(t) = 1
Given that y_in and y_out are binary variables, constraints (2) and (3) relate the x_ and y_ variables with each other and ensure that the x_ variables remain within bounds (fix bounds on the x_ variables can thus and should be removed from the problem formulation). Constraint (4) ensures that either the _in or the _out event occurs, but not both at the same time.

Related

Mixed Integer Quadratic Programming with linear constraints in Matlab calling Gurobi

I have some troubles to understand how to implement the following MIQP (Mixed Integer Quadratic Programming) with linear constraints in Matlab calling Gurobi.
Let me explain in a schematic way my setting.
(1) x is the unknown and it is a column vector with size 225x1.
(2) The objective function (which should be minimised wrto x) looks like
which can be rewritten as
I have a Matlab script computing alpha, Q,c (Q,c sparse) when some_known_parameters1 are given:
function [alpha, Q,c]=matrix_objective_function(some_known_parameters1)
%...
end
(3) The constraints are linear in x, include equalities and inequalities, and are written in the form
I have a Matlab script computing Aeq,beq,Aineq,bineq (Aeq,Aineq sparse) when some_known_parameters2 is given:
function [Aeq,beq,Aineq,bineq]=constraints(some_known_parameters2)
%...
end
(4) Some components of x are restricted to be in {0,1}. I have a Matlab script producing a string of letters B (binary), C (continous) when some_known_parameters3 is given:
function type=binary_continuous(some_known_parameters3)
%...
end
Now, I need to put together (1)-(4) using Gurobi. I am struggling to understand how. I found this example but it looks very cryptic to me. Below I report some lines I have attempted to write, but they are incomplete and I would like your help to complete them.
clear
rng default
%Define some_known_parameters1,
some_known_parameters2,some_known_parameters3 [...]
%1) generate alpha,Q,c,Aeq,beq,Aineq,bineq,type with Q,c,Aeq, Aineq sparse
[alpha, Q,c]=matrix_objective_function(some_known_parameters1)
[Aeq,beq,Aineq,bineq]=constraints(some_known_parameters2)
type=binary_continuous(some_known_parameters3)
%2) Set up Gurobi
clear model;
model.A=[Aineq; Aeq];
model.rhs=full([bineq(:); beq(:)]);
model.sense=[repmat('<', size(Aineq,1),1); repmat('=', size(Aeq,1),1)];
model.Q=Q; %not sure?
model.alpha=alpha; %not sure?
model.c=c; %not sure?
model.vtype=type;
result=gurobi(model); %how do I get just the objective function here without the minimiser?
Questions:
(1) I'm not sure about
model.Q=Q;
model.alpha=alpha;
model.c=c;
I'm just trying to set the matrices of the objective function using the letters provided here but it gives me error. The example here seems to me doing
model.Q=Q;
model.obj=c;
But then how do I set alpha? Is it ignoring it because it does not change the set of solutions?
(2) How do I get as output stored in a matrix just the minimum value of the objective function without the corresponding x?
(1) You're right, there's no need to pass the constant alpha since it doesn't affect the optimal solution. Gurobi's MATLAB API only accepts sparse matrices. Furthermore model.obj is always the c vector in the problem statement:
model.Q = sparse(Q);
model.obj = c;
(2) To get the optimal objective value, you first need to pass your model to gurobi and solve it. Then you can access it via the objval attribute:
results = gurobi(model);
val = results.objval + alpha

How to define equality constraints for integer variables in PSO

I'm using Matlab's global optimization toolbox to optimize a cost function using PSO. Some of my input variables are involved in equality constraints and they must be integers. How can I define that in PSO?
I've tried to use a penalty function by adding this if statement in the cost function file,
if(ceil(x(1))+duration~= ceil(x(2))|| x(1)>x(2))
C=10000*C^2;
end
x(1) is the starting time and x(2) is the ending time, the difference between the ending and starting time must be equal to the duration (initially defined). The time is supposed to be integer that's why I used ceil. Also, the starting time must be less than ending time (logically and as governed by the equation t_end-t_start=duration). when I run this,the output is non integer, and it doesn't satisfy the condition in the if statement, yet still the cost (C) is minimum. Am I missing something? or is there any alternative approach.
Thanks

Matlab symbolic

I am trying to compare two simple expressions using Matlab symbolic toolbox. For some reason, the code returns 0. Any idea ?
syms a b c
A = (a/b)^c
B = a^c/b^c
isequal(A,B)
It seems like MATLAB has a hard time telling that two expressions are the same when (potentially) fractional exponents are involved.
So, one solution, as suggested by Mikhail is to restrict the values of c to be only integers although, as discussed in the Math.SE question jodag posted, there is nothing wrong with fractional exponents in this case.
Hence, since this restriction to integers is not necessary for the statement to be true, another solution is to use simplify function on the expression for B but allowing it to run more simplification steps in order to get the most simplified expression.
syms a b c
A = (a/b)^c
B = a^c/b^c
isequal(A,simplify(B,'step',4))
Four steps is actually the smallest number that worked for me, but that could vary across versions of MATLAB I'm assuming. To be sure, I would include more, but for really large expressions, this could become computationally intensive, so some judgment is necessary. Note that, you could also use the 'Seconds' option to limit the amount of time allowed for simplification.
In general what you wrote isn't true, under the right "assumptions" it becomes true: for example, assuming c is an integer you can trick MATLAB into expanding A
clc; clear all;
syms a
syms b
syms c integer
A = (a/b)^c;
B = simplify((a^c)/(b^c));
disp(isequal(A,B));
disp(A);
disp(B);
1
a^c/b^c
a^c/b^c

fzero or fsolve ? differents results - Who is the correct ?

I have a function
b=2.02478;
g=3.45581;
s=0.6;
R=1;
p =#(r) 1 - (b./r).^2 - (g^-2)*((2/15)*(s/R)^9 *(1./(r - 1).^9 - 1./(r + 1).^9 - 9./(8*r).*(1./(r - 1).^8 - 1./(r + 1).^8)) -(s/R)^3 *(1./(r-1).^3 - 1./(r+1).^3 - 3./(2*r).*(1./(r-1).^2 - 1./(r+1).^2)));
options = optimset('Display','off');
tic
r2 = fzero(p,[1.001,100])
toc
tic
r3 = fsolve(p,[1.001,100],options)
toc
and the answer
r2 =
2.0198
Elapsed time is 0.002342 seconds.
r3 =
2.1648 2.2745
Elapsed time is 0.048991 seconds.
which is more confiable ? fzero returns different values than fsolve
You should always look at the exit flag (or output struct) of a function, especially when your result is not as expected.
This is what I get:
fzero(func,[1.00001,100]):
X = 4.9969
FVAL
EXITFLAG = 1 % fzero found a zero X.
OUTPUT.message = 'Zero found in the interval [1.00001, 100]'
fzero(func,1.1):
X = 1
FVAL = 8.2304e+136
EXITFLAG = -5 % fzero may have converged to a singular point.
OUTPUT.message = 'Current point x may be near a singular point. The interval [0.975549, 1.188] reduced to the requested tolerance and the function changes sign in the interval, but f(x) increased in magnitude as the interval reduced.'
The meaning of the exit flag is explained in the matlab documentation:
1 Function converged to a solution x.
-5 Algorithm might have converged to a singular point.
-6 fzero did not detect a sign change.
So, based on this information it is clear that the first one gives you the correct result.
Why does fzero fails
As documented in the manual, fzero calculates the zero by finding a sign change:
tries to find a point x where fun(x) = 0. This solution is where fun(x) changes sign—fzero cannot find a root of a function such as x^2.
Therefore, X = 1 is also a solution of your formulation as the sign changes at this location from +inf to -inf as can be seen on a plot:
Note that it is always a good idea to provide a search range if possible as mentioned in the manual:
Calling fzero with a finite interval guarantees fzero will return a value near a point where FUN changes sign.
Tip: Calling fzero with an interval (x0 with two elements) is often faster than calling it with a scalar x0.
Alternative: fsolve
Note that this method is developed for solving a system of multiple nonlinear equations. Therefore, it is not as efficient as fzero (~20x slower in your case). fzero uses gradient based methods (check the manual for more information), which may work better in certain situations, but may get stuck in a local extrema. In this case, the gradient of your function gives the correct direction as long as your initial value is larger than 1. So, for this specific function fsolve is somewhat more robust than fzero with a single initial value, i.e. fsolve(func, 1.1) returns the expected value.
Conclusion: In general, use fzero with a search range instead of an initial value if possible for a single variable and fsolve for multiple variables. If one method fails, you can try another method or another starting point.
As you can read in documentation:
The algorithm, which was originated by T. Dekker, uses a combination of bisection, secant, and inverse quadratic interpolation methods.
So, it is sensitive into the initial point and area which it is seeking for the solution. Hence, you have gotten different result for different initial value and scope.

Unable to code non linear equation in MATLAB R2013a - MATLAB giving warning message

I wanted to solve the following equation in MATLAB R2013a using the Symbolic Math Toolbox.
(y/x)-(((1+r)^n)-1)/r=0 where y,x and n>3 are given and r is the dependent variable
I tried myself & coded as follows:
f=solve('(y/x)-(((1+r)^n)-1)/r','r')
but as the solution for r is not exact i.e. it is converging on successive iterations hence MATLAB is giving a warning output with the message
Warning: Explicit solution could not be found.
f =
[ empty sym ]
How do I code this?
There are an infinite number of solutions to this for an unspecified value of n > 3 and unknown r. I hope that it's pretty clear why – it's effectively asking for a greater and greater number of roots of (1+r)^n. You can find solutions for fixed values of n, however. Note that as n becomes larger there are more and more solutions and of course some of them are complex. I'm going to assume that you're only interested in real values of r. You can use solve and symbolic math for n = 4, n = 5, and n = 6 (for n = 6, the solution may not be in a convenient form):
y = 441361;
x = 66990;
n = 5;
syms r;
rsol = solve(y/x-((1+r)^n-1)/r==0,r,'IgnoreAnalyticConstraints',true)
double(rsol)
However, the question is "do you need all the solutions or just a particular solution for a given value of n"? If you just need a particular solution, you shouldn't be using symbolic math at all as it's slower and has practical issues like the ones you're experiencing. You can instead just use a numerical approach to find a zero of the equation that is near a specified initial guess. fzero is the standard function for solving this sort of problem in a single variable:
y = 441361;
x = 66990;
n = 5;
f = #(r)y/x-((1+r).^n-1)./r;
r0 = 1;
rsol = fzero(f,r0)
You'll see that the value returned is the same as one of the solutions from the symbolic solution above. If you adjust the initial guess r0 (say r0 = -3), it will return the other solution. When using numeric approaches in cases when there are multiple solutions, if you want specific solutions you'll need to know about the behavior of your function and you'll need to add some clever extra code to choose initial guesses.
I think you forgot to define n as well.
f=solve('(y/x)-(((1+r)^n)-1)/r=0','n-3>0','r','n')
Should solve your problem :)