-
Notifications
You must be signed in to change notification settings - Fork 4
/
test_problems.py
151 lines (133 loc) · 3.82 KB
/
test_problems.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import numpy as np
"""
Test functions from
https://en.wikipedia.org/wiki/Test_functions_for_optimization
Plus two additional: Sminus and Splus
"""
# CONCAVE
class FonzecaFleming:
def __init__ (self,n=2):
self.name = 'FonzecaFleming'
self.n = n
@property
def invn (self):
return 1./np.sqrt(self.n)
@property
def bounds (self):
return np.array([[-4.,4.]]*self.n)
@property
def r (self):
return np.array([[0.,1.],[0.,1.]])
def f1 (self,x):
return self.f(x,1)
def f2 (self,x):
return self.f(x,2)
def f (self,x,i):
xx = (x + (2*i-3)*self.invn)**2
sx = np.sum(xx, axis = None if x.ndim == 1 else 1)
return 1. - np.exp(-sx)
# Derivatives
def df1 (self,x):
return self.df(x,1)
def df2 (self,x):
return self.df(x,2)
def df (self,x,i):
f = 1. - self.f(x,i)
f = f if x.ndim == 1 else f[:,None]
dx = 2.*(x + (2*i-3)*self.invn) * f
return dx if dx.ndim > 1 else dx[None,:]
# DISCONTINUOUS
class Kursawe:
def __init__ (self,n=3):
self.name = 'Kursawe'
self.n = n
@property
def bounds (self):
return np.array([[-5.,5.]]*self.n)
@property
def r (self):
b1 = -10 * (self.n - 1.) - 1e-2
b2 = -10 * (self.n - 1.) * np.exp(-np.sqrt(2)) + 1e-2
b3 = -3.8757617 * self.n - 1e-1
b4 = 8.6168728 * self.n + 1e-1
return np.array([[b1,b2],[b3,b4]])
def f1 (self,x):
m = x.ndim
x = x.copy() if m > 1 else x.copy()[None,:]
xx = -10. * np.exp(-0.2*np.sqrt(x[:,:-1]**2 + x[:,1:]**2))
sx = np.sum( xx, axis = None if m == 1 else 1 )
return sx
def f2 (self,x):
xx = np.abs(x)**0.8 + 5*np.sin(x**3)
return np.sum( xx, axis = None if x.ndim == 1 else 1 )
# Derivatives
def df1 (self,x):
x = x.copy() if x.ndim > 1 else x.copy()[None,:]
sqrt = lambda x1,x2: np.sqrt( x1**2 + x2**2 )
f = lambda x1,x2: 2. * x1/sqrt(x1,x2) * np.exp(-0.2*sqrt(x1,x2))
dx = np.zeros((len(x),self.n))
for i in range(self.n):
if i > 0:
dx[:,i] += f(x[:,i],x[:,i-1])
if i < self.n-1:
dx[:,i] += f(x[:,i],x[:,i+1])
return dx
def df2 (self,x):
dx = 0.8 * np.sign(x) * np.abs(x)**(-0.2)
dx[np.isnan(dx)] = 0.
return dx + 15. * np.cos(x**3) * x**2
# CONVEX
class Schaffer:
def __init__ (self):
self.name = 'Schaffer'
self.n = 1
@property
def bounds (self):
return np.array([[-3.,3.]])
@property
def r (self):
return np.array([[0.,3],[0.,25]])
def f1 (self,x):
return x**2
def f2 (self,x):
return (x-2)**2
# Derivatives
def df1 (self,x):
return 2*x
def df2 (self,x):
return 2*(x-2)
# MIXED
class S:
def __init__ (self,i):
self.i = i # Decides Sminus or Splus
self.n = 2
@property
def bounds (self):
sigma = 2.
return np.array([[0.,10.],[0.,sigma]])
@property
def r (self):
sigma = 2.
return np.array([[0.,10.],[0.,10.+sigma]])
def f1 (self,x):
return x[0] if x.ndim == 1 else x[:,0]
def f2 (self,x):
ns = x[1] if x.ndim == 1 else x[:,1]
f1 = self.f1(x)
return (10. - f1) + (2*self.i-3) * np.sin(f1) + ns
# Derivatives
def df1 (self,x):
return np.array( [[1,0]]*len(x) )
def df2 (self,x):
f1 = self.f1(x)
dx0 = -np.ones(len(x)) + (2*self.i-3)*np.cos(f1)
dx1 = np.ones(len(x))
return np.c_[ dx0, dx1 ]
class Sminus (S):
def __init__ (self):
S.__init__(self,1)
self.name = 'S-'
class Splus (S):
def __init__ (self):
S.__init__(self,2)
self.name = 'S+'