0

I am using matlab to solve a mixed integer programming, after I obtain a solution from linprog, I want to evaluate whether they are all integers(x is n dimensions), but I cannot figure out a way to do this.

All the functions, such as mod(x,1) == 0, isequal(x,floor(x)) will give a wrong anwser.

More strange is, if you manually input a vector with the same parameter, it will turn out to be right.

The result is shown: (all the x here is obtained from the result of linprog). Anyone can help with this or bring out some other useful way to evaluate this?

K>> x

x =

    7.0000
    1.0000

K>> mod(x,1)

ans =

    0.0000
    1.0000

K>> x

x =

    6.0000
    3.0000

K>> isequal(x,floor(x))

ans =
    0
Ionică Bizău
  • 109,027
  • 88
  • 289
  • 474
Jiahui Guo
  • 135
  • 2
  • 10
  • 1
    Seems to work for me. Have you considered using an integer type (one of the int/uints) instead of doubles for your problem? – abcd Feb 04 '13 at 19:56
  • I also tried it, got the results I would have expected. – robbrit Feb 04 '13 at 19:57
  • Yeah, if you type the x value manually, it works, but if it comes with an solution of linprog, it won't work.@LoremIpsum @robbit – Jiahui Guo Feb 04 '13 at 20:11
  • That’s because the numbers from linprog aren’t what they seem to be, see my answer. – Lumen Feb 04 '13 at 20:33
  • why don't you just round the results from linprog. the issue is that what you see as 7.0000 is really 7.00000001 or something like that – thang Feb 04 '13 at 21:20

1 Answers1

2

What seems to be an integral 1 coming from linprog, actually is a floating point number very close to 1, but not equal to it. It's just that you (by default) cannot tell the difference by outputting the number in MATLAB. See this Question about comparing floating point values. Also, see the MATLAB manual page about display format of numbers.

By default, MATLAB displays numbers using format short:

format sets the display of floating-point numeric values to the default display format, which is the short fixed decimal format. This format displays 5-digit scaled, fixed-point values.

So, 1 – 1e–10 would be displayed as 1 even though it is not equal to 1. Likewise, mod(1 – 1e–10, 1) would be displayed as 1, even though it really is 1 – 1e–10.

If you manually set x to its displayed representation, all the less significant digits are truncated, “strangely” giving you the expected results.

Check x after typing the command format long.

Community
  • 1
  • 1
Lumen
  • 3,554
  • 2
  • 20
  • 33
  • Yeah, I tested with setting format long, it is actually 6.000000000000003, 3.000000000000000, but this is not right, because for the linprog function, I have the limitation, say x1>=6, x2<=3, the optimal solution should always be (6,3). So in this case, how can I evaluate the solution to be integer? @Lumen Thanks a lot! – Jiahui Guo Feb 04 '13 at 20:54
  • @JiahuiGuo Well, 6 + 3e–15 ≥ 6 actually holds, as does 3 <= 3. So the solution found by linprog is feasible, but it’s not the exact optimal solution. That’s just because MIP solvers usually truncate their branch & bound algorithm when they are sufficiently close to the optimal solution (they can estimate the error by finding solutions to the dual problem). And 3e–15 is pretty close most of the time. However, this is a question more related to linprog than to MATLAB. – Lumen Feb 04 '13 at 22:55
  • @JiahuiGuo My bad, the solution obviously isn’t feasible, since it’s not an integer. You could check whether or not the solution is sufficiently close to being integral (a simple `norm(x - round(x)) < 1e-10` can work). May I ask why you want to do the check instead of just rounding? – Lumen Feb 04 '13 at 23:18
  • The reason is that I have tried to, I use norm(x-floor(x)) < 1e-20 to try to make it work, but in some case, the norm(x-floor(x)) would be bigger than the threshold, that is why I want to find a more universal solution rather than providing a threshold here. @Lumen – Jiahui Guo Feb 05 '13 at 03:13