Skip to content
This repository was archived by the owner on Jul 31, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions modea/Algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,12 +249,10 @@ def runLocalRestartOptimizer(self,target=None, threshold=None):
def determineRegime(self):
large = self.budgets['large']
small = self.budgets['small']
if large <= 0:
if large <= 0 or small > 0 and large <= small:
self.regime = 'small'
elif small <= 0 or large > small:
self.regime = 'large'
else:
self.regime = 'small'
Comment on lines -252 to -257
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function EvolutionaryOptimizer.determineRegime refactored with the following changes:

self.regime = 'large'


class OnePlusOneOptimizer(EvolutionaryOptimizer):
Expand Down Expand Up @@ -421,7 +419,7 @@ class CustomizedES(EvolutionaryOptimizer):
def __init__(self, n, fitnessFunction, budget, mu=None, lambda_=None, opts=None, values=None):

if opts is None:
opts = dict()
opts = {}
Comment on lines -424 to +422
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function CustomizedES.__init__ refactored with the following changes:

self.addDefaults(opts)

self.n = n
Expand Down
11 changes: 2 additions & 9 deletions modea/Individual.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,7 @@ def __copy__(self):
return return_copy

def __repr__(self):
return "<FloatIndividual [{}]: {}>".format(
str(np.round_(self.fitness,2)),
str(np.round_(self.genotype.flatten(), 2)),
)
return f"<FloatIndividual [{str(np.round_(self.fitness, 2))}]: {str(np.round_(self.genotype.flatten(), 2))}>"
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function FloatIndividual.__repr__ refactored with the following changes:


def __str__(self):
return self.__repr__()
Expand Down Expand Up @@ -96,11 +93,7 @@ def __init__(self, n, num_discrete, num_ints, num_floats=None):
self.maxStepSize = 0.5
self.initStepSize = 0.2

if n > 5:
self.baseStepSize = 1 / n
else:
self.baseStepSize = 0.175 # Random guess value, may need to be updated

self.baseStepSize = 1 / n if n > 5 else 0.175
Comment on lines -99 to +96
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function MixedIntIndividual.__init__ refactored with the following changes:

This removes the following comments ( why? ):

# Random guess value, may need to be updated

for x in range(self.n):
# self.baseStepSizeMIES[x] = 1/(3 * num_options[x])
self.stepSizeOffsetMIES[x] = self.initStepSize - self.baseStepSize
Expand Down
13 changes: 3 additions & 10 deletions modea/Mutation.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,7 @@ def _getXi():
Randomly returns 5/7 or 7/5 with equal probability
:return: float Xi
"""
if bool(random.getrandbits(1)):
return 5/7
else:
return 7/5
return 5/7 if bool(random.getrandbits(1)) else 7/5
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function _getXi refactored with the following changes:



'''-----------------------------------------------------------------------------
Expand Down Expand Up @@ -275,14 +272,10 @@ def MIES_MutateDiscrete(individual, begin, end, u, num_options, options):
threshold = np.random.random_sample()
# change discrete
if threshold < individual.stepSizeMIES(x):
temparray = []
for i in range(num_options[x]):
temparray.append(i)
temparray = list(range(num_options[x]))
temparray.remove(individual.genotype[x])
individual.genotype[x] = random.choice(temparray)
for i in range(options[x][2]):
conditional_mask.append(individual.genotype[x])

conditional_mask.extend(individual.genotype[x] for _ in range(options[x][2]))
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function MIES_MutateDiscrete refactored with the following changes:

return conditional_mask


Expand Down
17 changes: 7 additions & 10 deletions modea/Parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def __init__(self, n, budget, sigma=None,
if mu is None:
mu = 0.5
elif mu > lambda_:
raise Exception("mu ({}) cannot be greater than lambda ({})".format(mu, lambda_))
raise Exception(f"mu ({mu}) cannot be greater than lambda ({lambda_})")
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function Parameters.__init__ refactored with the following changes:

elif mu >= 1:
mu /= lambda_
if sigma is None:
Expand Down Expand Up @@ -208,7 +208,7 @@ def __init_values(self, values):
def mu_int(self):
"""Integer value of mu"""
if self.eff_lambda < 1:
raise Exception("Effective lambda ({}) should be at least 1!".format(self.eff_lambda))
raise Exception(f"Effective lambda ({self.eff_lambda}) should be at least 1!")
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function Parameters.mu_int refactored with the following changes:

return int(1 + floor((self.eff_lambda-1) * self.mu))


Expand Down Expand Up @@ -272,7 +272,7 @@ def adaptCovarianceMatrix(self, evalcount):
lambda_ = self.lambda_

self.p_sigma = (1-cs) * self.p_sigma + \
sqrt(cs*(2-cs)*mueff) * dot(invsqrt_C, (wcm - wcm_old) / self.sigma)
sqrt(cs*(2-cs)*mueff) * dot(invsqrt_C, (wcm - wcm_old) / self.sigma)
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function Parameters.adaptCovarianceMatrix refactored with the following changes:

power = (2*evalcount/lambda_)
if power < 1000: #TODO: Solve more neatly
hsig = sum(self.p_sigma**2)/(1-(1-cs)**power)/n < 2 + 4/(n+1)
Expand All @@ -284,8 +284,8 @@ def adaptCovarianceMatrix(self, evalcount):

# Regular update of C
self.C = (1 - c_1 - c_mu) * self.C \
+ c_1 * (outer(self.p_c, self.p_c) + (1-hsig) * cc * (2-cc) * self.C) \
+ c_mu * dot(offset, self.weights*offset.T)
+ c_1 * (outer(self.p_c, self.p_c) + (1-hsig) * cc * (2-cc) * self.C) \
+ c_mu * dot(offset, self.weights*offset.T)
if self.active and len(self.all_offspring) >= 2*self.mu_int: # Active update of C
offset_bad = self.offset[:, -self.mu_int:]
self.C -= c_mu * dot(offset_bad, self.weights*offset_bad.T)
Expand All @@ -298,10 +298,7 @@ def adaptCovarianceMatrix(self, evalcount):
self.sigma *= exp(self.alpha_s)
else:
exponent = (norm(self.p_sigma) / self.chiN - 1) * self.c_sigma / self.damps
if exponent < 1000: #TODO: Solve more neatly
self.sigma = self.sigma * exp(exponent)
else:
self.sigma = self.sigma_mean
self.sigma = self.sigma * exp(exponent) if exponent < 1000 else self.sigma_mean
self.sigma_mean = self.sigma

### Update BD ###
Expand Down Expand Up @@ -330,7 +327,7 @@ def adaptCovarianceMatrix(self, evalcount):
self.sqrt_C = dot(e_vector, e_value**-1 * e_vector.T)
except LinAlgError as e:
# raise Exception(e)
print("Restarting, degeneration detected: {}".format(e))
print(f"Restarting, degeneration detected: {e}")
degenerated = True

if degenerated:
Expand Down
7 changes: 2 additions & 5 deletions modea/Recombination.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ def random(pop, param):
:returns: A list of lambda individuals, each a copy of a randomly chosen individual from the population
"""

new_population = [copy(choice(pop)) for _ in range(param.lambda_)]
return new_population
return [copy(choice(pop)) for _ in range(param.lambda_)]
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function random refactored with the following changes:



def onePlusOne(pop, param):
Expand Down Expand Up @@ -77,9 +76,7 @@ def weighted(pop, param):
new_ind = copy(pop[0])
new_ind.genotype = param.wcm
new_population = [new_ind]
for _ in range(int(param.lambda_-1)):
new_population.append(copy(new_ind))

new_population.extend(copy(new_ind) for _ in range(int(param.lambda_-1)))
Comment on lines -80 to +79
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function weighted refactored with the following changes:

return new_population


Expand Down
11 changes: 4 additions & 7 deletions modea/Sampling.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,7 @@ class QuasiGaussianSobolSampling(object):
def __init__(self, n, shape='col', seed=None):
self.n = n
self.shape = (n,1) if shape == 'col' else (1,n)
if seed is None or seed < 2:
self.seed = np.random.randint(2, n**2) # seed=1 will give a null-vector as first result
else:
self.seed = seed
self.seed = np.random.randint(2, n**2) if seed is None or seed < 2 else seed
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function QuasiGaussianSobolSampling.__init__ refactored with the following changes:

This removes the following comments ( why? ):

# seed=1 will give a null-vector as first result


def next(self):
"""
Expand Down Expand Up @@ -131,7 +128,7 @@ class OrthogonalSampling(object):
"""
def __init__(self, n, lambda_, shape='col', base_sampler=None):
if n == 0 or lambda_ == 0:
raise ValueError("'n' ({}) and 'lambda_' ({}) cannot be zero".format(n, lambda_))
raise ValueError(f"'n' ({n}) and 'lambda_' ({lambda_}) cannot be zero")
Comment on lines -134 to +131
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function OrthogonalSampling.__init__ refactored with the following changes:


self.n = n
self.shape = (n,1) if shape == 'col' else (1,n)
Expand Down Expand Up @@ -162,7 +159,7 @@ def __generateSamples(self):
""" Draw <num_samples> new samples from the base_sampler, orthonormalize them and store to be drawn from """
samples = []
lengths = []
for i in range(self.num_samples):
for _ in range(self.num_samples):
Comment on lines -165 to +162
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function OrthogonalSampling.__generateSamples refactored with the following changes:

sample = self.base_sampler.next()
samples.append(sample)
lengths.append(norm(sample))
Expand All @@ -184,8 +181,8 @@ def __gramSchmidt(self, vectors):
for i in range(1, num_vectors):
for j in range(i):
vec_i = vectors[i]
vec_j = vectors[j]
if lengths[j]: # This will prevent Runtimewarning (Division over zero)
vec_j = vectors[j]
Comment on lines -187 to +185
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function OrthogonalSampling.__gramSchmidt refactored with the following changes:

vectors[i] = vec_i - vec_j * (dot(vec_i.T, vec_j) / lengths[j] ** 2)
lengths[i] = norm(vectors[i])

Expand Down
79 changes: 44 additions & 35 deletions modea/Utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,11 @@ def getVals(init_values):
:return: Dictionary containing name-indexed initial parameter values
"""

values = {initializable_parameters[i]: val for i, val in enumerate(init_values) if val is not None}
return values
return {
initializable_parameters[i]: val
for i, val in enumerate(init_values)
if val is not None
}
Comment on lines -50 to +54
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function getVals refactored with the following changes:


def getOpts(bitstring):
"""
Expand All @@ -58,8 +61,10 @@ def getOpts(bitstring):
:return: Dictionary with all option names and the chosen option
"""

opts = {option[0]: option[1][int(bitstring[i])] for i, option in enumerate(options)}
return opts
return {
option[0]: option[1][int(bitstring[i])]
for i, option in enumerate(options)
}
Comment on lines -61 to +67
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function getOpts refactored with the following changes:


def getBitString(opts):
"""
Expand All @@ -69,16 +74,12 @@ def getBitString(opts):
:return: A list of integers that serve as index for the options tuple
"""
bitstring = []
for i, option in enumerate(options):
for option in options:
name, choices, _ = option
if name in opts:
if opts[name] in choices:
bitstring.append(choices.index(opts[name]))
else:
bitstring.append(0)
if name in opts and opts[name] in choices:
bitstring.append(choices.index(opts[name]))
else:
bitstring.append(0)

Comment on lines -72 to -81
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function getBitString refactored with the following changes:

return bitstring

def getFullOpts(opts):
Expand Down Expand Up @@ -115,28 +116,44 @@ def getPrintName(opts):
ortho = 'Orthogonal-' if opts['orthogonal'] else ''
tpa = 'TPA-' if opts['tpa'] else ''
seq = 'Sequential ' if opts['sequential'] else ''
ipop = '{}-'.format(opts['ipop']) if opts['ipop'] is not None else ''
weight = '${}$-weighted '.format(opts['weights_option']) if opts['weights_option'] is not None else ''
ipop = f"{opts['ipop']}-" if opts['ipop'] is not None else ''
weight = (
f"${opts['weights_option']}$-weighted "
if opts['weights_option'] is not None
else ''
)

sel = 'Pairwise selection' if opts['selection'] == 'pairwise' else ''
sampler = 'a {} sampler'.format(opts['base-sampler']) if opts['base-sampler'] is not None else ''
sampler = (
f"a {opts['base-sampler']} sampler"
if opts['base-sampler'] is not None
else ''
)

if len(sel) + len(sampler) > 0:
append = ' with {}'
if len(sel) > 0 and len(sampler) > 0:
temp = '{} and {}'.format(sel, sampler)
if not sel or sampler == "":
temp = f'{sel}{sampler}'
else:
temp = '{}{}'.format(sel, sampler)
temp = f'{sel} and {sampler}'
append = append.format(temp)
else:
append = ''

base_string = "{seq}{thres}{weight}{mirror}{ortho}{active}(mu{elitist}lambda)-{tpa}{ipop}CMA-ES{append}"

name = base_string.format(elitist=elitist, active=active, thres=thres, mirror=mirror, ortho=ortho,
tpa=tpa, seq=seq, ipop=ipop, weight=weight, append=append)

return name
return base_string.format(
elitist=elitist,
active=active,
thres=thres,
mirror=mirror,
ortho=ortho,
tpa=tpa,
seq=seq,
ipop=ipop,
weight=weight,
append=append,
)
Comment on lines -118 to +156
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function getPrintName refactored with the following changes:



# TODO: make function of Individual base-class
Expand Down Expand Up @@ -178,11 +195,7 @@ def reprToInt(representation):
# TODO FIXME Hardcoded
max_length = 11
factors = [2304, 1152, 576, 288, 144, 72, 36, 18, 9, 3, 1]
integer = 0
for i in range(max_length):
integer += representation[i] * factors[i]

return integer
return sum(representation[i] * factors[i] for i in range(max_length))
Comment on lines -181 to +198
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function reprToInt refactored with the following changes:



def intToRepr(integer):
Expand Down Expand Up @@ -286,7 +299,7 @@ def __init__(self, fitnesses=None, target=1e-8, #

# The interesting values to display or use as comparison
self.ERT = ERT # Expected Running Time
self.FCE = FCE if FCE > target else target # Fixed Cost Error
self.FCE = max(FCE, target)
Comment on lines -289 to +302
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function ESFitness.__init__ refactored with the following changes:

This removes the following comments ( why? ):

# Fixed Cost Error

self.std_dev_ERT = std_dev_ERT # Standard deviation of ERT
self.std_dev_FCE = std_dev_FCE # Standard deviation of FCE
# Summary/memory values to use for reproducability
Expand All @@ -306,7 +319,7 @@ def __eq__(self, other):
def __lt__(self, other): # Assuming minimalization problems, so A < B means A is better than B
if self.ERT is not None and other.ERT is None:
return True # If only one has an ERT, it is better by default
elif self.ERT is not None and other.ERT is not None and self.ERT < other.ERT:
elif self.ERT is not None and self.ERT < other.ERT:
Comment on lines -309 to +322
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function ESFitness.__lt__ refactored with the following changes:

return True # If both have an ERT, we want the better one
elif self.ERT is None and other.ERT is None and self.FCE < other.FCE:
return True # If neither have an ERT, we want the better FCE
Expand All @@ -315,14 +328,10 @@ def __lt__(self, other): # Assuming minimalization problems, so A < B means A i

def __repr__(self):
if self.min_fitnesses is not None:
kwargs = "target={},min_fitnesses={},min_indices={},num_successful={}".format(
self.target, self.min_fitnesses, self.min_indices, self.num_successful
)
kwargs = f"target={self.target},min_fitnesses={self.min_fitnesses},min_indices={self.min_indices},num_successful={self.num_successful}"
else:
kwargs = "target={},ERT={},FCE={},std_dev_ERT={},std_dev_FCE={}".format(
self.target, self.ERT, self.FCE, self.std_dev_ERT, self.std_dev_FCE
)
return "ESFitness({})".format(kwargs)
kwargs = f"target={self.target},ERT={self.ERT},FCE={self.FCE},std_dev_ERT={self.std_dev_ERT},std_dev_FCE={self.std_dev_FCE}"
return f"ESFitness({kwargs})"
Comment on lines -318 to +334
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function ESFitness.__repr__ refactored with the following changes:


def __unicode__(self):
# TODO: pretty-print-ify
Expand Down
4 changes: 3 additions & 1 deletion tests/Mutation.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ def setUp(self):
def test_in_bounds(self):
vector = np.array([0, 1, 2, 3, 4])
result = vector
np.testing.assert_array_almost_equal(_keepInBounds(vector, self.lbound, self.ubound), result)
np.testing.assert_array_almost_equal(
_keepInBounds(result, self.lbound, self.ubound), result
)
Comment on lines -25 to +27
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function keepInBoundsTest.test_in_bounds refactored with the following changes:


def test_out_of_bounds(self):
vector = np.array([10,11,12,13,14])
Expand Down
Loading