Asked by annazy
on 22 Aug 2019

Hi,

I have to optimize matrix to obtain quantities that will be divisible by certain numbers. When I use MOD on numbers, it works fine, for example MOD(10,3)=1. However, when I try to create constraint that I want my optimization variable x to be divisible by let's say 3 MOD(x,3), I get an error

Undefined function 'mod' for input arguments of type 'optim.problemdef.OptimizationVariable'.

Is there anything I can do to solve this issue?

Thanks in advance.

Answer by Matt J
on 24 Aug 2019

Edited by Matt J
on 24 Aug 2019

Accepted Answer

No need to use constraints. Just declare x as an OptimizationExpression,

x=3*optimvar('z','Type', 'Integer','LowerBound',0)

x =

OptimizationExpression

3*z

Now use x freely to build the objective and constraints as you did previously. E.g.,

x=3*optimvar('z','Type', 'integer','LowerBound',0);

y=optimvar('y','LowerBound',0);

prob=optimproblem;

prob.Objective=2*x+4*y;

prob.Constraints=x+y>=7;

sol=solve(prob);

The solver will solve for z, not x,

>> sol

sol =

struct with fields:

y: 1.0000

z: 2.0000

but you can easily convert the optimal z to a corresponding result for x.

>> x_optimal=evaluate(x,sol)

x_optimal =

6.0000

Walter Roberson
on 24 Aug 2019

Nice!

Matt J
on 25 Aug 2019

annazy's comment moved here:

This is wonderful. What I actually need is this 'z', as I optimize quantities of products which must be divisible by number of products per cartoon. However this number varies depending on products. Also, I have multiple percentage constraints on quantities (not cartoons) which is why I can't focus on cartoons only, but in the end number of cartoons is what I need.

You are both amazing people, I hope one day I will be clever enough to help other lost souls like you do help me :)

Matt J
on 25 Aug 2019

I'm glad it's what you need but please Accept-click the answer if it addresses your question.

Sign in to comment.

Answer by Walter Roberson
on 22 Aug 2019

Introduce an extra integer variable and constrain equality x-3*extra = 1

Walter Roberson
on 23 Aug 2019

For a definitive answer as to whether there is any way to make mod() work, you will need to open a support case with Mathworks. Perhaps they have an in-house implementation that they might be willing to let you experiment with; I do not know.

What I do know is that there is no mod() available for optimization variables in any released version.

"I can't influence on values of x with some random integers as I have other requirements to be met :( "

I suspect you do not understand the process.

Suppose that you have a value of x = 16 and you want to check whether mod(x,3)=1 . If so, then by definition, there must be some integer N (that is not necessarily positive) such that 3*N+1 = x . This is not a "random integer": for 16 it is satisfied only by N = 5, 3*5 + 1 = 16. Likewise, if there is no integer N such that 3*N+1 = x, then mod(x,3)=1 is not true -- for example, for x = 17, then there is no such integer N.

Therefore if you introduce an integer-constrained variable N into the process and put in the equality constraint 3*N+1 = x, or 1 = x - 3*N or x - 3*N = 1 then N will not be random: it will be the exact integer needed such that 3*N+1 = x. You would not use the value of N in the calculation of your objective: it is enough to know that the constraint was met that there is some integer N such that x - 3*N = 1 is true.

annazy
on 24 Aug 2019

Wow, thank you a lot for such detailed answer and your patience. Honestly, this is my first experience with Matlab and I am a bit confused with its options. I used to solve simple optimization problems with Excel Solver, however due to the dimension of the matrix, in this case I cannot use Solver as it can't hadle such large size. I was forced to learn basic optimization tools in Matlab within a week :(

I understand the process, I just don't know how to create such Integer variable correctly. I only add new variables with numbers or create optimization variables for objective funtion. Is it supposed to be a new optimization variable? Something like N=optimvar('N','Type','integer')?

Thanks in advance, you're saving my life.

Walter Roberson
on 24 Aug 2019

Yes, N=optimvar('N','Type','integer') is good.

If you have upper and/or lower bound on x then you can use it to figure out upper and lower bounds on N to make the optimization more efficient.

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.