Exemplo n.º 1
0
 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))
Exemplo n.º 2
0
    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)