Source code for foxes_opt.objectives.max_n_turbines

from typing import Any

import numpy as np

from foxes_opt.core.farm_objective import FarmObjective
from foxes_opt.core.farm_opt_problem import FarmOptProblem
import foxes.constants as FC


[docs] class MaxNTurbines(FarmObjective): """ Maximizes the number of turrbines. """ def __init__( self, problem: FarmOptProblem, name: str = "max_n_turbines", check_valid: bool = True, **kwargs: Any, ) -> None: """ Parameters ---------- problem The underlying optimization problem name The name of the objective function check_valid Check FC.VALID variable before counting kwargs Additional parameters for `FarmObjective` """ super().__init__(problem, name, **kwargs) self.check_valid = check_valid
[docs] def n_components(self) -> int: """ Returns the number of components of the function. Returns ------- value The number of components. """ return 1
[docs] def maximize(self) -> list[bool]: """ Returns flag for maximization of each component. Returns ------- flags Bool array for component maximization, shape """ return [True]
[docs] def calc_individual( self, vars_int: np.ndarray, vars_float: np.ndarray, problem_results: Any, components: list[int] | None = None, ) -> np.ndarray: """ Calculate values for a single individual of the underlying problem. Parameters ---------- vars_int The integer variable values, shape: (n_vars_int,) vars_float The float variable values, shape: (n_vars_float,) problem_results The results of the variable application to the problem components The selected components or None for all Returns ------- values The component values, shape: (n_sel_components,) """ if FC.VALID in problem_results and self.check_valid: vld = np.sum(problem_results[FC.VALID].to_numpy(), axis=1) if np.min(vld) != np.max(vld): raise ValueError( f"Objective '{self.name}': Number of valid turbines is state dependend, counting impossible" ) return np.array([vld[0]], dtype=np.float64) else: return np.array([self.farm.n_turbines], dtype=np.float64)
[docs] def calc_population( self, vars_int: np.ndarray, vars_float: np.ndarray, problem_results: Any, components: list[int] | None = None, ) -> np.ndarray: """ Calculate values for all individuals of a population. Parameters ---------- vars_int The integer variable values, shape: (n_pop, n_vars_int) vars_float The float variable values, shape: (n_pop, n_vars_float) problem_results The results of the variable application to the problem components The selected components or None for all Returns ------- values The component values, shape: (n_pop, n_sel_components) """ n_pop = problem_results["n_pop"].to_numpy() if self.check_valid: n_states = problem_results["n_org_states"].to_numpy() n_turbines = self.farm.n_turbines vld = ( problem_results[FC.VALID] .to_numpy() .reshape(n_states, n_pop, n_turbines) ) vld = np.swapaxes(vld, 0, 1) vld = np.sum(vld, axis=2) if np.any(np.min(vld, axis=1) != np.max(vld, axis=1)): raise ValueError( f"Objective '{self.name}': Number of valid turbines is state dependend, counting impossible" ) return vld[:, 0, None] else: return np.full((n_pop, 1), self.farm.n_turbines, dtype=vars_float.dtype)