{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Trees (Graphs)\n",
    "\n",
    "In this reading (<a href=\"lec-10-graphs.ipynb\">notebook version</a>), we'll learn about generally about *graphs*, and more specifically about a special kind of graph, the *tree*.\n",
    "\n",
    "By the end, you should be comfortable with the following terms:\n",
    "* graph\n",
    "* node\n",
    "* edge\n",
    "* metadata\n",
    "* path\n",
    "* connected, weakly connected, strongly connected\n",
    "* cycle\n",
    "* directed graph\n",
    "* parent/child\n",
    "* DAG (directed acyclic graph)\n",
    "* tree\n",
    "* root\n",
    "* leaf\n",
    "* binary tree\n",
    "\n",
    "## Setup\n",
    "\n",
    "To follow these examples, you'll need graphviz (https://www.graphviz.org/) installed on your VM.  The graphviz program is called `dot`.  SSH to your VM and try running it:\n",
    "\n",
    "```\n",
    "trh@instance-1:~$ dot -V\n",
    "\n",
    "Command 'dot' not found, but can be installed with:\n",
    "\n",
    "apt install graphviz\n",
    "Please ask your administrator.\n",
    "```\n",
    "\n",
    "We don't have it, but Ubuntu is helpfully telling us how to install it (with `apt ...`)!  We'll take their suggestion, but use `sudo` so we can install as root (the name for the admin user):\n",
    "\n",
    "```\n",
    "sudo apt install graphviz\n",
    "```\n",
    "\n",
    "You'll probably be prompted to type something like \"Y\" or \"yes\" to approve the install.\n",
    "\n",
    "Let's try again and confirm that we can see the installed version:\n",
    "\n",
    "```\n",
    "trh@instance-1:~$ dot -V\n",
    "dot - graphviz version 2.43.0 (0)\n",
    "```\n",
    "\n",
    "Great!  You'll also need to install the graphviz package for Python so that we can write code to generate graphs (instead of creating them manually).\n",
    "\n",
    "```\n",
    "pip3 install graphviz\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Examples of Graphs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* Git: https://www.oreilly.com/library/view/git-pocket-guide/9781449327507/ch01.html#fig0101\n",
    "* Political Allignment: https://www.reddit.com/r/dataisbeautiful/comments/1q7b3s/voting_relationships_between_senators_in_the/\n",
    "* Evolution: https://commons.wikimedia.org/wiki/File:The_Ancestors_Tale_Mammals_Phylogenetic_Tree_in_mya.png\n",
    "* Friendship: https://facebook.com/notes/facebook-engineering/visualizing-friendships/469716398919/\n",
    "* Accounting: https://wisc-ds-projects.github.io/f19/past/langston-ellen-zan.pdf#page=22\n",
    "* Transit: https://arxiv.org/pdf/1611.01890.pdf#page=14"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Nodes and Edges\n",
    "\n",
    "First let's import a couple things from graphviz.  Note that we'll only use graphviz for visualization -- we'll be creating our own classes to represent graphs efficiently."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from graphviz import Digraph, Graph"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Graphs have nodes and edges.  Here's a graph with just one *node* (also called a *vertex*):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: %3 Pages: 1 -->\n",
       "<svg width=\"62pt\" height=\"44pt\"\n",
       " viewBox=\"0.00 0.00 62.00 44.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 40)\">\n",
       "<title>%3</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-40 58,-40 58,4 -4,4\"/>\n",
       "<!-- A -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>A</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">A</text>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Graph at 0x7f7f34145790>"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g = Graph()\n",
    "g.node(\"A\")\n",
    "g"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In graphviz, nodes have names and labels.  If you pass one argument, they're the same.  Alternatively, lets make the name \"A\" and the label \"Madison\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: %3 Pages: 1 -->\n",
       "<svg width=\"108pt\" height=\"44pt\"\n",
       " viewBox=\"0.00 0.00 108.09 44.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 40)\">\n",
       "<title>%3</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-40 104.09,-40 104.09,4 -4,4\"/>\n",
       "<!-- A -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>A</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"50.05\" cy=\"-18\" rx=\"50.09\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"50.05\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">Madison</text>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Graph at 0x7f7f3404e460>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g = Graph()\n",
    "g.node(\"A\", \"Madison\")\n",
    "g"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Edges* connect nodes.  Let's create another node, and an edge to connect them:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: %3 Pages: 1 -->\n",
       "<svg width=\"108pt\" height=\"116pt\"\n",
       " viewBox=\"0.00 0.00 108.09 116.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 112)\">\n",
       "<title>%3</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-112 104.09,-112 104.09,4 -4,4\"/>\n",
       "<!-- A -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>A</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"50.05\" cy=\"-90\" rx=\"50.09\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"50.05\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">Madison</text>\n",
       "</g>\n",
       "<!-- B -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>B</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"50.05\" cy=\"-18\" rx=\"48.19\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"50.05\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">Chicago</text>\n",
       "</g>\n",
       "<!-- A&#45;&#45;B -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>A&#45;&#45;B</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M50.05,-71.7C50.05,-60.85 50.05,-46.92 50.05,-36.1\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Graph at 0x7f7f3404e460>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g.node(\"B\", \"Chicago\")\n",
    "g.edge(\"A\", \"B\")\n",
    "g"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Although not common, there's no rule against having multiple edges between the same two nodes, or having an edge connecting a node to itself:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: %3 Pages: 1 -->\n",
       "<svg width=\"126pt\" height=\"116pt\"\n",
       " viewBox=\"0.00 0.00 126.09 116.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 112)\">\n",
       "<title>%3</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-112 122.09,-112 122.09,4 -4,4\"/>\n",
       "<!-- A -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>A</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"50.05\" cy=\"-90\" rx=\"50.09\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"50.05\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">Madison</text>\n",
       "</g>\n",
       "<!-- A&#45;&#45;A -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>A&#45;&#45;A</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M84.71,-103.06C102.31,-104.97 118.09,-100.62 118.09,-90 118.09,-79.38 102.31,-75.03 84.71,-76.94\"/>\n",
       "</g>\n",
       "<!-- B -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>B</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"50.05\" cy=\"-18\" rx=\"48.19\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"50.05\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">Chicago</text>\n",
       "</g>\n",
       "<!-- A&#45;&#45;B -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>A&#45;&#45;B</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M44.17,-72.05C43.02,-61.21 43.01,-47.18 44.13,-36.28\"/>\n",
       "</g>\n",
       "<!-- A&#45;&#45;B -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>A&#45;&#45;B</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M55.92,-72.05C57.07,-61.21 57.09,-47.18 55.96,-36.28\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Graph at 0x7f7f3404e460>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g.edge(\"A\", \"B\")\n",
    "g.edge(\"A\", \"A\")\n",
    "g"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Can you think why you might want multiple edges between the two nodes?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: %3 Pages: 1 -->\n",
       "<svg width=\"178pt\" height=\"146pt\"\n",
       " viewBox=\"0.00 0.00 177.66 146.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 142)\">\n",
       "<title>%3</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-142 173.66,-142 173.66,4 -4,4\"/>\n",
       "<!-- A -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>A</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"55.66\" cy=\"-120\" rx=\"50.09\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"55.66\" y=\"-116.3\" font-family=\"Times,serif\" font-size=\"14.00\">Madison</text>\n",
       "</g>\n",
       "<!-- B -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>B</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"55.66\" cy=\"-18\" rx=\"48.19\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"55.66\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">Chicago</text>\n",
       "</g>\n",
       "<!-- A&#45;&#45;B -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>A&#45;&#45;B</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M25.89,-105.42C17.49,-100.02 9.36,-92.93 4.66,-84 -1.55,-72.2 -1.55,-65.8 4.66,-54 9.41,-44.97 17.66,-37.83 26.16,-32.41\"/>\n",
       "<text text-anchor=\"middle\" x=\"45.16\" y=\"-72.8\" font-family=\"Times,serif\" font-size=\"14.00\">time=2h40</text>\n",
       "<text text-anchor=\"middle\" x=\"45.16\" y=\"-57.8\" font-family=\"Times,serif\" font-size=\"14.00\">tolls=yes</text>\n",
       "</g>\n",
       "<!-- A&#45;&#45;B -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>A&#45;&#45;B</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M73.68,-102.81C78.51,-97.37 83.1,-90.91 85.66,-84 90.29,-71.49 90.29,-66.51 85.66,-54 83.05,-46.94 78.31,-40.35 73.36,-34.83\"/>\n",
       "<text text-anchor=\"middle\" x=\"129.16\" y=\"-72.8\" font-family=\"Times,serif\" font-size=\"14.00\">time=3h10</text>\n",
       "<text text-anchor=\"middle\" x=\"129.16\" y=\"-57.8\" font-family=\"Times,serif\" font-size=\"14.00\">tolls=no</text>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Graph at 0x7f7f257c6430>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g = Graph()\n",
    "g.node(\"A\", \"Madison\")\n",
    "g.node(\"B\", \"Chicago\")\n",
    "g.edge(\"A\", \"B\", label=\"time=2h40\\ntolls=yes\")\n",
    "g.edge(\"A\", \"B\", label=\"time=3h10\\ntolls=no\", badparam=\"no error here!\")\n",
    "g"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Be careful!  Note above that passing to params that don't exist does not produce an error in graphviz -- it's just ignored.\n",
    "\n",
    "You can read about what params are supported here: https://www.graphviz.org/doc/info/attrs.html\n",
    "\n",
    "By each parameter, the \"Used By\" column tells us what features of the graph support that attribute.  The main ones to watch for are \"E\" for \"edge\" and \"N\" for \"node\".  For example:\n",
    "\n",
    "|Name|Used By|Type|Default|Minimum|Notes|\n",
    "|---|---|---|---|---|---|\n",
    "|color|ENC|color |colorList|black|\n",
    "    \n",
    "This tells us that both edges and nodes accept the color parameter.\n",
    "\n",
    "The other weird thing is that all arguments must be strings, even numeric data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: %3 Pages: 1 -->\n",
       "<svg width=\"178pt\" height=\"146pt\"\n",
       " viewBox=\"0.00 0.00 177.66 146.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 142)\">\n",
       "<title>%3</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-142 173.66,-142 173.66,4 -4,4\"/>\n",
       "<!-- A -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>A</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"55.66\" cy=\"-120\" rx=\"50.09\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"55.66\" y=\"-116.3\" font-family=\"Times,serif\" font-size=\"14.00\">Madison</text>\n",
       "</g>\n",
       "<!-- B -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>B</title>\n",
       "<ellipse fill=\"none\" stroke=\"gray\" cx=\"55.66\" cy=\"-18\" rx=\"48.19\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"55.66\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">Chicago</text>\n",
       "</g>\n",
       "<!-- A&#45;&#45;B -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>A&#45;&#45;B</title>\n",
       "<path fill=\"none\" stroke=\"red\" d=\"M25.89,-105.42C17.49,-100.02 9.36,-92.93 4.66,-84 -1.55,-72.2 -1.55,-65.8 4.66,-54 9.41,-44.97 17.66,-37.83 26.16,-32.41\"/>\n",
       "<text text-anchor=\"middle\" x=\"45.16\" y=\"-72.8\" font-family=\"Times,serif\" font-size=\"14.00\">time=2h40</text>\n",
       "<text text-anchor=\"middle\" x=\"45.16\" y=\"-57.8\" font-family=\"Times,serif\" font-size=\"14.00\">tolls=yes</text>\n",
       "</g>\n",
       "<!-- A&#45;&#45;B -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>A&#45;&#45;B</title>\n",
       "<path fill=\"none\" stroke=\"black\" stroke-width=\"3\" d=\"M73.68,-102.81C78.51,-97.37 83.1,-90.91 85.66,-84 90.29,-71.49 90.29,-66.51 85.66,-54 83.05,-46.94 78.31,-40.35 73.36,-34.83\"/>\n",
       "<text text-anchor=\"middle\" x=\"129.16\" y=\"-72.8\" font-family=\"Times,serif\" font-size=\"14.00\">time=3h10</text>\n",
       "<text text-anchor=\"middle\" x=\"129.16\" y=\"-57.8\" font-family=\"Times,serif\" font-size=\"14.00\">tolls=no</text>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Graph at 0x7f7f257c62e0>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g = Graph()\n",
    "g.node(\"A\", \"Madison\")\n",
    "g.node(\"B\", \"Chicago\", color=\"gray\")\n",
    "g.edge(\"A\", \"B\", label=\"time=2h40\\ntolls=yes\", color=\"red\")\n",
    "g.edge(\"A\", \"B\", label=\"time=3h10\\ntolls=no\", penwidth=\"3\")\n",
    "g"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Whether it affects the visual display or not, there is often a lot of *metadata* associated with nodes and edges.  For example, consider the friendship (an edge) between you and another person (two nodes).\n",
    "\n",
    "Node metadata: name, birthdate, SSN, address, phone, ...\n",
    "\n",
    "Edge metadata: when you became friends, messages exchanged, the type of relationship (work, social, etc)\n",
    "\n",
    "The variety of metadata that might be needed is one reason to build your own graphs."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Paths\n",
    "\n",
    "A sequence of edges to get from one node to another is called a *path*.  For example, B->A->E is one path (but not the only one) for getting from B to E."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: %3 Pages: 1 -->\n",
       "<svg width=\"89pt\" height=\"332pt\"\n",
       " viewBox=\"0.00 0.00 89.00 332.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 328)\">\n",
       "<title>%3</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-328 85,-328 85,4 -4,4\"/>\n",
       "<!-- A -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>A</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"54\" cy=\"-306\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"54\" y=\"-302.3\" font-family=\"Times,serif\" font-size=\"14.00\">A</text>\n",
       "</g>\n",
       "<!-- B -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>B</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-234\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-230.3\" font-family=\"Times,serif\" font-size=\"14.00\">B</text>\n",
       "</g>\n",
       "<!-- A&#45;&#45;B -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>A&#45;&#45;B</title>\n",
       "<path fill=\"none\" stroke=\"red\" stroke-width=\"3\" d=\"M47.6,-288.41C43.36,-277.41 37.81,-263.03 33.54,-251.96\"/>\n",
       "</g>\n",
       "<!-- C -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>C</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">C</text>\n",
       "</g>\n",
       "<!-- B&#45;&#45;C -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>B&#45;&#45;C</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M27,-215.7C27,-204.85 27,-190.92 27,-180.1\"/>\n",
       "</g>\n",
       "<!-- D -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>D</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">D</text>\n",
       "</g>\n",
       "<!-- C&#45;&#45;D -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>C&#45;&#45;D</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M27,-143.7C27,-132.85 27,-118.92 27,-108.1\"/>\n",
       "</g>\n",
       "<!-- E -->\n",
       "<g id=\"node5\" class=\"node\">\n",
       "<title>E</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"54\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"54\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">E</text>\n",
       "</g>\n",
       "<!-- D&#45;&#45;E -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>D&#45;&#45;E</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M33.4,-72.41C37.64,-61.41 43.19,-47.03 47.46,-35.96\"/>\n",
       "</g>\n",
       "<!-- E&#45;&#45;A -->\n",
       "<g id=\"edge5\" class=\"edge\">\n",
       "<title>E&#45;&#45;A</title>\n",
       "<path fill=\"none\" stroke=\"red\" stroke-width=\"3\" d=\"M57.65,-36.09C59.68,-46.43 61.98,-59.91 63,-72 69.72,-151.72 69.72,-172.28 63,-252 61.98,-264.09 59.68,-277.57 57.65,-287.91\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Graph at 0x7f7f257cf0a0>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g = Graph()\n",
    "g.node(\"A\")\n",
    "g.node(\"B\")\n",
    "g.node(\"C\")\n",
    "g.node(\"D\")\n",
    "g.node(\"E\")\n",
    "g.edge(\"A\", \"B\", color=\"red\", penwidth=\"3\")\n",
    "g.edge(\"B\", \"C\")\n",
    "g.edge(\"C\", \"D\")\n",
    "g.edge(\"D\", \"E\")\n",
    "g.edge(\"E\", \"A\", color=\"red\", penwidth=\"3\")\n",
    "g"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The above is an example of a *connected* graph -- there's a path between each pair of nodes.  Not all graphs are connected.  E.g., consider the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: %3 Pages: 1 -->\n",
       "<svg width=\"174pt\" height=\"188pt\"\n",
       " viewBox=\"0.00 0.00 174.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\n",
       "<title>%3</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-184 170,-184 170,4 -4,4\"/>\n",
       "<!-- A -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>A</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">A</text>\n",
       "</g>\n",
       "<!-- B -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>B</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">B</text>\n",
       "</g>\n",
       "<!-- A&#45;&#45;B -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>A&#45;&#45;B</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M27,-143.7C27,-132.85 27,-118.92 27,-108.1\"/>\n",
       "</g>\n",
       "<!-- C -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>C</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"126\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"126\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">C</text>\n",
       "</g>\n",
       "<!-- D -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>D</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"112\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"112\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">D</text>\n",
       "</g>\n",
       "<!-- C&#45;&#45;D -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>C&#45;&#45;D</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M122.61,-144.05C120.44,-133.21 117.64,-119.18 115.46,-108.28\"/>\n",
       "</g>\n",
       "<!-- E -->\n",
       "<g id=\"node5\" class=\"node\">\n",
       "<title>E</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"139\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"139\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">E</text>\n",
       "</g>\n",
       "<!-- D&#45;&#45;E -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>D&#45;&#45;E</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M118.4,-72.41C122.64,-61.41 128.19,-47.03 132.46,-35.96\"/>\n",
       "</g>\n",
       "<!-- E&#45;&#45;C -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>E&#45;&#45;C</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M143.66,-35.87C147.95,-53.88 152.95,-83.17 148,-108 145.43,-120.9 139.66,-134.59 134.68,-144.82\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Graph at 0x7f7f3404edf0>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g = Graph()\n",
    "g.node(\"A\")\n",
    "g.node(\"B\")\n",
    "g.node(\"C\")\n",
    "g.node(\"D\")\n",
    "g.node(\"E\")\n",
    "g.edge(\"A\", \"B\")\n",
    "g.edge(\"C\", \"D\")\n",
    "g.edge(\"D\", \"E\")\n",
    "g.edge(\"E\", \"C\")\n",
    "g"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Take a look at https://en.wikipedia.org/wiki/Path_(graph_theory) to see other ways paths (and similar structures) are commonly defined.\n",
    "\n",
    "A *cycle* is a path that forms a loop back to the original node (without reusing the same edges).  The red path is cycle:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: %3 Pages: 1 -->\n",
       "<svg width=\"174pt\" height=\"188pt\"\n",
       " viewBox=\"0.00 0.00 174.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\n",
       "<title>%3</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-184 170,-184 170,4 -4,4\"/>\n",
       "<!-- A -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>A</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">A</text>\n",
       "</g>\n",
       "<!-- B -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>B</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">B</text>\n",
       "</g>\n",
       "<!-- A&#45;&#45;B -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>A&#45;&#45;B</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M27,-143.7C27,-132.85 27,-118.92 27,-108.1\"/>\n",
       "</g>\n",
       "<!-- C -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>C</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"126\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"126\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">C</text>\n",
       "</g>\n",
       "<!-- D -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>D</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"112\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"112\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">D</text>\n",
       "</g>\n",
       "<!-- C&#45;&#45;D -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>C&#45;&#45;D</title>\n",
       "<path fill=\"none\" stroke=\"red\" stroke-width=\"3\" d=\"M122.61,-144.05C120.44,-133.21 117.64,-119.18 115.46,-108.28\"/>\n",
       "</g>\n",
       "<!-- E -->\n",
       "<g id=\"node5\" class=\"node\">\n",
       "<title>E</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"139\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"139\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">E</text>\n",
       "</g>\n",
       "<!-- D&#45;&#45;E -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>D&#45;&#45;E</title>\n",
       "<path fill=\"none\" stroke=\"red\" stroke-width=\"3\" d=\"M118.4,-72.41C122.64,-61.41 128.19,-47.03 132.46,-35.96\"/>\n",
       "</g>\n",
       "<!-- E&#45;&#45;C -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>E&#45;&#45;C</title>\n",
       "<path fill=\"none\" stroke=\"red\" stroke-width=\"3\" d=\"M143.66,-35.87C147.95,-53.88 152.95,-83.17 148,-108 145.43,-120.9 139.66,-134.59 134.68,-144.82\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Graph at 0x7f7f3404e490>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g = Graph()\n",
    "g.node(\"A\")\n",
    "g.node(\"B\")\n",
    "g.node(\"C\")\n",
    "g.node(\"D\")\n",
    "g.node(\"E\")\n",
    "g.edge(\"A\", \"B\")\n",
    "g.edge(\"C\", \"D\", color=\"red\", penwidth=\"3\")\n",
    "g.edge(\"D\", \"E\", color=\"red\", penwidth=\"3\")\n",
    "g.edge(\"E\", \"C\", color=\"red\", penwidth=\"3\")\n",
    "g"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Directed Graphs\n",
    "\n",
    "*Directed graphs* have special edges with a direction.  For example, imagine nodes are street intersections.  Some intersections are connected by one-way streets.  We can create directed graphs with `Digraph`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: %3 Pages: 1 -->\n",
       "<svg width=\"174pt\" height=\"188pt\"\n",
       " viewBox=\"0.00 0.00 174.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\n",
       "<title>%3</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-184 170,-184 170,4 -4,4\"/>\n",
       "<!-- A -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>A</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">A</text>\n",
       "</g>\n",
       "<!-- B -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>B</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">B</text>\n",
       "</g>\n",
       "<!-- A&#45;&gt;B -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>A&#45;&gt;B</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M27,-143.7C27,-135.98 27,-126.71 27,-118.11\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"30.5,-118.1 27,-108.1 23.5,-118.1 30.5,-118.1\"/>\n",
       "</g>\n",
       "<!-- C -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>C</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"126\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"126\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">C</text>\n",
       "</g>\n",
       "<!-- D -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>D</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"112\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"112\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">D</text>\n",
       "</g>\n",
       "<!-- C&#45;&gt;D -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>C&#45;&gt;D</title>\n",
       "<path fill=\"none\" stroke=\"red\" stroke-width=\"3\" d=\"M122.61,-144.05C121.07,-136.35 119.21,-127.03 117.47,-118.36\"/>\n",
       "<polygon fill=\"red\" stroke=\"red\" stroke-width=\"3\" points=\"120.85,-117.39 115.46,-108.28 113.98,-118.77 120.85,-117.39\"/>\n",
       "</g>\n",
       "<!-- E -->\n",
       "<g id=\"node5\" class=\"node\">\n",
       "<title>E</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"139\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"139\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">E</text>\n",
       "</g>\n",
       "<!-- D&#45;&gt;E -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>D&#45;&gt;E</title>\n",
       "<path fill=\"none\" stroke=\"red\" stroke-width=\"3\" d=\"M118.4,-72.41C121.51,-64.34 125.33,-54.43 128.83,-45.35\"/>\n",
       "<polygon fill=\"red\" stroke=\"red\" stroke-width=\"3\" points=\"132.13,-46.55 132.46,-35.96 125.6,-44.03 132.13,-46.55\"/>\n",
       "</g>\n",
       "<!-- E&#45;&gt;C -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>E&#45;&gt;C</title>\n",
       "<path fill=\"none\" stroke=\"red\" stroke-width=\"3\" d=\"M143.66,-35.87C147.95,-53.88 152.95,-83.17 148,-108 146.13,-117.37 142.58,-127.16 138.86,-135.74\"/>\n",
       "<polygon fill=\"red\" stroke=\"red\" stroke-width=\"3\" points=\"135.68,-134.27 134.68,-144.82 142.04,-137.2 135.68,-134.27\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Digraph at 0x7f7f257cf3d0>"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g = Digraph() # only line changed from last example!\n",
    "g.node(\"A\")\n",
    "g.node(\"B\")\n",
    "g.node(\"C\")\n",
    "g.node(\"D\")\n",
    "g.node(\"E\")\n",
    "g.edge(\"A\", \"B\")\n",
    "g.edge(\"C\", \"D\", color=\"red\", penwidth=\"3\")\n",
    "g.edge(\"D\", \"E\", color=\"red\", penwidth=\"3\")\n",
    "g.edge(\"E\", \"C\", color=\"red\", penwidth=\"3\")\n",
    "g"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The above still has a cycle, but the following is not a cycle, given the direction of the arrows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: %3 Pages: 1 -->\n",
       "<svg width=\"174pt\" height=\"188pt\"\n",
       " viewBox=\"0.00 0.00 174.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\n",
       "<title>%3</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-184 170,-184 170,4 -4,4\"/>\n",
       "<!-- A -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>A</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">A</text>\n",
       "</g>\n",
       "<!-- B -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>B</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">B</text>\n",
       "</g>\n",
       "<!-- A&#45;&gt;B -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>A&#45;&gt;B</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M27,-143.7C27,-135.98 27,-126.71 27,-118.11\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"30.5,-118.1 27,-108.1 23.5,-118.1 30.5,-118.1\"/>\n",
       "</g>\n",
       "<!-- C -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>C</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"126\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"126\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">C</text>\n",
       "</g>\n",
       "<!-- D -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>D</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"112\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"112\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">D</text>\n",
       "</g>\n",
       "<!-- C&#45;&gt;D -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>C&#45;&gt;D</title>\n",
       "<path fill=\"none\" stroke=\"red\" stroke-width=\"3\" d=\"M122.61,-144.05C121.07,-136.35 119.21,-127.03 117.47,-118.36\"/>\n",
       "<polygon fill=\"red\" stroke=\"red\" stroke-width=\"3\" points=\"120.85,-117.39 115.46,-108.28 113.98,-118.77 120.85,-117.39\"/>\n",
       "</g>\n",
       "<!-- E -->\n",
       "<g id=\"node5\" class=\"node\">\n",
       "<title>E</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"139\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"139\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">E</text>\n",
       "</g>\n",
       "<!-- C&#45;&gt;E -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>C&#45;&gt;E</title>\n",
       "<path fill=\"none\" stroke=\"red\" stroke-width=\"3\" d=\"M134.68,-144.82C139.66,-134.59 145.43,-120.9 148,-108 152.12,-87.34 149.35,-63.6 145.83,-45.83\"/>\n",
       "<polygon fill=\"red\" stroke=\"red\" stroke-width=\"3\" points=\"149.21,-44.9 143.66,-35.87 142.37,-46.39 149.21,-44.9\"/>\n",
       "</g>\n",
       "<!-- D&#45;&gt;E -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>D&#45;&gt;E</title>\n",
       "<path fill=\"none\" stroke=\"red\" stroke-width=\"3\" d=\"M118.4,-72.41C121.51,-64.34 125.33,-54.43 128.83,-45.35\"/>\n",
       "<polygon fill=\"red\" stroke=\"red\" stroke-width=\"3\" points=\"132.13,-46.55 132.46,-35.96 125.6,-44.03 132.13,-46.55\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Digraph at 0x7f7f257cf460>"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g = Digraph()\n",
    "g.node(\"A\")\n",
    "g.node(\"B\")\n",
    "g.node(\"C\")\n",
    "g.node(\"D\")\n",
    "g.node(\"E\")\n",
    "g.edge(\"A\", \"B\")\n",
    "g.edge(\"C\", \"D\", color=\"red\", penwidth=\"3\")\n",
    "g.edge(\"D\", \"E\", color=\"red\", penwidth=\"3\")\n",
    "g.edge(\"C\", \"E\", color=\"red\", penwidth=\"3\") # only change: flip C and E\n",
    "g"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With directed graphs, we often use parent/child terminology.\n",
    "\n",
    "For example, node C has two children: D and E.\n",
    "\n",
    "E has two parents: C and D."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Is the following graph connected?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: %3 Pages: 1 -->\n",
       "<svg width=\"89pt\" height=\"188pt\"\n",
       " viewBox=\"0.00 0.00 89.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\n",
       "<title>%3</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-184 85,-184 85,4 -4,4\"/>\n",
       "<!-- A -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>A</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"54\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"54\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">A</text>\n",
       "</g>\n",
       "<!-- B -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>B</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">B</text>\n",
       "</g>\n",
       "<!-- A&#45;&gt;B -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>A&#45;&gt;B</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M47.6,-144.41C44.49,-136.34 40.67,-126.43 37.17,-117.35\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"40.4,-116.03 33.54,-107.96 33.87,-118.55 40.4,-116.03\"/>\n",
       "</g>\n",
       "<!-- C -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>C</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"54\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"54\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">C</text>\n",
       "</g>\n",
       "<!-- A&#45;&gt;C -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>A&#45;&gt;C</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M57.65,-143.91C59.68,-133.57 61.98,-120.09 63,-108 64.34,-92.06 64.34,-87.94 63,-72 62.28,-63.5 60.93,-54.31 59.49,-46.01\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"62.91,-45.29 57.65,-36.09 56.03,-46.56 62.91,-45.29\"/>\n",
       "</g>\n",
       "<!-- B&#45;&gt;C -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>B&#45;&gt;C</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M33.4,-72.41C36.51,-64.34 40.33,-54.43 43.83,-45.35\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"47.13,-46.55 47.46,-35.96 40.6,-44.03 47.13,-46.55\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Digraph at 0x7f7f257c65e0>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g = Digraph()\n",
    "g.edge(\"A\", \"B\")\n",
    "g.edge(\"A\", \"C\")\n",
    "g.edge(\"B\", \"C\")\n",
    "g"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Sort of.  We need to be able to reach any node from any other node.  Can we reach A from C?  No, if we respect the direction of the edges, but yet if we're willing to drive the wrong way on a one-way street.  So with directed graphs, we'll have two definitions of connected:\n",
    "\n",
    "* *strongly directed*: there's a path between any two nodes, **respecting** direction of edges\n",
    "* *weakly directed*: there's a path between any two nodes, **ignoring** direction of edges\n",
    "\n",
    "So the above graph is weakly connected but not strongly connected.  If we just use the term \"connected\" for a directed graph, we mean \"strongly connected\"."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Directed Acyclic Graphs\n",
    "\n",
    "DAGs are directed graphs without cycles in them.  The directed graph show above is a DAG because it doesn't have any cycles.\n",
    "\n",
    "DAGs show up all the time in practice!  Which of the following are examples of DAGs?\n",
    "\n",
    "1. a network of mutual friends\n",
    "2. git commits\n",
    "3. a Python class hierarchy\n",
    "4. a network of streets in a City\n",
    "\n",
    "<details>\n",
    "<summary>Answers</summary>\n",
    "Only (2) and (3) are DAGs\n",
    "</details>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Trees\n",
    "\n",
    "*Directed graphs* are a kind of *graph*\n",
    "\n",
    "*DAGs* are a kind of *directed graph*.\n",
    "\n",
    "*Trees* are a kind of *DAG*.\n",
    "\n",
    "Trees have these additional restrictions beyond what DAGs require:\n",
    "* they have exactly one node with no parents, called the *root*\n",
    "* any additional nodes have exactly one parent\n",
    "\n",
    "Here's an example of a tree:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: %3 Pages: 1 -->\n",
       "<svg width=\"278pt\" height=\"332pt\"\n",
       " viewBox=\"0.00 0.00 278.00 332.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 328)\">\n",
       "<title>%3</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-328 274,-328 274,4 -4,4\"/>\n",
       "<!-- B -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>B</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"171\" cy=\"-306\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"171\" y=\"-302.3\" font-family=\"Times,serif\" font-size=\"14.00\">B</text>\n",
       "</g>\n",
       "<!-- A -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>A</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"117\" cy=\"-234\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"117\" y=\"-230.3\" font-family=\"Times,serif\" font-size=\"14.00\">A</text>\n",
       "</g>\n",
       "<!-- B&#45;&gt;A -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>B&#45;&gt;A</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M159.02,-289.46C152.02,-280.4 143.06,-268.79 135.21,-258.61\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"137.83,-256.27 128.95,-250.49 132.29,-260.55 137.83,-256.27\"/>\n",
       "</g>\n",
       "<!-- C -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>C</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"225\" cy=\"-234\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"225\" y=\"-230.3\" font-family=\"Times,serif\" font-size=\"14.00\">C</text>\n",
       "</g>\n",
       "<!-- B&#45;&gt;C -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>B&#45;&gt;C</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M182.98,-289.46C189.98,-280.4 198.94,-268.79 206.79,-258.61\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"209.71,-260.55 213.05,-250.49 204.17,-256.27 209.71,-260.55\"/>\n",
       "</g>\n",
       "<!-- F -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>F</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">F</text>\n",
       "</g>\n",
       "<!-- A&#45;&gt;F -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>A&#45;&gt;F</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M100.07,-219.83C86.5,-209.27 67.24,-194.3 51.91,-182.37\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"53.89,-179.48 43.85,-176.11 49.6,-185.01 53.89,-179.48\"/>\n",
       "</g>\n",
       "<!-- G -->\n",
       "<g id=\"node5\" class=\"node\">\n",
       "<title>G</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"99\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"99\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">G</text>\n",
       "</g>\n",
       "<!-- A&#45;&gt;G -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>A&#45;&gt;G</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M112.64,-216.05C110.61,-208.14 108.14,-198.54 105.86,-189.69\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"109.2,-188.6 103.32,-179.79 102.42,-190.35 109.2,-188.6\"/>\n",
       "</g>\n",
       "<!-- H -->\n",
       "<g id=\"node6\" class=\"node\">\n",
       "<title>H</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"171\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"171\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">H</text>\n",
       "</g>\n",
       "<!-- A&#45;&gt;H -->\n",
       "<g id=\"edge5\" class=\"edge\">\n",
       "<title>A&#45;&gt;H</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M128.98,-217.46C135.98,-208.4 144.94,-196.79 152.79,-186.61\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"155.71,-188.55 159.05,-178.49 150.17,-184.27 155.71,-188.55\"/>\n",
       "</g>\n",
       "<!-- I -->\n",
       "<g id=\"node7\" class=\"node\">\n",
       "<title>I</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"243\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"243\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">I</text>\n",
       "</g>\n",
       "<!-- C&#45;&gt;I -->\n",
       "<g id=\"edge6\" class=\"edge\">\n",
       "<title>C&#45;&gt;I</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M229.36,-216.05C231.39,-208.14 233.86,-198.54 236.14,-189.69\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"239.58,-190.35 238.68,-179.79 232.8,-188.6 239.58,-190.35\"/>\n",
       "</g>\n",
       "<!-- J -->\n",
       "<g id=\"node8\" class=\"node\">\n",
       "<title>J</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"243\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"243\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">J</text>\n",
       "</g>\n",
       "<!-- I&#45;&gt;J -->\n",
       "<g id=\"edge7\" class=\"edge\">\n",
       "<title>I&#45;&gt;J</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M243,-143.7C243,-135.98 243,-126.71 243,-118.11\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"246.5,-118.1 243,-108.1 239.5,-118.1 246.5,-118.1\"/>\n",
       "</g>\n",
       "<!-- K -->\n",
       "<g id=\"node9\" class=\"node\">\n",
       "<title>K</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"243\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"243\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">K</text>\n",
       "</g>\n",
       "<!-- J&#45;&gt;K -->\n",
       "<g id=\"edge8\" class=\"edge\">\n",
       "<title>J&#45;&gt;K</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M243,-71.7C243,-63.98 243,-54.71 243,-46.11\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"246.5,-46.1 243,-36.1 239.5,-46.1 246.5,-46.1\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Digraph at 0x7f7f257cf2b0>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g = Digraph()\n",
    "g.edge(\"B\", \"A\")\n",
    "g.edge(\"B\", \"C\")\n",
    "g.edge(\"A\", \"F\")\n",
    "g.edge(\"A\", \"G\")\n",
    "g.edge(\"A\", \"H\")\n",
    "g.edge(\"C\", \"I\")\n",
    "g.edge(\"I\", \"J\")\n",
    "g.edge(\"J\", \"K\")\n",
    "g"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Which node is the root in the above tree?\n",
    "\n",
    "<details>\n",
    "<summary>Answer</summary>\n",
    "B\n",
    "</details>\n",
    "\n",
    "A leaf is a node with no children.  What are the leaves in the above graph?\n",
    "\n",
    "<details>\n",
    "<summary>Answer</summary>\n",
    "F, G, H, K\n",
    "</details>\n",
    "\n",
    "**Note:** you might encounter different definitions of \"root\" in different classes.  In CS 320, we define it as any node that has no parents.  By this definition, some graphs (not trees) may have multiple roots.\n",
    "\n",
    "Consider your files, organized as a graph:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: %3 Pages: 1 -->\n",
       "<svg width=\"440pt\" height=\"332pt\"\n",
       " viewBox=\"0.00 0.00 440.29 332.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 328)\">\n",
       "<title>%3</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-328 436.29,-328 436.29,4 -4,4\"/>\n",
       "<!-- Users -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>Users</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"188.39\" cy=\"-306\" rx=\"38.19\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"188.39\" y=\"-302.3\" font-family=\"Times,serif\" font-size=\"14.00\">Users</text>\n",
       "</g>\n",
       "<!-- Tyler -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>Tyler</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"188.39\" cy=\"-234\" rx=\"34.39\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"188.39\" y=\"-230.3\" font-family=\"Times,serif\" font-size=\"14.00\">Tyler</text>\n",
       "</g>\n",
       "<!-- Users&#45;&gt;Tyler -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>Users&#45;&gt;Tyler</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M188.39,-287.7C188.39,-279.98 188.39,-270.71 188.39,-262.11\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"191.89,-262.1 188.39,-252.1 184.89,-262.1 191.89,-262.1\"/>\n",
       "</g>\n",
       "<!-- cs220 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>cs220</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"141.39\" cy=\"-162\" rx=\"38.19\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"141.39\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">cs220</text>\n",
       "</g>\n",
       "<!-- Tyler&#45;&gt;cs220 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>Tyler&#45;&gt;cs220</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M177.49,-216.76C171.76,-208.23 164.61,-197.58 158.19,-188.02\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"161.04,-185.98 152.56,-179.63 155.23,-189.89 161.04,-185.98\"/>\n",
       "</g>\n",
       "<!-- cs320 -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>cs320</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"236.39\" cy=\"-162\" rx=\"38.19\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"236.39\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">cs320</text>\n",
       "</g>\n",
       "<!-- Tyler&#45;&gt;cs320 -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>Tyler&#45;&gt;cs320</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M199.53,-216.76C205.38,-208.23 212.68,-197.58 219.24,-188.02\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"222.22,-189.86 224.99,-179.63 216.45,-185.9 222.22,-189.86\"/>\n",
       "</g>\n",
       "<!-- P1 -->\n",
       "<g id=\"node5\" class=\"node\">\n",
       "<title>P1</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"185.39\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"185.39\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">P1</text>\n",
       "</g>\n",
       "<!-- cs320&#45;&gt;P1 -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>cs320&#45;&gt;P1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M224.57,-144.76C218.1,-135.89 209.98,-124.74 202.8,-114.89\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"205.53,-112.69 196.81,-106.67 199.87,-116.81 205.53,-112.69\"/>\n",
       "</g>\n",
       "<!-- P2 -->\n",
       "<g id=\"node6\" class=\"node\">\n",
       "<title>P2</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"287.39\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"287.39\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">P2</text>\n",
       "</g>\n",
       "<!-- cs320&#45;&gt;P2 -->\n",
       "<g id=\"edge5\" class=\"edge\">\n",
       "<title>cs320&#45;&gt;P2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M248.22,-144.76C254.69,-135.89 262.81,-124.74 269.99,-114.89\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"272.92,-116.81 275.98,-106.67 267.26,-112.69 272.92,-116.81\"/>\n",
       "</g>\n",
       "<!-- main.ipynb -->\n",
       "<g id=\"node7\" class=\"node\">\n",
       "<title>main.ipynb</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"62.39\" cy=\"-18\" rx=\"62.29\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"62.39\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">main.ipynb</text>\n",
       "</g>\n",
       "<!-- P1&#45;&gt;main.ipynb -->\n",
       "<g id=\"edge6\" class=\"edge\">\n",
       "<title>P1&#45;&gt;main.ipynb</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M165.36,-77.6C147.17,-67.25 119.93,-51.74 98.03,-39.28\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"99.74,-36.23 89.32,-34.32 96.28,-42.31 99.74,-36.23\"/>\n",
       "</g>\n",
       "<!-- p1&#45;test -->\n",
       "<g id=\"node9\" class=\"node\">\n",
       "<title>p1&#45;test</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"185.39\" cy=\"-18\" rx=\"42.79\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"185.39\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">test.py</text>\n",
       "</g>\n",
       "<!-- P1&#45;&gt;p1&#45;test -->\n",
       "<g id=\"edge8\" class=\"edge\">\n",
       "<title>P1&#45;&gt;p1&#45;test</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M185.39,-71.7C185.39,-63.98 185.39,-54.71 185.39,-46.11\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"188.89,-46.1 185.39,-36.1 181.89,-46.1 188.89,-46.1\"/>\n",
       "</g>\n",
       "<!-- bus.py -->\n",
       "<g id=\"node8\" class=\"node\">\n",
       "<title>bus.py</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"287.39\" cy=\"-18\" rx=\"41.69\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"287.39\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">bus.py</text>\n",
       "</g>\n",
       "<!-- P2&#45;&gt;bus.py -->\n",
       "<g id=\"edge7\" class=\"edge\">\n",
       "<title>P2&#45;&gt;bus.py</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M287.39,-71.7C287.39,-63.98 287.39,-54.71 287.39,-46.11\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"290.89,-46.1 287.39,-36.1 283.89,-46.1 290.89,-46.1\"/>\n",
       "</g>\n",
       "<!-- p2&#45;test -->\n",
       "<g id=\"node10\" class=\"node\">\n",
       "<title>p2&#45;test</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"389.39\" cy=\"-18\" rx=\"42.79\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"389.39\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">test.py</text>\n",
       "</g>\n",
       "<!-- P2&#45;&gt;p2&#45;test -->\n",
       "<g id=\"edge9\" class=\"edge\">\n",
       "<title>P2&#45;&gt;p2&#45;test</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M305.63,-76.49C320.46,-66.31 341.71,-51.72 359.09,-39.79\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"361.51,-42.38 367.78,-33.83 357.55,-36.61 361.51,-42.38\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Digraph at 0x7f7f257cfbb0>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g = Digraph()\n",
    "g.edge(\"Users\", \"Tyler\")\n",
    "g.edge(\"Tyler\", \"cs220\")\n",
    "g.edge(\"Tyler\", \"cs320\")\n",
    "g.edge(\"cs320\", \"P1\")\n",
    "g.edge(\"cs320\", \"P2\")\n",
    "g.edge(\"P1\", \"main.ipynb\")\n",
    "g.edge(\"P2\", \"bus.py\")\n",
    "\n",
    "g.node(\"p1-test\", \"test.py\")\n",
    "g.node(\"p2-test\", \"test.py\")\n",
    "g.edge(\"P1\", \"p1-test\")\n",
    "g.edge(\"P2\", \"p2-test\")\n",
    "g"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The above is an example of a(n):\n",
    "1. graph\n",
    "2. DAG\n",
    "3. tree\n",
    "4. all of the above!\n",
    "\n",
    "<details>\n",
    "<summary>Answer</summary>\n",
    "(4) All of the above!  It satisfies all the requirements for being a tree.  Furthemore, a tree is a kind of DAG, and a DAG is a kind of graph.\n",
    "</details>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Tree Example\n",
    "\n",
    "Before we implemented a tree, review the LinkedList class you implemented in lab:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "'A','B','C'\n",
      "A\n",
      "B\n",
      "C\n"
     ]
    }
   ],
   "source": [
    "class Node:\n",
    "    def __init__(self, val):\n",
    "        self.val = val\n",
    "        self.next = None\n",
    "\n",
    "    def __len__(self):\n",
    "        if self.next == None:\n",
    "            # base case: I'm the only Node!  Length must be 1\n",
    "            return 1\n",
    "        else:\n",
    "            # recursive case: total length is the length of next plus 1\n",
    "            raise NotImplemented(\"recursive case not implemented yet\")\n",
    "\n",
    "    def __repr__(self):\n",
    "        if self.next == None:\n",
    "            return repr(self.val)\n",
    "        else:\n",
    "            return repr(self.val)+\",\"+repr(self.next)\n",
    "\n",
    "    def __getitem__(self, idx):\n",
    "        if idx == 0:\n",
    "            # base case\n",
    "            return self.val\n",
    "        else:\n",
    "            if self.next == None:\n",
    "                raise IndexError\n",
    "            \n",
    "            # recursive case\n",
    "            return self.next[idx-1]\n",
    "\n",
    "L = Node(\"A\")\n",
    "L2 = Node(\"B\")\n",
    "L3 = Node(\"C\")\n",
    "L.next = L2\n",
    "L2.next = L3\n",
    "print(L)\n",
    "for x in L:\n",
    "    print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The above is really a simple form of a graph, like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: %3 Pages: 1 -->\n",
       "<svg width=\"62pt\" height=\"188pt\"\n",
       " viewBox=\"0.00 0.00 62.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\n",
       "<title>%3</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-184 58,-184 58,4 -4,4\"/>\n",
       "<!-- A -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>A</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">A</text>\n",
       "</g>\n",
       "<!-- B -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>B</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">B</text>\n",
       "</g>\n",
       "<!-- A&#45;&gt;B -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>A&#45;&gt;B</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M27,-143.7C27,-135.98 27,-126.71 27,-118.11\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"30.5,-118.1 27,-108.1 23.5,-118.1 30.5,-118.1\"/>\n",
       "</g>\n",
       "<!-- C -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>C</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">C</text>\n",
       "</g>\n",
       "<!-- B&#45;&gt;C -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>B&#45;&gt;C</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M27,-71.7C27,-63.98 27,-54.71 27,-46.11\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"30.5,-46.1 27,-36.1 23.5,-46.1 30.5,-46.1\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Digraph at 0x7f7f257c68e0>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g = Digraph()\n",
    "g.edge(\"A\", \"B\")\n",
    "g.edge(\"B\", \"C\")\n",
    "g"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Each node is an object of type Node.  What are the edges?  The `next` attribute -- we didn't need to implement a special class for that in this case, though we might have if there were important edge metadata.\n",
    "\n",
    "To get a tree, we're going to need to have multiple children per node.  For simplicity, lets have at most two (such a tree is called a \"binary tree\").  Instead of `next`, we'll have `left` and `right`, both of which can reference other nodes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "A\n",
      "    B\n",
      "    C\n",
      "\n"
     ]
    }
   ],
   "source": [
    "class Node:\n",
    "    def __init__(self, val):\n",
    "        self.val = val\n",
    "        self.left = None\n",
    "        self.right = None\n",
    "    \n",
    "    def indented_str(self, indent):\n",
    "        s = \"    \" * indent + self.val + \"\\n\"\n",
    "        for child in [self.left, self.right]:\n",
    "            if child != None:\n",
    "                s += child.indented_str(indent+1)\n",
    "        return s\n",
    "        \n",
    "    def __str__(self):\n",
    "        return self.indented_str(0)\n",
    "    \n",
    "root = Node(\"A\")\n",
    "root.left = Node(\"B\")\n",
    "root.right = Node(\"C\")\n",
    "print(root)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Can we design our tree so that it "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: %3 Pages: 1 -->\n",
       "<svg width=\"134pt\" height=\"116pt\"\n",
       " viewBox=\"0.00 0.00 134.00 116.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 112)\">\n",
       "<title>%3</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-112 130,-112 130,4 -4,4\"/>\n",
       "<!-- A -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>A</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"63\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"63\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">A</text>\n",
       "</g>\n",
       "<!-- B -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>B</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">B</text>\n",
       "</g>\n",
       "<!-- A&#45;&gt;B -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>A&#45;&gt;B</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M54.65,-72.76C50.29,-64.28 44.85,-53.71 39.96,-44.2\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"42.99,-42.44 35.3,-35.15 36.77,-45.64 42.99,-42.44\"/>\n",
       "</g>\n",
       "<!-- C -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>C</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"99\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"99\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">C</text>\n",
       "</g>\n",
       "<!-- A&#45;&gt;C -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>A&#45;&gt;C</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M71.35,-72.76C75.71,-64.28 81.15,-53.71 86.04,-44.2\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"89.23,-45.64 90.7,-35.15 83.01,-42.44 89.23,-45.64\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Digraph at 0x7f7f257cf8b0>"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def to_graphviz(self, g=None):\n",
    "    if g == None:\n",
    "        g = Digraph()\n",
    "    g.node(self.val)\n",
    "    for child in [self.left, self.right]:\n",
    "        if child != None:\n",
    "            g.edge(self.val, child.val)\n",
    "            child.to_graphviz(g)\n",
    "    return g\n",
    "\n",
    "# add to_graphviz to Node as a new method.\n",
    "# this is not good style: https://www.geeksforgeeks.org/monkey-patching-in-python-dynamic-behavior/\n",
    "# but it means not copy/pasting the above code\n",
    "Node.to_graphviz = to_graphviz\n",
    "\n",
    "root.to_graphviz()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Wouldn't it be nice if we could automatically visualize the tree?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<__main__.Node at 0x7f7f257cf430>"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "root"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can if we implement `_repr_svg_`, like `Graph` does (well, Digraph names it something similar, `_repr_image_svg_xml`):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: %3 Pages: 1 -->\n",
       "<svg width=\"134pt\" height=\"116pt\"\n",
       " viewBox=\"0.00 0.00 134.00 116.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 112)\">\n",
       "<title>%3</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-112 130,-112 130,4 -4,4\"/>\n",
       "<!-- A -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>A</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"63\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"63\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">A</text>\n",
       "</g>\n",
       "<!-- B -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>B</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">B</text>\n",
       "</g>\n",
       "<!-- A&#45;&gt;B -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>A&#45;&gt;B</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M54.65,-72.76C50.29,-64.28 44.85,-53.71 39.96,-44.2\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"42.99,-42.44 35.3,-35.15 36.77,-45.64 42.99,-42.44\"/>\n",
       "</g>\n",
       "<!-- C -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>C</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"99\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"99\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">C</text>\n",
       "</g>\n",
       "<!-- A&#45;&gt;C -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>A&#45;&gt;C</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M71.35,-72.76C75.71,-64.28 81.15,-53.71 86.04,-44.2\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"89.23,-45.64 90.7,-35.15 83.01,-42.44 89.23,-45.64\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<__main__.Node at 0x7f7f257cf430>"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def _repr_svg_(self, g=None):\n",
    "    return self.to_graphviz()._repr_image_svg_xml()\n",
    "Node._repr_svg_ = _repr_svg_\n",
    "\n",
    "root"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
