Source code for enoppy.paper_based.pdo_2022

#!/usr/bin/env python
# Created by "Thieu" at 15:00, 29/07/2022 ----------%
#       Email: nguyenthieu2102@gmail.com            %                                                    
#       Github: https://github.com/thieu1995        %                         
# --------------------------------------------------%

# Paper: Prairie Dog Optimization Algorithm (PDO-2022)

import numpy as np
from enoppy.engineer import Engineer
from enoppy.utils.encoder import LabelEncoder


[docs]class WeldedBeamProblem(Engineer): """ x = [x1, x2, x3, x4] WBD is subjected to 4 design constraints: shear, beam blending stress, bar buckling load beam, and deflection variables: h=x1, l=x2, t=x3, b=x4 l: length, h: height, t: thickness, b: weld thickness of the bar https://sci-hub.se/10.1016/s0166-3615(99)00046-9 """ name = "Welded Beam Design Problem" def __init__(self, f_penalty=None): super().__init__() self._n_dims = 4 self._n_objs = 1 self._n_cons = 11 self._bounds = [(0.1, 2.), (0.1, 10.), (0.1, 10.), (0.1, 2.)] self.xichma_max = 30000 self.P = 6000 self.L = 14 self.delta_max = 0.25 self.E = 30 * 10 ** 6 self.theta_max = 13600 self.G = 12 * 10 ** 6 self.check_penalty_func(f_penalty)
[docs] def get_objs(self, x): f1 = x[0] ** 2 * x[1] * 1.10471 + 0.04811 * x[2] * x[3] * (14.0 + x[1]) return np.array([f1])
[docs] def get_cons(self, x): Pc_X = 4.013 * self.E * np.sqrt(x[2] ** 2 * x[3] ** 6 / 36) / self.L ** 2 * (1. - x[2] * np.sqrt(self.E / (4 * self.G)) / (2 * self.L)) J = 2 * (np.sqrt(2) * x[0] * x[1] * (x[1] ** 2 / 4 + (x[0] + x[2] / 2) ** 2)) M = self.P * (self.L + x[1] / 2) R = np.sqrt(x[1] ** 2 / 4 + (x[0] + x[2]) ** 2 / 4) t2 = M * R / J t1 = self.P / (np.sqrt(2) * x[0] * x[1]) t_X = np.sqrt(t1 ** 2 + 2 * t1 * t2 * x[1] / (2 * R) + t2 ** 2) xichma_X = 6 * self.P * self.L / (x[3] * x[2] ** 2) delta_X = 4 * self.P * self.L ** 3 / (self.E * x[2] ** 3 * x[3]) g1 = t_X - self.theta_max g2 = xichma_X - self.xichma_max g3 = x[0] - x[3] g4 = 0.10471 * x[0] ** 2 + 0.04811 * x[2] * x[3] * (14.0 + x[1]) - 5.0 g5 = 0.125 - x[0] g6 = delta_X - self.delta_max g7 = self.P - Pc_X return np.array([g1, g2, g3, g4, g5, g6, g7])
[docs] def evaluate(self, x): self.n_fe += 1 self.check_solution(x) list_objs = self.get_objs(x) list_cons = self.get_cons(x) return self.f_penalty(list_objs, list_cons)
[docs]class PressureVesselProblem(Engineer): """ x = [x1, x2, x3, x4] Variables: the inner radius (R=x3), the thickness of the head (Th=x2), the length of the cylindrical section of the vessel (L=x4), and the thickness of the shell (Ts=x1) https://sci-hub.se/10.1115/1.2912596 """ name = "Pressure Vessel Design Problem" def __init__(self, f_penalty=None): super().__init__() self._n_dims = 4 self._n_objs = 1 self._n_cons = 4 self._bounds = [(0., 99.), (0., 99.), (10., 200.), (10., 200.)] self.check_penalty_func(f_penalty)
[docs] def get_objs(self, x): f1 = 0.6224 * x[2] * x[0] * x[3] + 1.7781 * x[2] ** 2 * x[1] + 3.1611 * x[0] ** 2 * x[3] + 19.8621 * x[2] * x[0] ** 2 return np.array([f1])
[docs] def get_cons(self, x): g1 = -x[0] + 0.0193 * x[2] g2 = -x[2] + 0.00954 * x[2] g3 = -np.pi * x[1] ** 2 * x[3] - 4. / 3 * np.pi * x[2] ** 3 + 750 * 1728 g4 = -240 + x[3] return np.array([g1, g2, g3, g4])
[docs] def evaluate(self, x): self.n_fe += 1 self.check_solution(x) list_objs = self.get_objs(x) list_cons = self.get_cons(x) return self.f_penalty(list_objs, list_cons)
[docs]class CompressionSpringProblem(Engineer): """ x = [x1, x2, x3, x4] CSD aims to minimize the weight of a tension/compression spring given the values of 3 parameters: the wire diameter (d=x1), number of active coils (P=x3), and mean coil diameter (D=x2). https://sci-hub.se/10.1016/s0166-3615(99)00046-9 """ name = "Compression Spring Design Problem" def __init__(self, f_penalty=None): super().__init__() self._n_dims = 3 self._n_objs = 1 self._n_cons = 4 self._bounds = [(0.05, 2.), (0.25, 1.3), (2., 15.)] self.check_penalty_func(f_penalty)
[docs] def get_objs(self, x): f1 = (x[2] + 2)*x[1]*x[0]**2 return np.array([f1])
[docs] def get_cons(self, x): g1 = 1 - x[1] ** 3 * x[2] / (71785 * x[0] ** 4) g2 = (4 * x[1] ** 2 - x[0] * x[1]) / (12566 * (x[2] * x[0] ** 3 - x[0] ** 4)) + 1. / (5108 * x[0] ** 2) - 1 g3 = 1 - 140.45 * x[0] / (x[1] ** 2 * x[2]) g4 = (x[0] + x[1]) / 1.5 - 1 return np.array([g1, g2, g3, g4])
[docs] def evaluate(self, x): self.n_fe += 1 self.check_solution(x) list_objs = self.get_objs(x) list_cons = self.get_cons(x) return self.f_penalty(list_objs, list_cons)
[docs]class SpeedReducerProblem(Engineer): """ Depicts a gearbox that sits between the propeller and engine of an aeroplane [x1, x2, x3, x4, x5, x6, x7] = [b, m, z, l1, l2, d1, d2] """ name = "Speed Reducer Design Problem" def __init__(self, f_penalty=None): super().__init__() self._n_dims = 7 self._n_objs = 1 self._n_cons = 11 self._bounds = [(2.6, 3.6), (0.7, 0.8), (17, 28.99), (7.3, 8.3), (7.3, 8,3), (2.9, 3.9), (5.0, 5.5)] self.check_penalty_func(f_penalty)
[docs] def get_objs(self, x): f1 = 0.7854*x[0]*x[1]**2*(3.3333*x[2]**2 + 14.9334*x[2] - 43.0934) - 1.508*x[0]*(x[5]**2 + x[6]**2) +\ 7.4777*(x[5]**3 + x[6]**3) + 0.7854*(x[3]*x[5]**2 + x[4]*x[6]**2) return np.array([f1])
[docs] def amend_position(self, x, lb=None, ub=None): x[2] = int(x[2]) return x
[docs] def get_cons(self, x): g1 = 27. / (x[0] * x[1] ** 2 * x[2]) - 1 g2 = 397.5 / (x[0] * x[1] ** 2 * x[2] ** 2) - 1 g3 = 1.93 * x[3] ** 2 / (x[1] * x[5] ** 4 * x[2]) - 1 g4 = 1.93 * x[4] ** 2 / (x[1] * x[6] ** 4 * x[2]) - 1 g5 = np.sqrt((745 * x[3] / (x[1] * x[2])) ** 2 + 16 * 10 ** 6) / (110 * x[5] ** 3) - 1 g6 = np.sqrt((745 * x[4] / (x[1] * x[2])) ** 2 + 157.5 * 10 ** 6) / (85 * x[6] ** 3) - 1 g7 = x[1] * x[2] / 40 - 1 g8 = 5 * x[1] / x[0] - 1 g9 = x[0] / (12. * x[1]) - 1 g10 = (1.5 * x[5] + 1.9) / x[3] - 1 g11 = (1.1 * x[6] + 1.9) / x[4] - 1 return np.array([g1, g2, g3, g4, g5, g6, g7, g8, g9, g10, g11])
[docs] def evaluate(self, x): self.n_fe += 1 self.check_solution(x) list_objs = self.get_objs(x) list_cons = self.get_cons(x) return self.f_penalty(list_objs, list_cons)
[docs]class ThreeBarTrussProblem(Engineer): """ Minimize three-bar structure weight subject to supporting a total load P acting vertically downwards [x1, x2] """ name = "Three Bar Truss Design Problem" def __init__(self, f_penalty=None): super().__init__() self._n_dims = 2 self._n_objs = 1 self._n_cons = 3 self._bounds = [(0., 1.0), (0., 1.)] self.L = 100 self.P = 2 self.xichma = 2 self.check_penalty_func(f_penalty)
[docs] def get_objs(self, x): f1 = (2*np.sqrt(2)*x[0] + x[1]) * self.L return np.array([f1])
[docs] def get_cons(self, x): g1 = (np.sqrt(2) * x[0] + x[1]) / (np.sqrt(2) * x[0] ** 2 + 2 * x[0] * x[1]) * self.P - self.xichma g2 = x[1] * self.P / (np.sqrt(x[0] ** 2 + 2 * x[0] * x[1])) - self.xichma g3 = self.P / (np.sqrt(2) * x[1] + x[0]) - self.xichma return np.array([g1, g2, g3])
[docs] def evaluate(self, x): self.n_fe += 1 self.check_solution(x) list_objs = self.get_objs(x) list_cons = self.get_cons(x) return self.f_penalty(list_objs, list_cons)
[docs]class GearTrainProblem(Engineer): """ Unconstrained discrete design optimization problem [x1, x2, x3, x4] = [n_A, n_B, n_C, n_D] """ name = "Gear Train Design Problem" def __init__(self, f_penalty=None): super().__init__() self._n_dims = 4 self._n_objs = 1 self._n_cons = 0 self._bounds = [(12, 60.99), (12, 60.99), (12, 60.99), (12, 60.99)] self.check_penalty_func(f_penalty)
[docs] def get_objs(self, x): f1 = (1. / 6.931 - x[2]*x[1] / (x[0] * x[3]))**2 return np.array([f1])
[docs] def amend_position(self, x, lb=None, ub=None): return np.asarray(x, int)
[docs] def get_cons(self, x): return np.array([])
[docs] def evaluate(self, x): self.n_fe += 1 self.check_solution(x) list_objs = self.get_objs(x) list_cons = self.get_cons(x) return self.f_penalty(list_objs, list_cons)
[docs]class CantileverBeamProblem(Engineer): """ Minimize a cantilever beam's weight. [x1, x2, x3, x4, x5] """ name = "Cantilever Beam Design Problem" def __init__(self, f_penalty=None): super().__init__() self._n_dims = 5 self._n_objs = 1 self._n_cons = 1 self._bounds = [(0.01, 100.),] * 5 self.check_penalty_func(f_penalty)
[docs] def get_objs(self, x): f1 = 0.0624 * np.sum(x) return np.array([f1])
[docs] def get_cons(self, x): g1 = 61./x[0]**3 + 37./x[1]**3 + 19./x[2]**3 + 7./x[3]**3 + 1./x[4]**3 - 1 return np.array([g1, ])
[docs] def evaluate(self, x): self.n_fe += 1 self.check_solution(x) list_objs = self.get_objs(x) list_cons = self.get_cons(x) return self.f_penalty(list_objs, list_cons)
[docs]class IBeamProblem(Engineer): """ Minimizes the vertical deflection of a beam [x1, x2, x3, x4] = [b, h, t_w, t_f] """ name = "I Beam Design Problem" def __init__(self, f_penalty=None): super().__init__() self._n_dims = 4 self._n_objs = 1 self._n_cons = 2 self._bounds = [(10, 50.), (10, 80.), (0.9, 5.), (0.9, 5.)] self.check_penalty_func(f_penalty)
[docs] def get_objs(self, x): f1 = 500. / ( (x[2]*(x[1]-2*x[3])**3)/12 + (x[0]*x[3]**3/6) + 2*x[0]*x[3]*(x[1] - x[3])**2 ) return np.array([f1])
[docs] def get_cons(self, x): g1 = 2 * x[0] * x[2] + x[2] * (x[1] - 2 * x[3]) - 300 g2 = (18 * x[1] * 10 ** 4) / (x[2] * (x[1] - 2 * x[3]) ** 3 + 2 * x[0] * x[2] * (4 * x[3] ** 2 + 3 * x[1] * (x[1] - 2 * x[3]))) + \ 15 * x[0] * 10 ** 3 / ((x[1] - 2 * x[3]) * x[2] ** 2 + 2 * x[2] * x[0] ** 3) - 56 return np.array([g1, g2])
[docs] def evaluate(self, x): self.n_fe += 1 self.check_solution(x) list_objs = self.get_objs(x) list_cons = self.get_cons(x) return self.f_penalty(list_objs, list_cons)
[docs]class TubularColumnProblem(Engineer): """ [x1, x2] = [d, t] https://apmonitor.com/me575/index.php/Main/TubularColumn """ name = "Tubular Column Design Problem" def __init__(self, f_penalty=None): super().__init__() self._n_dims = 2 self._n_objs = 1 self._n_cons = 6 self._bounds = [(2., 14.), (0.2, 0.8)] self.xichma_y = 450 self.E = 0.65 * 10 ** 6 self.P = 2300 self.pro = 0.002 self.L = 300 self.check_penalty_func(f_penalty)
[docs] def get_objs(self, x): f1 = 9.8*x[0]*x[1] + 2*x[0] return np.array([f1])
[docs] def get_cons(self, x): g1 = self.P / (np.pi * x[0] * x[1] * self.xichma_y) - 1 g2 = (8 * self.P * self.L ** 2) / (np.pi ** 3 * self.E * x[0] * x[1] * (x[0] ** 2 + x[1] ** 2)) - 1 g3 = 2. / x[0] - 1 g4 = x[0] / 14 - 1 g5 = 0.2 / x[1] - 1 g6 = x[1] / 8 - 1 return np.array([g1, g2, g3, g4, g5, g6])
[docs] def evaluate(self, x): self.n_fe += 1 self.check_solution(x) list_objs = self.get_objs(x) list_cons = self.get_cons(x) return self.f_penalty(list_objs, list_cons)
[docs]class PistonLeverProblem(Engineer): """ [x1, x2, x3, x4] = [H, B, D, X] """ name = "Piston Lever Design Problem" def __init__(self, f_penalty=None): super().__init__() self._n_dims = 4 self._n_objs = 1 self._n_cons = 4 self._bounds = [(0.05, 500), (0.05, 500.), (0.05, 120.), (0.05, 500.)] self.L = 240 self.M_max = 1.8 * 10 ** 6 self.P = 1500 self.Q = 10000 self.theta = np.pi / 4 self.check_penalty_func(f_penalty)
[docs] def get_objs(self, x): L1 = np.sqrt((x[3] - x[1]) ** 2 + x[0] ** 2) L2 = np.sqrt((x[3] * np.sin(self.theta) + x[0]) ** 2 + (x[1] - x[3] * np.cos(self.theta)) ** 2) f1 = 0.25*np.pi*x[2]**2 * (L2 - L1) return np.array([f1])
[docs] def get_cons(self, x): L1 = np.sqrt((x[3] - x[1]) ** 2 + x[0] ** 2) L2 = np.sqrt((x[3] * np.sin(self.theta) + x[0]) ** 2 + (x[1] - x[3] * np.cos(self.theta)) ** 2) R = np.abs(-x[3] * (x[3] * np.sin(self.theta) + x[0]) + x[0] * (x[1] - x[3] * np.cos(self.theta))) / np.sqrt((x[3] - x[1]) ** 2 + x[0] ** 2) F = np.pi * self.P * x[2] ** 2 / 4 g1 = self.Q * self.L * np.cos(self.theta) - R * F g2 = self.Q * (self.L - x[3]) - self.M_max g3 = 1.2 * (L2 - L1) - L1 g4 = x[2] / 2 - x[1] return np.array([g1, g2, g3, g4])
[docs] def evaluate(self, x): self.n_fe += 1 self.check_solution(x) list_objs = self.get_objs(x) list_cons = self.get_cons(x) return self.f_penalty(list_objs, list_cons)
[docs]class CorrugatedBulkheadProblem(Engineer): """ [x1, x2, x3, x4] = [width, depth, length, thickness] """ name = "Corrugated Bulkhead Design Problem" def __init__(self, f_penalty=None): super().__init__() self._n_dims = 4 self._n_objs = 1 self._n_cons = 6 self._bounds = [(0., 100), (0., 100.), (0., 100.), (0., 5.)] self.check_penalty_func(f_penalty)
[docs] def get_objs(self, x): f1 = 5.885*x[3]*(x[0] + x[2]) / (x[0] + np.sqrt(np.abs(x[2]**2 - x[1]**2))) return np.array([f1])
[docs] def get_cons(self, x): g1 = -x[3] * x[2] * (0.4 * x[0] + x[2] / 6) + 8.94 * (x[0] + np.sqrt(np.abs(x[2] ** 2 - x[1] ** 2))) g2 = -x[3] * x[1] ** 2 * (0.2 * x[0] + x[2] / 12) + 2.2 * (8.94 * (x[0] + np.sqrt(np.abs(x[2] ** 2 - x[1] ** 2)))) ** (4. / 3) g3 = -x[3] + 0.0156 * x[0] + 0.15 g4 = -x[3] + 0.0156 * x[2] + 0.15 g5 = -x[3] + 1.05 g6 = -x[2] + x[1] return np.array([g1, g2, g3, g4, g5, g6])
[docs] def evaluate(self, x): self.n_fe += 1 self.check_solution(x) list_objs = self.get_objs(x) list_cons = self.get_cons(x) return self.f_penalty(list_objs, list_cons)
[docs]class ReinforcedConcreateBeamProblem(Engineer): """ [x1, x2, x3] """ name = "Reinforced Concreate Beam Design Problem" def __init__(self, f_penalty=None): super().__init__() self._n_dims = 3 self._n_objs = 1 self._n_cons = 2 self.x0 = [6.0, 6.16, 6.32, 6.6, 7.0, 7.11, 7.2, 7.8, 7.9, 8.0, 8.4] self.le = LabelEncoder() self.le.fit(self.x0) self._bounds = [(0., 10.99), (28., 40.99), (5., 10.)] self.check_penalty_func(f_penalty)
[docs] def amend_position(self, x, lb=None, ub=None): x[0] = self.le.inverse_transform([int(x[0])]) x[1] = int(x[1]) return x
[docs] def get_objs(self, x): f1 = 2.9*x[0] + 0.6*x[1]*x[2] return np.array([f1])
[docs] def get_cons(self, x): g1 = x[1] / x[2] - 4 g2 = 180 + 7.375 * x[0] ** 2 / x[2] - x[0] * x[1] return np.array([g1, g2])
[docs] def evaluate(self, x): self.n_fe += 1 self.check_solution(x) if type(x[0]) != int: x = self.amend_position(x, self.lb, self.ub) list_objs = self.get_objs(x) list_cons = self.get_cons(x) return self.f_penalty(list_objs, list_cons)
WBP = WeldedBeamProblem PVP = PressureVesselProblem CSP = CompressionSpringProblem SRD = SpeedReducerProblem TBTD = ThreeBarTrussProblem GTD = GearTrainProblem CBD = CantileverBeamProblem IBD = IBeamProblem TCD = TubularColumnProblem PLD = PistonLeverProblem CBHD = CorrugatedBulkheadProblem RCB = ReinforcedConcreateBeamProblem