def select_tear_mip(self, G, solver, solver_io=None, solver_options={}): """ This finds optimal sets of tear edges based on two criteria. The primary objective is to minimize the maximum number of times any cycle is broken. The seconday criteria is to minimize the number of tears. This function creates a MIP problem in Pyomo with a doubly weighted objective and solves it with the solver arguments. """ model, bin_list = self.select_tear_mip_model(G) from pyomo.environ import SolverFactory opt = SolverFactory(solver, solver_io=solver_io) if not opt.available(exception_flag=False): raise ValueError("Solver '%s' (solver_io=%r) is not available, please pass a " "different solver" % (solver, solver_io)) opt.solve(model, **solver_options) # collect final list by adding every edge with a "True" binary var tset = [] for i in range(len(bin_list)): if bin_list[i].value == 1: tset.append(i) return tset
def solve(model): opt = SolverFactory('ipopt') instance = model results = opt.solve(instance) instance.solutions.store_to(results) return results
def solve_model(model, solver='glpk', solver_io=None, keepfiles=True, verbose=True, symbolic_solver_labels=True, is_mip=True, mipgap=0.01): if solver == 'xpress': solver = SolverFactory(solver, solver_io=solver_io, is_mip=is_mip) else: solver = SolverFactory(solver, solver_io=solver_io) model.preprocess() if is_mip: solver.options['mipgap'] = mipgap with warnings.catch_warnings(): warnings.simplefilter(PSST_WARNING) solver.solve(model, suffixes=['dual'], tee=verbose, keepfiles=keepfiles, symbolic_solver_labels=symbolic_solver_labels) return model
def test_as_good_with_iteration_rand(self): # initialize model with data m = build_model() # create ipopt solver optsolver = SolverFactory('ipopt') optsolver.solve(m) for i in range(10): m2 = build_model() SolverFactory('multistart').solve(m2, iterations=10) m_objectives = m.component_data_objects(Objective, active=True) m_obj = next(m_objectives, None) m2_objectives = m2.component_data_objects(Objective, active=True) m2_obj = next(m2_objectives,None) self.assertTrue((value(m2_obj.expr)) >= (value(m_obj.expr) - .001)) del m2
def test_help_solvers(self): with capture_output() as OUT: help_solvers() OUT = OUT.getvalue() self.assertTrue(re.search('Pyomo Solvers and Solver Managers', OUT)) self.assertTrue(re.search('Serial Solver', OUT)) # Test known solvers and metasolver flags # ASL is a metasolver self.assertTrue(re.search('asl +\+', OUT)) # PS is bundles with Pyomo so should always be available self.assertTrue(re.search('ps +\*', OUT)) for solver in ('ipopt','baron','cbc','glpk'): s = SolverFactory(solver) if s.available(): self.assertTrue(re.search("%s +\* [a-zA-Z]" % solver, OUT)) else: self.assertTrue(re.search("%s +[a-zA-Z]" % solver, OUT))
def test_var_value_None(self): m = ConcreteModel() m.x = Var(bounds=(0, 1)) m.obj = Objective(expr=m.x) SolverFactory('multistart').solve(m)
ReactionParameterBlock, ReactionBlockBase, ReactionBlockDataBase, MaterialFlowBasis) from idaes.core.util.testing import PhysicalParameterTestBlock from idaes.core.util.model_statistics import degrees_of_freedom from idaes.generic_models.unit_models import CSTR, Mixer, MomentumMixingType from idaes.generic_models.control import PIDBlock, PIDForm from idaes.core.util.initialization import initialize_by_time_element from idaes.core.util.tests.test_initialization import \ AqueousEnzymeParameterBlock, EnzymeReactionParameterBlock import idaes.logger as idaeslog __author__ = "Robert Parker" # See if ipopt is available and set up solver if SolverFactory('ipopt').available(): solver = SolverFactory('ipopt') solver.options = {'tol': 1e-6} else: solver = None def make_model(horizon=6, ntfe=60, ntcp=2, inlet_E=11.91, inlet_S=12.92): time_set = [0, horizon] m = ConcreteModel(name='CSTR with level control') m.fs = FlowsheetBlock(default={'dynamic': True, 'time_set': time_set}) m.fs.properties = AqueousEnzymeParameterBlock() m.fs.reactions = EnzymeReactionParameterBlock(
""" import pytest from pyomo.environ import ConcreteModel, SolverFactory from idaes.core import FlowsheetBlock from idaes.unit_models.plug_flow_reactor import PFR from idaes.property_models.examples.saponification_thermo import ( SaponificationParameterBlock) from idaes.property_models.examples.saponification_reactions import ( SaponificationReactionParameterBlock) from idaes.ui.report import degrees_of_freedom # ----------------------------------------------------------------------------- # See if ipopt is available and set up solver if SolverFactory('ipopt').available(): solver = SolverFactory('ipopt') solver.options = {'tol': 1e-6, 'mu_init': 1e-8, 'bound_push': 1e-8} else: solver = None # ----------------------------------------------------------------------------- def test_build(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = SaponificationParameterBlock() m.fs.reactions = SaponificationReactionParameterBlock( default={"property_package": m.fs.properties})
def test_no_obj(self): m = ConcreteModel() m.x = Var() with self.assertRaisesRegexp(RuntimeError, "no active objective"): SolverFactory('multistart').solve(m)
def initialize( self, state_args={}, outlvl=idaeslog.NOTSET, solver="ipopt", optarg={ "tol": 1e-6, "max_iter": 30 }, ): """ Initialize the inlet turbine stage model. This deactivates the specialized constraints, then does the isentropic turbine initialization, then reactivates the constraints and solves. Args: state_args (dict): Initial state for property initialization outlvl (int): Amount of output (0 to 3) 0 is lowest solver (str): Solver to use for initialization optarg (dict): Solver arguments dictionary """ init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit") # sp is what to save to make sure state after init is same as the start # saves value, fixed, and active state, doesn't load originally free # values, this makes sure original problem spec is same but initializes # the values of free vars sp = StoreSpec.value_isfixed_isactive(only_fixed=True) istate = to_json(self, return_dict=True, wts=sp) # Deactivate special constraints self.inlet_flow_constraint.deactivate() self.isentropic_enthalpy.deactivate() self.efficiency_correlation.deactivate() self.deltaP.unfix() self.ratioP.unfix() # Fix turbine parameters + eff_isen self.eff_nozzle.fix() self.blade_reaction.fix() self.flow_coeff.fix() self.blade_velocity.fix() # fix inlet and free outlet for t in self.flowsheet().config.time: for k, v in self.inlet.vars.items(): v[t].fix() for k, v in self.outlet.vars.items(): v[t].unfix() # If there isn't a good guess for efficeny or outlet pressure # provide something reasonable. eff = self.efficiency_isentropic[t] eff.fix( eff.value if value(eff) > 0.3 and value(eff) < 1.0 else 0.8) # for outlet pressure try outlet pressure, pressure ratio, delta P, # then if none of those look reasonable use a pressure ratio of 0.8 # to calculate outlet pressure Pout = self.outlet.pressure[t] Pin = self.inlet.pressure[t] prdp = value((self.deltaP[t] - Pin) / Pin) if value(Pout / Pin) > 0.98 or value(Pout / Pin) < 0.3: if value(self.ratioP[t]) < 0.98 and value( self.ratioP[t]) > 0.3: Pout.fix(value(Pin * self.ratioP)) elif prdp < 0.98 and prdp > 0.3: Pout.fix(value(prdp * Pin)) else: Pout.fix(value(Pin * 0.8)) else: Pout.fix() self.deltaP[:] = value(Pout - Pin) self.ratioP[:] = value(Pout / Pin) for t in self.flowsheet().config.time: self.properties_isentropic[t].pressure.value = value( self.outlet.pressure[t]) self.properties_isentropic[t].flow_mol.value = value( self.inlet.flow_mol[t]) self.properties_isentropic[t].enth_mol.value = value( self.inlet.enth_mol[t] * 0.95) self.outlet.flow_mol[t].value = value(self.inlet.flow_mol[t]) self.outlet.enth_mol[t].value = value(self.inlet.enth_mol[t] * 0.95) # Make sure the initialization problem has no degrees of freedom # This shouldn't happen here unless there is a bug in this dof = degrees_of_freedom(self) try: assert dof == 0 except: init_log.exception("degrees_of_freedom = {}".format(dof)) raise # one bad thing about reusing this is that the log messages aren't # really compatible with being nested inside another initialization super().initialize(state_args=state_args, outlvl=outlvl, solver=solver, optarg=optarg) # Free eff_isen and activate sepcial constarints self.efficiency_isentropic.unfix() self.outlet.pressure.unfix() self.inlet_flow_constraint.activate() self.isentropic_enthalpy.activate() self.efficiency_correlation.activate() slvr = SolverFactory(solver) slvr.options = optarg with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = slvr.solve(self, tee=slc.tee) init_log.info("Initialization Complete: {}".format( idaeslog.condition(res))) # reload original spec from_json(self, sd=istate, wts=sp)
# Under the terms of Contract DE-NA0003525 with National Technology and # Engineering Solutions of Sandia, LLC, the U.S. Government retains certain # rights in this software. # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ import os from pyomo.environ import ( SolverFactory, ConcreteModel, Var, Constraint, Objective, Integers, Boolean, Suffix, maximize, ) from pyomo.common.tee import capture_output from pyomo.common.tempfiles import TempfileManager import pyomo.common.unittest as unittest opt_cbc = SolverFactory('cbc') cbc_available = opt_cbc.available(exception_flag=False) class CBCTests(unittest.TestCase): @unittest.skipIf(not cbc_available, "The CBC solver is not available") def test_warm_start(self): m = ConcreteModel() m.x = Var() m.z = Var(domain=Integers) m.w = Var(domain=Boolean) m.c = Constraint(expr=m.x + m.z + m.w >= 0) m.o = Objective(expr=m.x + m.z + m.w)
class TestGDPoptRIC(unittest.TestCase): """Tests for the GDPopt solver plugin.""" def test_infeasible_GDP(self): """Test for infeasible GDP.""" m = ConcreteModel() m.x = Var(bounds=(0, 2)) m.d = Disjunction(expr=[ [m.x ** 2 >= 3, m.x >= 3], [m.x ** 2 <= -1, m.x <= -1]]) m.o = Objective(expr=m.x) output = StringIO() with LoggingIntercept(output, 'pyomo.contrib.gdpopt', logging.WARNING): SolverFactory('gdpopt').solve( m, strategy='RIC', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertIn("Set covering problem was infeasible.", output.getvalue().strip()) def test_GDP_nonlinear_objective(self): m = ConcreteModel() m.x = Var(bounds=(-1, 10)) m.y = Var(bounds=(2, 3)) m.d = Disjunction(expr=[ [m.x + m.y >= 5], [m.x - m.y <= 3] ]) m.o = Objective(expr=m.x ** 2) SolverFactory('gdpopt').solve( m, strategy='RIC', mip_solver=mip_solver, nlp_solver=nlp_solver ) self.assertAlmostEqual(value(m.o), 0) m = ConcreteModel() m.x = Var(bounds=(-1, 10)) m.y = Var(bounds=(2, 3)) m.d = Disjunction(expr=[ [m.x + m.y >= 5], [m.x - m.y <= 3] ]) m.o = Objective(expr=-m.x ** 2, sense=maximize) SolverFactory('gdpopt').solve( m, strategy='RIC', mip_solver=mip_solver, nlp_solver=nlp_solver ) self.assertAlmostEqual(value(m.o), 0) @unittest.skipUnless(sympy_available, "Sympy not available") def test_logical_constraints_on_disjuncts(self): m = models.makeLogicalConstraintsOnDisjuncts() SolverFactory('gdpopt').solve(m, strategy='RIC', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertAlmostEqual(value(m.x), 8) @unittest.skipUnless(sympy_available, "Sympy not available") def test_boolean_vars_on_disjuncts(self): m = models.makeBooleanVarsOnDisjuncts() SolverFactory('gdpopt').solve(m, strategy='RIC', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertAlmostEqual(value(m.x), 8) def test_RIC_8PP_default_init(self): """Test logic-based outer approximation with 8PP.""" exfile = import_file( join(exdir, 'eight_process', 'eight_proc_model.py')) eight_process = exfile.build_eight_process_flowsheet() SolverFactory('gdpopt').solve( eight_process, strategy='RIC', mip_solver=mip_solver, nlp_solver=nlp_solver, tee=False) self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2) @unittest.skipUnless(sympy_available, "Sympy not available") def test_RIC_8PP_logical_default_init(self): """Test logic-based outer approximation with 8PP.""" exfile = import_file( join(exdir, 'eight_process', 'eight_proc_logical.py')) eight_process = exfile.build_eight_process_flowsheet() SolverFactory('gdpopt').solve( eight_process, strategy='RIC', mip_solver=mip_solver, nlp_solver=nlp_solver, tee=False) self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2) @unittest.skipUnless(SolverFactory('gams').available(exception_flag=False), 'GAMS solver not available') def test_RIC_8PP_gams_solver(self): # Make sure that the duals are still correct exfile = import_file( join(exdir, 'eight_process', 'eight_proc_model.py')) eight_process = exfile.build_eight_process_flowsheet() SolverFactory('gdpopt').solve( eight_process, strategy='RIC', mip_solver=mip_solver, nlp_solver='gams', max_slack=0, tee=False) self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2) def test_RIC_8PP_force_NLP(self): exfile = import_file( join(exdir, 'eight_process', 'eight_proc_model.py')) eight_process = exfile.build_eight_process_flowsheet() SolverFactory('gdpopt').solve( eight_process, strategy='RIC', mip_solver=mip_solver, nlp_solver=nlp_solver, force_subproblem_nlp=True, tee=False) self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2) def test_RIC_strip_pack_default_init(self): """Test logic-based outer approximation with strip packing.""" exfile = import_file( join(exdir, 'strip_packing', 'strip_packing_concrete.py')) strip_pack = exfile.build_rect_strip_packing_model() SolverFactory('gdpopt').solve( strip_pack, strategy='RIC', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertTrue( fabs(value(strip_pack.total_length.expr) - 11) <= 1E-2) @unittest.skipUnless(sympy_available, "Sympy not available") def test_RIC_strip_pack_default_init_logical_constraints(self): """Test logic-based outer approximation with strip packing with logical constraints.""" exfile = import_file( join(exdir, 'strip_packing', 'strip_packing_concrete.py')) strip_pack = exfile.build_rect_strip_packing_model() # add logical constraints strip_pack.Rec3AboveOrBelowRec1 = LogicalConstraint( expr=strip_pack.no_overlap[1,3].disjuncts[2].indicator_var.lor( strip_pack.no_overlap[1,3].disjuncts[3].indicator_var)) strip_pack.Rec3RightOrLeftOfRec2 = LogicalConstraint( expr=strip_pack.no_overlap[2,3].disjuncts[0].indicator_var.lor( strip_pack.no_overlap[2,3].disjuncts[1].indicator_var)) SolverFactory('gdpopt').solve( strip_pack, strategy='RIC', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertTrue( fabs(value(strip_pack.total_length.expr) - 13) <= 1E-2) @unittest.pytest.mark.expensive def test_RIC_constrained_layout_default_init(self): """Test RIC with constrained layout.""" exfile = import_file( join(exdir, 'constrained_layout', 'cons_layout_model.py')) cons_layout = exfile.build_constrained_layout_model() SolverFactory('gdpopt').solve( cons_layout, strategy='RIC', mip_solver=mip_solver, nlp_solver=nlp_solver, iterlim=120, max_slack=5, # problem is convex, so can decrease slack ) objective_value = value(cons_layout.min_dist_cost.expr) self.assertTrue( fabs(objective_value - 41573) <= 200, "Objective value of %s instead of 41573" % objective_value) def test_RIC_8PP_maxBinary(self): """Test logic-based OA with max_binary initialization.""" exfile = import_file( join(exdir, 'eight_process', 'eight_proc_model.py')) eight_process = exfile.build_eight_process_flowsheet() SolverFactory('gdpopt').solve( eight_process, strategy='RIC', init_strategy='max_binary', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2) def test_RIC_strip_pack_maxBinary(self): """Test RIC with strip packing using max_binary initialization.""" exfile = import_file( join(exdir, 'strip_packing', 'strip_packing_concrete.py')) strip_pack = exfile.build_rect_strip_packing_model() SolverFactory('gdpopt').solve( strip_pack, strategy='RIC', init_strategy='max_binary', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertTrue( fabs(value(strip_pack.total_length.expr) - 11) <= 1E-2) @unittest.skipUnless(sympy_available, "Sympy not available") def test_RIC_strip_pack_maxBinary_logical_constraints(self): """Test RIC with strip packing using max_binary initialization and including logical constraints.""" exfile = import_file( join(exdir, 'strip_packing', 'strip_packing_concrete.py')) strip_pack = exfile.build_rect_strip_packing_model() # add logical constraints strip_pack.Rec3AboveOrBelowRec1 = LogicalConstraint( expr=strip_pack.no_overlap[1,3].disjuncts[2].indicator_var.lor( strip_pack.no_overlap[1,3].disjuncts[3].indicator_var)) strip_pack.Rec3RightOrLeftOfRec2 = LogicalConstraint( expr=strip_pack.no_overlap[2,3].disjuncts[0].indicator_var.lor( strip_pack.no_overlap[2,3].disjuncts[1].indicator_var)) SolverFactory('gdpopt').solve( strip_pack, strategy='RIC', init_strategy='max_binary', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertTrue( fabs(value(strip_pack.total_length.expr) - 13) <= 1E-2) def test_RIC_8PP_fixed_disjuncts(self): """Test RIC with 8PP using fixed disjuncts initialization.""" exfile = import_file( join(exdir, 'eight_process', 'eight_proc_model.py')) eight_process = exfile.build_eight_process_flowsheet() initialize = [ # Use units 1, 4, 7, 8 eight_process.use_unit_1or2.disjuncts[0], eight_process.use_unit_3ornot.disjuncts[1], eight_process.use_unit_4or5ornot.disjuncts[0], eight_process.use_unit_6or7ornot.disjuncts[1], eight_process.use_unit_8ornot.disjuncts[0] ] for disj in eight_process.component_data_objects(Disjunct): if disj in initialize: disj.binary_indicator_var.set_value(1) else: disj.binary_indicator_var.set_value(0) SolverFactory('gdpopt').solve( eight_process, strategy='RIC', init_strategy='fix_disjuncts', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2) def test_RIC_custom_disjuncts(self): """Test logic-based OA with custom disjuncts initialization.""" exfile = import_file( join(exdir, 'eight_process', 'eight_proc_model.py')) eight_process = exfile.build_eight_process_flowsheet() initialize = [ # Use units 1, 4, 7, 8 [eight_process.use_unit_1or2.disjuncts[0], eight_process.use_unit_3ornot.disjuncts[1], eight_process.use_unit_4or5ornot.disjuncts[0], eight_process.use_unit_6or7ornot.disjuncts[1], eight_process.use_unit_8ornot.disjuncts[0]], # Use units 2, 4, 6, 8 [eight_process.use_unit_1or2.disjuncts[1], eight_process.use_unit_3ornot.disjuncts[1], eight_process.use_unit_4or5ornot.disjuncts[0], eight_process.use_unit_6or7ornot.disjuncts[0], eight_process.use_unit_8ornot.disjuncts[0]] ] def assert_correct_disjuncts_active(nlp_model, solve_data): if solve_data.master_iteration >= 1: return # only checking initialization iter_num = solve_data.nlp_iteration disjs_should_be_active = initialize[iter_num - 1] for orig_disj, soln_disj in zip( solve_data.original_model.GDPopt_utils.disjunct_list, nlp_model.GDPopt_utils.disjunct_list ): if orig_disj in disjs_should_be_active: self.assertTrue(soln_disj.binary_indicator_var.value == 1) SolverFactory('gdpopt').solve( eight_process, strategy='RIC', init_strategy='custom_disjuncts', custom_init_disjuncts=initialize, mip_solver=mip_solver, nlp_solver=nlp_solver, call_after_subproblem_feasible=assert_correct_disjuncts_active) self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2)
from pyomo.environ import SolverFactory import time from pyomo.contrib.mindtpy.tests.flay03m import * # from pyomo.contrib.mindtpy.tests.eight_process_problem import EightProcessFlowsheet # model = EightProcessFlowsheet() # with SolverFactory('mindtpy') as opt: with SolverFactory('mindtpy') as opt: print('\n Solving problem with Outer Approximation') start = time.time() # opt.solve(model, strategy='OA', init_strategy = 'rNLP') opt.solve(model) # model.pprint() print(time.time() - start)
class TestGDPopt(unittest.TestCase): """Tests for the GDPopt solver plugin.""" def test_infeasible_GDP(self): """Test for infeasible GDP.""" m = ConcreteModel() m.x = Var(bounds=(0, 2)) m.d = Disjunction(expr=[ [m.x ** 2 >= 3, m.x >= 3], [m.x ** 2 <= -1, m.x <= -1]]) m.o = Objective(expr=m.x) output = StringIO() with LoggingIntercept(output, 'pyomo.contrib.gdpopt', logging.WARNING): SolverFactory('gdpopt').solve( m, strategy='LOA', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertIn("Set covering problem was infeasible.", output.getvalue().strip()) def test_GDP_nonlinear_objective(self): m = ConcreteModel() m.x = Var(bounds=(-1, 10)) m.y = Var(bounds=(2, 3)) m.d = Disjunction(expr=[ [m.x + m.y >= 5], [m.x - m.y <= 3] ]) m.o = Objective(expr=m.x ** 2) SolverFactory('gdpopt').solve( m, strategy='LOA', mip_solver=mip_solver, nlp_solver=nlp_solver ) self.assertAlmostEqual(value(m.o), 0) m = ConcreteModel() m.x = Var(bounds=(-1, 10)) m.y = Var(bounds=(2, 3)) m.d = Disjunction(expr=[ [m.x + m.y >= 5], [m.x - m.y <= 3] ]) m.o = Objective(expr=-m.x ** 2, sense=maximize) SolverFactory('gdpopt').solve( m, strategy='LOA', mip_solver=mip_solver, nlp_solver=nlp_solver ) self.assertAlmostEqual(value(m.o), 0) def test_nested_disjunctions_set_covering(self): # This test triggers the InfeasibleConstraintException in # deactivate_trivial_constraints in one of the subproblem solves during # initialization. This makes sure we get the correct answer anyway, as # there is a feasible solution. m = models.makeNestedNonlinearModel() SolverFactory('gdpopt').solve(m, strategy='LOA', mip_solver=mip_solver, nlp_solver=nlp_solver, init_strategy='set_covering') self.assertAlmostEqual(value(m.x), sqrt(2)/2) self.assertAlmostEqual(value(m.y), sqrt(2)/2) self.assertTrue(value(m.disj.disjuncts[1].indicator_var)) self.assertFalse(value(m.disj.disjuncts[0].indicator_var)) self.assertTrue(value(m.d1.indicator_var)) self.assertFalse(value(m.d2.indicator_var)) def test_equality_propagation_infeasibility_in_subproblems(self): m = ConcreteModel() m.x = Var(bounds=(-10, 10)) m.y = Var(bounds=(-10, 10)) m.disj = Disjunction(expr=[[m.x == m.y, m.y == 2], [m.y == 8], [m.x + m.y >= 4, m.y == m.x + 1]]) m.cons = Constraint(expr=m.x == 3) m.obj = Objective(expr=m.x + m.y) SolverFactory('gdpopt').solve(m, strategy='RIC', mip_solver=mip_solver, nlp_solver=nlp_solver, init_strategy='set_covering') self.assertAlmostEqual(value(m.x), 3) self.assertAlmostEqual(value(m.y), 4) self.assertFalse(value(m.disj.disjuncts[0].indicator_var)) self.assertFalse(value(m.disj.disjuncts[1].indicator_var)) self.assertTrue(value(m.disj.disjuncts[2].indicator_var)) def test_bound_infeasibility_in_subproblems(self): m = ConcreteModel() m.x = Var(bounds=(2,4)) m.y = Var(bounds=(5,10)) m.disj = Disjunction(expr=[[m.x == m.y, m.x + m.y >= 8], [m.x == 4]]) m.obj = Objective(expr=m.x + m.y) SolverFactory('gdpopt').solve(m, strategy='RIC', mip_solver=mip_solver, nlp_solver=nlp_solver, init_strategy='set_covering') self.assertAlmostEqual(value(m.x), 4) self.assertAlmostEqual(value(m.y), 5) self.assertFalse(value(m.disj.disjuncts[0].indicator_var)) self.assertTrue(value(m.disj.disjuncts[1].indicator_var)) def test_subproblem_preprocessing_encounters_trivial_constraints(self): m = ConcreteModel() m.x = Var(bounds=(0, 10)) m.z = Var(bounds=(-10, 10)) m.disjunction = Disjunction(expr=[[m.x == 0, m.z >= 4], [m.x + m.z <= 0]]) m.cons = Constraint(expr=m.x*m.z <= 0) m.obj = Objective(expr=-m.z) m.disjunction.disjuncts[0].indicator_var.fix(True) m.disjunction.disjuncts[1].indicator_var.fix(False) SolverFactory('gdpopt').solve(m, strategy='RIC', mip_solver=mip_solver, nlp_solver=nlp_solver, init_strategy='fix_disjuncts') # The real test is that this doesn't throw an error when we preprocess # to solve the first subproblem (in the initialization). The nonlinear # constraint becomes trivial, which we need to make sure is handled # correctly. self.assertEqual(value(m.x), 0) self.assertEqual(value(m.z), 10) self.assertTrue(value(m.disjunction.disjuncts[0].indicator_var)) self.assertFalse(value(m.disjunction.disjuncts[1].indicator_var)) @unittest.skipUnless(sympy_available, "Sympy not available") def test_logical_constraints_on_disjuncts(self): m = models.makeLogicalConstraintsOnDisjuncts() SolverFactory('gdpopt').solve(m, strategy='LOA', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertAlmostEqual(value(m.x), 8) @unittest.skipUnless(sympy_available, "Sympy not available") def test_logical_constraints_on_disjuncts_nonlinear_convex(self): m = models.makeLogicalConstraintsOnDisjuncts_NonlinearConvex() SolverFactory('gdpopt').solve(m, strategy='LOA', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertAlmostEqual(value(m.x), 4) def test_nested_disjunctions_no_init(self): m = models.makeNestedNonlinearModel() SolverFactory('gdpopt').solve(m, strategy='LOA', mip_solver=mip_solver, nlp_solver=nlp_solver, init_strategy='no_init') self.assertAlmostEqual(value(m.x), sqrt(2)/2) self.assertAlmostEqual(value(m.y), sqrt(2)/2) def test_nested_disjunctions_max_binary(self): m = models.makeNestedNonlinearModel() SolverFactory('gdpopt').solve(m, strategy='LOA', mip_solver=mip_solver, nlp_solver=nlp_solver, init_strategy='max_binary') self.assertAlmostEqual(value(m.x), sqrt(2)/2) self.assertAlmostEqual(value(m.y), sqrt(2)/2) @unittest.skipUnless(sympy_available, "Sympy not available") def test_boolean_vars_on_disjuncts(self): m = models.makeBooleanVarsOnDisjuncts() SolverFactory('gdpopt').solve(m, strategy='LOA', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertAlmostEqual(value(m.x), 8) def test_LOA_8PP_default_init(self): """Test logic-based outer approximation with 8PP.""" exfile = import_file( join(exdir, 'eight_process', 'eight_proc_model.py')) eight_process = exfile.build_eight_process_flowsheet() SolverFactory('gdpopt').solve( eight_process, strategy='LOA', mip_solver=mip_solver, nlp_solver=nlp_solver, tee=False) self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2) @unittest.skipUnless(sympy_available, "Sympy not available") def test_LOA_8PP_logical_default_init(self): """Test logic-based outer approximation with 8PP.""" exfile = import_file( join(exdir, 'eight_process', 'eight_proc_logical.py')) eight_process = exfile.build_eight_process_flowsheet() SolverFactory('gdpopt').solve( eight_process, strategy='LOA', mip_solver=mip_solver, nlp_solver=nlp_solver, tee=False) self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2) @unittest.skipUnless(SolverFactory('gams').available(exception_flag=False), 'GAMS solver not available') def test_LOA_8PP_gams_solver(self): # Make sure that the duals are still correct exfile = import_file( join(exdir, 'eight_process', 'eight_proc_model.py')) eight_process = exfile.build_eight_process_flowsheet() SolverFactory('gdpopt').solve( eight_process, strategy='LOA', mip_solver=mip_solver, nlp_solver='gams', max_slack=0, tee=False) self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2) def test_LOA_8PP_force_NLP(self): exfile = import_file( join(exdir, 'eight_process', 'eight_proc_model.py')) eight_process = exfile.build_eight_process_flowsheet() SolverFactory('gdpopt').solve( eight_process, strategy='LOA', mip_solver=mip_solver, nlp_solver=nlp_solver, force_subproblem_nlp=True, tee=False) self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2) def test_LOA_strip_pack_default_init(self): """Test logic-based outer approximation with strip packing.""" exfile = import_file( join(exdir, 'strip_packing', 'strip_packing_concrete.py')) strip_pack = exfile.build_rect_strip_packing_model() SolverFactory('gdpopt').solve( strip_pack, strategy='LOA', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertTrue( fabs(value(strip_pack.total_length.expr) - 11) <= 1E-2) @unittest.skipUnless(sympy_available, "Sympy not available") def test_LOA_strip_pack_logical_constraints(self): """Test logic-based outer approximation with variation of strip packing with some logical constraints.""" exfile = import_file( join(exdir, 'strip_packing', 'strip_packing_concrete.py')) strip_pack = exfile.build_rect_strip_packing_model() # add logical constraints strip_pack.Rec3AboveOrBelowRec1 = LogicalConstraint( expr=strip_pack.no_overlap[1,3].disjuncts[2].indicator_var.lor( strip_pack.no_overlap[1,3].disjuncts[3].indicator_var)) strip_pack.Rec3RightOrLeftOfRec2 = LogicalConstraint( expr=strip_pack.no_overlap[2,3].disjuncts[0].indicator_var.lor( strip_pack.no_overlap[2,3].disjuncts[1].indicator_var)) SolverFactory('gdpopt').solve( strip_pack, strategy='LOA', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertTrue( fabs(value(strip_pack.total_length.expr) - 13) <= 1E-2) @unittest.pytest.mark.expensive def test_LOA_constrained_layout_default_init(self): """Test LOA with constrained layout.""" exfile = import_file( join(exdir, 'constrained_layout', 'cons_layout_model.py')) cons_layout = exfile.build_constrained_layout_model() SolverFactory('gdpopt').solve( cons_layout, strategy='LOA', mip_solver=mip_solver, nlp_solver=nlp_solver, iterlim=120, max_slack=5, # problem is convex, so can decrease slack ) objective_value = value(cons_layout.min_dist_cost.expr) self.assertTrue( fabs(objective_value - 41573) <= 200, "Objective value of %s instead of 41573" % objective_value) def test_LOA_8PP_maxBinary(self): """Test logic-based OA with max_binary initialization.""" exfile = import_file( join(exdir, 'eight_process', 'eight_proc_model.py')) eight_process = exfile.build_eight_process_flowsheet() SolverFactory('gdpopt').solve( eight_process, strategy='LOA', init_strategy='max_binary', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2) @unittest.skipUnless(sympy_available, "Sympy not available") def test_LOA_8PP_logical_maxBinary(self): """Test logic-based OA with max_binary initialization.""" exfile = import_file( join(exdir, 'eight_process', 'eight_proc_logical.py')) eight_process = exfile.build_eight_process_flowsheet() SolverFactory('gdpopt').solve( eight_process, strategy='LOA', init_strategy='max_binary', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2) def test_LOA_strip_pack_maxBinary(self): """Test LOA with strip packing using max_binary initialization.""" exfile = import_file( join(exdir, 'strip_packing', 'strip_packing_concrete.py')) strip_pack = exfile.build_rect_strip_packing_model() SolverFactory('gdpopt').solve( strip_pack, strategy='LOA', init_strategy='max_binary', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertTrue( fabs(value(strip_pack.total_length.expr) - 11) <= 1E-2) @unittest.skipUnless(sympy_available, "Sympy not available") def test_LOA_strip_pack_maxBinary_logical_constraints(self): """Test LOA with strip packing using max_binary initialization and logical constraints.""" exfile = import_file( join(exdir, 'strip_packing', 'strip_packing_concrete.py')) strip_pack = exfile.build_rect_strip_packing_model() # add logical constraints strip_pack.Rec3AboveOrBelowRec1 = LogicalConstraint( expr=strip_pack.no_overlap[1,3].disjuncts[2].indicator_var.lor( strip_pack.no_overlap[1,3].disjuncts[3].indicator_var)) strip_pack.Rec3RightOrLeftOfRec2 = LogicalConstraint( expr=strip_pack.no_overlap[2,3].disjuncts[0].indicator_var.lor( strip_pack.no_overlap[2,3].disjuncts[1].indicator_var)) SolverFactory('gdpopt').solve( strip_pack, strategy='LOA', init_strategy='max_binary', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertTrue( fabs(value(strip_pack.total_length.expr) - 13) <= 1E-2) def test_LOA_8PP_fixed_disjuncts(self): """Test LOA with 8PP using fixed disjuncts initialization.""" exfile = import_file( join(exdir, 'eight_process', 'eight_proc_model.py')) eight_process = exfile.build_eight_process_flowsheet() initialize = [ # Use units 1, 4, 7, 8 eight_process.use_unit_1or2.disjuncts[0], eight_process.use_unit_3ornot.disjuncts[1], eight_process.use_unit_4or5ornot.disjuncts[0], eight_process.use_unit_6or7ornot.disjuncts[1], eight_process.use_unit_8ornot.disjuncts[0] ] for disj in eight_process.component_data_objects(Disjunct): if disj in initialize: disj.binary_indicator_var.set_value(1) else: disj.binary_indicator_var.set_value(0) SolverFactory('gdpopt').solve( eight_process, strategy='LOA', init_strategy='fix_disjuncts', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2) def test_LOA_custom_disjuncts(self): """Test logic-based OA with custom disjuncts initialization.""" exfile = import_file( join(exdir, 'eight_process', 'eight_proc_model.py')) eight_process = exfile.build_eight_process_flowsheet() initialize = [ # Use units 1, 4, 7, 8 [eight_process.use_unit_1or2.disjuncts[0], eight_process.use_unit_3ornot.disjuncts[1], eight_process.use_unit_4or5ornot.disjuncts[0], eight_process.use_unit_6or7ornot.disjuncts[1], eight_process.use_unit_8ornot.disjuncts[0]], # Use units 2, 4, 6, 8 [eight_process.use_unit_1or2.disjuncts[1], eight_process.use_unit_3ornot.disjuncts[1], eight_process.use_unit_4or5ornot.disjuncts[0], eight_process.use_unit_6or7ornot.disjuncts[0], eight_process.use_unit_8ornot.disjuncts[0]] ] def assert_correct_disjuncts_active(nlp_model, solve_data): if solve_data.master_iteration >= 1: return # only checking initialization iter_num = solve_data.nlp_iteration disjs_should_be_active = initialize[iter_num - 1] for orig_disj, soln_disj in zip( solve_data.original_model.GDPopt_utils.disjunct_list, nlp_model.GDPopt_utils.disjunct_list ): if orig_disj in disjs_should_be_active: self.assertTrue(soln_disj.binary_indicator_var.value == 1) SolverFactory('gdpopt').solve( eight_process, strategy='LOA', init_strategy='custom_disjuncts', custom_init_disjuncts=initialize, mip_solver=mip_solver, nlp_solver=nlp_solver, call_after_subproblem_feasible=assert_correct_disjuncts_active) self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2)
class TestGDPoptUnit(unittest.TestCase): """Real unit tests for GDPopt""" @unittest.skipUnless(SolverFactory(mip_solver).available(), "MIP solver not available") def test_solve_linear_GDP_unbounded(self): m = ConcreteModel() m.GDPopt_utils = Block() m.x = Var(bounds=(-1, 10)) m.y = Var(bounds=(2, 3)) m.z = Var() m.d = Disjunction(expr=[ [m.x + m.y >= 5], [m.x - m.y <= 3] ]) m.o = Objective(expr=m.z) m.GDPopt_utils.variable_list = [m.x, m.y, m.z] m.GDPopt_utils.disjunct_list = [m.d._autodisjuncts[0], m.d._autodisjuncts[1]] output = StringIO() with LoggingIntercept(output, 'pyomo.contrib.gdpopt', logging.WARNING): solver_data = GDPoptSolveData() solver_data.timing = Bunch() with time_code(solver_data.timing, 'main', is_main_timer=True): solve_linear_GDP(m, solver_data, GDPoptSolver.CONFIG(dict(mip_solver=mip_solver, strategy='LOA'))) self.assertIn("Linear GDP was unbounded. Resolving with arbitrary " "bound values", output.getvalue().strip()) @unittest.skipUnless(SolverFactory(mip_solver).available(), "MIP solver not available") def test_solve_lp(self): m = ConcreteModel() m.x = Var(bounds=(-5, 5)) m.c = Constraint(expr=m.x >= 1) m.o = Objective(expr=m.x) output = StringIO() with LoggingIntercept(output, 'pyomo.contrib.gdpopt', logging.INFO): SolverFactory('gdpopt').solve(m, mip_solver=mip_solver, strategy='LOA') self.assertIn("Your model is an LP (linear program).", output.getvalue().strip()) self.assertAlmostEqual(value(m.o.expr), 1) @unittest.skipUnless(SolverFactory(nlp_solver).available(), 'NLP solver not available') def test_solve_nlp(self): m = ConcreteModel() m.x = Var(bounds=(-5, 5)) m.c = Constraint(expr=m.x >= 1) m.o = Objective(expr=m.x ** 2) output = StringIO() with LoggingIntercept(output, 'pyomo.contrib.gdpopt', logging.INFO): SolverFactory('gdpopt').solve(m, nlp_solver=nlp_solver, strategy='LOA') self.assertIn("Your model is an NLP (nonlinear program).", output.getvalue().strip()) self.assertAlmostEqual(value(m.o.expr), 1) @unittest.skipUnless(SolverFactory(mip_solver).available(), "MIP solver not available") def test_solve_constant_obj(self): m = ConcreteModel() m.x = Var(bounds=(-5, 5)) m.c = Constraint(expr=m.x >= 1) m.o = Objective(expr=1) output = StringIO() with LoggingIntercept(output, 'pyomo.contrib.gdpopt', logging.INFO): SolverFactory('gdpopt').solve(m, mip_solver=mip_solver, strategy='LOA') self.assertIn("Your model is an LP (linear program).", output.getvalue().strip()) self.assertAlmostEqual(value(m.o.expr), 1) @unittest.skipUnless(SolverFactory(nlp_solver).available(), 'NLP solver not available') def test_no_objective(self): m = ConcreteModel() m.x = Var(bounds=(-5, 5)) m.c = Constraint(expr=m.x ** 2 >= 1) output = StringIO() with LoggingIntercept(output, 'pyomo.contrib.gdpopt', logging.WARNING): SolverFactory('gdpopt').solve(m, nlp_solver=nlp_solver, strategy='LOA') self.assertIn("Model has no active objectives. Adding dummy " "objective.", output.getvalue().strip()) def test_multiple_objectives(self): m = ConcreteModel() m.x = Var() m.o = Objective(expr=m.x) m.o2 = Objective(expr=m.x + 1) with self.assertRaisesRegex(ValueError, "Model has multiple active " "objectives"): SolverFactory('gdpopt').solve(m, strategy='LOA') def test_is_feasible_function(self): m = ConcreteModel() m.x = Var(bounds=(0, 3), initialize=2) m.c = Constraint(expr=m.x == 2) self.assertTrue( is_feasible(m, GDPoptSolver.CONFIG(dict(strategy='LOA')))) m.c2 = Constraint(expr=m.x <= 1) self.assertFalse( is_feasible(m, GDPoptSolver.CONFIG(dict(strategy='LOA')))) m = ConcreteModel() m.x = Var(bounds=(0, 3), initialize=2) m.c = Constraint(expr=m.x >= 5) self.assertFalse( is_feasible(m, GDPoptSolver.CONFIG(dict(strategy='LOA')))) m = ConcreteModel() m.x = Var(bounds=(3, 3), initialize=2) self.assertFalse( is_feasible(m, GDPoptSolver.CONFIG(dict(strategy='LOA')))) m = ConcreteModel() m.x = Var(bounds=(0, 1), initialize=2) self.assertFalse( is_feasible(m, GDPoptSolver.CONFIG(dict(strategy='LOA')))) m = ConcreteModel() m.x = Var(bounds=(0, 1), initialize=2) m.d = Disjunct() with self.assertRaisesRegex(NotImplementedError, "Found active disjunct"): is_feasible(m, GDPoptSolver.CONFIG(dict(strategy='LOA')))
from pyomo.gdp.tests import models from pyomo.contrib.mcpp.pyomo_mcpp import mcpp_available from pyomo.opt import TerminationCondition from pyomo.core.expr.sympy_tools import sympy_available from pyomo.common.fileutils import PYOMO_ROOT_DIR exdir = normpath(join(PYOMO_ROOT_DIR, 'examples', 'gdp')) mip_solver = 'glpk' nlp_solver = 'ipopt' global_nlp_solver = 'baron' global_nlp_solver_args = dict() minlp_solver = 'baron' LOA_solvers = (mip_solver, nlp_solver) GLOA_solvers = (mip_solver, global_nlp_solver, minlp_solver) LOA_solvers_available = all(SolverFactory(s).available() for s in LOA_solvers) GLOA_solvers_available = all(SolverFactory(s).available() for s in GLOA_solvers) license_available = SolverFactory(global_nlp_solver).license_is_valid() if \ GLOA_solvers_available else False class TestGDPoptUnit(unittest.TestCase): """Real unit tests for GDPopt""" @unittest.skipUnless(SolverFactory(mip_solver).available(), "MIP solver not available") def test_solve_linear_GDP_unbounded(self): m = ConcreteModel() m.GDPopt_utils = Block() m.x = Var(bounds=(-1, 10)) m.y = Var(bounds=(2, 3))
import facility_pyomo from pyomo.environ import SolverFactory solver = SolverFactory("gurobi") solver.solve(facility_pyomo.model, options={"timelimit": 0}, load_solutions=False, tee=True)
def disjunctionToCut(m, pi, pi0, debug_print=False, use_cylp=True, eps=EPS): '''Generate the most violated valid inequality from a given disjunction''' me = "cglp_cuts: " lp = m.lp sol = lp.primalVariableSolution['x'] if debug_print: print(me, "constraints sense = ", m.sense) print(me, "matrix = ") print(m.A) print(me, "rhs = ", m.b) print(me, "vars lower bounds = ", lp.variablesLower) print(me, "vars upper bounds = ", lp.variablesUpper) print(me, "objective = ", lp.objective) print(me, "current solution = ", sol) print(me, "pi = ", pi) print(me, "pi0 = ", pi0) ############################################################################ ## There are two given LPs: ## s.t. Ax >= b s.t. Ax >= b ## -pi.x >= -pi_0 pi.x >= pi_0+1 ## A, b, c, pi, pi_0 are given ## ## CGLP: alpha.x >= beta should be valid for both LPs above ## ## min alpha.x* - beta ## uA - u0.pi = alpha ## vA + v0.pi = alpha ## ub - u0.pi_0 >= beta ## vb + v0.(pi_0 + 1) >= beta ## u0 + v0 = 1 ## u, v, u0, v0 >= 0 ## if min value comes out < 0, then (alpha.x >= beta) is a cut. ############################################################################ pi = CyLPArray(pi) Atran = m.A.transpose() b = CyLPArray(m.b) numRows, numCols = m.A.shape if use_cylp: sp = CyLPModel() u = sp.addVariable('u', numRows, isInt=False) v = sp.addVariable('v', numRows, isInt=False) u0 = sp.addVariable('u0', 1, isInt=False) v0 = sp.addVariable('v0', 1, isInt=False) alpha = sp.addVariable('alpha', lp.nVariables, isInt=False) beta = sp.addVariable('beta', 1, isInt=False) #This should be as simple as this, but it doesn't work. #Maybe a bug in CyLP? #sp += alpha - Atran*u - pi*u0 == 0 #sp += alpha - Atran*v + pi*v0 == 0 for i in range(numCols): sp += alpha[i] - sum(Atran[i, j] * u[j] for j in range(numRows)) - pi[i] * u0 == 0 for i in range(numCols): sp += alpha[i] - sum(Atran[i, j] * v[j] for j in range(numRows)) + pi[i] * v0 == 0 if m.sense == '<=': sp += beta - b * u - pi0 * u0 >= 0 sp += beta - b * v + (pi0 + 1) * v0 >= 0 else: sp += beta - b * u - pi0 * u0 <= 0 sp += beta - b * v + (pi0 + 1) * v0 <= 0 sp += u0 + v0 == 1 sp += u >= 0 sp += v >= 0 sp += u0 >= 0 sp += v0 >= 0 if m.sense == '<=': sp.objective = sum(-sol[i] * alpha[i] for i in range(numCols)) + beta else: #This direction is not debugged sp.objective = sum(sol[i] * alpha[i] for i in range(numCols)) - beta cglp = CyClpSimplex(sp) # If we want to solve it as an MILP # cglp = CyClpSimplex(sp).getCbcModel() #cglp.writeLp('lp.lp') cglp.logLevel = 0 cglp.primal(startFinishOptions='x') # Solve as MILP # cglp.solve() beta = cglp.primalVariableSolution['beta'][0] alpha = cglp.primalVariableSolution['alpha'] u = cglp.primalVariableSolution['u'] v = cglp.primalVariableSolution['v'] u0 = cglp.primalVariableSolution['u0'][0] v0 = cglp.primalVariableSolution['v0'][0] if debug_print: print(me, 'Objective Value: ', cglp.objectiveValue) if debug_print: print(me, 'u: ', u) print(me, 'v: ', v) print(me, 'u0: ', u0) print(me, 'v0: ', v0) else: CG = AbstractModel() CG.u = Var(list(range(numRows)), domain=NonNegativeReals, bounds=(0.0, None)) CG.v = Var(list(range(numRows)), domain=NonNegativeReals, bounds=(0.0, None)) CG.u0 = Var(domain=NonNegativeReals, bounds=(0.0, None)) CG.v0 = Var(domain=NonNegativeReals, bounds=(0.0, None)) CG.alpha = Var(list(range(numRows)), domain=Reals, bounds=(None, None)) CG.beta = Var(domain=Reals, bounds=(None, None)) ## Constraints def pi_rule_left(CG, i): x = float(pi[i]) return (sum(Atran[i, j] * CG.u[j] for j in range(numRows)) - x * CG.u0 - CG.alpha[i] == 0.0) CG.pi_rule_left = Constraint(list(range(numCols)), rule=pi_rule_left) def pi_rule_right(CG, i): x = float(pi[i]) return (sum(Atran[i, j] * CG.v[j] for j in range(numRows)) + x * CG.v0 - CG.alpha[i] == 0.0) CG.pi_rule_right = Constraint(list(range(numCols)), rule=pi_rule_right) if m.sense == '<=': def pi0_rule_left(CG): return (sum(b[j] * CG.u[j] for j in range(numRows)) - pi0 * CG.u0 - CG.beta <= 0.0) CG.pi0_rule_left = Constraint(rule=pi0_rule_left) def pi0_rule_right(CG): return (sum(b[j] * CG.v[j] for j in range(numRows)) + (pi0 + 1) * CG.v0 - CG.beta <= 0.0) CG.pi0_rule_right = Constraint(rule=pi0_rule_right) else: def pi0_rule_left(CG): return (sum(b[j] * CG.u[j] for j in range(numRows)) - pi0 * CG.u0 - CG.beta >= 0.0) CG.pi0_rule_left = Constraint(rule=pi0_rule_left) def pi0_rule_right(CG): return (sum(b[j] * CG.v[j] for j in range(numRows)) + (pi0 + 1) * CG.v0 - CG.beta >= 0.0) CG.pi0_rule_right = Constraint(rule=pi0_rule_right) def normalization_rule(CG): return (CG.u0 + CG.v0 == 1.0) CG.normalization_rule = Constraint(rule=normalization_rule) def objective_rule(CG): return (sum(sol[i] * CG.alpha[i] for i in range(numCols)) - CG.beta) if m.sense == '<=': CG.objective = Objective(sense=maximize, rule=objective_rule) else: CG.objective = Objective(sense=minimize, rule=objective_rule) opt = SolverFactory("cbc") instance = CG.create_instance() #instance.pprint() #instance.write("foo.nl", format = "nl") #opt.options['bonmin.bb_log_level'] = 5 #opt.options['bonmin.bb_log_interval'] = 1 results = opt.solve(instance, tee=False) #results = opt.solve(instance) instance.solutions.load_from(results) beta = instance.beta.value alpha = np.array( [instance.alpha[i].value for i in range(lp.nVariables)]) violation = beta - np.dot(alpha, sol) if debug_print: print(me, 'Beta: ', beta) print(me, 'alpha: ', alpha) print(me, 'Violation of cut: ', violation) if np.abs(violation) > 10**(-eps): return [(alpha, beta)] print('No violated cuts found solving CGLP', violation) return []
def disjunctionToCut(lp, pi, pi0, integerIndices = None, sense = '>=', sol = None, debug_print = False, use_cylp = True): me = "cglp_cuts: " if sol is None: sol = lp.primalVariableSolution['x'] infinity = lp.getCoinInfinity() if debug_print: print(me, "constraints sense = ", sense) print(me, "con lower bounds = ", lp.constraintsLower) print(me, "con upper bounds = ", lp.constraintsUpper) print(me, "con matrix = ", lp.coefMatrix.toarray()) print(me, "vars lower bounds = ", lp.variablesLower) print(me, "vars upper bounds = ", lp.variablesUpper) print(me, "Assuming objective is to minimize") print(me, "objective = ", lp.objective) print(me, "infinity = ", infinity) print(me, "current point = ", sol) print(me, "pi = ", pi) print(me, "pi0 = ", pi0) A = lp.coefMatrix.toarray() #c = lp.objective ## Convert to >= if the problem is in <= form. if sense == '<=': b = deepcopy(lp.constraintsUpper) b = -1.0*b A = -1.0*A else: b = deepcopy(lp.constraintsLower) #Add bounds on variables as explicit constraints for i in range(lp.nCols): e = np.zeros((1, lp.nCols)) if lp.variablesUpper[i] < infinity: b.resize(b.size+1, refcheck = False) e[0, i] = -1.0 b[-1] = -1.0*lp.variablesUpper[i] A = np.vstack((A, e)) if lp.variablesLower[i] > -infinity: b.resize(b.size+1, refcheck = False) e[0, i] = 1.0 b[-1] = lp.variablesLower[i] A = np.vstack((A, e)) A = csc_matrixPlus(A) ############################################################################ ## There are two given LPs: ## s.t. Ax >= b s.t. Ax >= b ## -pi.x >= -pi_0 pi.x >= pi_0+1 ## A, b, c, pi, pi_0 are given ## ## CGLP: alpha.x >= beta should be valid for both LPs above ## ## min alpha.x* - beta ## uA - u0.pi = alpha ## vA + v0.pi = alpha ## ub - u0.pi_0 >= beta ## vb + v0.(pi_0 + 1) >= beta ## u0 + v0 = 1 ## u, v, u0, v0 >= 0 ## if min value comes out < 0, then (alpha.x >= beta) is a cut. ############################################################################ b = CyLPArray(b) pi = CyLPArray(pi) Atran = A.transpose() if use_cylp: sp = CyLPModel() u = sp.addVariable('u', A.shape[0], isInt = False) v = sp.addVariable('v', A.shape[0], isInt = False) u0 = sp.addVariable('u0', 1, isInt = False) v0 = sp.addVariable('v0', 1, isInt = False) alpha = sp.addVariable('alpha', lp.nVariables, isInt = False) beta = sp.addVariable('beta', 1, isInt = False) for i in range(A.shape[1]): sp += alpha[i] - sum(Atran[i,j]*u[j] for j in range(A.shape[0])) + pi[i]*u0 == 0 for i in range(A.shape[1]): sp += alpha[i] - sum(Atran[i,j]*v[j] for j in range(A.shape[0])) - pi[i]*v0 == 0 sp += beta - b*u + pi0*u0 <= 0 sp += beta - b*v - (pi0 + 1)*v0 <= 0 sp += u0 + v0 == 1 if sense == '<=': sp += u >= 0 sp += v >= 0 sp += u0 >= 0 sp += v0 >= 0 else: #TODO this direction is not debugged # Is this all we need? sp += u <= 0 sp += v <= 0 sp += u0 <= 0 sp += v0 <= 0 sp.objective = sum(sol[i]*alpha[i] for i in range(A.shape[1])) - beta cbcModel = CyClpSimplex(sp).getCbcModel() cbcModel.logLevel = 0 #cbcModel.maximumSeconds = 5 cbcModel.solve() beta = cbcModel.primalVariableSolution['beta'][0] alpha = cbcModel.primalVariableSolution['alpha'] u = cbcModel.primalVariableSolution['u'] v = cbcModel.primalVariableSolution['v'] u0 = cbcModel.primalVariableSolution['u0'][0] v0 = cbcModel.primalVariableSolution['v0'][0] if debug_print: print('Objective Value: ', cbcModel.objectiveValue) print('alpha: ', alpha, 'alpha*sol: ', np.dot(alpha, sol)) print('beta: ', beta) print('Violation of cut: ', np.dot(alpha, sol) - beta) else: CG = AbstractModel() CG.u = Var(list(range(A.shape[0])), domain=NonNegativeReals, bounds = (0.0, None)) CG.v = Var(list(range(A.shape[0])), domain=NonNegativeReals, bounds = (0.0, None)) CG.u0 = Var(domain=NonNegativeReals, bounds = (0.0, None)) CG.v0 = Var(domain=NonNegativeReals, bounds = (0.0, None)) CG.alpha = Var(list(range(A.shape[0])), domain=Reals, bounds = (None, None)) CG.beta = Var(domain=Reals, bounds = (None, None)) ## Constraints def pi_rule_left(CG, i): x = float(pi[i]) return(sum(Atran[i, j]*CG.u[j] for j in range(A.shape[0])) - x*CG.u0 - CG.alpha[i] == 0.0) CG.pi_rule_left = Constraint(list(range(A.shape[1])), rule=pi_rule_left) def pi_rule_right(CG, i): x = float(pi[i]) return(sum(Atran[i, j]*CG.v[j] for j in range(A.shape[0])) + x*CG.v0 - CG.alpha[i] == 0.0) CG.pi_rule_right = Constraint(list(range(A.shape[1])), rule=pi_rule_right) def pi0_rule_left(CG): return(sum(b[j]*CG.u[j] for j in range(A.shape[0])) - pi0*CG.u0 - CG.beta >= 0.0) CG.pi0_rule_left = Constraint(rule=pi0_rule_left) def pi0_rule_right(CG): return(sum(b[j]*CG.v[j] for j in range(A.shape[0])) + (pi0 + 1)*CG.v0 - CG.beta >= 0.0) CG.pi0_rule_right = Constraint(rule=pi0_rule_right) def normalization_rule(CG): return(CG.u0 + CG.v0 == 1.0) CG.normalization_rule = Constraint(rule=normalization_rule) def objective_rule(CG): return(sum(sol[i]*CG.alpha[i] for i in range(A.shape[1])) - CG.beta) CG.objective = Objective(sense=minimize, rule=objective_rule) opt = SolverFactory("cbc") instance = CG.create_instance() #instance.pprint() #instance.write("foo.nl", format = "nl") #opt.options['bonmin.bb_log_level'] = 5 #opt.options['bonmin.bb_log_interval'] = 1 results = opt.solve(instance, tee=False) #results = opt.solve(instance) instance.solutions.load_from(results) beta = instance.beta.value alpha = np.array([instance.alpha[i].value for i in range(lp.nVariables)]) violation = beta - np.dot(alpha, sol) if debug_print: print(me, 'Beta: ', beta) print(me, 'alpha: ', alpha) print(me, 'Violation of cut: ', violation) if violation > 0.001: if (sense == ">="): return [(alpha, beta)] else: return [(-alpha, -beta)] return []
def test_logical_constraints_on_disjuncts(self): m = models.makeLogicalConstraintsOnDisjuncts() SolverFactory('gdpopt').solve(m, strategy='GLOA', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertAlmostEqual(value(m.x), 8)
def main(*args): t0 = time() # EXCEL-bol hivva if len(args) == 0: data = ExcelReader.read(Data())[0] ExcelWriter.clear(data) # ECLIPSE-bol hivva elif len(args) == 1: filename = args[0] data, wb = ExcelReader.read(Data(), Root.path() + filename) t1 = time() if len(args)==0: ExcelWriter.excelTime(t1-t0) model = Initialiser.init(data) opt = SolverFactory("asl", executable="xpress") opt.options["logfile"] = Root.resources() + "xpress_log.txt" Tools.Logger(Root.resources() + "xpress_log.txt", model.name) #opt = SolverFactory("gurobi") #opt.options["LogFile"] = Root.resources() + "gurobi_log.txt" t2 = time() if len(args)==0: ExcelWriter.pyomoTime(t2-t1) if Tools.Debug: model.write(Root.resources() + 'problem.lp', io_options={'symbolic_solver_labels':True}) results = opt.solve(model) try: pass except Exception as e: if type(e) == ZeroDivisionError: ExcelWriter.exception("Division by zero: 'alpha' should be < 1.") elif type(e) == Tools.OutOfHedgingPeriodException: ExcelWriter.exception("Empty planning horizon: T should be no more than the number of time periods.") elif type(e) == Tools.EpsilonIsZeroException: ExcelWriter.exception("Unbounded problem: epsilon should not equal 0.") elif type(e) == ApplicationError: ExcelWriter.exception("Unfeasible problem.") traceback.format_exc() # @UndefinedVariable #ExcelWriter.exception("Unhandled exception:", e) return model.solutions.load_from(results) t3 = time() if len(args)==0: ExcelWriter.gurobiTime(t3-t2) if Tools.Debug: print "Excel read: {0:0.3f} seconds".format(t1-t0) print "Model build: {0:0.3f} seconds".format(t2-t1) print "Solve: {0:0.3f} seconds".format(t3-t2) if len(args) == 0: if Tools.Debug: f = open(Root.resources() + "/yxc.txt", 'w') print >>f, results Plotter.plotTotalEnergy(data, model).show() ExcelWriter.write(model, results) elif len(args) == 1: wb.close() return (model, results, data)
def test_boolean_vars_on_disjuncts(self): m = models.makeBooleanVarsOnDisjuncts() SolverFactory('gdpopt').solve(m, strategy='GLOA', mip_solver=mip_solver, nlp_solver=nlp_solver) self.assertAlmostEqual(value(m.x), 8)
import pmedian_pyomo_linear from pyomo.environ import SolverFactory solver = SolverFactory("gurobi") solver.solve(pmedian_pyomo_linear.model, options={"timelimit": 0}, load_solutions=False, tee=True)
# constraints # positive forces along z # model.c0 = Constraint(rule=lambda minst: minst.f[2] >= 0) model.c1 = Constraint(rule=lambda minst: minst.f[5] >= 0) model.c2 = Constraint(rule=lambda minst: minst.f[8] >= 0) model.c3 = Constraint(rule=lambda minst: minst.f[11] >= 0) model.c4 = Constraint(rule=lambda minst: (1 - minst.c[0]) * minst.f[2] == 0) model.c5 = Constraint(rule=lambda minst: (1 - minst.c[1]) * minst.f[5] == 0) model.c6 = Constraint(rule=lambda minst: (1 - minst.c[2]) * minst.f[8] == 0) model.c7 = Constraint(rule=lambda minst: (1 - minst.c[3]) * minst.f[11] == 0) #Solve the model using MindtPy solver = SolverFactory('mindtpy') ################################# # instanciate and fill the values ################################# instance = model.create_instance() # retrieve data to setup the problem q = q_arr[0, :] dq = dq_arr[0, :] ddq = ddq_arr[0, :] tau_j = tau_arr[0, :] Jlinvel = compute_joint_jac(robot, q, contact_frame_ids) tau_cf = pin.rnea(rmodel, rdata, q, dq, ddq)[6:] tau_cf -= tau_j
# This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ import logging from io import StringIO import sys import pyomo.common.unittest as unittest from pyomo.common.log import LoggingIntercept from pyomo.contrib.trustregion.examples import example1, example2 from pyomo.environ import (SolverFactory) logger = logging.getLogger('pyomo.contrib.trustregion') @unittest.skipIf(not SolverFactory('ipopt').available(False), "The IPOPT solver is not available") class TestTrustRegionMethod(unittest.TestCase): def test_example1(self): # Check the log contents log_OUTPUT = StringIO() # Check the printed contents print_OUTPUT = StringIO() sys.stdout = print_OUTPUT with LoggingIntercept(log_OUTPUT, 'pyomo.contrib.trustregion', logging.INFO): example1.main() sys.stdout = sys.__stdout__ # Check number of iterations - which should be 4 total self.assertIn('Iteration 0', log_OUTPUT.getvalue()) self.assertIn('Iteration 4', log_OUTPUT.getvalue())
def MagicSquareSolver(n): # Create concrete model model = ConcreteModel() # Set of indices model.I = RangeSet(1, n) model.J = RangeSet(1, n) model.K = RangeSet(1, n * n) # Variables model.z = Var(within=PositiveIntegers) model.x = Var(model.I, model.J, model.K, within=Binary) # Objective Function model.obj = Objective(expr=model.z) # Every number "k" can appear in a single cell "(i,j)" def Unique(model, k): return sum(model.x[i, j, k] for j in model.J for i in model.I) == 1 model.unique = Constraint(model.K, rule=Unique) # Every cell "(i,j)" can contain a single number "k" def CellUnique(model, i, j): return sum(model.x[i, j, k] for k in model.K) == 1 model.cellUnique = Constraint(model.I, model.J, rule=CellUnique) # The sum of the numbers over each row "i" must be equal to "z" def Row(model, i): return sum(k * model.x[i, j, k] for j in model.J for k in model.K) == model.z model.row = Constraint(model.I, rule=Row) # The sum of the numbers over a column "j" must be equal to "z" def Col(model, j): return sum(k * model.x[i, j, k] for i in model.I for k in model.K) == model.z model.column = Constraint(model.J, rule=Col) # The sum over the main diagonal and the off-diagonal must be equal model.diag1 = Constraint(expr=sum(k * model.x[i, i, k] for i in model.I for k in model.K) == model.z) model.diag2 = Constraint(expr=sum(k * model.x[i, n - i + 1, k] for i in model.I for k in model.K) == model.z) # Write the LP model in standard format model.write("magic_{}.lp".format(n)) # Solve the model sol = SolverFactory('gurobi').solve(model, tee=True) # CHECK SOLUTION STATUS # Get a JSON representation of the solution sol_json = sol.json_repn() # Check solution status if sol_json['Solver'][0]['Status'] != 'ok': return None if sol_json['Solver'][0]['Termination condition'] != 'optimal': return None return model.x
def test_warm_start(self): m = ConcreteModel() m.x = Var() m.z = Var(domain=Integers) m.w = Var(domain=Boolean) m.c = Constraint(expr=m.x + m.z + m.w >= 0) m.o = Objective(expr=m.x + m.z + m.w) TempfileManager.push() tempdir = os.path.dirname(TempfileManager.create_tempfile()) TempfileManager.pop() sameDrive = os.path.splitdrive(tempdir)[0] == \ os.path.splitdrive(os.getcwd())[0] # At the moment, CBC does not cleanly handle windows-style drive # names in the MIPSTART file name (though at least 2.10.5). # # See https://github.com/coin-or/Cbc/issues/32 # The problematic source is https://github.com/coin-or/Cbc/blob/3dcedb27664ae458990e9d4d50bc11c2c55917a0/src/CbcSolver.cpp#L9445-L9459 # # We will try two different situations: running from the current # directory (which may or may not be on the same drive), and # then from the tempdir (which will be on the same drive). # Set some initial values for warm start. m.x.set_value(10) m.z.set_value(5) m.w.set_value(1) with SolverFactory("cbc") as opt, capture_output() as output: opt.solve(m, tee=True, warmstart=True, options={ 'sloglevel': 2, 'loglevel': 2}) log = output.getvalue() # Check if CBC loaded the warmstart file. self.assertIn('opening mipstart file', log) if sameDrive: # Only integer and binary variables are considered by CBC. self.assertIn('MIPStart values read for 2 variables.', log) # m.x is ignored because it is continuous, so cost should be 5+1 self.assertIn('MIPStart provided solution with cost 6', log) else: self.assertNotIn('MIPStart values read', log) # Set some initial values for warm start. m.x.set_value(10) m.z.set_value(5) m.w.set_value(1) try: _origDir = os.getcwd() os.chdir(tempdir) with SolverFactory("cbc") as opt, capture_output() as output: opt.solve(m, tee=True, warmstart=True, options={ 'sloglevel': 2, 'loglevel': 2}) finally: os.chdir(_origDir) log = output.getvalue() # Check if CBC loaded the warmstart file. self.assertIn('opening mipstart file', log) # Only integer and binary variables are considered by CBC. self.assertIn('MIPStart values read for 2 variables.', log) # m.x is ignored because it is continuous, so cost should be 5+1 self.assertIn('MIPStart provided solution with cost 6', log)
def get_kkt_info(self): """Takes the model and uses PyNumero or k_aug to get the jacobian and Hessian information as dataframes. This is done in place and does not return anything. kkt_data (dict): dictionary with the following structure: { 'J': J, # Jacobian 'H': H, # Hessian 'var_ind': var_index_names, # Variable index 'con_ind': con_index_names, # Constraint index 'duals': duals, # Duals } :return: None """ self.get_file_info() if self.kkt_method == 'pynumero': nlp = PyomoNLP(self.model_object) varList = nlp.get_pyomo_variables() conList = nlp.get_pyomo_constraints() duals = nlp.get_duals() J = nlp.extract_submatrix_jacobian(pyomo_variables=varList, pyomo_constraints=conList) H = nlp.extract_submatrix_hessian_lag(pyomo_variables_rows=varList, pyomo_variables_cols=varList) J = csc_matrix(J) var_index_names = [v.name for v in varList] con_index_names = [v.name for v in conList] elif self.kkt_method == 'k_aug': kaug = SolverFactory('k_aug') kaug.options["print_kkt"] = "" kaug.solve(self.model_object, tee=True) kaug_files = Path('GJH') var_index_names = pd.read_csv(self.sol_files['col'], sep=';', header=None) # dummy sep con_index_names = pd.read_csv(self.sol_files['row'], sep=';', header=None) # dummy sep var_index_names = [var_name for var_name in var_index_names[0]] con_index_names = [ con_name for con_name in con_index_names[0].iloc[:-1] ] # con_index_number = {v: k for k, v in enumerate(con_index_names)} n = len(var_index_names) m = len(con_index_names) print(f'size: vars: {n}, cons {m}') hess_file = kaug_files.joinpath('H_print.txt') hess = pd.read_csv(hess_file, delim_whitespace=True, header=None, skipinitialspace=True) hess.columns = ['irow', 'jcol', 'vals'] hess.irow -= 1 hess.jcol -= 1 # os.unlink(f'{kaug_files}hess_debug.in') jac_file = kaug_files.joinpath('A_print.txt') jac = pd.read_csv(jac_file, delim_whitespace=True, header=None, skipinitialspace=True) jac.columns = ['irow', 'jcol', 'vals'] jac.irow -= 1 jac.jcol -= 1 # os.unlink(f'{kaug_files}jacobi_debug.in') # try: # duals = read_duals(stub + '.sol') # except: duals = None J = coo_matrix((jac.vals, (jac.jcol, jac.irow)), shape=(m, n)) Hess_coo = coo_matrix((hess.vals, (hess.irow, hess.jcol)), shape=(n, n)) H = Hess_coo + triu(Hess_coo, 1).T print('This sizes of H and J') print(H.shape) print(J.shape) self.delete_sol_files() self.kkt_data = { 'J': J, 'H': H, 'var_ind': var_index_names, 'con_ind': con_index_names, 'duals': duals, } return None
from itertools import product from six import StringIO from six.moves import range import pyutilib.th as unittest from pyomo.common.log import LoggingIntercept from pyomo.contrib.multistart.high_conf_stop import should_stop from pyomo.contrib.multistart.reinit import strategies from pyomo.environ import ( ConcreteModel, Constraint, NonNegativeReals, Objective, SolverFactory, Var, maximize, sin, value ) @unittest.skipIf(not SolverFactory('ipopt').available(), "IPOPT not available") class MultistartTests(unittest.TestCase): """ Due to stochastic nature of the random restarts, these tests just demonstrate, that for a small sample, the test will not do worse than the standard solver. this is non-exhaustive due to the randomness. Hence all asserts are inequalities. """ def test_as_good_as_standard(self): standard_model = build_model() SolverFactory('ipopt').solve(standard_model) standard_objective_value = value(next(standard_model.component_data_objects(Objective, active=True))) fresh_model = build_model() multistart_iterations = 10
def optimize_model(self, d=None): """Takes the model object and performs the optimization for a reduced Hessian problem. :param dict d: The current state of the parameters :return: None """ if self.verbose: print(f'd: {d}') ipopt = SolverFactory('ipopt') tmpfile_i = self.get_tmp_file() if self.param_con_method == 'global': if d is not None: param_val_dict = { p: d[i] for i, p in enumerate(self.parameter_set) } for k, v in getattr(self.model_object, self.variable_name).items(): v.set_value(param_val_dict[k]) self.add_global_constraints() if self.set_param_bounds: set_scaled_parameter_bounds(self.model_object, parameter_set=self.parameter_set, rho=self.rho, scaled=self.scaled) elif self.param_con_method == 'fixed': if hasattr(self.model_object, self.global_constraint_name): self.model_object.del_component(self.global_constraint_name) delta = 1e-20 for k, v in getattr(self.model_object, self.variable_name).items(): if k in self.parameter_set: ub = v.value lb = v.value - delta v.setlb(lb) v.setub(ub) v.unfix() else: v.fix() ipopt.solve( self.model_object, symbolic_solver_labels=True, keepfiles=True, tee=True, logfile=tmpfile_i, ) # print(self.model_object.P.display()) # Create the file object so that it can be deleted self.get_file_info() return None
def test_const_obj(self): m = ConcreteModel() m.x = Var() m.o = Objective(expr = 5) with self.assertRaisesRegexp(RuntimeError, "constant objective"): SolverFactory('multistart').solve(m)
# at the URL "https://github.com/IDAES/idaes-pse". ############################################################################## """ Example for Caprese's module for NMPC. """ from idaes.apps.caprese import NMPCSim, ControlInitOption from pyomo.environ import SolverFactory import idaes.logger as idaeslog from idaes.apps.caprese.examples.cstr_model import make_model import pandas as pd import matplotlib.pyplot as plt __author__ = "Robert Parker" # See if ipopt is available and set up solver if SolverFactory('ipopt').available(): solver = SolverFactory('ipopt') solver.options = { 'tol': 1e-6, 'bound_push': 1e-8, 'halt_on_ampl_error': 'yes', } else: solver = None class PlotData(object): def __init__(self, group, location, name=None, t_switch=None): # Would really like a PlotData class that is constructed based on an # NMPCVar object that contains necessary setpoint/reference # information, instead of having to access that in the NMPCVarGroup
"""Contains the linear program for the correlation robust influence problem.""" # Python Standard library from typing import Hashable, Optional, Sequence, Union # packages from igraph import Graph from pyomo.environ import (AbstractModel, ConcreteModel, Constraint, Objective, Set, SolverFactory, Var, minimize, value) SOLVER = SolverFactory("gurobi") # modify this to use alternative solvers # An alternative is CBC, which uses the string "cbc" def inf_abs_mod(input_graph: Graph) -> AbstractModel: """Create the abstract model which is shared among all concrete models.""" # RESERVED SEED NAMES # if 's' in input_graph or 't' in input_graph: # raise ValueError # Abstract Model to be shared throughout greedy algorithm mod = AbstractModel() # Common sets mod.V = Set(initialize=[n.index for n in input_graph.vs()]) mod.E = Set(initialize=[e.tuple for e in input_graph.es()], dimen=2) # Common variables mod.pi = Var(mod.V, bounds=(0, 1)) return mod
dimen=2, filter=rec_pairs_filter, doc="set of possible rectangle conflicts") @model.Constraint(model.rectangles) def strip_ends_after_last_rec(model, i): return model.strip_length >= model.x[i] + model.rect_length[i] model.total_length = Objective(expr=model.strip_length, doc="Minimize length") @model.Disjunction( model.overlap_pairs, doc="Make sure that none of the rectangles on the strip overlap in " "either the x or y dimensions.") def no_overlap(m, i, j): return [ m.x[i] + m.rect_length[i] <= m.x[j], m.x[j] + m.rect_length[j] <= m.x[i], m.y[i] + m.rect_width[i] <= m.y[j], m.y[j] + m.rect_width[j] <= m.y[i], ] return model if __name__ == "__main__": model = build_rect_strip_packing_model() TransformationFactory('gdp.chull').apply_to(model) opt = SolverFactory('gurobi') results = opt.solve(model, tee=True)
from pyomo.environ import SolverFactory from concrete1 import model model.pprint() instance = model.create() instance.pprint() opt = SolverFactory("glpk") results = opt.solve(instance) results.write()
def test_handle_termination_condition(self): """Test the outer approximation decomposition algorithm.""" model = SimpleMINLP() config = _get_MindtPy_config() solve_data = set_up_solve_data(model, config) with time_code(solve_data.timing, 'total', is_main_timer=True), \ create_utility_block(solve_data.working_model, 'MindtPy_utils', solve_data): MindtPy = solve_data.working_model.MindtPy_utils MindtPy = solve_data.working_model.MindtPy_utils setup_results_object(solve_data, config) process_objective(solve_data, config, move_objective=(config.init_strategy == 'FP' or config.add_regularization is not None), use_mcpp=config.use_mcpp, update_var_con_list=config.add_regularization is None ) feas = MindtPy.feas_opt = Block() feas.deactivate() feas.feas_constraints = ConstraintList( doc='Feasibility Problem Constraints') lin = MindtPy.cuts = Block() lin.deactivate() if config.feasibility_norm == 'L1' or config.feasibility_norm == 'L2': feas.nl_constraint_set = RangeSet(len(MindtPy.nonlinear_constraint_list), doc='Integer index set over the nonlinear constraints.') # Create slack variables for feasibility problem feas.slack_var = Var(feas.nl_constraint_set, domain=NonNegativeReals, initialize=1) else: feas.slack_var = Var(domain=NonNegativeReals, initialize=1) # no-good cuts exclude particular discrete decisions lin.no_good_cuts = ConstraintList(doc='no-good cuts') fixed_nlp = solve_data.working_model.clone() TransformationFactory('core.fix_integer_vars').apply_to(fixed_nlp) MindtPy_initialize_main(solve_data, config) # test handle_subproblem_other_termination termination_condition = tc.maxIterations config.add_no_good_cuts = True handle_subproblem_other_termination(fixed_nlp, termination_condition, solve_data, config) self.assertEqual( len(solve_data.mip.MindtPy_utils.cuts.no_good_cuts), 1) # test handle_main_other_conditions main_mip, main_mip_results = solve_main(solve_data, config) main_mip_results.solver.termination_condition = tc.infeasible handle_main_other_conditions( solve_data.mip, main_mip_results, solve_data, config) self.assertIs( solve_data.results.solver.termination_condition, tc.feasible) main_mip_results.solver.termination_condition = tc.unbounded handle_main_other_conditions( solve_data.mip, main_mip_results, solve_data, config) self.assertIn(main_mip.MindtPy_utils.objective_bound, main_mip.component_data_objects(ctype=Constraint)) main_mip.MindtPy_utils.del_component('objective_bound') main_mip_results.solver.termination_condition = tc.infeasibleOrUnbounded handle_main_other_conditions( solve_data.mip, main_mip_results, solve_data, config) self.assertIn(main_mip.MindtPy_utils.objective_bound, main_mip.component_data_objects(ctype=Constraint)) main_mip_results.solver.termination_condition = tc.maxTimeLimit handle_main_other_conditions( solve_data.mip, main_mip_results, solve_data, config) self.assertIs( solve_data.results.solver.termination_condition, tc.maxTimeLimit) main_mip_results.solver.termination_condition = tc.other main_mip_results.solution.status = SolutionStatus.feasible handle_main_other_conditions( solve_data.mip, main_mip_results, solve_data, config) for v1, v2 in zip(main_mip.MindtPy_utils.variable_list, solve_data.working_model.MindtPy_utils.variable_list): self.assertEqual(v1.value, v2.value) # test handle_feasibility_subproblem_tc feas_subproblem = solve_data.working_model.clone() add_feas_slacks(feas_subproblem, config) MindtPy = feas_subproblem.MindtPy_utils MindtPy.feas_opt.activate() if config.feasibility_norm == 'L1': MindtPy.feas_obj = Objective( expr=sum(s for s in MindtPy.feas_opt.slack_var[...]), sense=minimize) elif config.feasibility_norm == 'L2': MindtPy.feas_obj = Objective( expr=sum(s*s for s in MindtPy.feas_opt.slack_var[...]), sense=minimize) else: MindtPy.feas_obj = Objective( expr=MindtPy.feas_opt.slack_var, sense=minimize) handle_feasibility_subproblem_tc( tc.optimal, MindtPy, solve_data, config) handle_feasibility_subproblem_tc( tc.infeasible, MindtPy, solve_data, config) self.assertIs(solve_data.should_terminate, True) self.assertIs(solve_data.results.solver.status, SolverStatus.error) solve_data.should_terminate = False solve_data.results.solver.status = None handle_feasibility_subproblem_tc( tc.maxIterations, MindtPy, solve_data, config) self.assertIs(solve_data.should_terminate, True) self.assertIs(solve_data.results.solver.status, SolverStatus.error) solve_data.should_terminate = False solve_data.results.solver.status = None handle_feasibility_subproblem_tc( tc.solverFailure, MindtPy, solve_data, config) self.assertIs(solve_data.should_terminate, True) self.assertIs(solve_data.results.solver.status, SolverStatus.error) # test NLP subproblem infeasible solve_data.working_model.Y[1].value = 0 solve_data.working_model.Y[2].value = 0 solve_data.working_model.Y[3].value = 0 fixed_nlp, fixed_nlp_results = solve_subproblem(solve_data, config) solve_data.working_model.Y[1].value = None solve_data.working_model.Y[2].value = None solve_data.working_model.Y[3].value = None # test handle_nlp_subproblem_tc fixed_nlp_results.solver.termination_condition = tc.maxTimeLimit handle_nlp_subproblem_tc( fixed_nlp, fixed_nlp_results, solve_data, config) self.assertIs(solve_data.should_terminate, True) self.assertIs( solve_data.results.solver.termination_condition, tc.maxTimeLimit) fixed_nlp_results.solver.termination_condition = tc.maxEvaluations handle_nlp_subproblem_tc( fixed_nlp, fixed_nlp_results, solve_data, config) self.assertIs(solve_data.should_terminate, True) self.assertIs( solve_data.results.solver.termination_condition, tc.maxEvaluations) fixed_nlp_results.solver.termination_condition = tc.maxIterations handle_nlp_subproblem_tc( fixed_nlp, fixed_nlp_results, solve_data, config) self.assertIs(solve_data.should_terminate, True) self.assertIs( solve_data.results.solver.termination_condition, tc.maxEvaluations) # test handle_fp_main_tc config.init_strategy = 'FP' solve_data.fp_iter = 1 init_rNLP(solve_data, config) feas_main, feas_main_results = solve_main( solve_data, config, fp=True) feas_main_results.solver.termination_condition = tc.optimal fp_should_terminate = handle_fp_main_tc( feas_main_results, solve_data, config) self.assertIs(fp_should_terminate, False) feas_main_results.solver.termination_condition = tc.maxTimeLimit fp_should_terminate = handle_fp_main_tc( feas_main_results, solve_data, config) self.assertIs(fp_should_terminate, True) self.assertIs( solve_data.results.solver.termination_condition, tc.maxTimeLimit) feas_main_results.solver.termination_condition = tc.infeasible fp_should_terminate = handle_fp_main_tc( feas_main_results, solve_data, config) self.assertIs(fp_should_terminate, True) feas_main_results.solver.termination_condition = tc.unbounded fp_should_terminate = handle_fp_main_tc( feas_main_results, solve_data, config) self.assertIs(fp_should_terminate, True) feas_main_results.solver.termination_condition = tc.other feas_main_results.solution.status = SolutionStatus.feasible fp_should_terminate = handle_fp_main_tc( feas_main_results, solve_data, config) self.assertIs(fp_should_terminate, False) feas_main_results.solver.termination_condition = tc.solverFailure fp_should_terminate = handle_fp_main_tc( feas_main_results, solve_data, config) self.assertIs(fp_should_terminate, True) # test generate_norm_constraint fp_nlp = solve_data.working_model.clone() config.fp_main_norm = 'L1' generate_norm_constraint(fp_nlp, solve_data, config) self.assertIsNotNone(fp_nlp.MindtPy_utils.find_component( 'L1_norm_constraint')) config.fp_main_norm = 'L2' generate_norm_constraint(fp_nlp, solve_data, config) self.assertIsNotNone(fp_nlp.find_component('norm_constraint')) fp_nlp.del_component('norm_constraint') config.fp_main_norm = 'L_infinity' generate_norm_constraint(fp_nlp, solve_data, config) self.assertIsNotNone(fp_nlp.find_component('norm_constraint')) # test set_solver_options config.mip_solver = 'gams' config.threads = 1 opt = SolverFactory(config.mip_solver) set_solver_options(opt, solve_data, config, 'mip', regularization=False) config.mip_solver = 'gurobi' config.mip_regularization_solver = 'gurobi' config.regularization_mip_threads = 1 opt = SolverFactory(config.mip_solver) set_solver_options(opt, solve_data, config, 'mip', regularization=True) config.nlp_solver = 'gams' config.nlp_solver_args['solver'] = 'ipopt' set_solver_options(opt, solve_data, config, 'nlp', regularization=False) config.nlp_solver_args['solver'] = 'ipopth' set_solver_options(opt, solve_data, config, 'nlp', regularization=False) config.nlp_solver_args['solver'] = 'conopt' set_solver_options(opt, solve_data, config, 'nlp', regularization=False) config.nlp_solver_args['solver'] = 'msnlp' set_solver_options(opt, solve_data, config, 'nlp', regularization=False) config.nlp_solver_args['solver'] = 'baron' set_solver_options(opt, solve_data, config, 'nlp', regularization=False) # test algorithm_should_terminate solve_data.should_terminate = True solve_data.primal_bound = float('inf') self.assertIs(algorithm_should_terminate( solve_data, config, check_cycling=False), True) self.assertIs( solve_data.results.solver.termination_condition, tc.noSolution) solve_data.primal_bound = 100 self.assertIs(algorithm_should_terminate( solve_data, config, check_cycling=False), True) self.assertIs( solve_data.results.solver.termination_condition, tc.feasible) solve_data.primal_bound_progress = [float('inf'), 5, 4, 3, 2, 1] solve_data.primal_bound_progress_time = [1, 2, 3, 4, 5, 6] solve_data.primal_bound = 1 self.assertEqual(get_primal_integral(solve_data, config), 14.5) solve_data.dual_bound_progress = [float('-inf'), 1, 2, 3, 4, 5] solve_data.dual_bound_progress_time = [1, 2, 3, 4, 5, 6] solve_data.dual_bound = 5 self.assertEqual(get_dual_integral(solve_data, config), 14.1) # test check_config config.add_regularization = 'level_L1' config.regularization_mip_threads = 0 config.threads = 8 check_config(config) self.assertEqual(config.regularization_mip_threads, 8) config.mip_solver = 'cplex' config.single_tree = True check_config(config) self.assertEqual(config.mip_solver, 'cplex_persistent') self.assertEqual(config.threads, 1) config.add_slack = True config.max_slack == 0.0 check_config(config) self.assertEqual(config.add_slack, False) config.strategy = 'GOA' config.add_slack = True config.use_mcpp = False config.equality_relaxation = True config.use_fbbt = False config.add_no_good_cuts = False config.use_tabu_list = False check_config(config) self.assertTrue(config.use_mcpp) self.assertTrue(config.use_fbbt) self.assertFalse(config.add_slack) self.assertFalse(config.equality_relaxation) self.assertTrue(config.add_no_good_cuts) self.assertFalse(config.use_tabu_list) config.single_tree = False config.strategy = 'FP' config.init_strategy = 'rNLP' config.iteration_limit = 100 config.add_no_good_cuts = False config.use_tabu_list = True check_config(config) self.assertEqual(config.init_strategy, 'FP') self.assertEqual(config.iteration_limit, 0) self.assertEqual(config.add_no_good_cuts, True) self.assertEqual(config.use_tabu_list, False)
from pyomo.environ import SolverFactory, DataPortal from DiseaseEstimation import model model.pprint() data = DataPortal(model=model) data.load(filename='DiseaseEstimation.dat') data.load(filename='DiseasePop.dat') instance = model.create(data) instance.pprint() solver = SolverFactory("ipopt") results = solver.solve(instance) instance.display()
def initialize(blk, state_args=None, outlvl=0, solver='ipopt', optarg={'tol': 1e-6}): ''' This is a general purpose initialization routine for simple unit models. This method assumes a single ControlVolume block called controlVolume, and first initializes this and then attempts to solve the entire unit. More complex models should overload this method with their own initialization routines, Keyword Arguments: state_args : a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}). outlvl : sets output level of initialisation routine * 0 = no output (default) * 1 = return solver state for each step in routine * 2 = return solver state for each step in subroutines * 3 = include solver output infomation (tee=True) optarg : solver options dictionary object (default={'tol': 1e-6}) solver : str indicating which solver to use during initialization (default = 'ipopt') Returns: None ''' # Set solver options if outlvl > 3: stee = True else: stee = False opt = SolverFactory(solver) opt.options = optarg # --------------------------------------------------------------------- # Initialize control volume block flags = blk.control_volume.initialize(outlvl=outlvl-1, optarg=optarg, solver=solver, state_args=state_args) if outlvl > 0: _log.info('{} Initialisation Step 1 Complete.'.format(blk.name)) # --------------------------------------------------------------------- # Solve unit try: results = opt.solve(blk, tee=stee) except ValueError: results = None if outlvl > 0: if (results is not None and results.solver.termination_condition == TerminationCondition.optimal): _log.info('{} Initialisation Step 2 Complete.' .format(blk.name)) else: _log.warning('{} Initialisation Step 2 Failed.' .format(blk.name)) # --------------------------------------------------------------------- # Release Inlet state blk.control_volume.release_state(flags, outlvl-1) if outlvl > 0: _log.info('{} Initialisation Complete.'.format(blk.name))
from pyomo.core import (Constraint, Objective, TransformationFactory, minimize, Var, RangeSet, NonNegativeReals) from pyomo.contrib.mindtpy.iterate import algorithm_should_terminate nonconvex_model_list = [EightProcessFlowsheet(convex=False)] LP_model = LP_unbounded() LP_model._generate_model() QCP_model = QCP_simple() QCP_model._generate_model() extreme_model_list = [LP_model.model, QCP_model.model] required_solvers = ('ipopt', 'glpk') # required_solvers = ('gams', 'gams') if all(SolverFactory(s).available() for s in required_solvers): subsolvers_available = True else: subsolvers_available = False @unittest.skipIf(not subsolvers_available, 'Required subsolvers %s are not available' % (required_solvers,)) class TestMindtPy(unittest.TestCase): """Tests for the MindtPy solver plugin.""" def test_handle_termination_condition(self): """Test the outer approximation decomposition algorithm.""" model = SimpleMINLP() config = _get_MindtPy_config()
def initialize(self, outlvl=idaeslog.NOTSET, solver="ipopt", optarg={ "tol": 1e-6, "max_iter": 35 }): """ Initialize """ # sp is what to save to make sure state after init is same as the start # saves value, fixed, and active state, doesn't load originally free # values, this makes sure original problem spec is same but initializes # the values of free vars init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit") sp = StoreSpec.value_isfixed_isactive(only_fixed=True) istate = to_json(self, return_dict=True, wts=sp) ni = self.config.num_parallel_inlet_stages flow_guess = self.inlet_split.inlet.flow_mol[0].value def init_section(stages, splits, disconnects, prev_port): if 0 in splits: _set_port(splits[0].inlet, prev_port) splits[0].initialize(outlvl=outlvl, solver=solver, optarg=optarg) prev_port = splits[0].outlet_1 for i in stages: if i - 1 not in disconnects: _set_port(stages[i].inlet, prev_port) stages[i].initialize(outlvl=outlvl, solver=solver, optarg=optarg) prev_port = stages[i].outlet if i in splits: _set_port(splits[i].inlet, prev_port) splits[i].initialize(outlvl=outlvl, solver=solver, optarg=optarg) prev_port = splits[i].outlet_1 return prev_port for k in [1]: # Initialize Splitter # Fix n - 1 split fractions self.inlet_split.split_fraction[0, "outlet_1"].value = 1.0 / ni for i in self.inlet_stage_idx: if i == 1: # fix rest of splits at leaving first one free continue self.inlet_split.split_fraction[0, "outlet_{}".format(i)].fix( 1.0 / ni) # fix inlet and free outlet self.inlet_split.inlet.fix() for i in self.inlet_stage_idx: ol = getattr(self.inlet_split, "outlet_{}".format(i)) ol.unfix() self.inlet_split.initialize(outlvl=outlvl, solver=solver, optarg=optarg) # free split fractions for i in self.inlet_stage_idx: self.inlet_split.split_fraction[0, "outlet_{}".format(i)].unfix() # Initialize valves for i in self.inlet_stage_idx: _set_port( self.throttle_valve[i].inlet, getattr(self.inlet_split, "outlet_{}".format(i)), ) self.throttle_valve[i].initialize(outlvl=outlvl, solver=solver, optarg=optarg) # Initialize turbine for i in self.inlet_stage_idx: _set_port(self.inlet_stage[i].inlet, self.throttle_valve[i].outlet) self.inlet_stage[i].initialize(outlvl=outlvl, solver=solver, optarg=optarg) # Initialize Mixer self.inlet_mix.use_minimum_inlet_pressure_constraint() for i in self.inlet_stage_idx: _set_port( getattr(self.inlet_mix, "inlet_{}".format(i)), self.inlet_stage[i].outlet, ) getattr(self.inlet_mix, "inlet_{}".format(i)).fix() self.inlet_mix.initialize(outlvl=outlvl, solver=solver, optarg=optarg) for i in self.inlet_stage_idx: getattr(self.inlet_mix, "inlet_{}".format(i)).unfix() self.inlet_mix.use_equal_pressure_constraint() prev_port = self.inlet_mix.outlet prev_port = init_section(self.hp_stages, self.hp_split, self.config.hp_disconnect, prev_port) if len(self.hp_stages) in self.config.hp_disconnect: prev_port = self.ip_stages[1].inlet prev_port = init_section(self.ip_stages, self.ip_split, self.config.ip_disconnect, prev_port) if len(self.ip_stages) in self.config.ip_disconnect: prev_port = self.lp_stages[1].inlet prev_port = init_section(self.lp_stages, self.lp_split, self.config.lp_disconnect, prev_port) _set_port(self.outlet_stage.inlet, prev_port) self.outlet_stage.initialize(outlvl=outlvl, solver=solver, optarg=optarg) for t in self.flowsheet().time: self.inlet_split.inlet.flow_mol[ t].value = self.outlet_stage.inlet.flow_mol[t].value slvr = SolverFactory(solver) slvr.options = optarg init_log.info_high("Solve full multistage turbine") self.inlet_split.inlet.flow_mol.unfix() with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = slvr.solve(self, tee=slc.tee) init_log.info( "Flow guess: {}, Initialized Flow: {}".format( flow_guess, self.outlet_stage.inlet.flow_mol[0].value), ) init_log.info("Initialization Complete: {}".format( idaeslog.condition(res))) from_json(self, sd=istate, wts=sp)