How do I set an integer condition for fmincon?

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)

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

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)
Thank you for your answer, Walter, but now ga tells me that it cannot find a feasible initital point, and I don't understand where I should place it. I have one in x0, though.
Your 4th linear constraint is not met. [-1 0 0 0]*x -> -100 which is not <= -300
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 =
[]
Oh, you're right, thank you! That was a mistake. -300 should be -100.
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.

Sign in to comment.

Categories

Products

Release

R2020a

Asked:

on 12 May 2020

Commented:

on 12 May 2020

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!