Skip to content

Commit 068bab7

Browse files
authored
The PAO cometh
add PAO - Particle attractor algorithm
2 parents dc45fa1 + e588f91 commit 068bab7

File tree

13 files changed

+459
-183
lines changed

13 files changed

+459
-183
lines changed

.github/workflows/pytest-benchmarking.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
runs-on: ubuntu-latest
1111
strategy:
1212
matrix:
13-
python-version: [3.9]
13+
python-version: [3.11]
1414

1515
steps:
1616
- uses: actions/checkout@v2

.github/workflows/pytest-testing.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
runs-on: ubuntu-latest
1616
strategy:
1717
matrix:
18-
python-version: [3.5, 3.6, 3.7, 3.8, 3.9]
18+
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
1919

2020
steps:
2121
- uses: actions/checkout@v2

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,6 @@ local/
150150
*.old
151151

152152
# Local sractch
153-
.misc/
153+
.misc/
154+
Paper
155+
fig.png

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
# This call to setup() does all the work
99
setup(
1010
name="freelunch",
11-
version="0.0.14",
11+
version="0.0.15",
1212
description="Heuristic and meta-heuristic optimisation suite in Python",
1313
long_description=rm,
1414
long_description_content_type="text/markdown",

src/freelunch/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "0.0.14"
1+
__version__ = "0.0.15"
22

33
from freelunch.optimisers import *
44
import freelunch.benchmarks as benchmarks

src/freelunch/base.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ def _obj(self, obj, vec):
106106
except(ValueError, TypeError):
107107
return None
108108

109+
def curve_callback(self, best=None, mean=None):
110+
if best is None:
111+
self.data = {'best':[], 'mean':[]}
112+
else:
113+
self.data['best'].append(best)
114+
self.data['mean'].append(mean)
109115

110116
# Subclasses for granularity
111117

src/freelunch/benchmarks.py

Lines changed: 135 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,10 @@ class benchmark:
1313
'''
1414
default_bounds = lambda n:None
1515
rtm_optimum = lambda n:None
16+
tol=None
1617

17-
def __init__(self, n=None):
18-
if n is None:
19-
self.n = 2
20-
else:
21-
self.n = n
18+
def __init__(self, n=2):
19+
self.n = n
2220
self.bounds = self.default_bounds()
2321
self.optimum = self.rtn_optimum()
2422

@@ -27,8 +25,7 @@ def __call__(self, dna):
2725
raise ZeroLengthSolutionError('An empty trial solution was passed')
2826
return self.obj(dna)
2927

30-
# %%
31-
28+
# %% some misc (v0.x) benchmarks
3229

3330
class ackley(benchmark):
3431
'''
@@ -97,3 +94,134 @@ def obj(self, dna):
9794
t2 = - 0.1 * np.exp(-np.sum(dna**2))
9895
return t1 + t2
9996

97+
98+
99+
# %% https://robertmarks.org/Classes/ENGR5358/Papers/functions.pdf
100+
101+
class DeJong(benchmark):
102+
'''
103+
DeJong's 1st function in n dimensions
104+
'''
105+
default_bounds = lambda self:np.array([[-5.12, 5.12]]*self.n)
106+
rtn_optimum = lambda self:np.array([0]*self.n)
107+
f0 = 0
108+
109+
def obj(self, dna):
110+
return np.sum(dna**2)
111+
112+
class HyperElipsoid(benchmark):
113+
'''
114+
HyperElipsoid function in n dimensions
115+
'''
116+
default_bounds = lambda self:np.array([[-5.12, 5.12]]*self.n)
117+
rtn_optimum = lambda self:np.array([0]*self.n)
118+
f0 = 0
119+
120+
def obj(self, dna):
121+
return np.sum(np.arange(1,self.n+1)*dna**2)
122+
123+
class RotatedHyperElipsoid(benchmark):
124+
'''
125+
RotatedHyperElipsoid function in n dimensions
126+
'''
127+
default_bounds = lambda self:np.array([[-65.536, 65.536]]*self.n)
128+
rtn_optimum = lambda self:np.array([0]*self.n)
129+
f0 = 0
130+
131+
def obj(self, dna):
132+
out = 0
133+
for i in range(self.n):
134+
out += np.sum(dna[:i+1]**2)
135+
return out
136+
137+
class Rosenbrock(benchmark):
138+
'''
139+
Rosenbrock's function in n dimensions (banana function)
140+
'''
141+
default_bounds = lambda self:np.array([[-2.048, 2.048]]*self.n)
142+
rtn_optimum = lambda self:np.array([1]*self.n)
143+
f0 = 0
144+
145+
def obj(self, dna):
146+
return np.sum(100*(dna[1:] - dna[:-1]**2)**2 + (1-dna[:-1])**2)
147+
148+
149+
class Ragstrin(benchmark):
150+
'''
151+
Ragstrin's function in n dimensions
152+
'''
153+
default_bounds = lambda self:np.array([[-5.12, 5.12]]*self.n)
154+
rtn_optimum = lambda self:np.array([0]*self.n)
155+
f0 = 0
156+
157+
def obj(self, dna):
158+
return 10 * self.n + np.sum(dna**2 - 10*np.cos(2* np.pi*dna))
159+
160+
class Schwefel(benchmark):
161+
'''
162+
Schwefel's function in n dimensions
163+
164+
(divided through by dimension for constant f0)
165+
'''
166+
default_bounds = lambda self:np.array([[-500, 500]]*self.n)
167+
rtn_optimum = lambda self:np.array([420.9687]*self.n)
168+
f0 = 0
169+
170+
def obj(self, dna):
171+
return 418.9828872721625-np.sum(dna*np.sin(np.sqrt(np.abs(dna))))/self.n
172+
173+
class Griewangk(benchmark):
174+
'''
175+
Griewangk's function in n dimensions
176+
177+
'''
178+
default_bounds = lambda self:np.array([[-600, 600]]*self.n)
179+
rtn_optimum = lambda self:np.array([0]*self.n)
180+
f0 = 0
181+
182+
def obj(self, dna):
183+
return (1/4000)* np.sum(dna**2) - np.prod(np.cos(dna/np.sqrt(np.arange(self.n)+1))) + 1
184+
185+
class PowerSum(benchmark):
186+
'''
187+
Powersum function in n dimensions
188+
189+
'''
190+
default_bounds = lambda self:np.array([[-1, 1]]*self.n)
191+
rtn_optimum = lambda self:np.array([0]*self.n)
192+
f0 = 0
193+
194+
def obj(self, dna):
195+
out = 0
196+
for i,x in enumerate(dna):
197+
out+=np.abs(x)**(i+1)
198+
return out
199+
200+
class Ackley(benchmark):
201+
'''
202+
Ackely function in n dimensions
203+
'''
204+
205+
default_bounds = lambda self:np.array([[-32.768, 32.768]]*self.n)
206+
rtn_optimum = lambda self:np.array([0]*self.n)
207+
f0 = 0
208+
209+
a,b,c = 20, 0.2, 2*np.pi
210+
def obj(self, dna):
211+
t1 = -self.a * np.exp(-self.b * (1/len(dna)) * np.sum(dna**2))
212+
t2 = - np.exp(1/len(dna) * np.sum(np.cos(self.c * dna)))
213+
t3 = self.a + np.exp(1)
214+
return t1 + t2 + t3
215+
216+
217+
MOLGA_TEST_SUITE = [
218+
DeJong,
219+
HyperElipsoid,
220+
RotatedHyperElipsoid,
221+
Rosenbrock,
222+
Ragstrin,
223+
Schwefel,
224+
Griewangk,
225+
PowerSum,
226+
Ackley
227+
]

0 commit comments

Comments
 (0)