Closed ZedongPeng closed 1 year ago
@michaelbynum
Isn't this correct? The new variable in the model is not the same one that is used in the constraints/objective.
Just to be clear, when a variable is deleted and a new one is created with the same name, it is not the same variable:
>>> import pyomo.environ as pe
>>> m = pe.ConcreteModel()
>>> m.x = pe.Var()
>>> m.c = pe.Constraint(expr=m.x == 1)
>>> m.del_component('x')
>>> m.x = pe.Var()
>>> from pyomo.core.expr.visitor import identify_variables
>>> from pyomo.common.collections import ComponentSet
>>> m.x in ComponentSet(identify_variables(m.c.body))
False
There is a better example. model.q3
is newly defined and only appears in model.obj
. If we delete both model.q3
and model.obj
, then define them again. The same error will be reported.
Is it too strict to raise a ValueError
here? I think in this case appsi_solver
should at least solve the new model, right?
from pyomo.environ import *
from pyomo.solvers.tests.models.QCP_simple import QCP_simple
QCP_model = QCP_simple()
QCP_model._generate_model()
model = QCP_model.model
model.q3 = Var(bounds=(-2, None))
model.obj = Objective(expr=model.x + model.q1 - model.q2 - model.q3, sense=maximize)
opt = SolverFactory('appsi_gurobi') # or 'appsi_cplex'
result = opt.solve(QCP_model.model,tee=True)
print(result)
model.del_component('q3')
model.q3 = Var(bounds=(-2, None))
model.del_component('obj')
model.obj = Objective(expr=model.x + model.q1 - model.q2 - model.q3, sense=maximize)
# opt = SolverFactory('appsi_gurobi')
result = opt.solve(QCP_model.model,tee=True)
print(result)
Thanks. This helps. I'll get this fixed.
Hi @michaelbynum . Any progress on this?
Hi @michaelbynum . #2903 didn't fix this issue.
If I run the following code, the same error will show up again with the latest Pyomo.(installed through python setup.py develop
)
from pyomo.environ import *
from pyomo.solvers.tests.models.QCP_simple import QCP_simple
QCP_model = QCP_simple()
QCP_model._generate_model()
model = QCP_model.model
model.q3 = Var(bounds=(-2, None))
model.obj = Objective(expr=model.x + model.q1 - model.q2 - model.q3, sense=maximize)
opt = SolverFactory('appsi_gurobi') # or 'appsi_cplex'
result = opt.solve(QCP_model.model,tee=True)
print(result)
model.del_component('q3')
model.q3 = Var(bounds=(-2, None))
model.del_component('obj')
model.obj = Objective(expr=model.x + model.q1 - model.q2 - model.q3, sense=maximize)
# opt = SolverFactory('appsi_gurobi')
result = opt.solve(QCP_model.model,tee=True)
print(result)
Output
WARNING: Implicitly replacing the Component attribute obj (type=<class
'pyomo.core.base.objective.ScalarObjective'>) on block QCP_simple with a new
Component (type=<class 'pyomo.core.base.objective.ScalarObjective'>). This is
usually indicative of a modelling error. To avoid this warning, use
block.del_component() and block.add_component().
Version identifier: 22.1.1.0 | 2022-11-28 | 9160aff4d
CPXPARAM_Read_DataCheck 1
Tried aggregator 1 time.
QCP Presolve eliminated 1 rows and 4 columns.
Reduced QCP has 7 rows, 7 columns, and 14 nonzeros.
Reduced QCP has 2 quadratic constraints.
Presolve time = 0.00 sec. (0.01 ticks)
Parallel mode: using up to 12 threads for barrier.
Number of nonzeros in lower triangle of A*A' = 21
Using Approximate Minimum Degree ordering
Total time for automatic ordering = 0.00 sec. (0.00 ticks)
Summary statistics for Cholesky factor:
Threads = 12
Rows in Factor = 7
Integer space required = 7
Total non-zeros in factor = 28
Total FP ops to factor = 140
Itn Primal Obj Dual Obj Prim Inf Upper Inf Dual Inf Inf Ratio
0 4.2000000e+00 4.2000000e+00 6.69e+00 0.00e+00 6.83e+00 1.00e+00
1 4.4505445e+00 4.5170460e+00 6.69e+00 0.00e+00 6.83e+00 1.37e+02
2 4.4887794e+00 4.4973082e+00 4.94e-01 0.00e+00 5.04e-01 6.77e+02
3 4.4905466e+00 4.4920134e+00 6.69e-02 0.00e+00 6.83e-02 2.69e+03
4 4.4915508e+00 4.4918356e+00 1.23e-02 0.00e+00 1.26e-02 9.06e+03
5 4.4915775e+00 4.4916018e+00 2.64e-03 0.00e+00 2.70e-03 9.32e+04
6 4.4915622e+00 4.4915628e+00 2.34e-04 0.00e+00 2.39e-04 1.81e+06
7 4.4915623e+00 4.4915623e+00 7.44e-06 0.00e+00 7.60e-06 6.78e+07
8 4.4915622e+00 4.4915622e+00 1.98e-07 0.00e+00 2.02e-07 6.27e+09
Problem:
- Lower bound: 4.491562247172249
Upper bound: 4.491562247172249
Number of objectives: 1
Number of constraints: 0
Number of variables: 0
Sense: -1
Solver:
- Status: ok
Termination condition: optimal
Termination message: TerminationCondition.optimal
Solution:
- number of solutions: 0
number of solutions displayed: 0
Traceback (most recent call last):
File "/Users/zedongpeng/Github/pyomo/pyomo/contrib/mindtpy/tests/test.py", line 19, in <module>
result = opt.solve(QCP_model.model, tee=True)
File "/Users/zedongpeng/opt/anaconda3/envs/py310/lib/python3.10/site-packages/Pyomo-6.6.2.dev0-py3.10.egg/pyomo/contrib/appsi/base.py", line 1554, in solve
results: Results = super(LegacySolverInterface, self).solve(model)
File "/Users/zedongpeng/opt/anaconda3/envs/py310/lib/python3.10/site-packages/Pyomo-6.6.2.dev0-py3.10.egg/pyomo/contrib/appsi/solvers/cplex.py", line 222, in solve
self._writer.write(model, self._filename + '.lp', timer=timer)
File "/Users/zedongpeng/opt/anaconda3/envs/py310/lib/python3.10/site-packages/Pyomo-6.6.2.dev0-py3.10.egg/pyomo/contrib/appsi/writers/lp_writer.py", line 168, in write
self.update(timer=timer)
File "/Users/zedongpeng/opt/anaconda3/envs/py310/lib/python3.10/site-packages/Pyomo-6.6.2.dev0-py3.10.egg/pyomo/contrib/appsi/base.py", line 1338, in update
self.remove_variables(old_vars)
File "/Users/zedongpeng/opt/anaconda3/envs/py310/lib/python3.10/site-packages/Pyomo-6.6.2.dev0-py3.10.egg/pyomo/contrib/appsi/base.py", line 1181, in remove_variables
raise ValueError(
ValueError: cannot remove variable q3 - it is still being used by constraints or the objective
Strange. I just ran this, and I did not get an error.
Yes. It's strange. I reinstalled appsi
, but the error still showed up.
# Name Version Build Channel
pyomo 6.6.2.dev0 dev_0 <develop>
You are on the main branch?
Yes. I am on the main branch. I found the problem.
If I define opt = SolverFactory('appsi_cplex')
again after the model has changed, the script will work well.
from pyomo.environ import *
from pyomo.solvers.tests.models.QCP_simple import QCP_simple
QCP_model = QCP_simple()
QCP_model._generate_model()
model = QCP_model.model
model.q3 = Var(bounds=(-2, None))
model.obj = Objective(expr=model.x + model.q1 - model.q2 - model.q3, sense=maximize)
opt = SolverFactory('appsi_cplex') # or 'appsi_cplex'
result = opt.solve(QCP_model.model, tee=True)
print(result)
model.del_component('q3')
model.q3 = Var(bounds=(-2, None))
model.del_component('obj')
model.obj = Objective(expr=model.x + model.q1 - model.q2 - model.q3, sense=maximize)
opt = SolverFactory('appsi_cplex')
result = opt.solve(QCP_model.model, tee=True)
print(result)
However, the key of appsi_solver
is defining opt
only once and repeatedly solving the model, right?
Correct. You should not have to reconstruct the solver. That defeats the purpose of Appsi. Something is wrong. It's hard to debug when I can't reproduce the issue though.
I tried to start from the beginning.
The error still showed up.
@michaelbynum Any suggestions to further test on this?
It suddenly works as expected. Thanks for your help.
Just one more question, I use anaconda. The base environment is Python 3.7 and works well. However, when I changed to another virtual environment with Python 3.10, it failed.
Do I need to rebuild the appsi_solver
in the new virtual environment?
It worked well after I rebuilt it in the new virtual environment. Thanks for your effort.
Summary
APPSI solver will report the
cannot remove variable q2 - it is still being used by constraints or the objective
error if the variable is deleted and defined again.Steps to reproduce the issue
Error Message
Information on your system
Pyomo version: 6.6.1.dev0 Python version: 3.9.10 Operating system: macOS Monterey Version 12.1 How Pyomo was installed (PyPI, conda, source): source Solver (if applicable):appsi_cplex, appsi_gurobi
Additional information