def test_should_stop(self): soln = [0] * 149 self.assertFalse(should_stop(soln, 0.5, 0.5, 0.001)) soln += [0.001] self.assertTrue(should_stop(soln, 0.5, 0.5, 0.001)) soln = [0] * 149 + [0.01] self.assertFalse(should_stop(soln, 0.5, 0.5, 0.001)) soln = [0] * 149 + [-0.001] self.assertTrue(should_stop(soln, 0.5, 0.5, 0.001))
def solve(self, model, **kwds): # initialize keyword args config = self.CONFIG(kwds.pop('options', {})) config.set_value(kwds) # initialize the solver solver = SolverFactory(config.solver) # Model sense objectives = model.component_data_objects(Objective, active=True) obj = next(objectives, None) if next(objectives, None) is not None: raise RuntimeError( "Multistart solver is unable to handle model with multiple active objectives." ) if obj is None: raise RuntimeError( "Multistart solver is unable to handle model with no active objective." ) # store objective values and objective/result information for best # solution obtained objectives = [] obj_sign = 1 if obj.sense == minimize else -1 best_objective = float('inf') * obj_sign best_model = model best_result = None try: # create temporary variable list for value transfer tmp_var_list_name = unique_component_name(model, "_vars_list") setattr( model, tmp_var_list_name, list(model.component_data_objects(ctype=Var, descend_into=True))) best_result = result = solver.solve(model, **config.solver_args) if (result.solver.status is SolverStatus.ok and result.solver.termination_condition is tc.optimal): obj_val = value(model.obj.expr) best_objective = obj_val objectives.append(obj_val) num_iter = 0 max_iter = config.iterations # if HCS rule is specified, reinitialize completely randomly until # rule specifies stopping using_HCS = config.iterations == -1 HCS_completed = False if using_HCS: assert config.strategy == "rand", \ "High confidence stopping rule requires rand strategy." max_iter = config.HCS_max_iterations while num_iter < max_iter: if using_HCS and should_stop(objectives, config.stopping_mass, config.stopping_delta, config.HCS_tolerance): HCS_completed = True break num_iter += 1 # at first iteration, solve the originally passed model m = model.clone() if num_iter > 1 else model reinitialize_variables(m, config) result = solver.solve(m, **config.solver_args) if (result.solver.status is SolverStatus.ok and result.solver.termination_condition is tc.optimal): obj_val = value(m.obj.expr) objectives.append(obj_val) if obj_val * obj_sign < obj_sign * best_objective: # objective has improved best_objective = obj_val best_model = m best_result = result if num_iter == 1: # if it's the first iteration, set the best_model and # best_result regardless of solution status in case the # model is infeasible. best_model = m best_result = result if using_HCS and not HCS_completed: logger.warning( "High confidence stopping rule was unable to complete " "after %s iterations. To increase this limit, change the " "HCS_max_iterations flag." % num_iter) # if no better result was found than initial solve, then return # that without needing to copy variables. if best_model is model: return best_result # reassign the given models vars to the new models vars orig_var_list = getattr(model, tmp_var_list_name) best_soln_var_list = getattr(best_model, tmp_var_list_name) for orig_var, new_var in zip(orig_var_list, best_soln_var_list): if not orig_var.is_fixed(): orig_var.value = new_var.value return best_result finally: # Remove temporary variable list delattr(model, tmp_var_list_name)