{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import sys\n", "sys.path.append(\"../\")\n", "sys.path.append(\"../RecipeAnalysis/\")\n", "\n", "import settings\n", "\n", "import pycrfsuite\n", "\n", "import json\n", "\n", "import db.db_settings as db_settings\n", "from db.database_connection import DatabaseConnection\n", "\n", "from Tagging.conllu_generator import ConlluGenerator\n", "from Tagging.crf_data_generator import *\n", "\n", "from RecipeAnalysis.Recipe import Ingredient\n", "\n", "from difflib import SequenceMatcher\n", "\n", "import numpy as np\n", "\n", "import plotly.graph_objs as go\n", "from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot\n", "from plotly.subplots import make_subplots\n", "init_notebook_mode(connected=True)\n", "\n", "from graphviz import Digraph\n", "\n", "import itertools\n", "\n", "import random\n", "\n", "import plotly.io as pio\n", "pio.renderers.default = \"jupyterlab\"\n", "\n", "from IPython.display import Markdown, HTML, display\n", "\n", "from copy import deepcopy" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import pickle\n", "m_act = pickle.load(open(\"m_act.pickle\", \"rb\"))\n", "m_mix = pickle.load(open(\"m_mix.pickle\", \"rb\"))\n", "m_base_act = pickle.load(open(\"m_base_act.pickle\", \"rb\"))\n", "m_base_mix = pickle.load(open(\"m_base_mix.pickle\", \"rb\"))\n", "\n", "c_act = m_act.get_csr()\n", "c_mix = m_mix.get_csr()\n", "c_base_act = m_base_act.get_csr()\n", "c_base_mix = m_base_mix.get_csr()\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "actions = m_act.get_labels()[0]" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "base_ingredients = m_base_mix.get_labels()" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "def get_sym_adjacent(key, m, c):\n", " index = m._label_index[key]\n", " i1 = c[index,:].nonzero()[1]\n", " i2 = c[:,index].nonzero()[0]\n", " \n", " i = np.concatenate((i1,i2))\n", " \n", " names = np.array(m.get_labels())[i]\n", " \n", " counts = np.concatenate((c[index, i1].toarray().flatten(), c[i2, index].toarray().flatten()))\n", " \n", " s = np.argsort(-counts)\n", " \n", " return names[s], counts[s]" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "def get_forward_adjacent(key, m, c):\n", " index = m._x_label_index[key]\n", " i = c[index,:].nonzero()[1]\n", " \n", " names = np.array(m._y_labels)[i]\n", " \n", " counts = c[index, i].toarray().flatten()\n", " \n", " s = np.argsort(-counts)\n", " \n", " return names[s], counts[s]" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "def get_backward_adjacent(key, m, c):\n", " index = m._y_label_index[key]\n", " i = c[:,index].nonzero()[0]\n", " \n", " names = np.array(m._x_labels)[i]\n", " \n", " counts = c[i, index].toarray().flatten()\n", " \n", " s = np.argsort(-counts)\n", " \n", " return names[s], counts[s]" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "def sym_sum(key, m, c):\n", " return np.sum(get_sym_adjacent(key,m,c)[1])\n", "\n", "def fw_sum(key, m, c):\n", " return np.sum(get_forward_adjacent(key,m,c)[1])\n", "\n", "def bw_sum(key, m, c):\n", " return np.sum(get_backward_adjacent(key,m,c)[1])" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "def sym_score(key_a, key_b, m, c):\n", "\n", " ia = m._label_index[key_a]\n", " ib = m._label_index[key_b]\n", " \n", " v = c[ia,ib] + c[ib,ia]\n", " \n", " if v == 0:\n", " return 0\n", " \n", " return max((v/sym_sum(key_a, m, c)), (v/sym_sum(key_b, m, c)))\n", "\n", "def asym_score(key_a, key_b, m, c):\n", " ia = m._x_label_index[key_a]\n", " ib = m._y_label_index[key_b]\n", " \n", " v = c[ia,ib]\n", " \n", " if v == 0:\n", " return 0\n", " \n", " return max(v/fw_sum(key_a, m, c), v/bw_sum(key_b, m, c))" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "class RecipeTreeNode(object):\n", " \n", " id = 0\n", " \n", " def __init__(self, name, constant=False, single_child=False):\n", " self._constant = constant\n", " self._name = name\n", " self._parent = None\n", " \n", " self._id = str(RecipeTreeNode.id)\n", " RecipeTreeNode.id += 1\n", " \n", " self._single_child = single_child\n", " \n", " if self._single_child:\n", " self._child = None\n", " \n", " def child():\n", " return self._child\n", " \n", " def remove_child(c):\n", " assert c == self._child\n", " self._child._parent = None\n", " self._child = None\n", " \n", " def childs():\n", " c = self.child()\n", " if c is None:\n", " return set()\n", " return set([c])\n", " \n", " def add_child(n):\n", " self._child = n\n", " n._parent = self\n", " \n", " self.child = child\n", " self.childs = childs\n", " self.add_child = add_child\n", " self.remove_child = remove_child\n", " else:\n", " self._childs = set()\n", " \n", " def childs():\n", " return self._childs\n", " \n", " def add_child(n):\n", " self._childs.add(n)\n", " n._parent = self\n", " \n", " def remove_child(c):\n", " assert c in self._childs\n", " c._parent = None\n", " self._childs.remove(c)\n", " \n", " self.childs = childs\n", " self.add_child = add_child\n", " self.remove_child = remove_child\n", " \n", " def parent(self):\n", " return self._parent\n", " \n", " def name(self):\n", " return self._name\n", " \n", " def traverse(self):\n", " l = []\n", " \n", " for c in self.childs():\n", " l += c.traverse()\n", " \n", " return [self] + l\n", " \n", " def traverse_ingredients(self):\n", " ingredient_set = []\n", " for c in self.childs():\n", " ingredient_set += c.traverse_ingredients()\n", " \n", " return ingredient_set\n", " \n", " def remove(self):\n", " p = self.parent()\n", " childs = self.childs().copy()\n", " \n", " assert p is None or not (len(childs) > 1 and p._single_child)\n", " \n", " for c in childs:\n", " self.remove_child(c)\n", " \n", " if p is not None:\n", " p.remove_child(self)\n", " \n", " if self._single_child and self._child is not None and p._name == self._child._name:\n", " # two adjacent nodes with same name would remain after deletion.\n", " # merge them! (by adding the child's childs to our parent instead of our childs)\n", " childs = self._child.childs()\n", " self._child.remove()\n", " \n", " \n", " for c in childs:\n", " p.add_child(c)\n", " \n", " def insert_before(self, n):\n", " p = self._parent\n", " if p is not None:\n", " p.remove_child(self)\n", " p.add_child(n)\n", " n.add_child(self)\n", " \n", " def mutate(self):\n", " n_node = self.n_node_mutate_options()\n", " n_edge = self.n_edge_mutate_options()\n", " \n", " choice = random.choice(range(n_node + n_edge))\n", " if choice < n_node:\n", " self.mutate_node()\n", " else:\n", " self.mutate_edges()\n", " \n", " def mutate_edges(self):\n", " ings = self.traverse_ingredients()\n", " ing = random.choice(ings)\n", " \n", " a, w = get_backward_adjacent(ing._base_ingredient, m_base_act, c_base_act)\n", " \n", " action = random.choices(a, w)[0]\n", " self.insert_before(ActionNode(action))\n", " \n", " def mutate_node(self):\n", " raise NotImplementedError\n", " \n", " def n_node_mutate_options(self):\n", " \n", " return 0 if self._constant else 1\n", " \n", " def n_edge_mutate_options(self):\n", " n = 1 if self._parent is not None else 0\n", " return n\n", " \n", " def n_mutate_options(self):\n", " return self.n_edge_mutate_options() + self.n_node_mutate_options()\n", " \n", " def dot_node(self, dot):\n", " raise NotImplementedError()\n", " \n", " def dot(self, d=None):\n", " if d is None:\n", " d = Digraph()\n", " self.dot_node(d)\n", " \n", " else:\n", " self.dot_node(d)\n", " if self._parent is not None:\n", " d.edge(self._parent._id, self._id)\n", " \n", " \n", " for c in self.childs():\n", " c.dot(d)\n", " \n", " return d\n", " \n", " def serialize(self):\n", " r = {}\n", " r['type'] = str(self.__class__.__name__)\n", " r['id'] = self._id\n", " r['parent'] = self._parent._id if self._parent is not None else None\n", " r['name'] = self._name\n", " r['childs'] = [c._id for c in self.childs()]\n", " r['constant'] = self._constant\n", " r['single_child'] = self._single_child\n", " \n", " return r\n", " \n", " def node_score(self):\n", " raise NotImplementedError()\n", " \n", " " ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "class MixNode(RecipeTreeNode):\n", " def __init__(self, constant=False):\n", " super().__init__(\"mix\", constant, single_child=False)\n", " \n", " def dot_node(self, dot):\n", " dot.node(self._id, label=f\"{self._name} ({self.node_score()})\", shape=\"diamond\")\n", " \n", " def split(self, set_above, set_below, node_between):\n", " assert len(set_above.difference(self.childs())) == 0\n", " assert len(set_below.difference(self.childs())) == 0\n", " \n", " n_above = MixNode()\n", " n_below = MixNode()\n", " \n", " p = self.parent()\n", " \n", " for c in self.childs().copy():\n", " self.remove_child(c)\n", " self.remove()\n", " \n", " for c in set_below:\n", " n_below.add_child(c)\n", " \n", " for c in set_above:\n", " n_above.add_child(c)\n", " \n", " n_above.add_child(node_between)\n", " node_between.add_child(n_below)\n", " \n", " if p is not None:\n", " p.add_child(n_above)\n", " \n", " # test whether the mix nodes are useless\n", " if len(n_above.childs()) == 1:\n", " n_above.remove()\n", " \n", " if len(n_below.childs()) == 1:\n", " n_below.remove()\n", " \n", " def n_node_mutate_options(self):\n", " return 0 if self._constant or len(self.childs()) <= 2 else len(self.childs())\n", " \n", " def mutate_node(self):\n", " \n", " childs = self.childs()\n", " \n", " if len(childs) <= 2:\n", " print(\"Warning: cannot modify mix node\")\n", " return\n", " \n", " childs = random.sample(childs, len(childs))\n", " \n", " n = random.choice(range(1, len(childs)-1))\n", " \n", " between_node = ActionNode(random.choice(actions))\n", " \n", " self.split(set(childs[:n]), set(childs[n:]), between_node)\n", " \n", " \n", " def node_score(self):\n", " child_ingredients = [c.traverse_ingredients() for c in self.childs()]\n", " products = [itertools.product(child_ingredients[i-1],child_ingredients[i]) for i in range(len(child_ingredients))]\n", " pairwise_tuples = []\n", " for p in products:\n", " pairwise_tuples += [x for x in p]\n", " \n", " s_base = 0\n", " s = 0\n", " \n", " for ing_a, ing_b in pairwise_tuples:\n", " try:\n", " #s_base += sym_score(ing_a._base_ingredient, ing_b._base_ingredient, m_base_mix, c_base_mix)\n", " s += sym_score(ing_a.to_json(), ing_b.to_json(), m_mix, c_mix)\n", " except:\n", " pass\n", " \n", " #s_base /= len(pairwise_tuples)\n", " s /= len(pairwise_tuples)\n", " \n", " #return 0.5 * (s_base + s)\n", " return s\n", " \n", " \n", " \n", " " ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "class IngredientNode(RecipeTreeNode):\n", " def __init__(self, name, constant=False):\n", " super().__init__(name, constant, single_child=True)\n", " \n", " def get_actions(self):\n", " a_set = set()\n", " n = self.parent()\n", " while n is not None:\n", " if type(n) == ActionNode:\n", " a_set.add(n.name())\n", " return a_set\n", " \n", " def mutate_node(self):\n", " self._name = random.choice(base_ingredients)\n", " \n", " def traverse_ingredients(self):\n", " return [Ingredient(self._name)]\n", " \n", " def node_score(self):\n", " return 0\n", " \n", " \n", " def dot_node(self, dot):\n", " dot.node(self._id, label=f\"{self._name} ({self.node_score()})\", shape=\"box\")" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "class ActionNode(RecipeTreeNode):\n", " def __init__(self, name, constant=False):\n", " super().__init__(name, constant, single_child=True)\n", " \n", " def n_node_mutate_options(self):\n", " # beacause we can change or remove ourselve!\n", " return 0 if self._constant else 2 \n", " def mutate_node(self):\n", " if random.choice(range(2)) == 0:\n", " # change action\n", " self._name = random.choice(actions)\n", " else:\n", " # delete\n", " self.remove()\n", " \n", " def traverse_ingredients(self):\n", " ingredient_set = super().traverse_ingredients()\n", " for ing in ingredient_set:\n", " ing.apply_action(self._name)\n", " \n", " return ingredient_set\n", " \n", " def node_score(self):\n", " ings = self.child().traverse_ingredients()\n", " \n", " s = 0\n", " \n", " for ing in ings:\n", " try:\n", " score = asym_score(self._name, ing.to_json(), m_act, c_act)\n", " #base_score = asym_score(self._name, ing._base_ingredient, m_base_act, c_base_act)\n", " s += score\n", " except KeyError as e:\n", " pass\n", " \n", " \n", " return s / len(ings)\n", " \n", " def dot_node(self, dot):\n", " dot.node(self._id, label=f\"{self._name} ({self.node_score()})\", shape=\"ellipse\")" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "class Tree(object):\n", " \n", " @staticmethod\n", " def from_ingredients(ingredients: list):\n", " root = MixNode()\n", " \n", " for ing in ingredients:\n", " root.add_child(IngredientNode(ing, constant=True))\n", " \n", " return Tree(root)\n", " \n", " @staticmethod\n", " def from_serialization(s):\n", " def empty_node(raw_n):\n", " if raw_n['type'] == \"MixNode\":\n", " node = MixNode(raw_n['constant'])\n", " elif raw_n['type'] == \"IngredientNode\":\n", " node = IngredientNode(raw_n['name'], raw_n['constant'])\n", " elif raw_n['type'] == \"ActionNode\":\n", " node = ActionNode(raw_n['name'], raw_n['constant'])\n", " else:\n", " print(\"unknown node detected\")\n", " return\n", " \n", " return node\n", " \n", " nodes = {}\n", " for n in s:\n", " nodes[n['id']] = empty_node(n)\n", " \n", " for n in s:\n", " childs = n['childs']\n", " id = n['id']\n", " for c in childs:\n", " nodes[id].add_child(nodes[c])\n", " \n", " return Tree(nodes[s[0]['id']])\n", " \n", " \n", " def __init__(self, root):\n", " # create a dummy entry node\n", " self._root = RecipeTreeNode(\"root\", single_child=True)\n", " self._root.add_child(root)\n", " \n", " def root(self):\n", " return self._root.child()\n", " \n", " def mutate(self):\n", " nodes = self.root().traverse()\n", " weights = [n.n_mutate_options() for n in nodes]\n", " \n", " n = random.choices(nodes, weights)[0]\n", " \n", " n.mutate()\n", " \n", " def dot(self):\n", " return self.root().dot()\n", " \n", " def serialize(self):\n", " return [n.serialize() for n in self.root().traverse()]\n", " \n", " def structure_score(self):\n", " n_duplicates = 0\n", " \n", " \n", " \n", " \n", " def score(self):\n", " \n", " scores = []\n", " \n", " nodes = self.root().traverse()\n", " n_nodes = 0\n", " s = 0\n", " for n in nodes:\n", " if type(n) != IngredientNode:\n", " scores.append(n.node_score())\n", " n_nodes += 1\n", " \n", " n_duplicates = 0\n", " seen_actions = set()\n", " \n", " for n in nodes:\n", " if type(n) == ActionNode:\n", " if n.name() in seen_actions:\n", " n_duplicates += 1\n", " else:\n", " seen_actions.add(n.name())\n", " \n", " \n", " return (sum(scores)/n_nodes) + 1 / (n_duplicates + 1)\n", " \n", " def copy(self):\n", " return Tree.from_serialization(self.serialize())\n" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "class Population(object):\n", " def __init__(self, start_ingredients, n_population = 10):\n", " self.population = [Tree.from_ingredients(start_ingredients) for i in range(n_population)]\n", " self._n = n_population\n", " \n", " def mutate(self):\n", " for tree in self.population.copy():\n", " t_clone = tree.copy()\n", " t_clone.mutate()\n", " self.population.append(t_clone)\n", " \n", " def pairwise_competition(self):\n", " new_population = []\n", " random.shuffle(self.population)\n", " \n", " for i in range(self._n):\n", " t_a = self.population[2*i]\n", " t_b = self.population[2*i+1]\n", " \n", " if t_a.score() > t_b.score():\n", " new_population.append(t_a)\n", " else:\n", " new_population.append(t_b)\n", " \n", " self.population = new_population\n", " \n", " def run(self, n=50):\n", " for i in range(n):\n", " print(i)\n", " self.mutate()\n", " self.pairwise_competition()\n", " \n", " def plot_population(self):\n", " for t in self.population:\n", " display(t.root().dot())" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "p = Population([\"bacon\", \"mushroom\", \"noodle\", \"water\", \"egg\"])" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "11\n", "12\n", "13\n", "14\n", "15\n", "16\n", "17\n", "18\n", "19\n" ] } ], "source": [ "p.run(20)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "2007\n", "\n", "cook (0.15189682906603946)\n", "\n", "\n", "\n", "2008\n", "\n", "mix (0.001416476454114257)\n", "\n", "\n", "\n", "2007->2008\n", "\n", "\n", "\n", "\n", "\n", "2010\n", "\n", "beat (0.33658536585365856)\n", "\n", "\n", "\n", "2008->2010\n", "\n", "\n", "\n", "\n", "\n", "2017\n", "\n", "mince (0.020833333333333332)\n", "\n", "\n", "\n", "2008->2017\n", "\n", "\n", "\n", "\n", "\n", "2012\n", "\n", "bacon (0)\n", "\n", "\n", "\n", "2008->2012\n", "\n", "\n", "\n", "\n", "\n", "2009\n", "\n", "noodle (0)\n", "\n", "\n", "\n", "2008->2009\n", "\n", "\n", "\n", "\n", "\n", "2014\n", "\n", "boil (0.25139664804469275)\n", "\n", "\n", "\n", "2008->2014\n", "\n", "\n", "\n", "\n", "\n", "2011\n", "\n", "egg (0)\n", "\n", "\n", "\n", "2010->2011\n", "\n", "\n", "\n", "\n", "\n", "2013\n", "\n", "mushroom (0)\n", "\n", "\n", "\n", "2017->2013\n", "\n", "\n", "\n", "\n", "\n", "2015\n", "\n", "water (0)\n", "\n", "\n", "\n", "2014->2015\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "887\n", "\n", "cook (0.1864481111173215)\n", "\n", "\n", "\n", "888\n", "\n", "mix (0.0)\n", "\n", "\n", "\n", "887->888\n", "\n", "\n", "\n", "\n", "\n", "890\n", "\n", "mushroom (0)\n", "\n", "\n", "\n", "888->890\n", "\n", "\n", "\n", "\n", "\n", "892\n", "\n", "beat (0.33658536585365856)\n", "\n", "\n", "\n", "888->892\n", "\n", "\n", "\n", "\n", "\n", "889\n", "\n", "bacon (0)\n", "\n", "\n", "\n", "888->889\n", "\n", "\n", "\n", "\n", "\n", "894\n", "\n", "bake (0.03333333333333333)\n", "\n", "\n", "\n", "888->894\n", "\n", "\n", "\n", "\n", "\n", "891\n", "\n", "noodle (0)\n", "\n", "\n", "\n", "888->891\n", "\n", "\n", "\n", "\n", "\n", "893\n", "\n", "egg (0)\n", "\n", "\n", "\n", "892->893\n", "\n", "\n", "\n", "\n", "\n", "897\n", "\n", "boil (0.25139664804469275)\n", "\n", "\n", "\n", "894->897\n", "\n", "\n", "\n", "\n", "\n", "895\n", "\n", "water (0)\n", "\n", "\n", "\n", "897->895\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "1636\n", "\n", "mix (0.0)\n", "\n", "\n", "\n", "1644\n", "\n", "mushroom (0)\n", "\n", "\n", "\n", "1636->1644\n", "\n", "\n", "\n", "\n", "\n", "1640\n", "\n", "bacon (0)\n", "\n", "\n", "\n", "1636->1640\n", "\n", "\n", "\n", "\n", "\n", "1641\n", "\n", "bake (0.03333333333333333)\n", "\n", "\n", "\n", "1636->1641\n", "\n", "\n", "\n", "\n", "\n", "1646\n", "\n", "cook (0.36065573770491804)\n", "\n", "\n", "\n", "1636->1646\n", "\n", "\n", "\n", "\n", "\n", "1638\n", "\n", "beat (0.33658536585365856)\n", "\n", "\n", "\n", "1636->1638\n", "\n", "\n", "\n", "\n", "\n", "1642\n", "\n", "boil (0.25139664804469275)\n", "\n", "\n", "\n", "1641->1642\n", "\n", "\n", "\n", "\n", "\n", "1643\n", "\n", "water (0)\n", "\n", "\n", "\n", "1642->1643\n", "\n", "\n", "\n", "\n", "\n", "1637\n", "\n", "noodle (0)\n", "\n", "\n", "\n", "1646->1637\n", "\n", "\n", "\n", "\n", "\n", "1639\n", "\n", "egg (0)\n", "\n", "\n", "\n", "1638->1639\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "2174\n", "\n", "mix (0.003508771929824561)\n", "\n", "\n", "\n", "2185\n", "\n", "place (0.01875)\n", "\n", "\n", "\n", "2174->2185\n", "\n", "\n", "\n", "\n", "\n", "2179\n", "\n", "bacon (0)\n", "\n", "\n", "\n", "2174->2179\n", "\n", "\n", "\n", "\n", "\n", "2175\n", "\n", "rinse (0.0)\n", "\n", "\n", "\n", "2174->2175\n", "\n", "\n", "\n", "\n", "\n", "2177\n", "\n", "slice (0.11458333333333333)\n", "\n", "\n", "\n", "2174->2177\n", "\n", "\n", "\n", "\n", "\n", "2182\n", "\n", "cook (0.36065573770491804)\n", "\n", "\n", "\n", "2174->2182\n", "\n", "\n", "\n", "\n", "\n", "2180\n", "\n", "boil (0.25139664804469275)\n", "\n", "\n", "\n", "2185->2180\n", "\n", "\n", "\n", "\n", "\n", "2181\n", "\n", "water (0)\n", "\n", "\n", "\n", "2180->2181\n", "\n", "\n", "\n", "\n", "\n", "2176\n", "\n", "egg (0)\n", "\n", "\n", "\n", "2175->2176\n", "\n", "\n", "\n", "\n", "\n", "2178\n", "\n", "mushroom (0)\n", "\n", "\n", "\n", "2177->2178\n", "\n", "\n", "\n", "\n", "\n", "2183\n", "\n", "noodle (0)\n", "\n", "\n", "\n", "2182->2183\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "1793\n", "\n", "cook (0.18731349573270611)\n", "\n", "\n", "\n", "1794\n", "\n", "mix (0.0022598870056497176)\n", "\n", "\n", "\n", "1793->1794\n", "\n", "\n", "\n", "\n", "\n", "1802\n", "\n", "noodle (0)\n", "\n", "\n", "\n", "1794->1802\n", "\n", "\n", "\n", "\n", "\n", "1796\n", "\n", "beat (0.33658536585365856)\n", "\n", "\n", "\n", "1794->1796\n", "\n", "\n", "\n", "\n", "\n", "1798\n", "\n", "bacon (0)\n", "\n", "\n", "\n", "1794->1798\n", "\n", "\n", "\n", "\n", "\n", "1795\n", "\n", "mushroom (0)\n", "\n", "\n", "\n", "1794->1795\n", "\n", "\n", "\n", "\n", "\n", "1800\n", "\n", "boil (0.25139664804469275)\n", "\n", "\n", "\n", "1794->1800\n", "\n", "\n", "\n", "\n", "\n", "1797\n", "\n", "egg (0)\n", "\n", "\n", "\n", "1796->1797\n", "\n", "\n", "\n", "\n", "\n", "1801\n", "\n", "water (0)\n", "\n", "\n", "\n", "1800->1801\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "2152\n", "\n", "mix (0.0)\n", "\n", "\n", "\n", "2153\n", "\n", "mushroom (0)\n", "\n", "\n", "\n", "2152->2153\n", "\n", "\n", "\n", "\n", "\n", "2155\n", "\n", "boil (0.25139664804469275)\n", "\n", "\n", "\n", "2152->2155\n", "\n", "\n", "\n", "\n", "\n", "2157\n", "\n", "cook (0.36065573770491804)\n", "\n", "\n", "\n", "2152->2157\n", "\n", "\n", "\n", "\n", "\n", "2159\n", "\n", "bacon (0)\n", "\n", "\n", "\n", "2152->2159\n", "\n", "\n", "\n", "\n", "\n", "2160\n", "\n", "rinse (0.0)\n", "\n", "\n", "\n", "2152->2160\n", "\n", "\n", "\n", "\n", "\n", "2156\n", "\n", "water (0)\n", "\n", "\n", "\n", "2155->2156\n", "\n", "\n", "\n", "\n", "\n", "2158\n", "\n", "noodle (0)\n", "\n", "\n", "\n", "2157->2158\n", "\n", "\n", "\n", "\n", "\n", "2161\n", "\n", "egg (0)\n", "\n", "\n", "\n", "2160->2161\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "2211\n", "\n", "mix (0.0)\n", "\n", "\n", "\n", "2207\n", "\n", "rinse (0.0)\n", "\n", "\n", "\n", "2211->2207\n", "\n", "\n", "\n", "\n", "\n", "2210\n", "\n", "soak (0.00318287037037037)\n", "\n", "\n", "\n", "2211->2210\n", "\n", "\n", "\n", "\n", "\n", "2208\n", "\n", "egg (0)\n", "\n", "\n", "\n", "2207->2208\n", "\n", "\n", "\n", "\n", "\n", "2212\n", "\n", "mix (0.0043859649122807015)\n", "\n", "\n", "\n", "2210->2212\n", "\n", "\n", "\n", "\n", "\n", "2206\n", "\n", "bacon (0)\n", "\n", "\n", "\n", "2212->2206\n", "\n", "\n", "\n", "\n", "\n", "2204\n", "\n", "cook (0.36065573770491804)\n", "\n", "\n", "\n", "2212->2204\n", "\n", "\n", "\n", "\n", "\n", "2201\n", "\n", "mushroom (0)\n", "\n", "\n", "\n", "2212->2201\n", "\n", "\n", "\n", "\n", "\n", "2202\n", "\n", "boil (0.25139664804469275)\n", "\n", "\n", "\n", "2212->2202\n", "\n", "\n", "\n", "\n", "\n", "2205\n", "\n", "noodle (0)\n", "\n", "\n", "\n", "2204->2205\n", "\n", "\n", "\n", "\n", "\n", "2203\n", "\n", "water (0)\n", "\n", "\n", "\n", "2202->2203\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "2289\n", "\n", "wash (0.00798913043478261)\n", "\n", "\n", "\n", "2290\n", "\n", "mix (0.0011299435028248588)\n", "\n", "\n", "\n", "2289->2290\n", "\n", "\n", "\n", "\n", "\n", "2295\n", "\n", "mushroom (0)\n", "\n", "\n", "\n", "2290->2295\n", "\n", "\n", "\n", "\n", "\n", "2291\n", "\n", "noodle (0)\n", "\n", "\n", "\n", "2290->2291\n", "\n", "\n", "\n", "\n", "\n", "2292\n", "\n", "beat (0.33658536585365856)\n", "\n", "\n", "\n", "2290->2292\n", "\n", "\n", "\n", "\n", "\n", "2294\n", "\n", "bacon (0)\n", "\n", "\n", "\n", "2290->2294\n", "\n", "\n", "\n", "\n", "\n", "2296\n", "\n", "boil (0.25139664804469275)\n", "\n", "\n", "\n", "2290->2296\n", "\n", "\n", "\n", "\n", "\n", "2293\n", "\n", "egg (0)\n", "\n", "\n", "\n", "2292->2293\n", "\n", "\n", "\n", "\n", "\n", "2297\n", "\n", "water (0)\n", "\n", "\n", "\n", "2296->2297\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "2264\n", "\n", "dice (0.004819277108433735)\n", "\n", "\n", "\n", "2275\n", "\n", "mix (0.0)\n", "\n", "\n", "\n", "2264->2275\n", "\n", "\n", "\n", "\n", "\n", "2272\n", "\n", "noodle (0)\n", "\n", "\n", "\n", "2275->2272\n", "\n", "\n", "\n", "\n", "\n", "2274\n", "\n", "whip (0.0024988004511549942)\n", "\n", "\n", "\n", "2275->2274\n", "\n", "\n", "\n", "\n", "\n", "2271\n", "\n", "bacon (0)\n", "\n", "\n", "\n", "2275->2271\n", "\n", "\n", "\n", "\n", "\n", "2276\n", "\n", "mix (0.005652167026979941)\n", "\n", "\n", "\n", "2274->2276\n", "\n", "\n", "\n", "\n", "\n", "2268\n", "\n", "beat (0.33658536585365856)\n", "\n", "\n", "\n", "2276->2268\n", "\n", "\n", "\n", "\n", "\n", "2270\n", "\n", "water (0)\n", "\n", "\n", "\n", "2276->2270\n", "\n", "\n", "\n", "\n", "\n", "2266\n", "\n", "cook (0.17708333333333334)\n", "\n", "\n", "\n", "2276->2266\n", "\n", "\n", "\n", "\n", "\n", "2269\n", "\n", "egg (0)\n", "\n", "\n", "\n", "2268->2269\n", "\n", "\n", "\n", "\n", "\n", "2267\n", "\n", "mushroom (0)\n", "\n", "\n", "\n", "2266->2267\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "2277\n", "\n", "mix (0.003508771929824561)\n", "\n", "\n", "\n", "2288\n", "\n", "slice (0.060240963855421686)\n", "\n", "\n", "\n", "2277->2288\n", "\n", "\n", "\n", "\n", "\n", "2283\n", "\n", "cook (0.36065573770491804)\n", "\n", "\n", "\n", "2277->2283\n", "\n", "\n", "\n", "\n", "\n", "2278\n", "\n", "mushroom (0)\n", "\n", "\n", "\n", "2277->2278\n", "\n", "\n", "\n", "\n", "\n", "2285\n", "\n", "beat (0.33658536585365856)\n", "\n", "\n", "\n", "2277->2285\n", "\n", "\n", "\n", "\n", "\n", "2280\n", "\n", "bake (0.03333333333333333)\n", "\n", "\n", "\n", "2277->2280\n", "\n", "\n", "\n", "\n", "\n", "2279\n", "\n", "bacon (0)\n", "\n", "\n", "\n", "2288->2279\n", "\n", "\n", "\n", "\n", "\n", "2284\n", "\n", "noodle (0)\n", "\n", "\n", "\n", "2283->2284\n", "\n", "\n", "\n", "\n", "\n", "2286\n", "\n", "egg (0)\n", "\n", "\n", "\n", "2285->2286\n", "\n", "\n", "\n", "\n", "\n", "2281\n", "\n", "boil (0.25139664804469275)\n", "\n", "\n", "\n", "2280->2281\n", "\n", "\n", "\n", "\n", "\n", "2282\n", "\n", "water (0)\n", "\n", "\n", "\n", "2281->2282\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "p.plot_population()" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [], "source": [ "t2 = Tree.from_serialization(t.serialize())" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [], "source": [ "t.mutate()" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.00499001996007984" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t.score()" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "43\n", "\n", "mix\n", "\n", "\n", "\n", "44\n", "\n", "chocolate\n", "\n", "\n", "\n", "43->44\n", "\n", "\n", "\n", "\n", "\n", "51\n", "\n", "beat\n", "\n", "\n", "\n", "43->51\n", "\n", "\n", "\n", "\n", "\n", "45\n", "\n", "sugar\n", "\n", "\n", "\n", "51->45\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t.root().dot()" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'pepper'" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(t.root().childs())[0]._name" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [], "source": [ "n = IngredientNode(\"test\")" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "n.traverse() == IngredientNode" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" } }, "nbformat": 4, "nbformat_minor": 4 }