emat/model/core_model.py
def optimize(
            self,
            searchover='levers',
            evaluator=None,
            nfe=10000,
            convergence='default',
            display_convergence=True,
            convergence_freq=100,
            constraints=None,
            reference=None,
            reverse_targets=False,
            algorithm=None,
            epsilons='auto',
            min_epsilon=0.1,
            cache_dir=None,
            cache_file=None,
            check_extremes=False,
            **kwargs,
    ):
        """
        Perform multi-objective optimization over levers or uncertainties.

        The targets for the multi-objective optimization (i.e. whether each
        individual performance measures is to be maximized or minimized) are
        read from the model's scope.

        Args:
            searchover ({'levers', 'uncertainties'}):
                Which group of inputs to search over.  The other group
                will be set at their default values, unless other values
                are provided in the `reference` argument.
            evaluator (Evaluator, optional): The evaluator to use to
                run the model. If not given, a SequentialEvaluator will
                be created.
            nfe (int, default 10_000): Number of function evaluations.
                This generally needs to be fairly large to achieve stable
                results in all but the most trivial applications.
            convergence ('default', None, or emat.optimization.ConvergenceMetrics):
                A convergence display during optimization.  The default
                value is to report the epsilon-progress (the number of
                solutions that ever enter the candidate pool of non-dominated
                solutions) and the number of solutions remaining in that candidate
                pool.  Pass `None` explicitly to disable convergence tracking.
            display_convergence (bool, default True): Whether to automatically
                display figures that dynamically track convergence.  Set to
                `False` if you are not using this method within a Jupyter
                interactive environment.
            convergence_freq (int, default 100): How frequently to update the
                convergence measures.  There is some computational overhead to
                these convergence updates, so setting a value too small may
                noticeably slow down the process.
            constraints (Collection[Constraint], optional):
                Solutions will be constrained to only include values that
                satisfy these constraints. The constraints can be based on
                the search parameters (levers or uncertainties, depending on the
                value given for `searchover`), or performance measures, or
                some combination thereof.
            reference (Mapping): A set of values for the non-active inputs,
                i.e. the uncertainties if `searchover` is 'levers', or the
                levers if `searchover` is 'uncertainties'.  Any values not
                set here revert to the default values identified in the scope.
            reverse_targets (bool, default False): Whether to reverse the
                optimization targets given in the scope (i.e., changing
                minimize to maximize, or vice versa).  This will result in
                the optimization searching for the worst outcomes, instead of
                the best outcomes.
            algorithm (platypus.Algorithm, optional): Select an
                algorithm for multi-objective optimization.  The default
                algorithm is EpsNSGAII. See `platypus` documentation for details.
            epsilons (float or array-like): Used to limit the number of
                distinct solutions generated.  Set to a larger value to get
                fewer distinct solutions.
            cache_dir (path-like, optional): A directory in which to
                cache results.  Most of the arguments will be hashed
                to develop a unique filename for these results, making this
                generally safer than `cache_file`.
            cache_file (path-like, optional): A file into which to
                cache results.  If this file exists, the contents of the
                file will be loaded and all other arguments are ignored.
                Use with great caution.
            kwargs: Any additional arguments will be passed on to the
                platypus algorithm.

        Returns:
            emat.OptimizationResult:
                The set of non-dominated solutions found.
                When `convergence` is given, the convergence measures are
                included, as a pandas.DataFrame in the `convergence` attribute.
        """
        from ..util.disk_cache import load_cache_if_available, save_cache
        if isinstance(algorithm, str) or algorithm is None:
            alg = algorithm
        else:
            alg = algorithm.__name__

        if reference is not None:
            from ema_workbench import Policy, Scenario
            if searchover == 'levers' and not isinstance(reference, Scenario):
                reference = Scenario("ReferenceScenario", **reference)
            elif searchover == 'uncertainties' and not isinstance(reference, Policy):
                reference = Policy("ReferencePolicy", **reference)
        else:
            if searchover == 'levers':
                reference = self.scope.default_scenario()
            elif searchover == 'uncertainties':
                reference = self.scope.default_policy()

        x, cache_file = load_cache_if_available(
            cache_file=cache_file,
            cache_dir=cache_dir,
            searchover=searchover,
            nfe=nfe,
            convergence=convergence,
            convergence_freq=convergence_freq,
            constraints=constraints,
            reference=reference,
            reverse_targets=reverse_targets,
            algorithm=alg,
            epsilons=epsilons,
        )

        if x is None:
            epsilons, convergence, display_convergence, evaluator = self._common_optimization_setup(
                epsilons, convergence, display_convergence, evaluator
            )

            if reverse_targets:
                for k in self.scope.get_measures():
                    k.kind_original = k.kind
                    k.kind = k.kind * -1

            try:
                with evaluator:

                    if epsilons == 'auto':
                        from ema_workbench import perform_experiments
                        if searchover == 'levers':
                            _, trial_outcomes = perform_experiments(
                                self,
                                scenarios=reference,
                                policies=30,
                                evaluator=evaluator,
                            )
                        else:
                            _, trial_outcomes = perform_experiments(
                                self,
                                scenarios=30,
                                policies=reference,
                                evaluator=evaluator,
                            )
                        epsilons = [max(min_epsilon, np.std(trial_outcomes[mn]) / 20) for mn in self.scope.get_measure_names()]

                    results = evaluator.optimize(
                        searchover=searchover,
                        reference=reference,
                        nfe=nfe,
                        constraints=constraints,
                        convergence=convergence,
                        convergence_freq=convergence_freq,
                        epsilons=epsilons,
                        **kwargs,
                    )

                    if isinstance(results, tuple) and len(results) == 2:
                        results, result_convergence = results
                    else:
                        result_convergence = None

                    # Put constants back in to results
                    for i in self.scope.get_constants():
                        results[i.name] = i.value

                    results = self.ensure_dtypes(results)
                    x = OptimizationResult(results, result_convergence, scope=self.scope)

                    if searchover == 'levers':
                        x.scenarios = reference
                    elif searchover == 'uncertainties':
                        x.policies = reference

                    if check_extremes:
                        x.check_extremes(
                            self,
                            1 if check_extremes is True else check_extremes,
                            evaluator=evaluator,
                            searchover=searchover,
                            robust=False,
                        )

            finally:
                if reverse_targets:
                    for k in self.scope.get_measures():
                        k.kind = k.kind_original
                        del k.kind_original


        elif display_convergence:
            _, convergence, display_convergence, _ = self._common_optimization_setup(
                None, convergence, display_convergence, False
            )
            for c in convergence:
                try:
                    c.rebuild(x.convergence)
                except:
                    pass

        x.cache_file = cache_file
        save_cache(x, cache_file)
        return x

        Perform multi-objective optimization over levers or uncertainties.

        The targets for the multi-objective optimization (i.e. whether each
        individual performance measures is to be maximized or minimized) are
        read from the model's scope.

        Args:
            searchover ({'levers', 'uncertainties'}):
                Which group of inputs to search over.  The other group
                will be set at their default values, unless other values
                are provided in the `reference` argument.
            evaluator (Evaluator, optional): The evaluator to use to
                run the model. If not given, a SequentialEvaluator will
                be created.
            nfe (int, default 10_000): Number of function evaluations.
                This generally needs to be fairly large to achieve stable
                results in all but the most trivial applications.
            convergence ('default', None, or emat.optimization.ConvergenceMetrics):
                A convergence display during optimization.  The default
                value is to report the epsilon-progress (the number of
                solutions that ever enter the candidate pool of non-dominated
                solutions) and the number of solutions remaining in that candidate
                pool.  Pass `None` explicitly to disable convergence tracking.
            display_convergence (bool, default True): Whether to automatically
                display figures that dynamically track convergence.  Set to
                `False` if you are not using this method within a Jupyter
                interactive environment.
            convergence_freq (int, default 100): How frequently to update the
                convergence measures.  There is some computational overhead to
                these convergence updates, so setting a value too small may
                noticeably slow down the process.
            constraints (Collection[Constraint], optional):
                Solutions will be constrained to only include values that
                satisfy these constraints. The constraints can be based on
                the search parameters (levers or uncertainties, depending on the
                value given for `searchover`), or performance measures, or
                some combination thereof.
            reference (Mapping): A set of values for the non-active inputs,
                i.e. the uncertainties if `searchover` is 'levers', or the
                levers if `searchover` is 'uncertainties'.  Any values not
                set here revert to the default values identified in the scope.
            reverse_targets (bool, default False): Whether to reverse the
                optimization targets given in the scope (i.e., changing
                minimize to maximize, or vice versa).  This will result in
                the optimization searching for the worst outcomes, instead of
                the best outcomes.
            algorithm (platypus.Algorithm, optional): Select an
                algorithm for multi-objective optimization.  The default
                algorithm is EpsNSGAII. See `platypus` documentation for details.
            epsilons (float or array-like): Used to limit the number of
                distinct solutions generated.  Set to a larger value to get
                fewer distinct solutions.
            cache_dir (path-like, optional): A directory in which to
                cache results.  Most of the arguments will be hashed
                to develop a unique filename for these results, making this
                generally safer than `cache_file`.
            cache_file (path-like, optional): A file into which to
                cache results.  If this file exists, the contents of the
                file will be loaded and all other arguments are ignored.
                Use with great caution.
            kwargs: Any additional arguments will be passed on to the
                platypus algorithm.

        Returns:
            emat.OptimizationResult:
                The set of non-dominated solutions found.
                When `convergence` is given, the convergence measures are
                included, as a pandas.DataFrame in the `convergence` attribute.
        
Perform multi-objective optimization over levers or uncertainties.
The targets for the multi-objective optimization  are
read from the model's scope.
Perform multi - objective optimization over levers or uncertainties . The targets for the multi - objective optimization are read from the model ' s scope .
def optimize(
            self,
            searchover='levers',
            evaluator=None,
            nfe=10000,
            convergence='default',
            display_convergence=True,
            convergence_freq=100,
            constraints=None,
            reference=None,
            reverse_targets=False,
            algorithm=None,
            epsilons='auto',
            min_epsilon=0.1,
            cache_dir=None,
            cache_file=None,
            check_extremes=False,
            **kwargs,
    ):
        from ..util.disk_cache import load_cache_if_available, save_cache
        if isinstance(algorithm, str) or algorithm is None:
            alg = algorithm
        else:
            alg = algorithm.__name__
        if reference is not None:
            from ema_workbench import Policy, Scenario
            if searchover == 'levers' and not isinstance(reference, Scenario):
                reference = Scenario("ReferenceScenario", **reference)
            elif searchover == 'uncertainties' and not isinstance(reference, Policy):
                reference = Policy("ReferencePolicy", **reference)
        else:
            if searchover == 'levers':
                reference = self.scope.default_scenario()
            elif searchover == 'uncertainties':
                reference = self.scope.default_policy()
        x, cache_file = load_cache_if_available(
            cache_file=cache_file,
            cache_dir=cache_dir,
            searchover=searchover,
            nfe=nfe,
            convergence=convergence,
            convergence_freq=convergence_freq,
            constraints=constraints,
            reference=reference,
            reverse_targets=reverse_targets,
            algorithm=alg,
            epsilons=epsilons,
        )
        if x is None:
            epsilons, convergence, display_convergence, evaluator = self._common_optimization_setup(
                epsilons, convergence, display_convergence, evaluator
            )
            if reverse_targets:
                for k in self.scope.get_measures():
                    k.kind_original = k.kind
                    k.kind = k.kind * -1
            try:
                with evaluator:
                    if epsilons == 'auto':
                        from ema_workbench import perform_experiments
                        if searchover == 'levers':
                            _, trial_outcomes = perform_experiments(
                                self,
                                scenarios=reference,
                                policies=30,
                                evaluator=evaluator,
                            )
                        else:
                            _, trial_outcomes = perform_experiments(
                                self,
                                scenarios=30,
                                policies=reference,
                                evaluator=evaluator,
                            )
                        epsilons = [max(min_epsilon, np.std(trial_outcomes[mn]) / 20) for mn in self.scope.get_measure_names()]
                    results = evaluator.optimize(
                        searchover=searchover,
                        reference=reference,
                        nfe=nfe,
                        constraints=constraints,
                        convergence=convergence,
                        convergence_freq=convergence_freq,
                        epsilons=epsilons,
                        **kwargs,
                    )
                    if isinstance(results, tuple) and len(results) == 2:
                        results, result_convergence = results
                    else:
                        result_convergence = None
                    for i in self.scope.get_constants():
                        results[i.name] = i.value
                    results = self.ensure_dtypes(results)
                    x = OptimizationResult(results, result_convergence, scope=self.scope)
                    if searchover == 'levers':
                        x.scenarios = reference
                    elif searchover == 'uncertainties':
                        x.policies = reference
                    if check_extremes:
                        x.check_extremes(
                            self,
                            1 if check_extremes is True else check_extremes,
                            evaluator=evaluator,
                            searchover=searchover,
                            robust=False,
                        )
            finally:
                if reverse_targets:
                    for k in self.scope.get_measures():
                        k.kind = k.kind_original
                        del k.kind_original
        elif display_convergence:
            _, convergence, display_convergence, _ = self._common_optimization_setup(
                None, convergence, display_convergence, False
            )
            for c in convergence:
                try:
                    c.rebuild(x.convergence)
                except:
                    pass
        x.cache_file = cache_file
        save_cache(x, cache_file)
        return x
def optimize ( self , searchover = 'levers' , evaluator = None , nfe = 10000 , convergence = 'default' , display_convergence = True , convergence_freq = 100 , constraints = None , reference = None , reverse_targets = False , algorithm = None , epsilons = 'auto' , min_epsilon = 0.1 , cache_dir = None , cache_file = None , check_extremes = False , ** kwargs , ) : from . . util . disk_cache import load_cache_if_available , save_cache if isinstance ( algorithm , str ) or algorithm is None : alg = algorithm else : alg = algorithm . __name__ if reference is not None : from ema_workbench import Policy , Scenario if searchover == 'levers' and not isinstance ( reference , Scenario ) : reference = Scenario ( "ReferenceScenario" , ** reference ) elif searchover == 'uncertainties' and not isinstance ( reference , Policy ) : reference = Policy ( "ReferencePolicy" , ** reference ) else : if searchover == 'levers' : reference = self . scope . default_scenario ( ) elif searchover == 'uncertainties' : reference = self . scope . default_policy ( ) x , cache_file = load_cache_if_available ( cache_file = cache_file , cache_dir = cache_dir , searchover = searchover , nfe = nfe , convergence = convergence , convergence_freq = convergence_freq , constraints = constraints , reference = reference , reverse_targets = reverse_targets , algorithm = alg , epsilons = epsilons , ) if x is None : epsilons , convergence , display_convergence , evaluator = self . _common_optimization_setup ( epsilons , convergence , display_convergence , evaluator ) if reverse_targets : for k in self . scope . get_measures ( ) : k . kind_original = k . kind k . kind = k . kind * - 1 try : with evaluator : if epsilons == 'auto' : from ema_workbench import perform_experiments if searchover == 'levers' : _ , trial_outcomes = perform_experiments ( self , scenarios = reference , policies = 30 , evaluator = evaluator , ) else : _ , trial_outcomes = perform_experiments ( self , scenarios = 30 , policies = reference , evaluator = evaluator , ) epsilons = [ max ( min_epsilon , np . std ( trial_outcomes [ mn ] ) / 20 ) for mn in self . scope . get_measure_names ( ) ] results = evaluator . optimize ( searchover = searchover , reference = reference , nfe = nfe , constraints = constraints , convergence = convergence , convergence_freq = convergence_freq , epsilons = epsilons , ** kwargs , ) if isinstance ( results , tuple ) and len ( results ) == 2 : results , result_convergence = results else : result_convergence = None for i in self . scope . get_constants ( ) : results [ i . name ] = i . value results = self . ensure_dtypes ( results ) x = OptimizationResult ( results , result_convergence , scope = self . scope ) if searchover == 'levers' : x . scenarios = reference elif searchover == 'uncertainties' : x . policies = reference if check_extremes : x . check_extremes ( self , 1 if check_extremes is True else check_extremes , evaluator = evaluator , searchover = searchover , robust = False , ) finally : if reverse_targets : for k in self . scope . get_measures ( ) : k . kind = k . kind_original del k . kind_original elif display_convergence : _ , convergence , display_convergence , _ = self . _common_optimization_setup ( None , convergence , display_convergence , False ) for c in convergence : try : c . rebuild ( x . convergence ) except : pass x . cache_file = cache_file save_cache ( x , cache_file ) return x
Perform multi-objective optimization over levers or uncertainties.
Perform multi - objective optimization over levers or uncertainties .
"""
        Perform multi-objective optimization over levers or uncertainties.

        The targets for the multi-objective optimization (i.e. whether each
        individual performance measures is to be maximized or minimized) are
        read from the model's scope.

        Args:
            searchover ({'levers', 'uncertainties'}):
                Which group of inputs to search over.  The other group
                will be set at their default values, unless other values
                are provided in the `reference` argument.
            evaluator (Evaluator, optional): The evaluator to use to
                run the model. If not given, a SequentialEvaluator will
                be created.
            nfe (int, default 10_000): Number of function evaluations.
                This generally needs to be fairly large to achieve stable
                results in all but the most trivial applications.
            convergence ('default', None, or emat.optimization.ConvergenceMetrics):
                A convergence display during optimization.  The default
                value is to report the epsilon-progress (the number of
                solutions that ever enter the candidate pool of non-dominated
                solutions) and the number of solutions remaining in that candidate
                pool.  Pass `None` explicitly to disable convergence tracking.
            display_convergence (bool, default True): Whether to automatically
                display figures that dynamically track convergence.  Set to
                `False` if you are not using this method within a Jupyter
                interactive environment.
            convergence_freq (int, default 100): How frequently to update the
                convergence measures.  There is some computational overhead to
                these convergence updates, so setting a value too small may
                noticeably slow down the process.
            constraints (Collection[Constraint], optional):
                Solutions will be constrained to only include values that
                satisfy these constraints. The constraints can be based on
                the search parameters (levers or uncertainties, depending on the
                value given for `searchover`), or performance measures, or
                some combination thereof.
            reference (Mapping): A set of values for the non-active inputs,
                i.e. the uncertainties if `searchover` is 'levers', or the
                levers if `searchover` is 'uncertainties'.  Any values not
                set here revert to the default values identified in the scope.
            reverse_targets (bool, default False): Whether to reverse the
                optimization targets given in the scope (i.e., changing
                minimize to maximize, or vice versa).  This will result in
                the optimization searching for the worst outcomes, instead of
                the best outcomes.
            algorithm (platypus.Algorithm, optional): Select an
                algorithm for multi-objective optimization.  The default
                algorithm is EpsNSGAII. See `platypus` documentation for details.
            epsilons (float or array-like): Used to limit the number of
                distinct solutions generated.  Set to a larger value to get
                fewer distinct solutions.
            cache_dir (path-like, optional): A directory in which to
                cache results.  Most of the arguments will be hashed
                to develop a unique filename for these results, making this
                generally safer than `cache_file`.
            cache_file (path-like, optional): A file into which to
                cache results.  If this file exists, the contents of the
                file will be loaded and all other arguments are ignored.
                Use with great caution.
            kwargs: Any additional arguments will be passed on to the
                platypus algorithm.

        Returns:
            emat.OptimizationResult:
                The set of non-dominated solutions found.
                When `convergence` is given, the convergence measures are
                included, as a pandas.DataFrame in the `convergence` attribute.
        """ # Put constants back in to results
The set of non-dominated solutions found.
When `convergence` is given, the convergence measures are
included, as a pandas.DataFrame in the `convergence` attribute.
The set of non - dominated solutions found . When ` convergence ` is given the convergence measures are included as a pandas . DataFrame in the ` convergence ` attribute .
emat.OptimizationResult
self
searchover
Which group of inputs to search over.  The other group
will be set at their default values, unless other values
are provided in the `reference` argument.
Which group of inputs to search over . The other group will be set at their default values unless other values are provided in the ` reference ` argument .
evaluator
The evaluator to use to
run the model. If not given, a SequentialEvaluator will
be created.
The evaluator to use to run the model . If not given a SequentialEvaluator will be created .
nfe
Number of function evaluations.
This generally needs to be fairly large to achieve stable
results in all but the most trivial applications.
Number of function evaluations . This generally needs to be fairly large to achieve stable results in all but the most trivial applications .
convergence
A convergence display during optimization.  The default
value is to report the epsilon-progress (the number of
solutions that ever enter the candidate pool of non-dominated
solutions) and the number of solutions remaining in that candidate
pool.  Pass `None` explicitly to disable convergence tracking.
A convergence display during optimization . The default value is to report the epsilon - progress ( the number of solutions that ever enter the candidate pool of non - dominated solutions ) and the number of solutions remaining in that candidate pool . Pass ` None ` explicitly to disable convergence tracking .
display_convergence
Whether to automatically
display figures that dynamically track convergence.  Set to
`False` if you are not using this method within a Jupyter
interactive environment.
Whether to automatically display figures that dynamically track convergence . Set to ` False ` if you are not using this method within a Jupyter interactive environment .
convergence_freq
None
constraints
Solutions will be constrained to only include values that
satisfy these constraints. The constraints can be based on
the search parameters (levers or uncertainties, depending on the
value given for `searchover`), or performance measures, or
some combination thereof.
Solutions will be constrained to only include values that satisfy these constraints . The constraints can be based on the search parameters ( levers or uncertainties depending on the value given for ` searchover ` ) or performance measures or some combination thereof .
reference
A set of values for the non-active inputs,
i.e. the uncertainties if `searchover` is 'levers', or the
levers if `searchover` is 'uncertainties'.  Any values not
set here revert to the default values identified in the scope.
A set of values for the non - active inputs i . e . the uncertainties if ` searchover ` is ' levers ' or the levers if ` searchover ` is ' uncertainties ' . Any values not set here revert to the default values identified in the scope .
reverse_targets
Whether to reverse the
optimization targets given in the scope .  This will result in
the optimization searching for the worst outcomes, instead of
the best outcomes.
Whether to reverse the optimization targets given in the scope . This will result in the optimization searching for the worst outcomes instead of the best outcomes .
algorithm
Select an
algorithm for multi-objective optimization.  The default
algorithm is EpsNSGAII. See `platypus` documentation for details.
Select an algorithm for multi - objective optimization . The default algorithm is EpsNSGAII . See ` platypus ` documentation for details .
epsilons
Used to limit the number of
distinct solutions generated.  Set to a larger value to get
fewer distinct solutions.
Used to limit the number of distinct solutions generated . Set to a larger value to get fewer distinct solutions .
min_epsilon
cache_dir
A directory in which to
cache results.  Most of the arguments will be hashed
to develop a unique filename for these results, making this
generally safer than `cache_file`.
A directory in which to cache results . Most of the arguments will be hashed to develop a unique filename for these results making this generally safer than ` cache_file ` .
cache_file
A file into which to
cache results.  If this file exists, the contents of the
file will be loaded and all other arguments are ignored.
Use with great caution.
A file into which to cache results . If this file exists the contents of the file will be loaded and all other arguments are ignored . Use with great caution .
check_extremes
kwargs
Any additional arguments will be passed on to the
platypus algorithm.
Any additional arguments will be passed on to the platypus algorithm .