class NLWriter(PersistentBase): def __init__(self): super(NLWriter, self).__init__() self._config = WriterConfig() self._writer = None self._symbol_map = SymbolMap() self._var_labeler = None self._con_labeler = None self._param_labeler = None self._pyomo_var_to_solver_var_map = dict() self._pyomo_con_to_solver_con_map = dict() self._solver_var_to_pyomo_var_map = dict() self._solver_con_to_pyomo_con_map = dict() self._pyomo_param_to_solver_param_map = dict() self._walker = PyomoToCModelWalker( self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map) @property def config(self): return self._config @config.setter def config(self, val: WriterConfig): self._config = val @property def symbol_map(self): return self._symbol_map def set_instance(self, model): saved_config = self.config saved_update_config = self.update_config self.__init__() self.config = saved_config self.update_config = saved_update_config self._model = model if self.config.symbolic_solver_labels: self._var_labeler = TextLabeler() self._con_labeler = TextLabeler() self._param_labeler = TextLabeler() else: self._var_labeler = NumericLabeler('x') self._con_labeler = NumericLabeler('c') self._param_labeler = NumericLabeler('p') self._writer = cmodel.NLWriter() self.add_block(model) if self._objective is None: self.set_objective(None) def _add_variables(self, variables: List[_GeneralVarData]): cvars = cmodel.create_vars(len(variables)) for ndx, v in enumerate(variables): cv = cvars[ndx] cv.name = self._symbol_map.getSymbol(v, self._var_labeler) if not v.is_continuous(): raise NotImplementedError( 'NLWriter currently only supports continuous variables') lb = value(v.lb) ub = value(v.ub) if lb is not None: cv.lb = lb if ub is not None: cv.ub = ub if v.value is not None: cv.value = v.value if v.is_fixed(): cv.fixed = True self._pyomo_var_to_solver_var_map[id(v)] = cv self._solver_var_to_pyomo_var_map[cv] = v def _add_params(self, params: List[_ParamData]): cparams = cmodel.create_params(len(params)) for ndx, p in enumerate(params): cp = cparams[ndx] cp.name = self._symbol_map.getSymbol(p, self._param_labeler) cp.value = p.value self._pyomo_param_to_solver_param_map[id(p)] = cp def _add_constraints(self, cons: List[_GeneralConstraintData]): for c in cons: cname = self._symbol_map.getSymbol(c, self._con_labeler) repn = generate_standard_repn(c.body, compute_values=False, quadratic=False) const = self._walker.dfs_postorder_stack(repn.constant) lin_vars = [ self._pyomo_var_to_solver_var_map[id(i)] for i in repn.linear_vars ] lin_coef = [ self._walker.dfs_postorder_stack(i) for i in repn.linear_coefs ] if repn.nonlinear_expr is None: nonlin = self._walker.dfs_postorder_stack(0) else: nonlin = self._walker.dfs_postorder_stack(repn.nonlinear_expr) cc = cmodel.NLConstraint(const, lin_coef, lin_vars, nonlin) lb = c.lower ub = c.upper if lb is not None: cc.lb = self._walker.dfs_postorder_stack(lb) if ub is not None: cc.ub = self._walker.dfs_postorder_stack(ub) self._writer.add_constraint(cc) self._pyomo_con_to_solver_con_map[c] = cc self._solver_con_to_pyomo_con_map[cc] = c def _add_sos_constraints(self, cons: List[_SOSConstraintData]): if len(cons) != 0: raise NotImplementedError( 'NL writer does not support SOS constraints') def _remove_constraints(self, cons: List[_GeneralConstraintData]): for c in cons: cc = self._pyomo_con_to_solver_con_map.pop(c) self._writer.remove_constraint(cc) self._symbol_map.removeSymbol(c) self._con_labeler.remove_obj(c) del self._solver_con_to_pyomo_con_map[cc] def _remove_sos_constraints(self, cons: List[_SOSConstraintData]): if len(cons) != 0: raise NotImplementedError( 'NL writer does not support SOS constraints') def _remove_variables(self, variables: List[_GeneralVarData]): for v in variables: cvar = self._pyomo_var_to_solver_var_map.pop(id(v)) del self._solver_var_to_pyomo_var_map[cvar] self._symbol_map.removeSymbol(v) self._var_labeler.remove_obj(v) def _remove_params(self, params: List[_ParamData]): for p in params: del self._pyomo_param_to_solver_param_map[id(p)] self._symbol_map.removeSymbol(p) self._param_labeler.remove_obj(p) def _update_variables(self, variables: List[_GeneralVarData]): for v in variables: cv = self._pyomo_var_to_solver_var_map[id(v)] if not v.is_continuous(): raise NotImplementedError( 'NLWriter currently only supports continuous variables') lb = value(v.lb) ub = value(v.ub) if lb is None: cv.lb = -cmodel.inf else: cv.lb = lb if ub is None: cv.ub = cmodel.inf else: cv.ub = ub if v.value is not None: cv.value = v.value if v.is_fixed(): cv.fixed = True else: cv.fixed = False def update_params(self): for p_id, p in self._params.items(): cp = self._pyomo_param_to_solver_param_map[p_id] cp.value = p.value def _set_objective(self, obj: _GeneralObjectiveData): if obj is None: const = cmodel.Constant(0) lin_vars = list() lin_coef = list() nonlin = cmodel.Constant(0) sense = 0 else: repn = generate_standard_repn(obj.expr, compute_values=False, quadratic=False) const = self._walker.dfs_postorder_stack(repn.constant) lin_vars = [ self._pyomo_var_to_solver_var_map[id(i)] for i in repn.linear_vars ] lin_coef = [ self._walker.dfs_postorder_stack(i) for i in repn.linear_coefs ] if repn.nonlinear_expr is None: nonlin = cmodel.Constant(0) else: nonlin = self._walker.dfs_postorder_stack(repn.nonlinear_expr) if obj.sense is minimize: sense = 0 else: sense = 1 cobj = cmodel.NLObjective(const, lin_coef, lin_vars, nonlin) cobj.sense = sense self._writer.objective = cobj def write(self, model: _BlockData, filename: str, timer: HierarchicalTimer = None): if timer is None: timer = HierarchicalTimer() if model is not self._model: timer.start('set_instance') self.set_instance(model) timer.stop('set_instance') else: timer.start('update') self.update(timer=timer) for cv, v in self._solver_var_to_pyomo_var_map.items(): if v.value is not None: cv.value = v.value timer.stop('update') timer.start('write file') self._writer.write(filename) timer.stop('write file') def get_ordered_vars(self): return [ self._solver_var_to_pyomo_var_map[i] for i in self._writer.get_solve_vars() ] def get_ordered_cons(self): return [ self._solver_con_to_pyomo_con_map[i] for i in self._writer.get_solve_cons() ] def get_active_objective(self): return self._objective
class LPWriter(PersistentBase): def __init__(self): super(LPWriter, self).__init__() self._config = WriterConfig() self._writer = None self._symbol_map = SymbolMap() self._var_labeler = None self._con_labeler = None self._param_labeler = None self._obj_labeler = None self._pyomo_var_to_solver_var_map = dict() self._pyomo_con_to_solver_con_map = dict() self._solver_var_to_pyomo_var_map = dict() self._solver_con_to_pyomo_con_map = dict() self._pyomo_param_to_solver_param_map = dict() self._walker = PyomoToCModelWalker( self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map) @property def config(self): return self._config @config.setter def config(self, val: WriterConfig): self._config = val def set_instance(self, model): saved_config = self.config saved_update_config = self.update_config self.__init__() self.config = saved_config self.update_config = saved_update_config self._model = model if self.config.symbolic_solver_labels: self._var_labeler = TextLabeler() self._con_labeler = TextLabeler() self._param_labeler = TextLabeler() self._obj_labeler = TextLabeler() else: self._var_labeler = NumericLabeler('x') self._con_labeler = NumericLabeler('c') self._param_labeler = NumericLabeler('p') self._obj_labeler = NumericLabeler('obj') self._writer = cmodel.LPWriter() self.add_block(model) if self._objective is None: self.set_objective(None) def _add_variables(self, variables: List[_GeneralVarData]): cvars = cmodel.create_vars(len(variables)) for ndx, v in enumerate(variables): cv = cvars[ndx] cv.name = self._symbol_map.getSymbol(v, self._var_labeler) if v.is_binary(): cv.domain = 'binary' elif v.is_integer(): cv.domain = 'integer' else: assert v.is_continuous( ), 'LP writer only supports continuous, binary, and integer variables' cv.domain = 'continuous' _, lb, ub, v_is_fixed, v_domain, v_value = self._vars[id(v)] if lb is not None: cv.lb = lb if ub is not None: cv.ub = ub if v_value is not None: cv.value = v_value if v_is_fixed: cv.fixed = True self._pyomo_var_to_solver_var_map[id(v)] = cv self._solver_var_to_pyomo_var_map[cv] = v def _add_params(self, params: List[_ParamData]): cparams = cmodel.create_params(len(params)) for ndx, p in enumerate(params): cp = cparams[ndx] cp.name = self._symbol_map.getSymbol(p, self._param_labeler) cp.value = p.value self._pyomo_param_to_solver_param_map[id(p)] = cp def _add_constraints(self, cons: List[_GeneralConstraintData]): cmodel.process_lp_constraints(cons, self) def _add_sos_constraints(self, cons: List[_SOSConstraintData]): if len(cons) != 0: raise NotImplementedError( 'LP writer does not yet support SOS constraints') def _remove_constraints(self, cons: List[_GeneralConstraintData]): for c in cons: cc = self._pyomo_con_to_solver_con_map.pop(c) self._writer.remove_constraint(cc) self._symbol_map.removeSymbol(c) self._con_labeler.remove_obj(c) del self._solver_con_to_pyomo_con_map[cc] def _remove_sos_constraints(self, cons: List[_SOSConstraintData]): if len(cons) != 0: raise NotImplementedError( 'LP writer does not yet support SOS constraints') def _remove_variables(self, variables: List[_GeneralVarData]): for v in variables: cvar = self._pyomo_var_to_solver_var_map.pop(id(v)) del self._solver_var_to_pyomo_var_map[cvar] self._symbol_map.removeSymbol(v) self._var_labeler.remove_obj(v) def _remove_params(self, params: List[_ParamData]): for p in params: del self._pyomo_param_to_solver_param_map[id(p)] self._symbol_map.removeSymbol(p) self._param_labeler.remove_obj(p) def update_variables(self, variables: List[_GeneralVarData]): for v in variables: cv = self._pyomo_var_to_solver_var_map[id(v)] if v.is_binary(): cv.domain = 'binary' elif v.is_integer(): cv.domain = 'integer' else: assert v.is_continuous( ), 'LP writer only supports continuous, binary, and integer variables' cv.domain = 'continuous' lb = value(v.lb) ub = value(v.ub) if lb is None: cv.lb = -cmodel.inf else: cv.lb = lb if ub is None: cv.ub = cmodel.inf else: cv.ub = ub if v.value is not None: cv.value = v.value if v.is_fixed(): cv.fixed = True else: cv.fixed = False def update_params(self): for p_id, p in self._params.items(): cp = self._pyomo_param_to_solver_param_map[p_id] cp.value = p.value def _set_objective(self, obj: _GeneralObjectiveData): if obj is None: const = cmodel.Constant(0) lin_coef = list() lin_vars = list() quad_coef = list() quad_vars_1 = list() quad_vars_2 = list() sense = 0 else: repn = generate_standard_repn(obj.expr, compute_values=False, quadratic=True) const = self._walker.dfs_postorder_stack(repn.constant) lin_coef = [ self._walker.dfs_postorder_stack(i) for i in repn.linear_coefs ] lin_vars = [ self._pyomo_var_to_solver_var_map[id(i)] for i in repn.linear_vars ] quad_coef = [ self._walker.dfs_postorder_stack(i) for i in repn.quadratic_coefs ] quad_vars_1 = [ self._pyomo_var_to_solver_var_map[id(i[0])] for i in repn.quadratic_vars ] quad_vars_2 = [ self._pyomo_var_to_solver_var_map[id(i[1])] for i in repn.quadratic_vars ] if obj.sense is minimize: sense = 0 else: sense = 1 cobj = cmodel.LPObjective(const, lin_coef, lin_vars, quad_coef, quad_vars_1, quad_vars_2) cobj.sense = sense if obj is None: cname = 'objective' else: cname = self._symbol_map.getSymbol(obj, self._obj_labeler) cobj.name = cname self._writer.objective = cobj def write(self, model: _BlockData, filename: str, timer: HierarchicalTimer = None): if timer is None: timer = HierarchicalTimer() if model is not self._model: timer.start('set_instance') self.set_instance(model) timer.stop('set_instance') else: timer.start('update') self.update(timer=timer) timer.stop('update') timer.start('write file') self._writer.write(filename) timer.stop('write file') def get_vars(self): return [ self._solver_var_to_pyomo_var_map[i] for i in self._writer.get_solve_vars() ] def get_ordered_cons(self): return [ self._solver_con_to_pyomo_con_map[i] for i in self._writer.get_solve_cons() ] def get_active_objective(self): return self._objective @property def symbol_map(self): return self._symbol_map
class IntervalTightener(PersistentBase): def __init__(self): super(IntervalTightener, self).__init__() self._config = IntervalConfig() self._cmodel = None self._var_map = dict() self._con_map = dict() self._param_map = dict() self._rvar_map = dict() self._rcon_map = dict() self._pyomo_expr_types = cmodel.PyomoExprTypes() self._symbolic_solver_labels: bool = False self._symbol_map = SymbolMap() self._var_labeler = None self._con_labeler = None self._param_labeler = None self._obj_labeler = None self._objective = None @property def config(self): return self._config @config.setter def config(self, val: IntervalConfig): self._config = val def set_instance(self, model, symbolic_solver_labels: Optional[bool] = None): saved_config = self.config saved_update_config = self.update_config self.__init__() self.config = saved_config self.update_config = saved_update_config self._expr_types = cmodel.PyomoExprTypes() if symbolic_solver_labels is not None: self._symbolic_solver_labels = symbolic_solver_labels if self._symbolic_solver_labels: self._var_labeler = TextLabeler() self._con_labeler = TextLabeler() self._param_labeler = TextLabeler() self._obj_labeler = TextLabeler() self._model = model self._cmodel = cmodel.FBBTModel() self.add_block(model) if self._objective is None: self.set_objective(None) def _add_variables(self, variables: List[_GeneralVarData]): if self._symbolic_solver_labels: set_name = True symbol_map = self._symbol_map labeler = self._var_labeler else: set_name = False symbol_map = None labeler = None cmodel.process_pyomo_vars(self._pyomo_expr_types, variables, self._var_map, self._param_map, self._vars, self._rvar_map, set_name, symbol_map, labeler, False) def _add_params(self, params: List[_ParamData]): cparams = cmodel.create_params(len(params)) for ndx, p in enumerate(params): cp = cparams[ndx] cp.value = p.value self._param_map[id(p)] = cp if self._symbolic_solver_labels: for ndx, p in enumerate(params): cp = cparams[ndx] cp.name = self._symbol_map.getSymbol(p, self._param_labeler) def _add_constraints(self, cons: List[_GeneralConstraintData]): cmodel.process_fbbt_constraints(self._cmodel, self._pyomo_expr_types, cons, self._var_map, self._param_map, self._active_constraints, self._con_map, self._rcon_map) if self._symbolic_solver_labels: for c, cc in self._con_map.items(): cc.name = self._symbol_map.getSymbol(c, self._con_labeler) def _add_sos_constraints(self, cons: List[_SOSConstraintData]): if len(cons) != 0: raise NotImplementedError( 'IntervalTightener does not support SOS constraints') def _remove_constraints(self, cons: List[_GeneralConstraintData]): if self._symbolic_solver_labels: for c in cons: self._symbol_map.removeSymbol(c) for c in cons: cc = self._con_map.pop(c) self._cmodel.remove_constraint(cc) del self._rcon_map[cc] def _remove_sos_constraints(self, cons: List[_SOSConstraintData]): if len(cons) != 0: raise NotImplementedError( 'IntervalTightener does not support SOS constraints') def _remove_variables(self, variables: List[_GeneralVarData]): if self._symbolic_solver_labels: for v in variables: self._symbol_map.removeSymbol(v) for v in variables: cvar = self._var_map.pop(id(v)) del self._rvar_map[cvar] def _remove_params(self, params: List[_ParamData]): if self._symbolic_solver_labels: for p in params: self._symbol_map.removeSymbol(p) for p in params: del self._param_map[id(p)] def _update_variables(self, variables: List[_GeneralVarData]): cmodel.process_pyomo_vars(self._pyomo_expr_types, variables, self._var_map, self._param_map, self._vars, self._rvar_map, False, None, None, True) def update_params(self): for p_id, p in self._params.items(): cp = self._param_map[p_id] cp.value = p.value def set_objective(self, obj: _GeneralObjectiveData): if self._symbolic_solver_labels: if self._objective is not None: self._symbol_map.removeSymbol(self._objective) super().set_objective(obj) def _set_objective(self, obj: _GeneralObjectiveData): if obj is None: ce = cmodel.Constant(0) sense = 0 else: ce = cmodel.appsi_expr_from_pyomo_expr(obj.expr, self._var_map, self._param_map, self._pyomo_expr_types) if obj.sense is minimize: sense = 0 else: sense = 1 cobj = cmodel.FBBTObjective(ce) cobj.sense = sense self._cmodel.objective = cobj self._objective = obj if self._symbolic_solver_labels and obj is not None: cobj.name = self._symbol_map.getSymbol(obj, self._obj_labeler) def _update_pyomo_var_bounds(self): for cv, v in self._rvar_map.items(): cv_lb = cv.get_lb() cv_ub = cv.get_ub() if -cmodel.inf < cv_lb: v.setlb(cv_lb) v_id = id(v) _v, _lb, _ub, _fixed, _domain, _value = self._vars[v_id] self._vars[v_id] = (_v, cv_lb, _ub, _fixed, _domain, _value) if cv_ub < cmodel.inf: v.setub(cv_ub) v_id = id(v) _v, _lb, _ub, _fixed, _domain, _value = self._vars[v_id] self._vars[v_id] = (_v, _lb, cv_ub, _fixed, _domain, _value) def _deactivate_satisfied_cons(self): cons_to_deactivate = list() if self.config.deactivate_satisfied_constraints: for c, cc in self._con_map.items(): if not cc.active: cons_to_deactivate.append(c) self.remove_constraints(cons_to_deactivate) for c in cons_to_deactivate: c.deactivate() def perform_fbbt(self, model: _BlockData, symbolic_solver_labels: Optional[bool] = None): if model is not self._model: self.set_instance(model, symbolic_solver_labels=symbolic_solver_labels) else: if symbolic_solver_labels is not None and symbolic_solver_labels != self._symbolic_solver_labels: raise RuntimeError( 'symbolic_solver_labels can only be changed through the set_instance method. ' 'Please either use set_instance or create a new instance of IntervalTightener.' ) self.update() try: n_iter = self._cmodel.perform_fbbt( self.config.feasibility_tol, self.config.integer_tol, self.config.improvement_tol, self.config.max_iter, self.config.deactivate_satisfied_constraints) finally: # we want to make sure the pyomo model and cmodel stay in sync # even if an exception is raised and caught self._update_pyomo_var_bounds() self._deactivate_satisfied_cons() return n_iter def perform_fbbt_with_seed(self, model: _BlockData, seed_var: _GeneralVarData): if model is not self._model: self.set_instance(model) else: self.update() try: n_iter = self._cmodel.perform_fbbt_with_seed( self._var_map[id(seed_var)], self.config.feasibility_tol, self.config.integer_tol, self.config.improvement_tol, self.config.max_iter, self.config.deactivate_satisfied_constraints) finally: # we want to make sure the pyomo model and cmodel stay in sync # even if an exception is raised and caught self._update_pyomo_var_bounds() self._deactivate_satisfied_cons() return n_iter
class NLWriter(PersistentBase): def __init__(self): super(NLWriter, self).__init__() self._config = WriterConfig() self._writer = None self._symbol_map = SymbolMap() self._var_labeler = None self._con_labeler = None self._param_labeler = None self._pyomo_var_to_solver_var_map = dict() self._pyomo_con_to_solver_con_map = dict() self._solver_var_to_pyomo_var_map = dict() self._solver_con_to_pyomo_con_map = dict() self._pyomo_param_to_solver_param_map = dict() self._expr_types = None @property def config(self): return self._config @config.setter def config(self, val: WriterConfig): self._config = val @property def symbol_map(self): return self._symbol_map def set_instance(self, model): saved_config = self.config saved_update_config = self.update_config self.__init__() self.config = saved_config self.update_config = saved_update_config self._model = model self._expr_types = cmodel.PyomoExprTypes() if self.config.symbolic_solver_labels: self._var_labeler = TextLabeler() self._con_labeler = TextLabeler() self._param_labeler = TextLabeler() else: self._var_labeler = NumericLabeler('x') self._con_labeler = NumericLabeler('c') self._param_labeler = NumericLabeler('p') self._writer = cmodel.NLWriter() self.add_block(model) if self._objective is None: self.set_objective(None) self._set_pyomo_amplfunc_env() def _add_variables(self, variables: List[_GeneralVarData]): cmodel.process_pyomo_vars(self._expr_types, variables, self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map, self._vars, self._solver_var_to_pyomo_var_map, False, None, None, False) def _add_params(self, params: List[_ParamData]): cparams = cmodel.create_params(len(params)) for ndx, p in enumerate(params): cp = cparams[ndx] cp.name = self._symbol_map.getSymbol(p, self._param_labeler) cp.value = p.value self._pyomo_param_to_solver_param_map[id(p)] = cp def _add_constraints(self, cons: List[_GeneralConstraintData]): cmodel.process_nl_constraints(self._writer, self._expr_types, cons, self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map, self._active_constraints, self._pyomo_con_to_solver_con_map, self._solver_con_to_pyomo_con_map) def _add_sos_constraints(self, cons: List[_SOSConstraintData]): if len(cons) != 0: raise NotImplementedError( 'NL writer does not support SOS constraints') def _remove_constraints(self, cons: List[_GeneralConstraintData]): for c in cons: cc = self._pyomo_con_to_solver_con_map.pop(c) self._writer.remove_constraint(cc) self._con_labeler.remove_obj(c) del self._solver_con_to_pyomo_con_map[cc] def _remove_sos_constraints(self, cons: List[_SOSConstraintData]): if len(cons) != 0: raise NotImplementedError( 'NL writer does not support SOS constraints') def _remove_variables(self, variables: List[_GeneralVarData]): for v in variables: cvar = self._pyomo_var_to_solver_var_map.pop(id(v)) del self._solver_var_to_pyomo_var_map[cvar] # self._symbol_map.removeSymbol(v) self._var_labeler.remove_obj(v) def _remove_params(self, params: List[_ParamData]): for p in params: del self._pyomo_param_to_solver_param_map[id(p)] self._symbol_map.removeSymbol(p) self._param_labeler.remove_obj(p) def _update_variables(self, variables: List[_GeneralVarData]): cmodel.process_pyomo_vars(self._expr_types, variables, self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map, self._vars, self._solver_var_to_pyomo_var_map, False, None, None, True) def update_params(self): for p_id, p in self._params.items(): cp = self._pyomo_param_to_solver_param_map[p_id] cp.value = p.value def _set_objective(self, obj: _GeneralObjectiveData): if obj is None: const = cmodel.Constant(0) lin_vars = list() lin_coef = list() nonlin = cmodel.Constant(0) sense = 0 else: pyomo_expr_types = cmodel.PyomoExprTypes() repn = generate_standard_repn(obj.expr, compute_values=False, quadratic=False) const = cmodel.appsi_expr_from_pyomo_expr( repn.constant, self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map, pyomo_expr_types) lin_vars = [ self._pyomo_var_to_solver_var_map[id(i)] for i in repn.linear_vars ] lin_coef = [ cmodel.appsi_expr_from_pyomo_expr( i, self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map, pyomo_expr_types) for i in repn.linear_coefs ] if repn.nonlinear_expr is None: nonlin = cmodel.appsi_expr_from_pyomo_expr( 0, self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map, pyomo_expr_types) else: nonlin = cmodel.appsi_expr_from_pyomo_expr( repn.nonlinear_expr, self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map, pyomo_expr_types) if obj.sense is minimize: sense = 0 else: sense = 1 cobj = cmodel.NLObjective(const, lin_coef, lin_vars, nonlin) cobj.sense = sense self._writer.objective = cobj def write(self, model: _BlockData, filename: str, timer: HierarchicalTimer = None): if timer is None: timer = HierarchicalTimer() if model is not self._model: timer.start('set_instance') self.set_instance(model) timer.stop('set_instance') else: timer.start('update') self.update(timer=timer) for cv, v in self._solver_var_to_pyomo_var_map.items(): if v.value is not None: cv.value = v.value timer.stop('update') timer.start('write file') self._writer.write(filename) timer.stop('write file') def update(self, timer: HierarchicalTimer = None): super(NLWriter, self).update(timer=timer) self._set_pyomo_amplfunc_env() def get_ordered_vars(self): return [ self._solver_var_to_pyomo_var_map[i] for i in self._writer.get_solve_vars() ] def get_ordered_cons(self): return [ self._solver_con_to_pyomo_con_map[i] for i in self._writer.get_solve_cons() ] def get_active_objective(self): return self._objective def _set_pyomo_amplfunc_env(self): if self._external_functions: external_Libs = OrderedSet() for con, ext_funcs in self._external_functions.items(): external_Libs.update([i._fcn._library for i in ext_funcs]) set_pyomo_amplfunc_env(external_Libs) elif "PYOMO_AMPLFUNC" in os.environ: del os.environ["PYOMO_AMPLFUNC"]
class LPWriter(PersistentBase): def __init__(self): super(LPWriter, self).__init__() self._config = WriterConfig() self._writer = None self._symbol_map = SymbolMap() self._var_labeler = None self._con_labeler = None self._param_labeler = None self._obj_labeler = None self._pyomo_var_to_solver_var_map = dict() self._pyomo_con_to_solver_con_map = dict() self._solver_var_to_pyomo_var_map = dict() self._solver_con_to_pyomo_con_map = dict() self._pyomo_param_to_solver_param_map = dict() self._expr_types = None @property def config(self): return self._config @config.setter def config(self, val: WriterConfig): self._config = val def set_instance(self, model): saved_config = self.config saved_update_config = self.update_config self.__init__() self.config = saved_config self.update_config = saved_update_config self._model = model self._expr_types = cmodel.PyomoExprTypes() if self.config.symbolic_solver_labels: self._var_labeler = TextLabeler() self._con_labeler = TextLabeler() self._param_labeler = TextLabeler() self._obj_labeler = TextLabeler() else: self._var_labeler = NumericLabeler('x') self._con_labeler = NumericLabeler('c') self._param_labeler = NumericLabeler('p') self._obj_labeler = NumericLabeler('obj') self._writer = cmodel.LPWriter() self.add_block(model) if self._objective is None: self.set_objective(None) def _add_variables(self, variables: List[_GeneralVarData]): cmodel.process_pyomo_vars(self._expr_types, variables, self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map, self._vars, self._solver_var_to_pyomo_var_map, True, self._symbol_map, self._var_labeler, False) def _add_params(self, params: List[_ParamData]): cparams = cmodel.create_params(len(params)) for ndx, p in enumerate(params): cp = cparams[ndx] cp.name = self._symbol_map.getSymbol(p, self._param_labeler) cp.value = p.value self._pyomo_param_to_solver_param_map[id(p)] = cp def _add_constraints(self, cons: List[_GeneralConstraintData]): cmodel.process_lp_constraints(cons, self) def _add_sos_constraints(self, cons: List[_SOSConstraintData]): if len(cons) != 0: raise NotImplementedError('LP writer does not yet support SOS constraints') def _remove_constraints(self, cons: List[_GeneralConstraintData]): for c in cons: cc = self._pyomo_con_to_solver_con_map.pop(c) self._writer.remove_constraint(cc) self._symbol_map.removeSymbol(c) self._con_labeler.remove_obj(c) del self._solver_con_to_pyomo_con_map[cc] def _remove_sos_constraints(self, cons: List[_SOSConstraintData]): if len(cons) != 0: raise NotImplementedError('LP writer does not yet support SOS constraints') def _remove_variables(self, variables: List[_GeneralVarData]): for v in variables: cvar = self._pyomo_var_to_solver_var_map.pop(id(v)) del self._solver_var_to_pyomo_var_map[cvar] self._symbol_map.removeSymbol(v) self._var_labeler.remove_obj(v) def _remove_params(self, params: List[_ParamData]): for p in params: del self._pyomo_param_to_solver_param_map[id(p)] self._symbol_map.removeSymbol(p) self._param_labeler.remove_obj(p) def _update_variables(self, variables: List[_GeneralVarData]): cmodel.process_pyomo_vars(self._expr_types, variables, self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map, self._vars, self._solver_var_to_pyomo_var_map, False, None, None, True) def update_params(self): for p_id, p in self._params.items(): cp = self._pyomo_param_to_solver_param_map[p_id] cp.value = p.value def _set_objective(self, obj: _GeneralObjectiveData): cobj = cmodel.process_lp_objective(self._expr_types, obj, self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map) if obj is None: sense = 0 cname = 'objective' else: cname = self._symbol_map.getSymbol(obj, self._obj_labeler) if obj.sense is minimize: sense = 0 else: sense = 1 cobj.sense = sense cobj.name = cname self._writer.objective = cobj def write(self, model: _BlockData, filename: str, timer: HierarchicalTimer = None): if timer is None: timer = HierarchicalTimer() if model is not self._model: timer.start('set_instance') self.set_instance(model) timer.stop('set_instance') else: timer.start('update') self.update(timer=timer) timer.stop('update') timer.start('write file') self._writer.write(filename) timer.stop('write file') def get_vars(self): return [self._solver_var_to_pyomo_var_map[i] for i in self._writer.get_solve_vars()] def get_ordered_cons(self): return [self._solver_con_to_pyomo_con_map[i] for i in self._writer.get_solve_cons()] def get_active_objective(self): return self._objective @property def symbol_map(self): return self._symbol_map