Source code for enoppy.engineer

#!/usr/bin/env python
# Created by "Thieu" at 16:39, 05/05/2023 ----------%                                                                               
#       Email: nguyenthieu2102@gmail.com            %                                                    
#       Github: https://github.com/thieu1995        %                         
# --------------------------------------------------%

import numpy as np
from abc import ABC


[docs]class Engineer(ABC): """ Defines an abstract class for engineering design problems. All subclasses should implement the ``evaluate`` method for a particular problem. Attributes ---------- bounds : list The lower/upper bounds of the problem. This a 2D-matrix of [lower, upper] array that contain the lower and upper bounds. By default, each problem has its own bounds. But user can try to put different bounds to test the problem. n_dims : int The dimensionality of the problem. It is calculated from bounds lb : np.ndarray The lower bounds for the problem ub : np.ndarray The upper bounds for the problem f_global : float The global optimum of the evaluated function. x_global : np.ndarray A list of vectors that provide the locations of the global minimum. Note that some problems have multiple global minima, not all of which may be listed. n_fe : int The number of function evaluations that the object has been asked to calculate. """ name = "Benchmark name" linear = False convex = True differentiable = True parametric = True def __init__(self): self._bounds = None self._n_dims = None self._n_objs = 1 self._n_cons = 0 self._n_ineq_cons = -1 self._n_eq_cons = -1 self.f_penalty = None self.f_global = None self.x_global = None self.n_fe = 0 self.paras = {} self.epsilon = 1e-8 self.w = 1e8
[docs] def get_objs(self, x): """ Compute the values of the objective functions for a given set of input values. """ pass
[docs] def get_cons(self, x): """ Compute the values of the constraint functions for a given set of input values. """ pass
[docs] def get_eq_cons(self, x): """ Compute the values of the equality constraint functions for a given set of input values. """ pass
[docs] def get_ineq_cons(self, x): """ Compute the values of the inequality constraint functions for a given set of input values. """ pass
[docs] def get_paras(self): """ Return the parameters of the problem. Depended on function """ default = {"bounds": self._bounds, "n_dims": self._n_dims, } return {**default, **self.paras}
@property def bounds(self): """ The lower/upper bounds to be used for optimization problem. This a 2D-matrix of [lower, upper] array that contain the lower and upper bounds for the problem. The problem should not be asked for evaluation outside these bounds. ``len(bounds) == n_dims``. """ return self._bounds @property def n_dims(self): """ The dimensionality of the problem. """ return self._n_dims @property def n_objs(self): """ The number of objective functions of the problem. """ return self._n_objs @property def n_cons(self): """ The number of constraint functions of the problem. """ return self._n_cons @property def n_eq_cons(self): """ The number of equality constraint functions of the problem. """ return self._n_eq_cons @property def n_ineq_cons(self): """ The number of inequality constraint functions of the problem. """ return self._n_ineq_cons @property def lb(self): """ The lower bounds for the problem Returns ------- lb : 1D-vector The lower bounds for the problem """ return np.array([x[0] for x in self.bounds]) @property def ub(self): """ The upper bounds for the problem Returns ------- ub : 1D-vector The upper bounds for the problem """ return np.array([x[1] for x in self.bounds])
[docs] def amend_position(self, x, lb=None, ub=None): """ Amend position to fit the format of the problem Parameters ---------- x : np.ndarray The current position (solution) """ return x
[docs] def create_solution(self): """ Create a random solution for the current problem Returns ------- solution: np.ndarray The random solution """ return np.random.uniform(self.lb, self.ub)
[docs] def check_solution(self, x): """ Raise the error if the problem size is not equal to the solution length Parameters ---------- x : np.ndarray The solution """ if len(x) != self._n_dims: raise ValueError(f"The length of solution should has {self._n_dims} variables!")
[docs] def default_penalty(self, list_objs=None, list_cons=None): list_objs_new = np.zeros_like(list_objs) for idx, val in enumerate(list_objs): temp = val + self.w * np.sum([max(0, f_con) for f_con in list_cons]) list_objs_new[idx] = temp return list_objs_new
[docs] def check_penalty_func(self, func=None): if callable(func): self.f_penalty = func else: self.f_penalty = self.default_penalty
[docs] def evaluate(self, x): """ Evaluation of the benchmark function. Parameters ---------- x : np.ndarray, list, tuple The candidate vector for evaluating the benchmark problem. Must have ``len(x) == self.n_dims``. Returns ------- val : float the evaluated benchmark function """ pass