def _preprocess_scenario(self, scenario_name, solver): # TODO: Does this import need to be delayed because # it is in a plugins subdirectory from pyomo.solvers.plugins.solvers.persistent_solver import \ PersistentSolver assert scenario_name in self._scenario_instances scenario_objective_active = self._scenario_objectives[ scenario_name].active # because the preprocessor will skip the scenario objective if it is # part of a bundle and not active self._scenario_objectives[scenario_name].activate() def _cleanup(): if not scenario_objective_active: self._scenario_objectives[scenario_name].deactivate() scenario_instance = self._scenario_instances[scenario_name] instance_first_preprocess = self._scenario_first_preprocess[ scenario_name] instance_fixed_variables = self.fixed_variables[scenario_name] instance_freed_variables = self.freed_variables[scenario_name] instance_constraints_updated_list = \ self.constraints_updated_list[scenario_name] instance_constraints_added_list = \ self.constraints_added_list[scenario_name] instance_constraints_removed_list = \ self.constraints_removed_list[scenario_name] instance_objective_updated = self.objective_updated[scenario_name] persistent_solver_in_use = isinstance(solver, PersistentSolver) if (not instance_first_preprocess) and \ (not instance_objective_updated) and \ (not instance_fixed_variables) and \ (not instance_freed_variables) and \ (len(instance_constraints_updated_list) == 0) and \ (len(instance_constraints_added_list) == 0) and \ (len(instance_constraints_removed_list) == 0): if persistent_solver_in_use: assert solver.has_instance() # instances are already preproccessed, nothing # needs to be done if self.get_option("verbose"): print("No preprocessing necessary for scenario %s" % (scenario_name)) _cleanup() return if (not instance_first_preprocess) and \ (instance_fixed_variables or instance_freed_variables): if persistent_solver_in_use: if solver.has_instance(): if self.get_option("verbose"): print( "Compiling fixed status updates in persistent solver " "for scenario %s" % (scenario_name)) # it can be the case that the solver plugin no longer has an # instance compiled, depending on what state the solver plugin # is in relative to the instance. if this is the case, just # don't compile the variable bounds. if solver.has_instance(): variables_to_change = \ instance_fixed_variables + instance_freed_variables for var in variables_to_change: solver.update_var(var) else: if self.get_option("preprocess_fixed_variables"): if self.get_option("verbose"): print("Running full preprocessing for scenario %s " "due to fixing of variables" % (scenario_name)) if solver.problem_format() == ProblemFormat.nl: ampl_expression_preprocessor({}, model=scenario_instance) else: canonical_expression_preprocessor( {}, model=scenario_instance) # We've preprocessed the entire instance, no point in checking # anything else _cleanup() return if (not instance_first_preprocess) and \ instance_objective_updated: if self.get_option("verbose"): print("Preprocessing objective for scenario %s" % (scenario_name)) if persistent_solver_in_use: if solver.has_instance(): obj_count = 0 for obj in scenario_instance.component_data_objects( ctype=Objective, descend_into=True, active=True): obj_count += 1 if obj_count > 1: raise RuntimeError( "Persistent solver interface only " "supports a single active objective.") solver.set_objective(obj) else: # if only the objective changed, there is minimal work to do. if solver.problem_format() == ProblemFormat.nl: ampl_preprocess_block_objectives(scenario_instance) else: canonical_preprocess_block_objectives(scenario_instance) if (not instance_first_preprocess) and \ ((len(instance_constraints_updated_list) > 0) or \ (len(instance_constraints_added_list) > 0) or \ (len(instance_constraints_removed_list) > 0)): if persistent_solver_in_use: if solver.has_instance(): if self.get_option("verbose"): print("Compiling constraint list (size=%s) for " "scenario %s" % (scenario_name)) for con in instance_constraints_updated_list: if (not con.has_lb()) and \ (not con.has_ub()): assert not con.equality continue # non-binding, so skip solver.remove_constraint(con) solver.add_constraint(con) for con in instance_constraints_removed_list: if (not con.has_lb()) and \ (not con.has_ub()): assert not con.equality continue # non-binding, so skip solver.remove_constraint(con) for con in instance_constraints_added_list: if (not con.has_lb()) and \ (not con.has_ub()): assert not con.equality continue # non-binding, so skip solver.add_constraint(con) elif (len(instance_constraints_updated_list) > 0) or \ (len(instance_constraints_added_list) > 0): if self.get_option("verbose"): print("Preprocessing constraint list (size=%s) for " "scenario %s" % (len(instance_constraints_updated_list), scenario_name)) idMap = {} repn_name = None repn_func = None if solver.problem_format() == ProblemFormat.nl: repn_name = "_ampl_repn" repn_func = generate_ampl_repn else: repn_name = "_canonical_repn" repn_func = generate_canonical_repn for list_ in (instance_constraints_updated_list, instance_constraints_added_list): for constraint_data in list_: if isinstance(constraint_data, LinearCanonicalRepn): continue block = constraint_data.parent_block() # Get/Create the ComponentMap for the repn storage if not hasattr(block, repn_name): setattr(block, repn_name, ComponentMap()) getattr(block, repn_name)[constraint_data] = \ repn_func(constraint_data.body, idMap=idMap) if persistent_solver_in_use: if not solver.has_instance(): solver.set_instance( scenario_instance, symbolic_solver_labels=\ self.get_option("symbolic_solver_labels"), output_fixed_variable_bounds=\ not self.get_option("preprocess_fixed_variables")) elif instance_first_preprocess: if self.get_option("verbose"): print("Running initial full preprocessing for scenario %s" % (scenario_name)) if solver.problem_format() == ProblemFormat.nl: ampl_expression_preprocessor({}, model=scenario_instance) else: canonical_expression_preprocessor({}, model=scenario_instance) _cleanup()
def preprocess_scenario_instance( scenario_instance, instance_variables_fixed, instance_variables_freed, instance_user_constraints_modified, instance_ph_constraints_modified, instance_ph_constraints, instance_objective_modified, preprocess_fixed_variables, solver): persistent_solver_in_use = isinstance(solver, PersistentSolver) if (not instance_objective_modified) and \ (not instance_variables_fixed) and \ (not instance_variables_freed) and \ (not instance_ph_constraints_modified) and \ (not instance_user_constraints_modified): # the condition of "nothing modified" should only be triggered # at PH iteration 0. instances are already preprocessed # following construction, and there isn't any augmentation of # the objective function yet. return if instance_objective_modified: # if only the objective changed, there is minimal work to do. if solver.problem_format() == ProblemFormat.nl: ampl_preprocess_block_objectives(scenario_instance) else: canonical_preprocess_block_objectives(scenario_instance) if persistent_solver_in_use and solver.instance_compiled(): solver.compile_objective(scenario_instance) if (instance_variables_fixed or instance_variables_freed) and \ (preprocess_fixed_variables): if solver.problem_format() == ProblemFormat.nl: ampl_expression_preprocessor({}, model=scenario_instance) else: canonical_expression_preprocessor({}, model=scenario_instance) # We've preprocessed the entire instance, no point in checking # anything else return if (instance_variables_fixed or instance_variables_freed) and \ (persistent_solver_in_use): # it can be the case that the solver plugin no longer has an # instance compiled, depending on what state the solver plugin # is in relative to the instance. if this is the case, just # don't compile the variable bounds. if solver.instance_compiled(): variables_to_change = \ instance_variables_fixed + instance_variables_freed solver.compile_variable_bounds(scenario_instance, vars_to_update=variables_to_change) if instance_user_constraints_modified: if solver.problem_format() == ProblemFormat.nl: idMap = {} for block in scenario_instance.block_data_objects( active=True, descend_into=True): ampl_preprocess_block_constraints(block, idMap=idMap) else: idMap = {} for block in scenario_instance.block_data_objects( active=True, descend_into=True): canonical_preprocess_block_constraints(block, idMap=idMap) elif instance_ph_constraints_modified: # only pre-process the piecewise constraints if solver.problem_format() == ProblemFormat.nl: idMap = {} for constraint_name in instance_ph_constraints: ampl_preprocess_constraint(scenario_instance, getattr(scenario_instance, constraint_name), idMap=idMap) else: idMap = {} for constraint_name in instance_ph_constraints: canonical_preprocess_constraint(scenario_instance, getattr( scenario_instance, constraint_name), idMap=idMap)
def preprocess_bundles(self, bundles=None, force_preprocess_bundle_objective=False, force_preprocess_bundle_constraints=False): # TODO: Does this import need to be delayed because # it is in a plugins subdirectory from pyomo.solvers.plugins.solvers.persistent_solver import \ PersistentSolver start_time = time.time() if len(self._bundle_instances) == 0: raise RuntimeError( "Unable to preprocess scenario bundles. Bundling " "does not seem to be activated.") if bundles is None: bundles = self._bundle_instances.keys() if self.get_option("verbose"): print("Preprocessing %s bundles" % len(bundles)) preprocess_bundle_objective = 0b01 preprocess_bundle_constraints = 0b10 for bundle_name in bundles: preprocess_bundle = 0 solver = self._bundle_solvers[bundle_name] persistent_solver_in_use = isinstance(solver, PersistentSolver) bundle_ef_instance = self._bundle_instances[bundle_name] if persistent_solver_in_use and \ (not solver.has_instance()): assert self._bundle_first_preprocess[bundle_name] solver.set_instance(bundle_ef_instance) self._bundle_first_preprocess[bundle_name] = False for scenario_name in self._bundle_scenarios[bundle_name]: self._scenario_solvers[scenario_name].set_instance( self._scenario_instances[scenario_name]) # We've preprocessed the instance, reset the relevant flags self._scenario_first_preprocess[scenario_name] = False self.clear_update_flags(scenario_name) self.clear_fixed_variables(scenario_name) self.clear_freed_variables(scenario_name) else: if persistent_solver_in_use: assert not self._bundle_first_preprocess[bundle_name] for scenario_name in self._bundle_scenarios[bundle_name]: if self.objective_updated[scenario_name]: preprocess_bundle |= preprocess_bundle_objective if ((len(self.fixed_variables[scenario_name]) > 0) or \ (len(self.freed_variables[scenario_name]) > 0)) and \ self.get_option("preprocess_fixed_variables"): preprocess_bundle |= \ preprocess_bundle_objective | \ preprocess_bundle_constraints if self._bundle_first_preprocess[bundle_name]: preprocess_bundle |= \ preprocess_bundle_objective | \ preprocess_bundle_constraints self._bundle_first_preprocess[bundle_name] = False if persistent_solver_in_use: # also preprocess on the scenario solver scenario_solver = self._scenario_solvers[scenario_name] isinstance(scenario_solver, PersistentSolver) self._preprocess_scenario(scenario_name, scenario_solver) self._preprocess_scenario(scenario_name, solver) # We've preprocessed the instance, reset the relevant flags self._scenario_first_preprocess[scenario_name] = False self.clear_update_flags(scenario_name) self.clear_fixed_variables(scenario_name) self.clear_freed_variables(scenario_name) if force_preprocess_bundle_objective: preprocess_bundle |= preprocess_bundle_objective if force_preprocess_bundle_constraints: preprocess_bundle |= preprocess_bundle_constraints if preprocess_bundle: if persistent_solver_in_use: assert solver.has_instance() if preprocess_bundle & preprocess_bundle_objective: obj_count = 0 for obj in bundle_ef_instance.component_data_objects( ctype=Objective, descend_into=False, active=True): obj_count += 1 if obj_count > 1: raise RuntimeError( "Persistent solver interface only " "supports a single active objective.") solver.set_objective(obj) if preprocess_bundle & preprocess_bundle_constraints: # we assume the bundle constraints are just simple # linking constraints (e.g., no SOSConstraints) for con in bundle_ef_instance.component_data_objects( ctype=Constraint, descend_into=False, active=True): solver.remove_constraint(con) solver.add_constraint(con) else: if solver.problem_format == ProblemFormat.nl: idMap = {} if preprocess_bundle & preprocess_bundle_objective: ampl_preprocess_block_objectives( bundle_ef_instance, idMap=idMap) if preprocess_bundle & preprocess_bundle_constraints: ampl_preprocess_block_constraints( bundle_ef_instance, idMap=idMap) else: idMap = {} if preprocess_bundle & preprocess_bundle_objective: canonical_preprocess_block_objectives( bundle_ef_instance, idMap=idMap) if preprocess_bundle & preprocess_bundle_constraints: canonical_preprocess_block_constraints( bundle_ef_instance, idMap=idMap) end_time = time.time() if self.get_option("output_times"): print("Bundle preprocessing time=%.2f seconds" % (end_time - start_time))
def preprocess_bundles(self, bundles=None, force_preprocess_bundle_objective=False, force_preprocess_bundle_constraints=False): start_time = time.time() if len(self._bundle_instances) == 0: raise RuntimeError( "Unable to preprocess scenario bundles. Bundling " "does not seem to be activated.") if bundles is None: bundles = self._bundle_instances.keys() if self.get_option("verbose"): print("Preprocessing %s bundles" % len(bundles)) preprocess_bundle_objective = 0b01 preprocess_bundle_constraints = 0b10 for bundle_name in bundles: preprocess_bundle = 0 solver = self._bundle_solvers[bundle_name] for scenario_name in self._bundle_scenarios[bundle_name]: if self.objective_updated[scenario_name]: preprocess_bundle |= preprocess_bundle_objective if ((len(self.fixed_variables[scenario_name]) > 0) or \ (len(self.freed_variables[scenario_name]) > 0)) and \ self.get_option("preprocess_fixed_variables"): preprocess_bundle |= \ preprocess_bundle_objective | \ preprocess_bundle_constraints if self._bundle_first_preprocess[bundle_name]: preprocess_bundle |= \ preprocess_bundle_objective | \ preprocess_bundle_constraints self._bundle_first_preprocess[bundle_name] = False self._preprocess_scenario(scenario_name, solver) # We've preprocessed the instance, reset the relevant flags self.clear_update_flags(scenario_name) self.clear_fixed_variables(scenario_name) self.clear_freed_variables(scenario_name) if force_preprocess_bundle_objective: preprocess_bundle |= preprocess_bundle_objective if force_preprocess_bundle_constraints: preprocess_bundle |= preprocess_bundle_constraints if preprocess_bundle: bundle_ef_instance = \ self._bundle_instances[bundle_name] if solver.problem_format == ProblemFormat.nl: idMap = {} if preprocess_bundle & preprocess_bundle_objective: ampl_preprocess_block_objectives(bundle_ef_instance, idMap=idMap) if preprocess_bundle & preprocess_bundle_constraints: ampl_preprocess_block_constraints(bundle_ef_instance, idMap=idMap) else: idMap = {} if preprocess_bundle & preprocess_bundle_objective: canonical_preprocess_block_objectives( bundle_ef_instance, idMap=idMap) if preprocess_bundle & preprocess_bundle_constraints: canonical_preprocess_block_constraints( bundle_ef_instance, idMap=idMap) end_time = time.time() if self.get_option("output_times"): print("Bundle preprocessing time=%.2f seconds" % (end_time - start_time))
def preprocess_scenario_instance(scenario_instance, instance_variables_fixed, instance_variables_freed, instance_user_constraints_modified, instance_ph_constraints_modified, instance_ph_constraints, instance_objective_modified, preprocess_fixed_variables, solver): persistent_solver_in_use = isinstance(solver, PersistentSolver) if (not instance_objective_modified) and \ (not instance_variables_fixed) and \ (not instance_variables_freed) and \ (not instance_ph_constraints_modified) and \ (not instance_user_constraints_modified): # the condition of "nothing modified" should only be triggered # at PH iteration 0. instances are already preprocessed # following construction, and there isn't any augmentation of # the objective function yet. return if instance_objective_modified: # if only the objective changed, there is minimal work to do. if solver.problem_format() == ProblemFormat.nl: ampl_preprocess_block_objectives(scenario_instance) else: canonical_preprocess_block_objectives(scenario_instance) if persistent_solver_in_use and solver.instance_compiled(): solver.compile_objective(scenario_instance) if (instance_variables_fixed or instance_variables_freed) and \ (preprocess_fixed_variables): if solver.problem_format() == ProblemFormat.nl: ampl_expression_preprocessor({}, model=scenario_instance) else: canonical_expression_preprocessor({}, model=scenario_instance) # We've preprocessed the entire instance, no point in checking # anything else return if (instance_variables_fixed or instance_variables_freed) and \ (persistent_solver_in_use): # it can be the case that the solver plugin no longer has an # instance compiled, depending on what state the solver plugin # is in relative to the instance. if this is the case, just # don't compile the variable bounds. if solver.instance_compiled(): variables_to_change = \ instance_variables_fixed + instance_variables_freed solver.compile_variable_bounds(scenario_instance, vars_to_update=variables_to_change) if instance_user_constraints_modified: if solver.problem_format() == ProblemFormat.nl: idMap = {} for block in scenario_instance.block_data_objects(active=True, descend_into=True): ampl_preprocess_block_constraints(block, idMap=idMap) else: idMap = {} for block in scenario_instance.block_data_objects(active=True, descend_into=True): canonical_preprocess_block_constraints(block, idMap=idMap) elif instance_ph_constraints_modified: # only pre-process the piecewise constraints if solver.problem_format() == ProblemFormat.nl: idMap = {} for constraint_name in instance_ph_constraints: ampl_preprocess_constraint( scenario_instance, getattr(scenario_instance, constraint_name), idMap=idMap) else: idMap = {} for constraint_name in instance_ph_constraints: canonical_preprocess_constraint( scenario_instance, getattr(scenario_instance, constraint_name), idMap=idMap)
def preprocess_scenario_instance( scenario_instance, instance_variables_fixed, instance_variables_freed, instance_user_constraints_modified, instance_ph_constraints_modified, instance_ph_constraints, instance_objective_modified, preprocess_fixed_variables, solver): # TODO: Does this import need to be delayed because # it is in a plugins subdirectory from pyomo.solvers.plugins.solvers.persistent_solver import \ PersistentSolver persistent_solver_in_use = isinstance(solver, PersistentSolver) if (not instance_objective_modified) and \ (not instance_variables_fixed) and \ (not instance_variables_freed) and \ (not instance_ph_constraints_modified) and \ (not instance_user_constraints_modified): # the condition of "nothing modified" should only be triggered # at PH iteration 0. instances are already preprocessed # following construction, and there isn't any augmentation of # the objective function yet. return if instance_objective_modified: # if only the objective changed, there is minimal work to do. if solver.problem_format() == ProblemFormat.nl: ampl_preprocess_block_objectives(scenario_instance) else: canonical_preprocess_block_objectives(scenario_instance) if persistent_solver_in_use and solver.has_instance(): obj_count = 0 for obj in scenario_instance.component_data_objects( ctype=Objective, descend_into=True, active=True): obj_count += 1 if obj_count > 1: raise RuntimeError( 'Persistent solver interface only supports a single objective.' ) solver.set_objective(obj) if (instance_variables_fixed or instance_variables_freed) and \ (preprocess_fixed_variables): if solver.problem_format() == ProblemFormat.nl: ampl_expression_preprocessor({}, model=scenario_instance) else: canonical_expression_preprocessor({}, model=scenario_instance) # We've preprocessed the entire instance, no point in checking # anything else return if (instance_variables_fixed or instance_variables_freed) and \ (persistent_solver_in_use): # it can be the case that the solver plugin no longer has an # instance compiled, depending on what state the solver plugin # is in relative to the instance. if this is the case, just # don't compile the variable bounds. if solver.has_instance(): variables_to_change = \ instance_variables_fixed + instance_variables_freed for var_name, var_index in variables_to_change: solver.update_var( scenario_instance.find_component(var_name)[var_index]) if instance_user_constraints_modified: if solver.problem_format() == ProblemFormat.nl: idMap = {} for block in scenario_instance.block_data_objects( active=True, descend_into=True): ampl_preprocess_block_constraints(block, idMap=idMap) else: idMap = {} for block in scenario_instance.block_data_objects( active=True, descend_into=True): canonical_preprocess_block_constraints(block, idMap=idMap) elif instance_ph_constraints_modified: # only pre-process the piecewise constraints if solver.problem_format() == ProblemFormat.nl: idMap = {} for constraint_name in instance_ph_constraints: ampl_preprocess_constraint(scenario_instance, getattr(scenario_instance, constraint_name), idMap=idMap) else: idMap = {} for constraint_name in instance_ph_constraints: canonical_preprocess_constraint(scenario_instance, getattr( scenario_instance, constraint_name), idMap=idMap)
def solve_separation_problem(solver, model, fallback): xfrm = TransformationFactory('core.relax_discrete') if PYOMO_4_0: xfrm.apply(model, inplace=True) else: xfrm.apply_to(model) _block = model._interscenario_plugin # Switch objectives _block.original_obj().deactivate() _block.separation_obj.activate() #_block.separation_variables.unfix() _par = _block.fixed_variable_values _sep = _block.separation_variables allow_slack = _block.allow_slack if allow_slack: epsilon = _block.epsilon for idx in _sep: _sep[idx].setlb(None) _sep[idx].setub(None) else: _sep.unfix() # Note: preprocessing is only necessary if we are changing a # fixed/freed variable. if FALLBACK_ON_BRUTE_FORCE_PREPROCESS: model.preprocess() else: if solver.problem_format() == ProblemFormat.nl: ampl_preprocess_block_objectives(_block) ampl_preprocess_block_constraints(_block) else: _map = {} canonical_preprocess_block_objectives(_block,_map) canonical_preprocess_block_constraints(_block,_map) #SOLVE output_buffer = StringIO() pyutilib.misc.setup_redirect(output_buffer) try: results = solver.solve(model, tee=True) except: logger.warning("Exception raised solving the interscenario " "evaluation subproblem") logger.warning("Solver log:\n%s" % output_buffer.getvalue()) raise finally: pyutilib.misc.reset_redirect() ss = results.solver.status tc = results.solver.termination_condition #self.timeInSolver += results['Solver'][0]['Time'] if ss == SolverStatus.ok and tc in _acceptable_termination_conditions: state = '' if PYOMO_4_0: model.load(results) else: model.solutions.load_from(results) elif tc in _infeasible_termination_conditions: state = 'INFEASIBLE' ans = "!!!!" else: state = 'NONOPTIMAL' ans = "????" if state: if fallback: #logger.warning("Initial attempt to solve the interscenario cut " # "separation subproblem failed with the default " # "solver (%s)." % (state,) ) pass else: logger.warning("Solving the interscenario cut separation " "subproblem failed (%s)." % (state,) ) logger.warning("Solver log:\n%s" % output_buffer.getvalue()) else: cut = dict((vid, (value(_sep[vid]), value(_par[vid]))) for vid in _block.STAGE1VAR) obj = value(_block.separation_obj) ans = (math.sqrt(obj), cut) output_buffer.close() # Restore the objective _block.original_obj().activate() _block.separation_obj.deactivate() # Turn off the separation variables if allow_slack: for idx in _sep: _sep[idx].setlb(-epsilon) _sep[idx].setub(epsilon) else: _sep.fix(0) if PYOMO_4_0: xfrm.apply(model, inplace=True, undo=True) else: xfrm.apply_to(model, undo=True) if FALLBACK_ON_BRUTE_FORCE_PREPROCESS: pass else: if solver.problem_format() == ProblemFormat.nl: ampl_preprocess_block_objectives(_block) else: _map = {} canonical_preprocess_block_objectives(_block,_map) return ans
def _preprocess_scenario(self, scenario_name, solver): assert scenario_name in self._scenario_instance scenario_objective_active = self._scenario_objective[ scenario_name].active # because the preprocessor will skip the scenario objective if it is # part of a bundle and not active self._scenario_objective[scenario_name].activate() def _cleanup(): if not scenario_objective_active: self._scenario_objective[scenario_name].deactivate() scenario_instance = self._scenario_instance[scenario_name] instance_fixed_variables = self.fixed_variables[scenario_name] instance_freed_variables = self.freed_variables[scenario_name] instance_all_constraints_updated = \ self.all_constraints_updated[scenario_name] instance_constraints_updated_list = \ self.constraints_updated_list[scenario_name] instance_objective_updated = self.objective_updated[scenario_name] persistent_solver_in_use = isinstance(solver, PersistentSolver) if (not instance_objective_updated) and \ (not instance_fixed_variables) and \ (not instance_freed_variables) and \ (not instance_all_constraints_updated) and \ (len(instance_constraints_updated_list) == 0): # instances are already preproccessed, nothing # needs to be done if self._options.verbose: print("No preprocessing necessary for scenario %s" % (scenario_name)) _cleanup() return if (instance_fixed_variables or instance_freed_variables) and \ (self._options.preprocess_fixed_variables): if self._options.verbose: print("Running full preprocessing for scenario %s" % (scenario_name)) if solver.problem_format() == ProblemFormat.nl: ampl_expression_preprocessor({}, model=scenario_instance) else: canonical_expression_preprocessor({}, model=scenario_instance) # We've preprocessed the entire instance, no point in checking # anything else _cleanup() return if instance_objective_updated: if self._options.verbose: print("Preprocessing objective for scenario %s" % (scenario_name)) # if only the objective changed, there is minimal work to do. if solver.problem_format() == ProblemFormat.nl: ampl_preprocess_block_objectives(scenario_instance) else: canonical_preprocess_block_objectives(scenario_instance) if persistent_solver_in_use and \ solver.instance_compiled(): solver.compile_objective(scenario_instance) if (instance_fixed_variables or instance_freed_variables) and \ (persistent_solver_in_use): if self._options.verbose: print("Compiling fixed status updates in persistent solver " "for scenario %s" % (scenario_name)) # it can be the case that the solver plugin no longer has an # instance compiled, depending on what state the solver plugin # is in relative to the instance. if this is the case, just # don't compile the variable bounds. if solver.instance_compiled(): variables_to_change = \ instance_fixed_variables + instance_freed_variables solver.compile_variable_bounds( scenario_instance, vars_to_update=variables_to_change) if instance_all_constraints_updated: if self._options.verbose: print("Preprocessing all constraints for scenario %s" % (scenario_name)) if solver.problem_format() == ProblemFormat.nl: idMap = {} for block in scenario_instance.block_data_objects( active=True, descend_into=True): ampl_preprocess_block_constraints(block, idMap=idMap) else: idMap = {} for block in scenario_instance.block_data_objects( active=True, descend_into=True): canonical_preprocess_block_constraints(block, idMap=idMap) elif len(instance_constraints_updated_list) > 0: if self._options.verbose: print("Preprocessing constraint list (size=%s) for " "scenario %s" % (len(instance_constraints_updated_list), scenario_name)) idMap = {} repn_name = None repn_func = None if solver.problem_format() == ProblemFormat.nl: repn_name = "_ampl_repn" repn_func = generate_ampl_repn else: repn_name = "_canonical_repn" repn_func = generate_canonical_repn for constraint_data in instance_constraints_updated_list: if isinstance(constraint_data, LinearCanonicalRepn): continue block = constraint_data.parent_block() # Get/Create the ComponentMap for the repn storage if not hasattr(block, repn_name): setattr(block, repn_name, ComponentMap()) getattr(block, repn_name)[constraint_data] = \ repn_func(constraint_data.body, idMap=idMap) _cleanup()
def _preprocess_scenario(self, scenario_name, solver): assert scenario_name in self._scenario_instance scenario_objective_active = self._scenario_objective[scenario_name].active # because the preprocessor will skip the scenario objective if it is # part of a bundle and not active self._scenario_objective[scenario_name].activate() def _cleanup(): if not scenario_objective_active: self._scenario_objective[scenario_name].deactivate() scenario_instance = self._scenario_instance[scenario_name] instance_fixed_variables = self.fixed_variables[scenario_name] instance_freed_variables = self.freed_variables[scenario_name] instance_all_constraints_updated = self.all_constraints_updated[scenario_name] instance_constraints_updated_list = self.constraints_updated_list[scenario_name] instance_objective_updated = self.objective_updated[scenario_name] persistent_solver_in_use = isinstance(solver, PersistentSolver) if ( (not instance_objective_updated) and (not instance_fixed_variables) and (not instance_freed_variables) and (not instance_all_constraints_updated) and (len(instance_constraints_updated_list) == 0) ): if persistent_solver_in_use: assert solver.instance_compiled() # instances are already preproccessed, nothing # needs to be done if self._options.verbose: print("No preprocessing necessary for scenario %s" % (scenario_name)) _cleanup() return if (instance_fixed_variables or instance_freed_variables) and (self._options.preprocess_fixed_variables): if self._options.verbose: print("Running full preprocessing for scenario %s" % (scenario_name)) if solver.problem_format() == ProblemFormat.nl: ampl_expression_preprocessor({}, model=scenario_instance) else: canonical_expression_preprocessor({}, model=scenario_instance) # We've preprocessed the entire instance, no point in checking # anything else _cleanup() return if instance_objective_updated: if self._options.verbose: print("Preprocessing objective for scenario %s" % (scenario_name)) # if only the objective changed, there is minimal work to do. if solver.problem_format() == ProblemFormat.nl: ampl_preprocess_block_objectives(scenario_instance) else: canonical_preprocess_block_objectives(scenario_instance) if persistent_solver_in_use and solver.instance_compiled(): solver.compile_objective(scenario_instance) if (instance_fixed_variables or instance_freed_variables) and (persistent_solver_in_use): if self._options.verbose: print("Compiling fixed status updates in persistent solver " "for scenario %s" % (scenario_name)) # it can be the case that the solver plugin no longer has an # instance compiled, depending on what state the solver plugin # is in relative to the instance. if this is the case, just # don't compile the variable bounds. if solver.instance_compiled(): variables_to_change = instance_fixed_variables + instance_freed_variables solver.compile_variable_bounds(scenario_instance, vars_to_update=variables_to_change) if instance_all_constraints_updated: if self._options.verbose: print("Preprocessing all constraints for scenario %s" % (scenario_name)) if solver.problem_format() == ProblemFormat.nl: idMap = {} for block in scenario_instance.block_data_objects(active=True, descend_into=True): ampl_preprocess_block_constraints(block, idMap=idMap) else: idMap = {} for block in scenario_instance.block_data_objects(active=True, descend_into=True): canonical_preprocess_block_constraints(block, idMap=idMap) elif len(instance_constraints_updated_list) > 0: # TODO assert not persistent_solver_in_use if self._options.verbose: print( "Preprocessing constraint list (size=%s) for " "scenario %s" % (len(instance_constraints_updated_list), scenario_name) ) idMap = {} repn_name = None repn_func = None if solver.problem_format() == ProblemFormat.nl: repn_name = "_ampl_repn" repn_func = generate_ampl_repn else: repn_name = "_canonical_repn" repn_func = generate_canonical_repn for constraint_data in instance_constraints_updated_list: if isinstance(constraint_data, LinearCanonicalRepn): continue block = constraint_data.parent_block() # Get/Create the ComponentMap for the repn storage if not hasattr(block, repn_name): setattr(block, repn_name, ComponentMap()) getattr(block, repn_name)[constraint_data] = repn_func(constraint_data.body, idMap=idMap) if persistent_solver_in_use and (not solver.instance_compiled()): solver.compile_instance( scenario_instance, symbolic_solver_labels=self._options.symbolic_solver_labels, output_fixed_variable_bounds=not self._options.preprocess_fixed_variables, ) _cleanup()
def preprocess_bundles( self, bundles=None, force_preprocess_bundle_objective=False, force_preprocess_bundle_constraints=False ): start_time = time.time() if len(self._bundle_instances) == 0: raise RuntimeError("Unable to preprocess scenario bundles. Bundling " "does not seem to be activated.") if bundles is None: bundles = self._bundle_instances.keys() if self._options.verbose: print("Preprocessing %s bundles" % len(bundles)) preprocess_bundle_objective = 0b01 preprocess_bundle_constraints = 0b10 for bundle_name in bundles: preprocess_bundle = 0 solver = self._bundle_solvers[bundle_name] for scenario_name in self._bundle_scenarios[bundle_name]: if self.objective_updated[scenario_name]: preprocess_bundle |= preprocess_bundle_objective if ( (len(self.fixed_variables[scenario_name]) > 0) or (len(self.freed_variables[scenario_name]) > 0) ) and self._options.preprocess_fixed_variables: preprocess_bundle |= preprocess_bundle_objective | preprocess_bundle_constraints if self._bundle_first_preprocess[bundle_name]: preprocess_bundle |= preprocess_bundle_objective | preprocess_bundle_constraints self._bundle_first_preprocess[bundle_name] = False self._preprocess_scenario(scenario_name, solver) # We've preprocessed the instance, reset the relevant flags self.clear_update_flags(scenario_name) self.clear_fixed_variables(scenario_name) self.clear_freed_variables(scenario_name) if force_preprocess_bundle_objective: preprocess_bundle |= preprocess_bundle_objective if force_preprocess_bundle_constraints: preprocess_bundle |= preprocess_bundle_constraints if preprocess_bundle: bundle_ef_instance = self._bundle_instances[bundle_name] if solver.problem_format == ProblemFormat.nl: idMap = {} if preprocess_bundle & preprocess_bundle_objective: ampl_preprocess_block_objectives(bundle_ef_instance, idMap=idMap) if preprocess_bundle & preprocess_bundle_constraints: ampl_preprocess_block_constraints(bundle_ef_instance, idMap=idMap) else: idMap = {} if preprocess_bundle & preprocess_bundle_objective: canonical_preprocess_block_objectives(bundle_ef_instance, idMap=idMap) if preprocess_bundle & preprocess_bundle_constraints: canonical_preprocess_block_constraints(bundle_ef_instance, idMap=idMap) end_time = time.time() if self._options.output_times: print("Bundle preprocessing time=%.2f seconds" % (end_time - start_time))