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