How do I set an integer condition for fmincon?
Show older comments
I need to find an optima of my function and search for solutions which only belong to set of integers.
Here's my function:
fun = @(x)(-(x(1)-100)*(12*x(2)+8*x(3)+10*x(4)+6*x(1)-2050))
Starting point and conditions:
x0 = [100 0 150 25];
A=[1 2 1 2
1 4 2 0
1 1 3 2
-1 0 0 0
-6 -12 -8 -10];
b=[300
400
600
-300
-2050];
lb = [0 0 0 0];
ub =[];
Aeq = [];
beq=[];
nonlcon=@ceq;
So the actual question is about the last row, which contains a function with my nonlinear integer condition. I set it up like this:
function [c,ceq] = ceq(x)
c=[];
ceq=mod(x(1),1)+mod(x(2),1)+mod(x(3),1)+mod(x(4),1);
end
The sum of mods of roots and 1's should equal 0, which, since mods are nonnegative, can be achieved only if all mods are zeros and, therefore, my solution is integer.
But it doesn't work! I get this answer:
sol = 1×4
199.6679 0.0000 100.1811 5.0517
The thing is I don't misuse the mod function. I can type this:
mod(sol(1),1)+mod(sol(2),1)+mod(sol(3),1)+mod(sol(4),1)
And get this:
ans = 0.9007
Which obviously violates my condition. So what's the problem? Why does Matlab ignore this condition and how do I set it up correctly?
Answers (1)
John D'Errico
on 12 May 2020
0 votes
You cannot do this using fmincon. Period. fmincon is not designed to allow this class of condition. Use a different optimizer that will work properly with such a constraint. Currently, the only tool in MATLAB that will do so is GA, from the global optimization toolbox.
6 Comments
Walter Roberson
on 12 May 2020
Apparently patternsearch() can also more or less handle integer constraints, if you abuse some of the parameters. But ga() and gamultiobj() are the only two for nonlinear functions that handle integer constraints cleanly. (For linear functions, there is a mixed integer solver)
Mikhail Konovalov
on 12 May 2020
Edited: Mikhail Konovalov
on 12 May 2020
Walter Roberson
on 12 May 2020
Your 4th linear constraint is not met. [-1 0 0 0]*x -> -100 which is not <= -300
John D'Errico
on 12 May 2020
Edited: John D'Errico
on 12 May 2020
x0 = [100 0 150 25];
A=[1 2 1 2
1 4 2 0
1 1 3 2
-1 0 0 0
-6 -12 -8 -10];
b=[300
400
600
-300
-2050];
[A*x0',b]
ans =
300 300
400 400
600 600
-100 -300
-2050 -2050
Which is as pointed out, is not feasible. Feasible solutions do exist, if you ignore the bound constraint.
x1 = linprog(ones(1,4),A,b)
Optimal solution found.
x1 =
300
-25
100
-25
[A*x1,b]
ans =
300 300
400 400
525 600
-300 -300
-2050 -2050
Surprisingly, it even found an integer solution.
However, you require the solution be bounded from below by zeros, and linprog shows that no feasible solution exists at all with that additional requirement.
x1 = linprog(ones(1,4),A,b,[],[],zeros(1,4))
No feasible solution found.
Linprog stopped because no point satisfies the constraints.
x1 =
[]
Mikhail Konovalov
on 12 May 2020
John D'Errico
on 12 May 2020
Then you should be able to use GA. However, you do not want to employ a nonlinear constraint of the form you have done. Nonlinear constraints are a bad choice when there are better options available. And GA has a direct facility to force the unknowns to take on only integer values. USE THAT, as GA will be far more effective if you use it properly.
The point is, if you allow GA to search over a continuous space, but then require the solutions to be integer, this makes the search space be relatively huge, when you can tell GA to restrict the search to integer solutions.
Categories
Find more on Linear Programming and Mixed-Integer Linear Programming in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!