Skip to content

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

Open
@feroi35

Description

@feroi35

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions