paper version of Algorithm
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -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)
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user