Skip to content

GLPK/exact isn't exact on simple, rational LPs #35727

@ed359

Description

@ed359

Is there an existing issue for this?

  • I have searched the existing issues for a bug report that matches the one I want to file, without success.

Did you read the documentation and troubleshoot guide?

  • I have read the documentation and troubleshoot guide

Environment

- **OS**: macOS 13.4
- **Sage Version**: 10.0 binaries from the manifold project

Steps To Reproduce

From a fresh install run the following code:

def build_prog(solver):
    p = MixedIntegerLinearProgram(solver=solver, maximization=False, base_ring=QQ)
    x = p.new_variable(nonnegative=True)
    p.set_objective(p.sum(x[i] for i in range(6)))
    for i in range(6):
        p.add_constraint(x[i], min=1/6)
    return p, x

p1, x1 = build_prog('PPL')
print(f'PPL: {p1.solve()}')
print(p1.get_values(x1, convert=True))
print()

p2, x2 = build_prog('InteractiveLP')
print(f'InteractiveLP: {p2.solve()}')
print(p2.get_values(x3, convert=True))
print()

p3, x3 = build_prog('GLPK/exact')
print(f'GLPK/exact: {p3.solve()}')
print(p3.get_values(x3, convert=True))

Expected Behavior

The expected behavior is that both PPL and GLPK/exact are able to find the exact rational solution 1 to the LP

PPL: 1
{0: 1/6, 1: 1/6, 2: 1/6, 3: 1/6, 4: 1/6, 5: 1/6}

InteractiveLP: 1
{0: 1/6, 1: 1/6, 2: 1/6, 3: 1/6, 4: 1/6, 5: 1/6}

GLPK/exact: 1
{0: 1/6, 1: 1/6, 2: 1/6, 3: 1/6, 4: 1/6, 5: 1/6}

Actual Behavior

The actual behavior is that GLPK/exact is not exact, even when getting the values with convert=True.

PPL: 1
{0: 1/6, 1: 1/6, 2: 1/6, 3: 1/6, 4: 1/6, 5: 1/6}

InteractiveLP: 1
{0: 1/6, 1: 1/6, 2: 1/6, 3: 1/6, 4: 1/6, 5: 1/6}

GLPK/exact: 0.9999999999999999
{0: 0.16666666666666666, 1: 0.16666666666666666, 2: 0.16666666666666666, 3: 0.16666666666666666, 4: 0.16666666666666666, 5: 0.16666666666666666}

Additional Information

I can read the documentation and observe that GLPK/exact is (supposed to be) doing exact rational computation on the inside, but data input and output is via double precision floats. See https://doc.sagemath.org/html/en/reference/numerical/sage/numerical/backends/glpk_exact_backend.html: "The only access to data is via double-precision floats, however. It reconstructs rationals from doubles and also provides results as doubles." It thus appears that I am reporting something like a bug with reconstructing rationals, or if (strangely) this is how GLPK/exact is supposed to work then the documentation should clearly indicate that GLPK.exact cannot be expected to solve simple rational LPs correctly. This kind of bug is felt downstream as it's tempting to check p.solve() == 1 when with errors we need something like abs(p.solve() - 1) < 0.00001 instead. Sage's own use of MILPs is/was littered with this kind of bug (#32191 and also #23798 for a slightly different issue).

I can also see that this summer the optimization functionality in sage is getting a major overhaul. We have lots of open tickets, including some relevant ones:

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions