From: Sandgren, E. (1990). Nonlinear integer and discrete programming in mechanical design optimization. Transactions of the ASME, Journal of Mechanical Design, 112(2):223–229, June 1990. ISSN 0738-0666
Global Optimum (according to Lampinen): 2.65856
Note: In the runs below, you should be able to yield the exact global minimum, but in general, because a stochastic optimization method is being used, you will usually get close to, but not exactly to, the global minimum. You may want to play with the control parameters of the optimization.
import numpy as np
from math import pi
import PyCEGO
# Problem originally from Sandgren
allowable_wire_diameters= [
0.009, 0.0095, 0.0104, 0.0118, 0.0128, 0.0132,
0.014, 0.015, 0.0162, 0.0173, 0.018, 0.020,
0.023, 0.025, 0.028, 0.032, 0.035, 0.041,
0.047, 0.054, 0.063, 0.072, 0.080, 0.092,
0.105, 0.120, 0.135, 0.148, 0.162, 0.177,
0.192, 0.207, 0.225, 0.244, 0.263, 0.283,
0.307, 0.331, 0.362, 0.394, 0.4375, 0.500
]
# Constants of the problem
F_max = 1000.0 # [lb] Maximum working load
S = 189000.0 # [psi] Allowable maximum shear stress
l_max = 14.0 # [in] Maximum free length
d_min = 0.2 # [in] Minimum wire diameter
D_max = 3.0 # [in] Maximum outer diameter of the spring
F_p = 300.0 # [lb] Preload compression force
sigma_pm = 6.0 # [in] Maximum deflection under preload
sigma_w = 1.25 # [in] Deflection from preload to full load
G = 11.5e6 # [] Shear modulus of the material
def CEGO_obj(x):
return obj([x[0].as_int(),
x[1].as_double(),
allowable_wire_diameters[x[2].as_int()]])
def obj(x):
# Unpack the inputs
N,D,d = x
# Intermediate terms
C_f = (4*(D/d)-1)/(4*(D/d)-4)+0.615*d/D
K = G*d**4/(8*N*D**3)
sigma_p = F_p/K
l_f = F_max/K + 1.05*(N+2)*d
g = np.zeros((9,))
g[1] = 8*C_f*F_max*D/(pi*d**3) - S
g[2] = l_f - l_max
# g3, g4, and g5 are handled explicitly via bounds; will always be met
g[3] = d_min - d # will always be met
g[4] = D-D_max # will always be met
g[5] = 3.0-D/d # will always be met
g[6] = sigma_p-sigma_pm
g[7] = sigma_p+(F_max-F_p)/K + 1.05*(N+2)*d - l_f
g[8] = sigma_w - (F_max - F_p)/K
s = np.ones_like(g)
s[7] = 1e5
s[8] = 1e5
c = np.array([1 if g_i < 0 else 1+s_i*g_i for s_i,g_i in zip(s,g)])
assert((c >= 1).all())
f = pi**2*D*d**2*(N+2)/4
return f*np.product(c**3)
print('Quasi-optimal Values of the objective function according to the literature')
print('Sandgren:',obj([10, 1.180701, 0.283]), "(typo seems likely in Lampinen)") # Sandgren (see Lampinen)
print('Chen:',obj([9, 1.2287, 0.283])) # Chen and Tsao (see Lampinen)
print('Wu and Chao:',obj([9, 1.227411, 0.283])) # Wu and Chao (see Lampinen)
print('Lampinen:',obj([9, 1.2230410, 0.283])) # Lampinen
Quasi-optimal Values of the objective function according to the literature Sandgren: 221838.49974522655 (typo seems likely in Lampinen) Chen: 2.670860274197602 Wu and Chao: 2.6680583380916043 Lampinen: 2.682999597110495
D = 3
Nwired = len(allowable_wire_diameters)
CEGO_bounds = [PyCEGO.Bound(1, int(l_max/d_min)), # N
PyCEGO.Bound(3*d_min, D_max), # D
PyCEGO.Bound(27, Nwired-1) # d (indices thereof)
]
for ocounter in range(5):
layers = PyCEGO.NumberishLayers(CEGO_obj, D, D*20, 1, 3)
layers.set_bounds(CEGO_bounds)
layers.set_builtin_evolver(PyCEGO.BuiltinEvolvers.differential_evolution)
objs = []
for counter in range(1000):
layers.do_generation()
objective, coeffs = layers.get_best()
if counter % 50 == 0:
print(layers.print_diagnostics())
objs.append(objective)
i: 0 best: 5.00286 c: 12, 1.536645, 36, queue: 0 i: 50 best: 3.02387 c: 18, 0.885894, 34, queue: 0 i: 100 best: 2.66119 c: 9, 1.224252, 35, queue: 0 i: 150 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 200 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 250 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 300 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 350 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 400 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 450 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 500 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 550 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 600 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 650 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 700 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 750 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 800 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 850 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 900 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 950 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 0 best: 8.68977 c: 36, 0.813757, 35, queue: 0 i: 50 best: 2.83485 c: 10, 1.195462, 35, queue: 0 i: 100 best: 2.65856 c: 9, 1.223043, 35, queue: 0 i: 150 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 200 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 250 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 300 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 350 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 400 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 450 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 500 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 550 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 600 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 650 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 700 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 750 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 800 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 850 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 900 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 950 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 0 best: 7.98714 c: 17, 1.555042, 37, queue: 0 i: 50 best: 2.70755 c: 5, 1.663264, 36, queue: 0 i: 100 best: 2.65963 c: 9, 1.223534, 35, queue: 0 i: 150 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 200 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 250 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 300 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 350 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 400 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 450 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 500 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 550 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 600 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 650 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 700 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 750 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 800 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 850 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 900 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 950 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 0 best: 3.34426 c: 4, 2.061832, 37, queue: 0 i: 50 best: 2.82774 c: 10, 1.192467, 35, queue: 0 i: 100 best: 2.65857 c: 9, 1.223044, 35, queue: 0 i: 150 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 200 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 250 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 300 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 350 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 400 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 450 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 500 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 550 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 600 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 650 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 700 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 750 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 800 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 850 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 900 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 950 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 0 best: 6.72479 c: 26, 1.032771, 36, queue: 0 i: 50 best: 2.67581 c: 9, 1.230977, 35, queue: 0 i: 100 best: 2.65858 c: 9, 1.223049, 35, queue: 0 i: 150 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 200 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 250 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 300 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 350 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 400 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 450 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 500 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 550 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 600 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 650 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 700 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 750 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 800 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 850 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 900 best: 2.65856 c: 9, 1.223041, 35, queue: 0 i: 950 best: 2.65856 c: 9, 1.223041, 35, queue: 0