paper version of Algorithm

This commit is contained in:
Jonas Weinz
2020-02-16 13:20:04 +01:00
parent 6115df7945
commit 3f075ff941
14 changed files with 36128 additions and 41184 deletions

File diff suppressed because it is too large Load Diff

View File

@ -727,9 +727,21 @@ class MixNode(RecipeTreeNode):
n = random.choice(range(1, len(childs)-1))
between_node = ActionNode(random.choice(actions))
ings = self.traverse_ingredients()
ing = random.choice(ings)
self.split(set(childs[:n]), set(childs[n:]), between_node)
base_ing = ing._base_ingredient
act = None
try:
a, w = m_base_act.get_backward_adjacent(base_ing)
act = ea_tools.wheel_of_fortune_selection(a,w)
except ValueError:
print("Warning: cannot mutate given node")
if act is not None:
between_node = ActionNode(act)
self.split(set(childs[:n]), set(childs[n:]), between_node)
def node_score(self):
@ -760,13 +772,19 @@ class MixNode(RecipeTreeNode):
#p2 = sym_p_a_given_b(ing_b.to_json(), ing_a.to_json(), m_mix, c_mix)
#s += 0.5 * p1 + 0.5 * p2
grouped_ing_a = to_grouped_ingredient(ing_a)
grouped_ing_b = to_grouped_ingredient(ing_b)
#grouped_ing_a = to_grouped_ingredient(ing_a)
#grouped_ing_b = to_grouped_ingredient(ing_b)
ia = m_grouped_mix._label_index[grouped_ing_a.to_json()]
ib = m_grouped_mix._label_index[grouped_ing_b.to_json()]
#ia = m_grouped_mix._label_index[grouped_ing_a.to_json()]
#ib = m_grouped_mix._label_index[grouped_ing_b.to_json()]
if c_grouped_mix[ia,ib] > 0 or c_grouped_mix[ib,ia] > 0:
#if c_grouped_mix[ia,ib] > 0 or c_grouped_mix[ib,ia] > 0:
# s += 1
ia = m_mix._label_index[grouped_ing_a.to_json()]
ib = m_mix._label_index[grouped_ing_b.to_json()]
if c_mix[ia,ib] > 0 or c_mix[ib,ia] > 0:
s += 1
@ -1302,11 +1320,12 @@ class Tree(object):
return Tree(nodes[s[0]['id']])
def __init__(self, root):
def __init__(self, root, main_ingredients=None):
# create a dummy entry node
self._root = RecipeTreeNode("root", single_child=True)
self._root.add_child(root)
self._touched = True
self._main_ingredients = main_ingredients
def root(self):
return self._root.child()
@ -1321,7 +1340,7 @@ class Tree(object):
n.mutate()
# check for simplification after modification
# self.root().simplify()
self.root().simplify()
def dot(self):
return self.root().dot()
@ -1379,6 +1398,29 @@ class Tree(object):
def ing_scores(self):
return self._ing_scores
def main_ingredient_score(self):
if self._main_ingredients is None:
return 1
ings = self.root().traverse_ingredients()
actions_for_ing = {}
score_for_ing = {}
for ing in ings:
if ing._base_ingredient in self._main_ingredients:
actions_for_ing[ing._base_ingredient] = ing._action_set
score_for_ing[ing._base_ingredient] = 0
for ing in self._main_ingredients:
for act in actions_for_ing[ing]:
s = fw_p_a_given_b(act, ing, m_base_act, c_base_act)
if s > 0.5:
score_for_ing[ing] = 1
return sum([score_for_ing[ing] for ing in self._main_ingredients]) / len(self._main_ingredients)
def score(self):
if not self._touched:
return self._score
@ -1408,6 +1450,7 @@ class Tree(object):
else:
self._score = (sum_mix + sum_act + sum_ing) / n
self._score *= (len(s_ing) - self._n_duplicates) / len(s_ing)
#self._score = 0.95 * self._score + 0.05 * self.main_ingredient_score()
return self._score
@ -1418,17 +1461,19 @@ class Tree(object):
# ## Population
class Population(object):
def __init__(self, start_ingredients, main_ingredients, n_population = 50, min_additional=0, max_additional=15):
def __init__(self, start_ingredients, main_ingredients, n_population = 50, min_additional=0, max_additional=15, mutations=3):
self.population = []
for i in tqdm(range(n_population), desc="build initial population"):
self.population.append(Tree.from_ingredients(start_ingredients, main_ingredients, min_additional=min_additional, max_additional=max_additional))
self._n = n_population
self._n_mutations = mutations
def mutate(self):
for tree in self.population.copy():
t_clone = tree.copy()
t_clone.mutate()
t_clone.mutate()
for i in range(self._n_mutations):
t_clone.mutate()
#t_clone.mutate()
#t_clone.mutate()
self.population.append(t_clone)
@ -1457,6 +1502,7 @@ class Population(object):
self.population = np.array(self.population)[sorted_indices[:n]].tolist()
def run(self, n=50):
avg_scores = []
for i in tqdm(range(n), desc="run evolutionary cycles"):
self.mutate()
#self.mutate()
@ -1465,7 +1511,9 @@ class Population(object):
self.pairwise_competition()
#self.collect_scores()
#self.hold_best(self._n)
scores = [t.score() for t in self.population]
avg_scores.append(scores)
return avg_scores
def plot_population(self, n_best=10):
@ -1482,16 +1530,16 @@ class Population(object):
# ## Run Evolutionary Algorithm
# p = Population(["noodle"],['noodle'], min_additional=4, max_additional=13, n_population = 50)
#p = Population(["noodle"],['noodle'], min_additional=4, max_additional=13, n_population = 50)
#p_ingredient_unprepared(list(p.population[0].root().childs())[0]._name) < 0.2
# p.run(50)
#p.run(50)
# p.plot_population(n_best=20)
#p.plot_population(n_best=20)