Goals
Goals are described in the class rtctools.optimization.goal_programming_mixin.Goal
.
- class rtctools.optimization.goal_programming_mixin.Goal[source]
Bases:
object
Base class for lexicographic goal programming goals.
Types of goals
There are 2 types of goals: minimization goals and target goals.
Minimization goals
Minimization goals are of the form:
\[\text{minimize } f(x).\]Target goals
Target goals weakly enforce a constraint of the form
\[m_{target} \leq g(x) \leq M_{target},\]by turning it into a minimization problem of the form
\[\begin{split}\text{minimize } & \epsilon^r, \\ \text{subject to } &g_{low}(\epsilon) \leq g(x) \leq g_{up}(\epsilon), \\ \text{and } &0 \leq \epsilon \leq 1,\end{split}\]where
\[\begin{split}g_{low}(\epsilon) &:= (1-\epsilon) m_{target} + \epsilon m, \\ g_{up}(\epsilon) &:= (1-\epsilon) M_{target} + \epsilon M.\end{split}\]Here, \(m\) and \(M\) are hard constraints for \(g(x)\), \(m_{target}\) and \(M_{target}\) are target bounds for \(g(x)\), \(\epsilon\) is an auxiliary variable that indicates how strongly the target bounds are violated, and \(\epsilon^r\) is a function that indicates the variation of \(\epsilon\), where the order \(r\) is by default \(2\). We have
\[m < m_{target} \leq M_{target} < M.\]Note that when \(\epsilon=0\), the constraint on \(g(x)\) becomes
\[m_{target} \leq g(x) \leq M_{target}\]and if \(\epsilon=1\), it becomes
\[m \leq g(x) \leq M.\]Scaling goals
Goals can be scaled by a nominal value \(c_{nom}\) to improve the performance of the solvers. In case of a minimization goal, the scaled problem is given by
\[\text{minimize } \hat{f}(x),\]where \(\hat{f}(x) := f(x) / c_{nom}\). In case of a target goal, the scaled problem is given by
\[\begin{split}\text{minimize } & \epsilon^r, \\ \text{subject to } &\hat{g}_{low}(\epsilon) \leq \hat{g}(x) \leq \hat{g}_{up}(\epsilon), \\ \text{and } &0 \leq \epsilon \leq 1,\end{split}\]where \(\hat{g}(x) := g(x) / c_{nom}\), \(\hat{g}_{low}(\epsilon) := {g}_{low}(\epsilon) / c_{nom}\), and \(\hat{g}_{up}(\epsilon) := {g}_{up}(\epsilon) / c_{nom}\).
Implementing goals
A goal class is created by inheriting from the :py:class:Goal class and overriding the
function()
method. This method defines the goal function \(f(x)\) in case of a minimization goal, and the goal function \(g(x)\) in case of a target goal. A goal becomes a target goal if either the class attributetarget_min
ortarget_max
is set.To further define a goal, the following class attributes can also be set.
- Variables:
function_range – Range of goal function \([m ,M]\). Only applies to target goals. Required for a target goal.
function_nominal – Nominal value of a function \(c_{nom}\). Used for scaling. Default is
1
.target_min – Desired lower bound for goal function \(m_{target}\). Default is
numpy.nan
.target_max – Desired upper bound for goal function \(M_{target}\). Default is
numpy.nan
.priority – Priority of a goal. Default is
1
.weight – Optional weighting applied to the goal. Default is
1.0
.order – Penalization order of goal violation \(r\). Default is
2
.critical – If
True
, the algorithm will abort if this goal cannot be fully met. Default isFalse
.relaxation – Amount of slack added to the hard constraints related to the goal. Must be a nonnegative value. The unit is equal to that of the goal function. Default is
0.0
.
When
target_min
is set, but nottarget_max
, the target goal becomes a lower bound target goal and the constraint on \(g(x)\) becomes\[g_{low}(\epsilon) \leq g(x).\]Similary, if
target_max
is set, but nottarget_min
, the target goal becomes a upper bound target goal and the constraint on \(g(x)\) becomes\[g(x) \leq g_{up}(\epsilon).\]Relaxation is used to loosen the constraints that are set after the optimization of the goal’s priority.
- Notes:
If one is unsure about the function range, it is recommended to overestimate this interval. However, this will negatively influence how accurately the target bounds are met.
The function range should be strictly larger than the target range. In particular, \(m < m_{target}\) and \(M_{target} < M\).
In a path goal, the target can be a Timeseries.
In case of multiple goals with the same priority, it is crucial that an accurate function nominal value is provided. This ensures that all goals are given similar importance.
- A goal can be written in vector form. In a vector goal:
The goal size determines how many goals there are.
The goal function has shape
(goal size, 1)
.The function is either minimized or has, possibly various, targets.
Function nominal can either be an array with as many entries as the goal size or have a single value.
Function ranges can either be an array with as many entries as the goal size or have a single value.
In a goal, the target can either be an array with as many entries as the goal size or have a single value.
In a path goal, the target can also be a Timeseries whose values are either a 1-dimensional vector or have as many columns as the goal size.
Examples
Example definition of the point goal \(x(t) \geq 1.1\) for \(t=1.0\) at priority 1:
class MyGoal(Goal): def function(self, optimization_problem, ensemble_member): # State 'x' at time t = 1.0 t = 1.0 return optimization_problem.state_at('x', t, ensemble_member) function_range = (1.0, 2.0) target_min = 1.1 priority = 1
Example definition of the path goal \(x(t) \geq 1.1\) for all \(t\) at priority 2:
class MyPathGoal(Goal): def function(self, optimization_problem, ensemble_member): # State 'x' at any point in time return optimization_problem.state('x') function_range = (1.0, 2.0) target_min = 1.1 priority = 2
Note path goals
Note that for path goals, the ensemble member index is not passed to the call to
OptimizationProblem.state()
. This call returns a time-independent symbol that is also independent of the active ensemble member. Path goals are applied to all times and all ensemble members simultaneously.- critical = False
Critical goals must always be fully satisfied.
- abstract function(optimization_problem: OptimizationProblem, ensemble_member: int) MX [source]
This method returns a CasADi
MX
object describing the goal function.- Returns:
A CasADi
MX
object.
- function_nominal = 1.0
Nominal value of function (used for scaling)
- function_range = (nan, nan)
Range of goal function
- function_value_timeseries_id = None
Timeseries ID for function value data (optional)
- get_function_key(optimization_problem: OptimizationProblem, ensemble_member: int) str [source]
Returns a key string uniquely identifying the goal function. This is used to eliminate linearly dependent constraints from the optimization problem.
- property has_target_bounds: bool
True
if the user goal has min/max bounds.
- property has_target_max: bool
True
if the user goal has max bounds.
- property has_target_min: bool
True
if the user goal has min bounds.
- order = 2
The goal violation value is taken to the order’th power in the objective function.
- priority = 1
Lower priority goals take precedence over higher priority goals.
- relaxation = 0.0
Absolute relaxation applied to the optimized values of this goal
- size = 1
The size of the goal if it’s a vector goal.
- target_max = nan
Desired upper bound for goal function
- target_min = nan
Desired lower bound for goal function
- violation_timeseries_id = None
Timeseries ID for goal violation data (optional)
- weight = 1.0
Goals with the same priority are weighted off against each other in a single objective function.
- class rtctools.optimization.goal_programming_mixin.StateGoal(optimization_problem)[source]
Bases:
Goal
Base class for lexicographic goal programming path goals that act on a single model state.
A state goal is defined by setting at least the
state
class variable.- Variables:
state – State on which the goal acts. Required.
target_min – Desired lower bound for goal function. Default is
numpy.nan
.target_max – Desired upper bound for goal function. Default is
numpy.nan
.priority – Integer priority of goal. Default is
1
.weight – Optional weighting applied to the goal. Default is
1.0
.order – Penalization order of goal violation. Default is
2
.critical – If
True
, the algorithm will abort if this goal cannot be fully met. Default isFalse
.
Example definition of the goal \(x(t) \geq 1.1\) for all \(t\) at priority 2:
class MyStateGoal(StateGoal): state = 'x' target_min = 1.1 priority = 2
Contrary to ordinary
Goal
objects,PathGoal
objects need to be initialized with anOptimizationProblem
instance to allow extraction of state metadata, such as bounds and nominal values. Consequently, state goals must be instantiated as follows:my_state_goal = MyStateGoal(optimization_problem)
Note that
StateGoal
is a helper class. State goals can also be defined usingGoal
as direct base class, by implementing thefunction
method and providing thefunction_range
andfunction_nominal
class variables manually.