ampl / amplpy

Python API for AMPL

Home Page:https://amplpy.ampl.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Integer variables are not integers after solving with KNITRO solver

CratesDeThebes opened this issue · comments

Solving with KNITRO solver sometimes results in integer variables not being integer.

Here is a minimal working example:

ampl = AMPL()
ampl.eval(r"""
        var a, integer, >= 1, <= 20, :=1 ;
        var b, integer, >= 1, <= 20, :=1 ;
        s.t. h1: a + b = 8 ;
        minimize objective: a**2 + b**2;
        """)

# Solve
ampl.set_option("solver", "knitro")
ampl.solve()

print("\nResult: " + ampl.get_value("solve_result"))

a = ampl.get_value("a")
b = ampl.get_value("b")

print("a={0}; b={1}".format(a, b))
print("Type of a:" + str(type(a)))
print("Type of b:" + str(type(b)))
print("Objective: " + str(a**2 + b**2))

The result of this MWE is:

Knitro 13.2.0: Locally optimal or satisfactory solution.
objective 32; optimality gap 0
1 nodes; 1 subproblem solves

suffix feaserror OUT;
suffix opterror OUT;
suffix numfcevals OUT;
suffix numiters OUT;
suffix incumbent OUT;
suffix relaxbnd OUT;

Result: solved
a=4.0; b=3.9999999999999996
Type of a:<class 'float'>
Type of b:<class 'float'>
Objective: 31.999999999999996

Just like when I use COUENNE or BONMIN as solvers, I would expect:

a=4.0; b=4.0
Type of a:<class 'float'>
Type of b:<class 'float'>
Objective: 32.0

Python: 3.9.2
amplpy: 0.9.1
Knitro: 13.2.0

Best regards,
MJ

Hi @CratesDeThebes,

The values returned are always floating point since typically there is integrality tolerance and solvers will not always find completely integer solutions unless tolerances are set to zero and in which case it may be substantially harder to solver the problem.

If you really want to make sure the solutions are integer, you can assert that the values are very close to integer as follows:

assert abs(value-math.round(value)) <= 1e-5

You can replace 1e-5 by 0 if no tolerance is really allowed. If you get solutions that are not within your tolerance you can adjust the options for KNITRO (see, e.g., https://dev.ampl.com/solvers/knitro/options.html or https://www.artelys.com/docs/knitro/3_referenceManual/knitroamplReference.html)

Thank you for your very clear and complete answer !