Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warmstart with cbc - bug with Binary and Real variables #3443

Open
feroi35 opened this issue Dec 5, 2024 · 0 comments
Open

Warmstart with cbc - bug with Binary and Real variables #3443

feroi35 opened this issue Dec 5, 2024 · 0 comments
Labels

Comments

@feroi35
Copy link

feroi35 commented Dec 5, 2024

Summary

Hello,
I was trying to use a warmstart with cbc but I had the error:

Colum1: Third column in mipstart file should be numeric, ignoring.
...
And finally:
Cbc0045I Warning: mipstart values could not be used to build a solution.

I know the warmstart was correct because it was ok with cplex. So I started to debug. It comes from the method _write_soln_file
in the CBCSHELL class (solvers > plugins > CBCplugin.py).

        column_index = 0
        with open(filename, 'w') as solnfile:
            for var in instance.component_data_objects(Var):
                # Cbc only expects integer variables with non-zero
                # values for mipstart.
                if (
                    var.value
                    and (var.is_integer() or var.is_binary())
                    and (id(var) in byObject)
                ):
                    name = byObject[id(var)]
                    solnfile.write('{} {} {}\n'.format(column_index, name, var.value))
                    # Cbc ignores column indexes, so the value does not matter.
                    column_index += 1

There are 2 problems:

  • If the variable is a Real, it is not considered in the warmstart but the latest stable version of cbc (2.10.7) accepts it
  • If the variable is Binary, and is set to True in the warmstart, pyomo writes "True" but cbc can only read numeric valid, so it should be 1

Steps to reproduce the issue

$ python pyomo_cbc_warmstart_bug.py
# pyomo_cbc_warmstart_bug.py
from pyomo.environ import (
    ConcreteModel,
    Var,
    Integers,
    Binary,
    Reals,
    Objective,
    Constraint,
    SolverFactory,
    maximize
)

m = ConcreteModel()

# decision variables
m.x1 = Var(domain=Integers, name="x1", bounds=(0, 10))
m.x2 = Var(domain=Reals, name="x2", bounds=(0, 10))
m.x3 = Var(domain=Binary, name="x3")

# objective function
m.OBJ = Objective(expr=(3*m.x1 + 2*m.x2 + 4*m.x3), sense=maximize)

# constraints
m.C1 = Constraint(expr=m.x1 + m.x2 <= 9)
m.C2 = Constraint(expr=3*m.x1 + m.x2 <= 18)
m.C3 = Constraint(expr=m.x1 <= 7)
m.C4 = Constraint(expr=m.x2 <= 6)

# MIP start
m.x1 = 4
m.x2 = 4.5
m.x3 = True

# solving process
SolverFactory('cbc').solve(m, tee=True, warmstart=True).write()

Error Message

$ command line - /usr/bin/cbc -printingOptions all -import /tmp/tmpjeb6cedi.pyomo.lp -mipstart /tmp/tmpgkdx66mk.cbc.soln -stat=1 -solve -solu /tmp/tmpjeb6cedi.pyomo.soln (default strategy 1)
$ Option for printingOptions changed from normal to all
$ CoinLpIO::readLp(): Maximization problem reformulated as minimization
$ Coin0009I Switching back to maximization to get correct duals etc
$ opening mipstart file /tmp/tmpgkdx66mk.cbc.soln.
$ Reading: /tmp/tmpgkdx66mk.cbc.soln, line 2 - Third column in mipstart file should be numeric, ignoring.
$ MIPStart values read for 1 variables.
...

The important part is that The third column should be numeric, (in this case, it is "True")
And only 1 variable was read, the Integer one, and neither the Real one nor the Binary one.

Information on your system

Pyomo version: 6.8.2
Python version: 3.10.12
Operating system: Ubuntu 22.04
How Pyomo was installed (PyPI, conda, source): pip
Solver (if applicable): cbc 2.10.7

Additional information

I can suggest a correction, maybe I should directly have done a PR, I'm not sure.

        column_index = 0
        with open(filename, 'w') as solnfile:
            for var in instance.component_data_objects(Var):
                # Cbc only expects variables with non-zero
                # values for mipstart.
                if (
                    var.value
                    and (var.is_integer() or var.is_binary() or var.is_continuous())
                    and (id(var) in byObject)
                ):
                    name = byObject[id(var)]
                    if var.is_binary():
                        var_value = 1
                    else:
                        var_value = var.value
                    solnfile.write('{} {} {}\n'.format(column_index, name, var_value))
                    # Cbc ignores column indexes, so the value does not matter.
                    column_index += 1
@feroi35 feroi35 added the bug label Dec 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant