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

Inconsistent behavior between the CBC and HiGHS #2656

Closed
SolverMax opened this issue Dec 5, 2022 · 5 comments · Fixed by #2763
Closed

Inconsistent behavior between the CBC and HiGHS #2656

SolverMax opened this issue Dec 5, 2022 · 5 comments · Fixed by #2763
Labels

Comments

@SolverMax
Copy link

I'm puzzled by inconsistent behavior between the CBC and HiGHS solvers.

Given the attached model, CBC returns the correct optimal solution of 15, while HiGHS fails with an error: "ValueError: Error when adding rows". The choice of solver is specified on line 3.

The HiGHS error occurs on line 30. However, if we comment out line 30 and uncomment line 31, then HiGHS works correctly.

When using HiGHS, why is it necessary to use pyo.value(Model.ShelfHeights[s]) rather than just Model.ShelfHeights[s] like we can with CBC (and GLPK)?

Pyomo version 6.4.3
HiGHS version 1.4.0

HiGHS_test.txt

@blnicho
Copy link
Member

blnicho commented Dec 5, 2022

@SolverMax it would help us debug this if you could provide the full stacktrace of the error you're seeing.

I haven't tried running your model but on first glance this seems like a bug, the APPSI HiGHS interface should work on models with mutable parameters without needing to call the value function.

For reference for others these are lines 30 and 31 mentioned above:

# Model.ShelfHeights is a mutable indexed Param
def rule_fit(Model, P):
        # line 30
        return sum(Model.ShelfHeights[s] * Model.Allocation[P, s] for s in Model.S) >= Model.Pallets[P]
        # line 31
        #return sum(pyo.value(Model.ShelfHeights[s]) * Model.Allocation[P, s] for s in Model.S) >= Model.Pallets[P]
Model.PalletFits = pyo.Constraint(Model.P, rule = rule_fit)

@SolverMax
Copy link
Author

When I run the model, the error message is:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [7], in <cell line: 1>()
----> 1 Main()

Input In [6], in Main()
      5 DefineData(Model, Pallets, ShelfHeights)
      6 DefineModel(Model)
----> 7 Results = Solver.solve(Model)
      8 print(f'Objective = {pyo.value(Model.Racks()):5,.0f}')

File D:\onedrive\python\blog\lib\site-packages\pyomo\contrib\appsi\base.py:1308, in LegacySolverInterface.solve(self, model, tee, load_solutions, logfile, solnfile, timelimit, report_timing, solver_io, suffixes, options, keepfiles, symbolic_solver_labels)
   1305 if options is not None:
   1306     self.options = options
-> 1308 results: Results = super(LegacySolverInterface, self).solve(model)
   1310 legacy_results = LegacySolverResults()
   1311 legacy_soln = LegacySolution()

File D:\onedrive\python\blog\lib\site-packages\pyomo\contrib\appsi\solvers\highs.py:215, in Highs.solve(self, model, timer)
    213 if model is not self._model:
    214     timer.start('set_instance')
--> 215     self.set_instance(model)
    216     timer.stop('set_instance')
    217 else:

File D:\onedrive\python\blog\lib\site-packages\pyomo\contrib\appsi\solvers\highs.py:320, in Highs.set_instance(self, model)
    317     self._expr_types = cmodel.PyomoExprTypes()
    319 self._solver_model = highspy.Highs()
--> 320 self.add_block(model)
    321 if self._objective is None:
    322     self.set_objective(None)

File D:\onedrive\python\blog\lib\site-packages\pyomo\contrib\appsi\base.py:951, in PersistentBase.add_block(self, block)
    949 if self._only_child_vars:
    950     self.add_variables(list(dict((id(var), var) for var in block.component_data_objects(Var, descend_into=True)).values()))
--> 951 self.add_constraints([con for con in block.component_data_objects(Constraint, descend_into=True,
    952                                                                   active=True)])
    953 self.add_sos_constraints([con for con in block.component_data_objects(SOSConstraint, descend_into=True,
    954                                                                       active=True)])
    955 obj = get_objective(block)

File D:\onedrive\python\blog\lib\site-packages\pyomo\contrib\appsi\base.py:878, in PersistentBase.add_constraints(self, cons)
    876             v.unfix()
    877             all_fixed_vars[id(v)] = v
--> 878 self._add_constraints(cons)
    879 for v in all_fixed_vars.values():
    880     v.fix()

File D:\onedrive\python\blog\lib\site-packages\pyomo\contrib\appsi\solvers\highs.py:382, in Highs._add_constraints(self, cons)
    379     self._solver_con_to_pyomo_con_map[current_num_cons] = con
    380     current_num_cons += 1
--> 382 self._solver_model.addRows(len(lbs),
    383                            np.array(lbs, dtype=np.double),
    384                            np.array(ubs, dtype=np.double),
    385                            len(coef_values),
    386                            np.array(starts),
    387                            np.array(var_indices),
    388                            np.array(coef_values, dtype=np.double))

ValueError: Error when adding rows

@Loisel
Copy link

Loisel commented Mar 8, 2023

+1

@michaelbynum
Copy link
Contributor

This should get fixed by #2763

@michaelbynum
Copy link
Contributor

The problem was mutable parameters that resulted in coefficients with a value of 0. We were handing these coefficients to HiGHS so we can efficiently modify them if the mutable parameter value changes, but HiGHS was unhappy with that. It turns out that we can skip these coefficients and still update them efficiently if the mutable parameter value changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants