> AbEC/abec/optimizers/optimizer.py
This is the file where we are going to implement the optimizer. First of all, lets talk
about some requirements.
The template of a new optimizer can be downloaded in the link:
[ Optimizer template ].
> Hyper-parameters
In order to set the hyper-parameters of the component, inside of the file it is necessary to be
defined one list, named
params, where each element of this list we put the hyper-parameters
of our new component. Below a generic example of this list.
params = ["HYPER-PARAMETER-1", "HYPER-PARAMETER-2", ..., "HYPER-PARAMETER-N"]
With the hyper-parameters defined, There are two methods that are mandatory, they are
cp and
optimizer.
> Confirmation of hyper-parameters (cp)
This method is used to confirm that all the values of the hyper-parameters are within the allowed range.
A generic example of this method is showed below:
from aux.aux import errorWarning
import sys
def cp(parameters):
if not (MIN <= parameters["<NAME-OF-OPTIMIZER>_<HYPER-PARAMETER-1>"] <= MAX):
errorWarning("3.X.1", "algoConfig.ini", "<NAME-OF-THE-OPTIMIZER>_<HYPER-PARAMETER-1>", "The <HYPER-PARAMETER-1> should be in the interval [MIN, MAX]")
sys.exit()
if not (MIN <= parameters["<NAME-OF-OPTIMIZER>_<HYPER-PARAMETER-2>"] <= MAX):
errorWarning("3.X.2", "algoConfig.ini", "<NAME-OF-THE-OPTIMIZER>_<HYPER-PARAMETER-2>", "The <HYPER-PARAMETER-2> should be in the interval [MIN, MAX]")
sys.exit()
if not (MIN <= parameters["<NAME-OF-OPTIMIZER>_<HYPER-PARAMETER-N>"] <= MAX):
errorWarning("3.X.N", "algoConfig.ini", "<NAME-OF-THE-OPTIMIZER>_<HYPER-PARAMETER-N>", "The <HYPER-PARAMETER-N> should be in the interval [MIN, MAX]")
sys.exit()
return 1
> The optimizer (optimizer)
This method is the implementation of the optimizer itself, hence, this is the most important
method and need to be carefully writen.
def optimizer(pop, best, runVars, parameters):
.
.
.
return pop, runVars
> optimizer.py
And then the complete file will be something like:
from aux.aux import errorWarning
import sys
params = ["HYPER-PARAMETER-1", "HYPER-PARAMETER-2", ..., "HYPER-PARAMETER-N"]
def cp(parameters):
if not (MIN <= parameters["<NAME-OF-OPTIMIZER>_<HYPER-PARAMETER-1>"] <= MAX):
errorWarning("3.X.1", "algoConfig.ini", "<NAME-OF-THE-OPTIMIZER>_<HYPER-PARAMETER-1>", "The <HYPER-PARAMETER-1> should be in the interval [MIN, MAX]")
sys.exit()
if not (MIN <= parameters["<NAME-OF-OPTIMIZER>_<HYPER-PARAMETER-2>"] <= MAX):
errorWarning("3.X.2", "algoConfig.ini", "<NAME-OF-THE-OPTIMIZER>_<HYPER-PARAMETER-2>", "The <HYPER-PARAMETER-2> should be in the interval [MIN, MAX]")
sys.exit()
if not (MIN <= parameters["<NAME-OF-OPTIMIZER>_<HYPER-PARAMETER-N>"] <= MAX):
errorWarning("3.X.N", "algoConfig.ini", "<NAME-OF-THE-OPTIMIZER>_<HYPER-PARAMETER-N>", "The <HYPER-PARAMETER-N> should be in the interval [MIN, MAX]")
sys.exit()
return 1
def optimizer(pop, best, runVars, parameters):
.
.
.
return pop, runVars
> algoConfig.ini
Once you have added the optimizer script in the respective folder, you will be able to configure
this component in the configuration file
"algoConfig.ini". The component will appers
in the file as follows:
{
"<NAME-OF-THE-OPTIMIZER>_POP_PERC": 1 -> This is the percentage of the individuals in the population that will perform this optimizer; 0 is turned off and 1 is 100% of the individuals. (float) in [0, 1]
}
The optimizer parameters:
{
"<NAME-OF-THE-OPTIMIZER>_POP_PERC": 1, -> This is the percentage of the individuals in the population that will perform this optimizer; 0 is turned off and 1 is 100% of the individuals. (float) in [0, 1]
"<NAME-OF-THE-OPTIMIZER>_<HYPER-PARAMETER-1>": value, -> range permitted for the value (type)
"<NAME-OF-THE-OPTIMIZER>_<HYPER-PARAMETER-2>": value, -> range permitted for the value (type)
.
.
"<NAME-OF-THE-OPTIMIZER>_<HYPER-PARAMETER-N>": value -> range permitted for the value (type)
}
As an example, we are going now to add an optimizer, the Differential Evolution (DE).
> AbEC/abec/optimizers/de.py
$ nano abec/optimizers/de.py
>
[ file ]
import sys
import copy
import abec
import aux.globalVar as globalVar
from aux.aux import errorWarning
params = ["F", "CR"]
def cp(parameters):
if not (0 < parameters["DE_F"] <= 10):
errorWarning("3.3.1", "algoConfig.ini", "DE_F", "The F parameters should be in the interval ]0, 10]")
sys.exit()
if not (0 < parameters["DE_CR"] <= 10):
errorWarning("3.3.2", "algoConfig.ini", "DE_CR", "The CR parameter should be in the interval ]0, 10]")
sys.exit()
return 1
def optimizer(pop, best, runVars, parameters):
tempPop = copy.deepcopy(pop)
tempPop.ind = sorted(tempPop.ind, key = lambda x:x["id"])
dePop = [d for d in tempPop.ind if d["type"]=="DE"]
for ind in dePop:
x = []
candidates = [c for c in dePop if c["id"] != ind["id"]]
a, b, c = globalVar.rng.choice(candidates, 3, replace=False)
for d in range(parameters["NDIM"]):
x.append(a["pos"][d] + parameters["DE_F"]*(b["pos"][d] - c["pos"][d]))
if x[d] > parameters["MAX_POS"]:
x[d] = parameters["MAX_POS"]
elif x[d] > parameters["MIN_POS"]:
x[d] = parameters["MIN_POS"]
for d in range(parameters["NDIM"]):
if globalVar.rng.random() < parameters["DE_CR"]:
ind["pos"][d] = x[d]
for ind in dePop:
ind = abec.evaluate(ind, parameters)
for i in range(len(pop.ind)):
if ind["id"] == pop.ind[i]["id"]:
if ind["fit"] < pop.ind[i]["fit"]:
pop.ind[i] = ind.copy()
ind, globalVar.best = abec.updateBest(pop.ind[i], globalVar.best)
else ind["fit"] < pop.ind[i]["fit"]:
pop.ind[i]["ae"] = 1
return pop, runVars
And then to use it in the algorithm, we set it up in the configuration file
algoConfig.ini, just like this:
$ nano abec/algoConfig.ini
>
[ file ]
{
"ALGORITHM": "DE",
"POPSIZE": 50,
"MIN_POS": -10,
"MAX_POS": 10,
"DE_POP_PERC": 1,
"DE_F": 0.5,
"DE_CR": 0.7
}