Commit 573795d9 authored by Mateusz Slazynski's avatar Mateusz Slazynski
Browse files

Changes eval function to use log

parent 989aaa2d
No related merge requests found
Showing with 776 additions and 0 deletions
+776 -0
MIT License
Copyright (c) [year] [fullname]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# Co-evolutionary Probabilistic Structured Grammatical Evolution python3 code
Co-evolutionary Probabilistic Structured Grammatical Evolution (Co-PSGE) is an extension to Structured Grammatical Evolution (SGE).
In Co-PSGE each individual in the population is composed by a grammar and a genotype, which is a list of dynamic lists, each corresponding to a non-terminal of the grammar containing real numbers that correspond to the probability of choosing a derivation rule. Each individual uses its own grammar to map the genotype into a program. During the evolutionary process both the grammar and the genotype are subject to variation operators.
A more in-depth explanation of the method and an analysis of its performance can be found in the article, soon to be publicly available. If you want a pre-print version you can send us an e-mail.
### Requirements
This code needs python3.5 or a newer version. More detail on the required libraries can be found in the `requirements.txt` file.
### Execution
The folder `examples/` contains the code for some benchmark problems used in GP. To run, for example, Symbolic Regression, you can use the following command:
```python3 -m examples.symreg --experiment_name dumps/example --seed 791021 --parameters parameters/standard.yml --grammars/regressiob.pybnf```
### Support
Any questions, comments or suggestion should be directed to Jessica Mégane ([jessicac@dei.uc.pt](mailto:jessicac@dei.uc.pt)) or Nuno Lourenço ([naml@dei.uc.pt](mailto:naml@dei.uc.pt)).
## References
O'Neill, M. and Ryan, C. "Grammatical Evolution: Evolutionary Automatic Programming in an Arbitrary Language", Kluwer Academic Publishers, 2003.
Fenton, M., McDermott, J., Fagan, D., Forstenlechner, S., Hemberg, E., and O'Neill, M. PonyGE2: Grammatical Evolution in Python. arXiv preprint, arXiv:1703.08535, 2017.
Lourenço, N., Assunção, F., Pereira, F. B., Costa, E., and Machado, P.. Structured Grammatical Evolution: A Dynamic Approach. In Handbook of Grammatical Evolution. Springer Int, 2018.
Mégane, J., Lourenço, N., and Machado, P.. Probabilistic Grammatical Evolution. In Genetic Programming, Ting Hu, Nuno Lourenço, and Eric Medvet (Eds.). Springer International Publishing, Cham, 198–213, 2021.
.idea
.DS_Store
.vscode
.pytest_cache
*.pyc
dumps/*
import random
from sge.parameters import params
from sge.utilities.protected_math import _log_, _div_, _exp_, _inv_, _sqrt_, protdiv
from numpy import cos, sin
def drange(start, stop, step):
r = start
while r < stop:
yield r
r += step
class BostonHousing():
def __init__(self, run=0, has_test_set=True, invalid_fitness=9999999):
self.__train_set = []
self.__test_set = None
self.__invalid_fitness = invalid_fitness
self.run = run
self.has_test_set = has_test_set
self.read_dataset()
self.calculate_rrse_denominators()
def read_dataset(self):
dataset = []
trn_ind = []
tst_ind = []
with open('resources/BostonHousing/housing.data', 'r') as dataset_file:
for line in dataset_file:
dataset.append([float(value.strip(" ")) for value in line.split(" ") if value != ""])
with open('resources/BostonHousing/housing.folds', 'r') as folds_file:
for _ in range(self.run - 1): folds_file.readline()
tst_ind = folds_file.readline()
tst_ind = [int(value.strip(" ")) - 1 for value in tst_ind.split(" ") if value != ""]
trn_ind = filter(lambda x: x not in tst_ind, range(len(dataset)))
self.__train_set = [dataset[i] for i in trn_ind]
self.__test_set = [dataset[i] for i in tst_ind]
def calculate_rrse_denominators(self):
self.__RRSE_train_denominator = 0
self.__RRSE_test_denominator = 0
train_outputs = [entry[-1] for entry in self.__train_set]
train_output_mean = float(sum(train_outputs)) / len(train_outputs)
self.__RRSE_train_denominator = sum([(i - train_output_mean)**2 for i in train_outputs])
if self.__test_set:
test_outputs = [entry[-1] for entry in self.__test_set]
test_output_mean = float(sum(test_outputs)) / len(test_outputs)
self.__RRSE_test_denominator = sum([(i - test_output_mean)**2 for i in test_outputs])
def get_error(self, individual, dataset):
pred_error = 0
for case in dataset:
target = case[-1]
try:
output = eval(individual, globals(), {"x": case[:-1]})
pred_error += (target - output)**2
except (ValueError, OverflowError, SyntaxError):
return self.__invalid_fitness
return pred_error
def evaluate(self, individual):
error = 0.0
test_error = 0.0
if individual is None:
return None
error = self.get_error(individual, self.__train_set)
error = _sqrt_( error /self.__RRSE_train_denominator)
if error is None:
error = self.__invalid_fitness
if self.__test_set is not None:
test_error = 0
test_error = self.get_error(individual, self.__test_set)
test_error = _sqrt_( test_error / float(self.__RRSE_test_denominator))
return error, {'generation': 0, "evals": 1, "test_error": test_error}
if __name__ == "__main__":
import sge
sge.setup("parameters/standard.yml")
eval_func = BostonHousing(params['RUN'])
sge.evolutionary_algorithm(evaluation_function=eval_func, parameters_file="parameters/standard.yml")
# This file is part of DEAP.
#
# DEAP is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# DEAP is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with DEAP. If not, see <http://www.gnu.org/licenses/>.
"""
This example is from "John R. Koza. Genetic Programming: On the Programming
of Computers by Natural Selection. MIT Press, Cambridge, MA, USA, 1992.".
The problem is called The Artificial Ant Problem.
<http://www.cs.ucl.ac.uk/staff/w.langdon/bloat_csrp-97-29/node2.html>
The goal of this example is to show how to use DEAP and its GP framework with
with complex system of functions and object.
Given an AntSimulator ant, this solution should get the 89 pieces of food
within 543 moves.
ant.routine = ant.if_food_ahead(ant.move_forward, prog3(ant.turn_left,
prog2(ant.if_food_ahead(ant.move_forward, ant.turn_right),
prog2(ant.turn_right, prog2(ant.turn_left, ant.turn_right))),
prog2(ant.if_food_ahead(ant.move_forward, ant.turn_left), ant.move_forward)))
Best solution found with DEAP:
prog3(prog3(move_forward,
turn_right,
if_food_ahead(if_food_ahead(prog3(move_forward,
move_forward,
move_forward),
prog2(turn_left,
turn_right)),
turn_left)),
if_food_ahead(turn_left,
turn_left),
if_food_ahead(move_forward,
turn_right))
fitness = (89,)
"""
import copy
from functools import partial
def dummy():
return
def progn(*args):
for arg in args:
arg()
def prog2(out1, out2):
return partial(progn, out1 ,out2)
def prog3(out1, out2, out3):
return partial(progn, out1, out2, out3)
def progN(*args):
return partial(progn,*args)
def if_food_ahead_RL(ant, out1, *targs):
return partial(if_then_else, ant.sense_food, out1, *targs)
def if_then_else(condition, out1, *targs):
if condition():
out1()
else:
for out in targs:
out()
class AntSimulator:
direction = ["north", "east", "south", "west"]
dir_row = [1, 0, -1, 0]
dir_col = [0, 1, 0, -1]
def __init__(self, max_moves=400, trail="sft"):
self.max_moves = max_moves
self.moves = 0
self.eaten = 0
self.routine = None
if trail == "sft":
self.parse_matrix(open("resources/santafe_trail.txt"))
self.total_pieces = 89
else:
self.parse_matrix(open("resources/losaltos.txt"))
self.total_pieces = 157
def _reset(self):
self.row = self.row_start
self.col = self.col_start
self.dir = 1
self.moves = 0
self.eaten = 0
self.matrix_exc = copy.deepcopy(self.matrix)#self.matrix[:]
#NOTE: with annotations is not possible to use the functions as
# named arguments in progn. With eval the @property is not necessary.
#For multi-line programs (uses exec) the full notation must be used
# eg.: 'if ant.sense_food():\n\tant.move_forward()\n'
@property
def position(self):
return (self.row, self.col, self.direction[self.dir])
def turn_left(self):
if self.moves < self.max_moves:
self.moves += 1
self.dir = (self.dir - 1) % 4
def turn_right(self):
if self.moves < self.max_moves:
self.moves += 1
self.dir = (self.dir + 1) % 4
def move_forward(self):
if self.moves < self.max_moves:
self.moves += 1
self.row = (self.row + self.dir_row[self.dir]) % self.matrix_row
self.col = (self.col + self.dir_col[self.dir]) % self.matrix_col
if self.matrix_exc[self.row][self.col] == "food":
self.eaten += 1
self.matrix_exc[self.row][self.col] = "passed"
def sense_food(self):
ahead_row = (self.row + self.dir_row[self.dir]) % self.matrix_row
ahead_col = (self.col + self.dir_col[self.dir]) % self.matrix_col
return self.matrix_exc[ahead_row][ahead_col] == "food"
def if_food_ahead(self, out1, *targs):
return partial(if_then_else, self.sense_food, out1, *targs)
def run(self):
self._reset()
while self.moves < self.max_moves:
try:
self.routine()
except SyntaxError:
print("SYNTAX ERROR:\n"+self.routine)
exit(0)
def runstring(self,routine,callable_ = False):
self._reset()
while self.moves < self.max_moves and self.eaten != 89:
last = self.moves
try:
if callable_:
eval(routine,{'ant':self,'prog3':prog3,
'prog2':prog2, 'progN':progN, 'dummy':dummy})()
else:
exec(routine,{'ant':self})
# protection for circuits that don't make the ant move
# loosing energy
if last == self.moves:
self.moves += 1
except SyntaxError:
print("SYNTAX ERROR:\n"+routine)
exit(0)
def evaluate(self, individual):
if individual is None:
return 1000, {'generation':0,"moves_needed" : self.max_moves, "evals" : 1, "test_error" : 0}
self.runstring(individual, False)
return self.total_pieces-self.eaten, {'generation': 0, "moves_needed": self.moves, "evals": 1, "test_error"
: 0}
def parse_matrix(self, matrix):
self.matrix = list()
self.matrix_exc = list()
for i, line in enumerate(matrix):
self.matrix.append(list())
self.matrix_exc.append(list())
for j, col in enumerate(line):
if col == "#":
self.matrix[-1].append("food")
self.matrix_exc[-1].append("food")
elif col == ".":
self.matrix[-1].append("empty")
self.matrix_exc[-1].append("empty")
elif col == "S":
self.matrix[-1].append("empty")
self.matrix_exc[-1].append("empty")
self.row_start = self.row = i
self.col_start = self.col = j
self.dir = 1
self.matrix_row = len(self.matrix)
self.matrix_col = len(self.matrix[0])
if __name__ == "__main__":
import sge
eval_func = AntSimulator(650)
sge.evolutionary_algorithm(evaluation_function=eval_func, parameters_file="parameters/standard_gp_ant.yml")
\ No newline at end of file
"""
# This file was adapted from the DEAP.
#
# DEAP is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# DEAP is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with DEAP. If not, see <http://www.gnu.org/licenses/>.
"""
MUX_SELECT_LINES = 3
MUX_IN_LINES = 2 ** MUX_SELECT_LINES
MUX_TOTAL_LINES = MUX_SELECT_LINES + MUX_IN_LINES
input_names = ['s0', 's1', 's2', 'i0', 'i1', 'i2', 'i3', 'i4', 'i5', 'i6', 'i7']
inputs = [[0] * MUX_TOTAL_LINES for i in range(2 ** MUX_TOTAL_LINES)]
outputs = [None] * (2 ** MUX_TOTAL_LINES)
for i in range(2 ** MUX_TOTAL_LINES):
value = i
divisor = 2 ** MUX_TOTAL_LINES
# Fill the input bits
for j in range(MUX_TOTAL_LINES):
divisor /= 2
if value >= divisor:
inputs[i][j] = 1
value -= divisor
# Determine the corresponding output
# The Select most valuable bit is s2
indexOutput = MUX_SELECT_LINES
for j, k in enumerate(inputs[i][:MUX_SELECT_LINES]):
indexOutput += k * 2 ** j
outputs[i] = inputs[i][indexOutput]
to_evaluate = [dict(zip(input_names, i)) for i in inputs]
class Multiplexer_11:
def evaluate(self, individual):
"""
SOLUTION = "(i0 and (not s2) and (not s1) and (not s0)) or (i1 and (not s2) and (not s1) and (s0)) or (i2 and (not s2) and (s1) and (not s0)) or (i3 and (not s2) and (s1) and (s0)) or (i4 and s2 and not(s1) and not(s0)) or (i5 and s2 and (not s1) and s0) or (i6 and s2 and s1 and (not s0)) or (i7 and s2 and s1 and s0)"
"""
error = len(inputs)
try:
program = compile("res = " + individual, '<string>', 'exec')
except(SyntaxError, MemoryError):
return 1000, -1
for i, variables in enumerate(to_evaluate):
exec(program, variables)
res = variables['res']
if res == outputs[i]:
error -= 1
return (error, {'generation': 0, "evals": 1, "test_error": 0.0})
if __name__ == "__main__":
import sge
eval_func = Multiplexer_11()
sge.evolutionary_algorithm(evaluation_function=eval_func, parameters_file="parameters/standard.yml")
\ No newline at end of file
"""
Lots of code taken from deap
"""
input_names = ['b0', 'b1', 'b2', 'b3', 'b4']
PARITY_FANIN_M = 5
PARITY_SIZE_M = 2**PARITY_FANIN_M
inputs = [None] * PARITY_SIZE_M
outputs = [None] * PARITY_SIZE_M
for i in range(PARITY_SIZE_M):
inputs[i] = [None] * PARITY_FANIN_M
value = i
dividor = PARITY_SIZE_M
parity = 1
for j in range(PARITY_FANIN_M):
dividor /= 2
if value >= dividor:
inputs[i][j] = 1
parity = int(not parity)
value -= dividor
else:
inputs[i][j] = 0
outputs[i] = parity
class Parity5():
def evaluate(self, individual):
error = PARITY_SIZE_M
for i, inpt in enumerate(inputs):
res = eval(individual, dict(zip(input_names, inpt)))
if res == outputs[i]:
error -= 1
return (error, {})
if __name__ == "__main__":
import sge
eval_func = Parity5()
sge.evolutionary_algorithm(evaluation_function=eval_func, parameters_file="parameters/standard.yml")
\ No newline at end of file
import numpy as np
import sge
class SimpleSymbolicRegression():
def __init__(self, num_fitness_cases=20, invalid_fitness=9999999):
self.invalid_fitness = invalid_fitness
self.function = lambda x: (x + 1) * (x - 3)
self.fitness_cases = num_fitness_cases
self.x_points = np.asarray([x for x in range(self.fitness_cases)])
self.y_points = np.asarray([self.function(x) for x in self.x_points])
self.x_evals = np.empty(self.fitness_cases)
def evaluate(self, individual):
try:
code = compile('result = lambda x: ' + individual, 'solution', 'exec')
globals_code = {}
locals_code = {}
exec(code, globals_code, locals_code)
func = locals_code['result']
self.x_evals = np.apply_along_axis(func, 0, self.x_points)
error = np.sum(np.sqrt(np.square(self.x_evals - self.y_points)))
except (OverflowError, ValueError) as e:
error = self.invalid_fitness
if np.isnan(error):
error = self.invalid_fitness
return error, {'generation': 0, "evals": 1}
if __name__ == "__main__":
fitness = SimpleSymbolicRegression()
sge.evolutionary_algorithm(evaluation_function=fitness, parameters_file="parameters/standard.yml")
import random
from numpy import cos, sin
from sge.utilities.protected_math import _log_, _div_, _exp_, _inv_, _sqrt_, protdiv
def drange(start, stop, step):
r = start
while r < stop:
yield r
r += step
class SymbolicRegression():
def __init__(self, function="pagiepolynomial", has_test_set=False, invalid_fitness=9999999):
self.__train_set = []
self.__test_set = None
self.__number_of_variables = 1
self.__invalid_fitness = invalid_fitness
self.partition_rng = random.Random()
self.function = function
self.has_test_set = has_test_set
self.readpolynomial()
self.calculate_rrse_denominators()
def calculate_rrse_denominators(self):
self.__RRSE_train_denominator = 0
self.__RRSE_test_denominator = 0
train_outputs = [entry[-1] for entry in self.__train_set]
train_output_mean = float(sum(train_outputs)) / len(train_outputs)
self.__RRSE_train_denominator = sum([(i - train_output_mean)**2 for i in train_outputs])
if self.__test_set:
test_outputs = [entry[-1] for entry in self.__test_set]
test_output_mean = float(sum(test_outputs)) / len(test_outputs)
self.__RRSE_test_denominator = sum([(i - test_output_mean)**2 for i in test_outputs])
def read_fit_cases(self):
f_in = open(self.__file_problem,'r')
data = f_in.readlines()
f_in.close()
fit_cases_str = [ case[:-1].split() for case in data[1:]]
self.__train_set = [[float(elem) for elem in case] for case in fit_cases_str]
self.__number_of_variables = len(self.__train_set[0]) - 1
def readpolynomial(self):
def quarticpolynomial(inp):
return pow(inp,4) + pow(inp,3) + pow(inp,2) + inp
def kozapolynomial(inp):
return pow(inp,6) - (2 * pow(inp,4)) + pow(inp,2)
def pagiepolynomial(inp1,inp2):
return 1.0 / (1 + pow(inp1,-4.0)) + 1.0 / (1 + pow(inp2,-4))
def keijzer6(inp):
return sum([1.0/i for i in range(1,inp+1,1)])
def keijzer9(inp):
return _log_(inp + (inp**2 + 1)**0.5)
if self.function in ["pagiepolynomial"]:
function = eval(self.function)
# two variables
l = []
for xx in drange(-5,5.4,0.4):
for yy in drange(-5,5.4,0.4):
zz = pagiepolynomial(xx,yy)
l.append([xx,yy,zz])
self.__train_set=l
self.training_set_size = len(self.__train_set)
if self.has_test_set:
xx = list(drange(-5,5.0,.1))
yy = list(drange(-5,5.0,.1))
function = eval(self.function)
zz = map(function, xx, yy)
self.__test_set = [xx,yy,zz]
self.test_set_size = len(self.__test_set)
elif self.function in ["quarticpolynomial"]:
function = eval(self.function)
l = []
for xx in drange(-1,1.1,0.1):
yy = quarticpolynomial(xx)
l.append([xx,yy])
self.__train_set = l
self.training_set_size = len(self.__train_set)
if self.has_test_set:
xx = list(drange(-1,1.1,0.1))
function = eval(self.function)
yy = map(function, xx)
self.__test_set = [xx,yy]
self.test_set_size = len(self.__test_set)
else:
if self.function == "keijzer6":
xx = list(drange(1,51,1))
elif self.function == "keijzer9":
xx = list(drange(0,101,1))
else:
xx = list(drange(-1,1.1,.1))
function = eval(self.function)
yy = map(function,xx)
self.__train_set = list(zip(xx, yy))
self.__number_of_variables = 1
self.training_set_size = len(self.__train_set)
if self.has_test_set:
if self.function == "keijzer6":
xx = list(drange(51,121,1))
elif self.function == "keijzer9":
xx = list(drange(0,101,.1))
yy = map(function,xx)
self.__test_set = [xx, yy]
self.test_set_size = len(self.__test_set)
def get_error(self, individual, dataset):
pred_error = 0
for fit_case in dataset:
case_output = fit_case[-1]
try:
result = eval(individual, globals(), {"x": fit_case[:-1]})
pred_error += (case_output - result)**2
except (OverflowError, ValueError) as e:
return self.__invalid_fitness
return pred_error
def evaluate(self, individual):
error = 0.0
test_error = 0.0
if individual is None:
return None
error = self.get_error(individual, self.__train_set)
error = _sqrt_( error /self.__RRSE_train_denominator)
if error is None:
error = self.__invalid_fitness
if self.__test_set is not None:
test_error = 0
test_error = self.get_error(individual, self.__test_set)
test_error = _sqrt_( test_error / float(self.__RRSE_test_denominator))
return error, {'generation': 0, "evals": 1, "test_error": test_error}
if __name__ == "__main__":
import sge
eval_func = SymbolicRegression()
sge.evolutionary_algorithm(evaluation_function=eval_func, parameters_file="parameters/standard.yml")
<start> ::= <B>
<B> ::= <B> and <B>|<B> or <B>|not(<B> and <B>)|not(<B> or <B>)|<var>
<var> ::= b0|b1|b2|b3|b4
#core
<start> ::= <code>
<code> ::= <line>|<code>\n<line>
<line> ::= if ant.sense_food():{:<line>:}else:{:<line>:}|<op>
<op> ::= ant.turn_left()|ant.turn_right()|ant.move_forward()
#core
<start> ::= <expr>
<expr> ::= <expr><op><expr>|(<expr><op><expr>)|<pre_op>(<expr>)|<var>
<op> ::= +|-|*|\eb_div_\eb
<pre_op> ::= sin|cos|_exp_|_log_|_inv_
<var> ::= x[0]|x[1]|x[2]|x[3]|x[4]|x[5]|x[6]|x[7]|x[8]|x[9]|x[10]|x[11]|x[12]|1.0
<start> ::= <expr>
<expr> ::= <expr><op><expr>|(<expr><op><expr>)|<pre_op>(<expr>)|<var>
<op> ::= +|-|*|\eb_div_\eb
<pre_op> ::= sin|cos|_exp_|_log_|_inv_
<var> ::= x[0]|x[1]|x[2]|x[3]|x[4]|x[5]|x[6]|x[7]|x[8]|x[9]|x[10]|x[11]|x[12]|1.0
\ No newline at end of file
<start> ::= <B>
<B> ::= (<B>) and (<B>)|(<B>) or (<B>)|not (<B>)|(<B>) if (<B>) else (<B>)|<var>
<var> ::= s0|s1|s2|i0|i1|i2|i3|i4|i5|i6|i7
#core
<start> ::= <expr>
<expr> ::= <expr><op><expr>|(<expr><op><expr>)|<var>
<op> ::= +|-|*|\eb_div_\eb
<var> ::= x[0]|1.0
<start> ::= <function>
<function> ::= <value> <operator> <value> | ( <function> ) <operator> <value>
<operator> ::= + | - | *
<value> ::= <variable> | <integer>
<integer> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
<variable> ::= x
\ No newline at end of file
<program> ::= (neighbor :- <opening>, <move>).
<move> ::= <atomic-move>, <move> |
<meta-move>, <move> |
flip_variable(<var-next>, <range-indexes>, <range-indexes>) |
set_value(<var-next>, <range-indexes>) |
swap_values(<var-next>, <var-next>) |
<meta-move>
<flat-move> ::= <flat-atomic-move>, <flat-move> |
flip_variable(<all-var-next>, <all-range-indexes>, <all-range-indexes>) |
set_value(<all-var-next>, <all-range-indexes>) |
swap_values(<all-var-next>, <all-var-next>)
<atomic-move> ::= flip_variable(<var-next>, <range-indexes>, <range-indexes>) |
set_value(<var-next>, <range-indexes>) |
swap_values(<var-next>, <var-next>) |
is_satisfied(alldifferent_next_1, <var-next>, <var-next>) |
is_violated(alldifferent_next_1, <var-next>, <var-next>) |
<var-next> "\=" <var-next> |
<var-next> = <var-next> |
<range-indexes> = <range-indexes> |
<range-indexes> "\=" <range-indexes> |
<range-indexes> "<" <range-indexes>
<flat-atomic-move> ::= variable(next, <all-range-indexes>, <all-var-next>) |
constraint(alldifferent_next_1, <all-var-next>, <all-var-next>) |
value(next, <all-var-next>, <all-range-indexes>) |
flip_variable(<all-var-next>, <all-range-indexes>, <all-range-indexes>) |
set_value(<all-var-next>, <all-range-indexes>) |
swap_values(<all-var-next>, <all-var-next>) |
is_satisfied(alldifferent_next_1, <all-var-next>, <all-var-next>) |
is_violated(alldifferent_next_1, <all-var-next>, <all-var-next>) |
range_element("'City'", <all-range-indexes>) |
<all-var-next> "\=" <all-var-next> |
<all-var-next> = <all-var-next> |
<all-range-indexes> = <all-range-indexes> |
<all-range-indexes> "\=" <all-range-indexes> |
<all-range-indexes> "<" <all-range-indexes>
<meta-snippet> ::= walk_over(constraint(alldifferent_next_1, MN0, MN1), <var-next>, (is_violated(alldifferent_next_1, MN0, MN1), <flat-move>)) |
walk_over_inversed(constraint(alldifferent_next_1, MN0, MN1), <var-next>, (is_violated(alldifferent_next_1, MN0, MN1), <flat-move>)) |
iterate_backward(variable(next, MI0, MN0) - variable(next, MI1, MN1), <var-next>, (MN0 \= <var-next>, <flat-move>)) |
iterate(variable(next, MI0, MN0) - variable(next, MI1, MN1), <var-next>, (MN0 \= <var-next>, <flat-move>))
<meta-move> ::= for_each(variable(next, MI0, MN0), (<flat-move>)) |
for_each(constraint(alldifferent_next_1, MN0, MN1), (<flat-move>)) |
for_each(range_element("'City'", MI0), (<flat-move>)) |
walk_over(constraint(alldifferent_next_1, MN0, MN1), <var-next>, (<flat-move>)) |
walk_over_inversed(constraint(alldifferent_next_1, MN0, MN1), <var-next>, (<flat-move>)) |
iterate_backward(variable(next, MI0, MN0) - variable(next, MI1, MN1), <var-next>, (<flat-move>)) |
iterate(variable(next, MI0, MN0) - variable(next, MI1, MN1), <var-next>, (<flat-move>)) |
<meta-snippet>
<opening> ::= <first-action> |
<first-action>, <get>
<get> ::= variable(next, <range-indexes>, <var-next>) |
constraint(alldifferent_next_1, <var-next>, <var-next>) |
value(next, <var-next>, <range-indexes>) |
range_element("'City'", <range-indexes>) |
variable(next, <range-indexes>, <var-next>), variable(next, <range-indexes>, <var-next>), <var-next> \= <var-next> |
variable(next, <range-indexes>, <var-next>), variable(next, <range-indexes>, <var-next>), <range-indexes> "<" <range-indexes> |
variable(next, <range-indexes>, <var-next>), value(next, <var-next>, I1) |
value(next, <var-next>, <range-indexes>), variable(next, <range-indexes>, <var-next>) |
range_element("'City'", <range-indexes>), value(next, <var-next>, <range-indexes>) |
<get>, <get>
<first-action> ::= variable(next, I0, N0) |
constraint(alldifferent_next_1, N0, N1) |
value(next, N0, I0) |
range_element("'City'", I0)
<meta-range-indexes> ::= MI0 | MI1
<meta-var-next> ::= MN0 | MN1
<range-indexes> ::= I<i>
<var-next> ::= N<n>
<all-var-next> ::= <meta-var-next> | <var-next>
<all-range-indexes> ::= <meta-range-indexes> | <range-indexes>
<n> ::= GE_RANGE:4
<i> ::= GE_RANGE:8
\ No newline at end of file
POPSIZE: 1000
GENERATIONS: 50
ELITISM: 100 # number of individuals that survive
PROB_CROSSOVER: 0.9
PROB_MUTATION: 0.1
TSIZE: 3
GRAMMAR: 'grammars/regression.pybnf'
EXPERIMENT_NAME: 'dumps/Test'
RUN: 1
INCLUDE_GENOTYPE: True
SAVE_STEP: 1
VERBOSE: True
MIN_TREE_DEPTH: 5
MAX_TREE_DEPTH: 17
NORMAL_DIST_SD: 0.9
PROB_MUTATION_GRAMMAR: 0.05
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment