Skip to content

Commit

Permalink
very useless code:
Browse files Browse the repository at this point in the history
  • Loading branch information
coado committed Dec 18, 2023
1 parent 9557f1f commit 269a03d
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 26 deletions.
41 changes: 29 additions & 12 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,21 @@ def __init__(self):
self.min_blocks = 2
self.max_blocks = 5

self.max_blocks_depth = 3
self.max_operations_depth = 2
self.max_logic_depth = 2
self.max_blocks_depth = 2
self.max_operations_depth = 4
self.max_logic_depth = 4

# between 0 and 1
# 0 means no complexity
# 1 means max complexity
self.complexity_of_operations = 0.1
self.complexity_of_logic = 0.1
self.complexity_of_operations = 0.3
self.complexity_of_logic = 0.3

self.population = 100000
self.population = 1
self.generations = 0
self.tournament_size = 3

self.not_prob = 30
self.evolution_prob = {
'crossover': 20,
'mutation': 80
Expand All @@ -40,8 +41,16 @@ def __init__(self):

# Use more vars or consts?
self.operation_prob = {
'variable': 50,
'constant': 50,
'variable': 45,
'constant': 45,
'input': 10,
}

self.condition_prob = {
'operation': 20,
'true': 40,
'false': 40,
'input': 0,
}

self.equation_prob = {
Expand All @@ -56,18 +65,26 @@ def __init__(self):
'open_scope': '{',
'close_scope': '}',
'equation': '=',
'operations': ['+', '-', '*', '/'],
'operations': ['+', '-', '*', '//'],
'conditions': ['<', '>', '==', '!=', '>=', '<='],
'logic': ['and', 'or'],
'logic': ['and', 'or', '^'],
'not': 'not',
'variable_prefix': 'var',
'input': 'input',
'output': 'output'
'output': 'output',
'true': 'true',
'false': 'false',

# TODO: add "not", "false", "true"

# TODO: Fix empty blocks


}

def assert_probabilities(self):
assert sum(self.block_prob.values()) == 100, "Block probabilities should sum up to 100"
assert sum(self.operation_prob.values()) == 100, "Expression probabilities should sum up to 100"
assert sum(self.evolution_prob.values()) == 100, "Evolution probabilities should sum up to 100"
assert sum(self.equation_prob.values()) == 100, "Equation probabilities should sum up to 100"
assert sum(self.equation_prob.values()) == 100, "Equation probabilities should sum up to 100"
assert sum(self.condition_prob.values()) == 100, "Condition probabilities should sum up to 100"
11 changes: 9 additions & 2 deletions evolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ def negative_tournament(self):
worst_indiv_index = random_indiv_index

return worst_indiv_index

def stats(self):
fitness_avg = sum(self.state.fitness) / len(self.state.fitness)
best_fitness = max(self.state.fitness)
best_indiv_index = self.state.fitness.index(best_fitness)
best_indiv = self.state.stack[best_indiv_index]
print(f"Generation {g} fitness avg: {fitness_avg}")

def evolve(self):
for g in range(self.config.generations):
Expand All @@ -119,7 +126,6 @@ def evolve(self):
pass

elif evolution_type == 'mutation':
# TODO: Change varriable generation to be static
indiv_index = self._tournament()
new_indiv = self._mutation(indiv_index)

Expand All @@ -128,7 +134,8 @@ def evolve(self):
# Get worst individual and replace it with new individual
offspring_index = self.negative_tournament()
self.state.replace_indiv(offspring_index, new_indiv, new_fitness)

self.stats()




Expand Down
2 changes: 1 addition & 1 deletion fitness.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ def fitness_function(self, indiv):
# TODO run interpreter and heuristic


# print(result + "\n\n")
print(result + "\n\n")
return random_number
54 changes: 48 additions & 6 deletions gpParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,17 @@ def _parse_operation(self):
left_side = ''
if self.is_operation(token):
left_side = self._parse_operation()
elif self.is_not(token):
left_side = self._parse_not(token)
else:
left_side = token

token = self.next_token()
right_side = ''
if self.is_operation(token):
right_side = self._parse_operation()
elif self.is_not(token):
right_side = self._parse_not(token)
else:
right_side = token

Expand All @@ -49,13 +53,17 @@ def _parse_condition(self):
left_side = ''
if self.is_operation(token):
left_side = self._parse_condition()
elif self.is_not(token):
left_side = self._parse_not(token)
else:
left_side = token

token = self.next_token()
right_side = ''
if self.is_operation(token):
right_side = self._parse_condition()
elif self.is_not(token):
right_side = self._parse_not(token)
else:
right_side = token

Expand All @@ -71,6 +79,8 @@ def _parse_logic(self):
left_side = self._parse_logic()
elif self.is_condition(token):
left_side = self._parse_condition()
elif self.is_not(token):
left_side = self._parse_not(token)
else:
left_side = token

Expand All @@ -80,6 +90,8 @@ def _parse_logic(self):
right_side = self._parse_logic()
elif self.is_condition(token):
right_side = self._parse_condition()
elif self.is_not(token):
right_side = self._parse_not(token)
else:
right_side = token

Expand All @@ -103,6 +115,8 @@ def _parse_equation(self):
elif self.is_condition(token):
right_side = self._parse_condition()

elif self.is_not(token):
right_side = self._parse_not(token)
else:
right_side = token

Expand All @@ -125,6 +139,8 @@ def _parse_if(self):
condition = self._parse_logic()
elif self.is_condition(token):
condition = self._parse_condition()
elif self.is_not(token):
condition = self._parse_not(token)
else:
condition = token

Expand All @@ -140,11 +156,37 @@ def _parse_while(self):
condition = self._parse_logic()
elif self.is_condition(token):
condition = self._parse_condition()
elif self.is_not(token):
condition = self._parse_not(token)
else:
condition = token

parsed = f"{while_token} ({condition})"
return parsed

def _parse_not(self, token):
not_token = self.current_token()
token = self.next_token()
expression = ''

if self.is_logic(token):
expression = self._parse_logic()
elif self.is_condition(token):
expression = self._parse_condition()
elif self.is_operation(token):
expression = self._parse_operation()
elif self.is_true(token):
expression = token
elif self.is_false(token):
expression = token
elif self.is_input(token):
expression = token
else:
expression = token

parsed = f"({not_token} {expression})"
return parsed


def parse(self):
while self.iterator < self.length:
Expand Down Expand Up @@ -173,10 +215,10 @@ def parse(self):


# read from output.txt
# with open('output.txt', 'r') as f:
# data = f.read()
with open('output.txt', 'r') as f:
data = f.read()

# data = [elem.strip().replace("'", "") for elem in data.strip()[1:-1].split(',')]
# gpParser = GpParser(data)
# res = gpParser.parse()
# print("RES: ", res)
data = [elem.strip().replace("'", "") for elem in data.strip()[1:-1].split(',')]
gpParser = GpParser(data)
res = gpParser.parse()
print("RES: ", res)
2 changes: 2 additions & 0 deletions output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
['=', 'var0', '-49', 'output', 'var0', 'if', '<=', 'true', '-75', '{', '=', 'var0', 'var0', '=', 'var1', 'input', 'output', 'var1', '}', 'if', 'not', '>=', 'not', 'input', 'false', '{', 'output', 'var0', 'output', 'var1', '}']

29 changes: 28 additions & 1 deletion state.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,21 @@ def get_equation(self):
equation_syntax = self.config.syntax['equation']
self._save_equation(equation_syntax)
return equation_syntax

def get_true(self):
true_syntax = self.config.syntax['true']
self._save_true(true_syntax)
return true_syntax

def get_false(self):
false_syntax = self.config.syntax['false']
self._save_false(false_syntax)
return false_syntax

def get_not(self):
not_syntax = self.config.syntax['not']
self._save_not(not_syntax)
return not_syntax

def get_indiv_stack(self, i):
return self.stack[i]
Expand Down Expand Up @@ -165,4 +180,16 @@ def _save_equation(self, equation_syntax):

def _save_logic(self, logic):
stack = self._get_current_stack()
stack.append(logic)
stack.append(logic)

def _save_true(self, true_syntax):
stack = self._get_current_stack()
stack.append(true_syntax)

def _save_false(self, false_syntax):
stack = self._get_current_stack()
stack.append(false_syntax)

def _save_not(self, not_syntax):
stack = self._get_current_stack()
stack.append(not_syntax)
29 changes: 26 additions & 3 deletions treeFactory.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,53 @@ def __init__(self, state, config=Config()):
super().__init__(config)
self.state = state

def denial_expression_with_probability(self):
if self.add_not():
self.state.get_not()

def _generate_operation(self, depth=1):
def _generate_operation(self, depth=1):
if depth > self.config.max_operations_depth or random.random() < (1 - self.config.complexity_of_operations):

operation_leaf = self.get_random_operation_leaf()
if operation_leaf == 'variable':
self.state.get_random_variable()
elif operation_leaf == 'constant':
self.state.get_random_const()
elif operation_leaf == 'input':
self.state.get_input()
else:
# Choose an arithmetic expression
self.state.get_random_operation()
self._generate_operation(depth + 1)
self._generate_operation(depth + 1)

def _generate_condition(self):
self.denial_expression_with_probability()
self.state.get_random_condition()
self._generate_operation()
self._generate_operation()

left_condition_leaf = self.get_random_condition_leaf()
right_condition_leaf = self.get_random_condition_leaf()
children = [left_condition_leaf, right_condition_leaf]

for child in children:
self.denial_expression_with_probability()
if child == 'operation':
self._generate_operation()
elif child == 'true':
self.state.get_true()
elif child == 'false':
self.state.get_false()
elif child == 'input':
self.state.get_input()
else:
raise Exception('Unknown condition leaf')


def _generate_logic(self, depth=1):
if depth > self.config.max_logic_depth or random.random() < (1 - self.config.complexity_of_logic):
self._generate_condition()
else:
self.denial_expression_with_probability()
self.state.get_random_logic()
self._generate_logic(depth + 1)
self._generate_logic(depth + 1)
Expand Down
18 changes: 17 additions & 1 deletion utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ def is_variable(self, token):
def is_constant(self, token):
return str(token).isdigit()

def is_not(self, token):
return token == self.config.syntax['not']

def is_true(self, token):
return token == self.config.syntax['true']

def is_false(self, token):
return token == self.config.syntax['false']

def choose_random_operation(self, exclude=None):
operations = self.config.syntax['operations'][:]
if exclude:
Expand Down Expand Up @@ -85,4 +94,11 @@ def get_random_equation_type(self):

def get_random_evolution_type(self):
evolution_type = self.get_random_key(self.config.evolution_prob)
return evolution_type
return evolution_type

def get_random_condition_leaf(self):
condition = self.get_random_key(self.config.condition_prob)
return condition

def add_not(self):
return random.randint(1, 100) <= self.config.not_prob

0 comments on commit 269a03d

Please sign in to comment.