-
Notifications
You must be signed in to change notification settings - Fork 2
/
coco.py
89 lines (73 loc) · 3.98 KB
/
coco.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
import numpy as np
import worker.bbobbenchmarks as bn
import random
class CoCoData(object):
def __init__(self, dim, function, instance, nbptsevals= 20, nbptsf = 5):
self.evalsTrigger = 1
self.function = function
self.instance = instance
self.lasteval_num = 0
self.fTrigger = np.inf
self.idxFTrigger = np.inf
self.nbptsf = nbptsf
self.idxEvalsTrigger = 0
self.nbptsevals = nbptsevals
self.dim = dim
self.idxDIMEvalsTrigger = 0.
self.nbFirstEvalsToAlwaysWrite = 1
def evalfun(self, algorithm, gen, ngen, fmin, fopt, error, sol,buffr=None,hbuffr=None):
fmin = float(fmin)
fopt = float(fopt)
error = float(error)
self.lasteval_num = self.lasteval_num + int(ngen)
if (self.lasteval_num >= self.evalsTrigger or fmin - fopt < self.fTrigger):
#We must write if we are past the trigger?
if self.lasteval_num >= self.evalsTrigger:
#In order to pass an assertion in DataSet() we add a fake first eval using a random solution
if not buffr:
#buffr.append(self.sprintData(1, algorithm, gen, ngen, fmin, fopt, error, sol))
random_sol = [10. * random.random() - 5 for _ in range(self.dim)]
function = bn.dictbbob[self.function](self.instance)
fval = function(random_sol)
fopt = function.getfopt()
buffr.append(self.sprintData(1, algorithm, gen, ngen, fval, fopt, fopt - fval, random_sol))
buffr.append(self.sprintData(self.lasteval_num, algorithm, gen, ngen, fmin, fopt, error, sol))
while self.lasteval_num >= np.floor(10 ** (self.idxEvalsTrigger / self.nbptsevals)):
self.idxEvalsTrigger += 1
while self.lasteval_num >= self.dim * 10 ** self.idxDIMEvalsTrigger:
self.idxDIMEvalsTrigger += 1
self.evalsTrigger = min(np.floor(10 ** (self.idxEvalsTrigger / self.nbptsevals)),
self.dim * 10 ** self.idxDIMEvalsTrigger)
if self.lasteval_num < self.nbFirstEvalsToAlwaysWrite:
self.evalsTrigger = self.lasteval_num + 1
# Also if we have a better solution
if fmin - fopt < self.fTrigger: # minimization only
if not hbuffr:
random_sol = [10. * random.random() - 5 for _ in range(self.dim)]
function = bn.dictbbob[self.function](self.instance)
fval = function(random_sol)
fopt = function.getfopt()
hbuffr.append(self.sprintData(1, algorithm, gen, ngen, fval, fopt, fopt - fval, random_sol))
#hbuffr.append(self.sprintData(1, algorithm, gen, ngen, fmin, fopt, error, sol))
hbuffr.append(self.sprintData(self.lasteval_num, algorithm, gen, ngen, fmin, fopt, error, sol))
if fmin <= fopt:
self.fTrigger = -np.inf
else:
if np.isinf(self.idxFTrigger):
self.idxFTrigger = np.ceil(np.log10(fmin - fopt)) * self.nbptsf
while fmin - fopt <= 10 ** (self.idxFTrigger / self.nbptsf):
self.idxFTrigger -= 1
self.fTrigger = min(self.fTrigger, 10 ** (self.idxFTrigger / self.nbptsf)) # TODO: why?
def sprintData(self, lasteval_num, algorithm, gen, ngen, fmin, fopt, error, sol):
"""Format data for printing."""
res = ('%d %+10.9e %+10.9e %+10.9e %+10.9e'
% (lasteval_num, fmin - fopt,
fmin - fopt, fmin,
fopt))
if len(sol) < 22:
tmp = []
for i in sol:
tmp.append(' %+5.4e' % i)
res += ''.join(tmp)
res += '\n'
return res