{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Une exploration visuelle de l'algorithme du Simplexe en 3D avec Python\n", "\n", "Dans ce notebook (utilisant Python 3), je souhaite montrer des animations de l'[algorithme du Simplexe](https://fr.wikipedia.org/wiki/Algorithme_du_simplexe), un peu comme dans la [vidéo suivante](https://www.youtube.com/watch?v=W_U8ozVsh8s) :\n", "\n", "\n", "\n", "J'aimerai bien écrire un petit morceau de code Python qui fait les étapes suivantes :\n", "\n", "- on lui donne le programme linéaire à résoudre (éventuellement sous forme acceptée par [lp_solve](http://web.mit.edu/lpsolve/doc/)) ;\n", "- il résoud le problème avec [`scipy.optimize.linprog(method=\"simplex\")`](https://docs.scipy.org/doc/scipy/reference/optimize.linprog-simplex.html), et s'arrête s'il n'y a pas de solution trouvée par le simplexe ;\n", "- puis utilise le `callback` de cette fonction pour afficher des équations en LaTeX représentant l'évolution du système et des variables de la base et hors base ;\n", "- j'aimerai bien avoir une animation étape par étape, avec un simple \"slider\" avec [le widget `interact`](https://ipywidgets.readthedocs.io/en/stable/examples/Using%20Interact.html) ;\n", "- bonus : afficher un graphique 3D, avec TikZ ?\n", "\n", "Ce document ne sera pas :\n", "\n", "- une implémentation maison de l'algorithme du simplexe : c'est trop long et je n'ai pas le temps en ce moment ;\n", "- des explications sur l'algorithme du simplexe : pour cela regardez les notes de cours de [ALGO2](http://people.irisa.fr/Francois.Schwarzentruber/algo2/), et la page Wikipédia sur l'[algorithme du Simplexe](https://fr.wikipedia.org/wiki/Algorithme_du_simplexe) ;\n", "- probablement capable de se faire exporter proprement en HTML statique ;\n", "- et pas non plus capable de se faire exporter proprement en PDF." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## A propros\n", "- Auteur : [Lilian Besson](https://perso.crans.org/besson/)\n", "- License : [MIT](https://lbesson.mit-license.org/)\n", "- Date : 09/02/2021\n", "- Cours : [ALGO2](http://people.irisa.fr/Francois.Schwarzentruber/algo2/) @ [ENS Rennes](http://www.dit.ens-rennes.fr/)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Vidéo d'explication\n", "\n", "Regardez [cette vidéo](https://www.youtube.com/watch?v=W_U8ozVsh8s)." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:29:34.652757Z", "start_time": "2021-02-09T21:29:34.577657Z" }, "scrolled": false }, "outputs": [ { "data": { "image/jpeg": "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\n", "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import YouTubeVideo\n", "# https://www.youtube.com/watch?v=W_U8ozVsh8s\n", "YouTubeVideo(\"W_U8ozVsh8s\", width=944, height=531)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## Dépendances" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On a sûrement besoin de Numpy et Matplotlib :" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:29:41.188341Z", "start_time": "2021-02-09T21:29:40.876145Z" } }, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On a besoin de la fonction [`scipy.optimize.linprog(method=\"simplex\")`](https://docs.scipy.org/doc/scipy/reference/optimize.linprog-simplex.html) du module [`scipy.optimize`](https://docs.scipy.org/doc/scipy/reference/optimize.html) :" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:29:42.060383Z", "start_time": "2021-02-09T21:29:41.871061Z" } }, "outputs": [], "source": [ "from scipy.optimize import linprog" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On a aussi besoin de la fonction `IPython.display.Latex` pour facilement afficher du code LaTeX généré depuis nos cellules Python :" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:29:42.878157Z", "start_time": "2021-02-09T21:29:42.874659Z" } }, "outputs": [], "source": [ "from IPython.display import Latex, display" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Par exemple :" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:29:43.804399Z", "start_time": "2021-02-09T21:29:43.794814Z" } }, "outputs": [ { "data": { "text/latex": [ "$$\\cos(x)^1 = 0$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$\\cos(x)^2 = 0$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$\\cos(x)^3 = 0$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$\\cos(x)^4 = 0$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def display_cos_power(power=1):\n", " return display(Latex(fr\"$$\\cos(x)^{power} = 0$$\"))\n", "\n", "for power in range(1, 5):\n", " display_cos_power(power)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On va avoir besoin des widgets IPywidgets, plus tard :" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:29:46.078351Z", "start_time": "2021-02-09T21:29:46.021554Z" } }, "outputs": [], "source": [ "from ipywidgets import interact, interactive, fixed, interact_manual\n", "import ipywidgets as widgets" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:30:11.244706Z", "start_time": "2021-02-09T21:30:11.197577Z" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "d0a7b99b5149417cbb82b6ab977ab651", "version_major": 2, "version_minor": 0 }, "text/plain": [ "interactive(children=(IntSlider(value=1, description='power', max=10, min=1), Output()), _dom_classes=('widget…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "interactive(display_cos_power,\n", " power=(1, 10, 1)\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Et enfin, de l'extension [itikz](https://github.com/jbn/itikz)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:30:21.391520Z", "start_time": "2021-02-09T21:30:21.301266Z" } }, "outputs": [], "source": [ "%load_ext itikz" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Première expérience" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Déjà, je vais écrire le problème étudié comme un dictionnaire, que l'on pourra passer à [`scipy.optimize.linprog(method=\"simplex\")`](https://docs.scipy.org/doc/scipy/reference/optimize.linprog-simplex.html) :" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:30:22.758769Z", "start_time": "2021-02-09T21:30:22.755402Z" } }, "outputs": [], "source": [ "# Objective Function: 50x_1 + 80x_2\n", "# Constraint 1: 5x_1 + 2x_2 <= 20\n", "# Constraint 2: -10x_1 + -12x_2 <= -90\n", "\n", "\n", "problem1 = {\n", " # Cost function: 50x_1 + 80x_2\n", " \"cost\": [50, 80],\n", " # Coefficients for inequalities\n", " \"A_ub\": [[5, 2], [-10, -12]],\n", " # Constraints for inequalities: 20 and -90\n", " \"b_ub\": [20, -90],\n", " # Bounds on x, 0 <= x_i <= +oo by default\n", " \"bounds\": (0, None),\n", "}" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:30:23.189914Z", "start_time": "2021-02-09T21:30:23.180929Z" } }, "outputs": [], "source": [ "# Objective Function: maximize x_1 + 6*x_2 + 13*x_3\n", "# => so cost will be opposite\n", "# Constraint 1: x1 <= 200\n", "# Constraint 2: x2 <= 300\n", "# Constraint 3: x1+x2+x3 <= 400\n", "# Constraint 2: x2+3x3 <= 600\n", "\n", "problem2 = {\n", " # Cost function: minimize -1*x_1 + -6*x_2 + -13*x_3\n", " \"cost\": [-1, -6, -13],\n", " # Coefficients for inequalities\n", " \"A_ub\": [\n", " [1, 0, 0],\n", " [0, 1, 0],\n", " [1, 1, 1],\n", " [0, 1, 3],\n", " ],\n", " # Constraints for inequalities:\n", " \"b_ub\": [200, 300, 400, 600],\n", " # Bounds on x, 0 <= x_i <= +oo by default\n", " \"bounds\": (0, None),\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Puis une petite fonction qui s'occupe de prendre ce dictionnaire et le donner à [`scipy.optimize.linprog(method=\"simplex\")`](https://docs.scipy.org/doc/scipy/reference/optimize.linprog-simplex.html) :" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:30:23.943304Z", "start_time": "2021-02-09T21:30:23.940064Z" } }, "outputs": [], "source": [ "def linprog_wrapper(problem, **kwargs):\n", " result = linprog(\n", " problem[\"cost\"],\n", " A_ub=problem[\"A_ub\"],\n", " b_ub=problem[\"b_ub\"],\n", " bounds=problem[\"bounds\"],\n", " method=\"simplex\",\n", " **kwargs\n", " )\n", " return result" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On va déjà vérifier que l'on peut résoudre ces deux exemples de problème de programmation linéaire :" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:30:24.689787Z", "start_time": "2021-02-09T21:30:24.683481Z" } }, "outputs": [ { "data": { "text/plain": [ " con: array([], dtype=float64)\n", " fun: 575.0\n", " message: 'Optimization terminated successfully.'\n", " nit: 2\n", " slack: array([0., 0.])\n", " status: 0\n", " success: True\n", " x: array([1.5 , 6.25])" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "linprog_wrapper(problem1)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:30:25.268075Z", "start_time": "2021-02-09T21:30:25.258717Z" } }, "outputs": [ { "data": { "text/plain": [ " con: array([], dtype=float64)\n", " fun: -3100.0\n", " message: 'Optimization terminated successfully.'\n", " nit: 5\n", " slack: array([2.00000000e+02, 5.68434189e-14, 0.00000000e+00, 0.00000000e+00])\n", " status: 0\n", " success: True\n", " x: array([ 0., 300., 100.])" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "linprog_wrapper(problem2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "C'est bien la solution $x^* = [0, 300, 100]$, avec un objectif valant $+3100$, qui était trouvée dans la vidéo !" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Et si on ajoute un `callback` ?" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:30:29.831159Z", "start_time": "2021-02-09T21:30:29.822496Z" } }, "outputs": [], "source": [ "def round(np_array):\n", " res = np.array(np.round(np_array), dtype=int)\n", " if res.size > 1:\n", " return list(res)\n", " else:\n", " return res" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:30:30.252253Z", "start_time": "2021-02-09T21:30:30.244314Z" } }, "outputs": [], "source": [ "def dummy_callback(r):\n", " print(f\"\\n- Itération #{r['nit']}, phase {r['phase']} :\")\n", " fun = round(r['fun'])\n", " print(f\" Valeur objectif = {fun}\")\n", " slack = round(r['slack'])\n", " print(f\" Variables d'écart = {slack}\")\n", " x = round(r['x'])\n", " print(f\" Variables objectif = {x}\")\n", " # print(r)\n" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:30:31.423494Z", "start_time": "2021-02-09T21:30:31.375181Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "- Itération #0, phase 1 :\n", " Valeur objectif = 0\n", " Variables d'écart = [200, 300, 400, 600]\n", " Variables objectif = [0, 0, 0]\n", "\n", "- Itération #1, phase 1 :\n", " Valeur objectif = -2600\n", " Variables d'écart = [200, 300, 200, 0]\n", " Variables objectif = [0, 0, 200]\n", "\n", "- Itération #2, phase 1 :\n", " Valeur objectif = -2800\n", " Variables d'écart = [0, 300, 0, 0]\n", " Variables objectif = [200, 0, 200]\n", "\n", "- Itération #3, phase 1 :\n", " Valeur objectif = -2800\n", " Variables d'écart = [0, 300, 0, 0]\n", " Variables objectif = [200, 0, 200]\n", "\n", "- Itération #4, phase 1 :\n", " Valeur objectif = -3100\n", " Variables d'écart = [200, 0, 0, 0]\n", " Variables objectif = [0, 300, 100]\n", "\n", "- Itération #5, phase 1 :\n", " Valeur objectif = -3100\n", " Variables d'écart = [200, 0, 0, 0]\n", " Variables objectif = [0, 300, 100]\n", "\n", "- Itération #5, phase 2 :\n", " Valeur objectif = -3100\n", " Variables d'écart = [200, 0, 0, 0]\n", " Variables objectif = [0, 300, 100]\n" ] }, { "data": { "text/plain": [ " con: array([], dtype=float64)\n", " fun: -3100.0\n", " message: 'Optimization terminated successfully.'\n", " nit: 5\n", " slack: array([2.00000000e+02, 5.68434189e-14, 0.00000000e+00, 0.00000000e+00])\n", " status: 0\n", " success: True\n", " x: array([ 0., 300., 100.])" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "linprog_wrapper(problem2, callback=dummy_callback)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Afficher un système d'équation en LaTeX" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:34:19.007367Z", "start_time": "2021-02-09T21:34:18.993897Z" } }, "outputs": [], "source": [ "step_by_step_results = []\n", "step_by_step_nitphase = []\n", "\n", "def print_and_store_callback(r):\n", " global step_by_step_results, step_by_step_nitphase\n", "\n", " nit, phase = r['nit'], r['phase']\n", " print(f\"\\n- Itération #{nit}, phase {phase} :\")\n", " fun = round(r['fun'])\n", " print(f\" Valeur objectif = {fun}\")\n", " slack = round(r['slack'])\n", " print(f\" Variables d'écart = {slack}\")\n", " x = round(r['x'])\n", " print(f\" Variables objectif = {x}\")\n", "\n", " if (nit, phase) not in step_by_step_nitphase:\n", " step_by_step_results.append(r)\n", " step_by_step_nitphase.append((nit, phase))" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:34:19.445285Z", "start_time": "2021-02-09T21:34:19.421773Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "- Itération #0, phase 1 :\n", " Valeur objectif = 0\n", " Variables d'écart = [200, 300, 400, 600]\n", " Variables objectif = [0, 0, 0]\n", "\n", "- Itération #1, phase 1 :\n", " Valeur objectif = -2600\n", " Variables d'écart = [200, 300, 200, 0]\n", " Variables objectif = [0, 0, 200]\n", "\n", "- Itération #2, phase 1 :\n", " Valeur objectif = -2800\n", " Variables d'écart = [0, 300, 0, 0]\n", " Variables objectif = [200, 0, 200]\n", "\n", "- Itération #3, phase 1 :\n", " Valeur objectif = -2800\n", " Variables d'écart = [0, 300, 0, 0]\n", " Variables objectif = [200, 0, 200]\n", "\n", "- Itération #4, phase 1 :\n", " Valeur objectif = -3100\n", " Variables d'écart = [200, 0, 0, 0]\n", " Variables objectif = [0, 300, 100]\n", "\n", "- Itération #5, phase 1 :\n", " Valeur objectif = -3100\n", " Variables d'écart = [200, 0, 0, 0]\n", " Variables objectif = [0, 300, 100]\n", "\n", "- Itération #5, phase 2 :\n", " Valeur objectif = -3100\n", " Variables d'écart = [200, 0, 0, 0]\n", " Variables objectif = [0, 300, 100]\n", " con: array([], dtype=float64)\n", " fun: -3100.0\n", " message: 'Optimization terminated successfully.'\n", " nit: 5\n", " slack: array([2.00000000e+02, 5.68434189e-14, 0.00000000e+00, 0.00000000e+00])\n", " status: 0\n", " success: True\n", " x: array([ 0., 300., 100.])\n" ] } ], "source": [ "step_by_step_results = []\n", "\n", "result_final = linprog_wrapper(problem2, callback=print_and_store_callback)\n", "print(result_final)\n", "\n", "step_by_step_results.append(result_final)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On a donc récupéré un certain nombre d'objets résultat intermédiaire d'optimisation :" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:34:21.731851Z", "start_time": "2021-02-09T21:34:21.720388Z" } }, "outputs": [ { "data": { "text/plain": [ "8" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(step_by_step_results)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "En fait, je me rends compte que les informations données par ces `results` successifs ne sont pas suffisantes pour afficher des équations comme dans la vidéo." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Implémentation maison du Simplexe en dimension 3" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exemples" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Suite des expérimentations" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On va écrire une fonction qui produit du code LaTeX représentant ce système d'optimisation, au cours des réécritures qu'il subit :" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def equation_latex_from_step(result):\n", " return r\"\"\"\n", " \\text{Maximiser}\"\"\" + cout + r\"\"\"\\\\\n", " \\begin{cases}\n", " \n", " \\end{cases}\n", " \"\"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "TODO: terminer ça !" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Ajouter de l'interactivité" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def interactive_latex_exploration(problem):\n", " problem_solved = make_show_latex(problem1)\n", " if problem_solved.status != 0:\n", " print(\"Error: problem was not solve correctly, stopping this...\")\n", " interactive_function = make_show_latex(problem1)\n", " max_step = problem_solved.nitint\n", "\n", " return interact(, step=(0, max_step))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Allez on essaie :" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T19:56:52.325853Z", "start_time": "2021-02-09T19:56:52.283697Z" } }, "outputs": [ { "ename": "NameError", "evalue": "name 'interactive_latex_exploration' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0minteractive_latex_exploration\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mproblem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'interactive_latex_exploration' is not defined" ] } ], "source": [ "interactive_latex_exploration(problem)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Ajouter des figures TikZ\n", "\n", "Avec [itikz](https://github.com/jbn/itikz)" ] }, { "cell_type": "code", "execution_count": 135, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T20:50:16.160768Z", "start_time": "2021-02-09T20:50:16.149504Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The itikz extension is already loaded. To reload it, use:\n", " %reload_ext itikz\n" ] } ], "source": [ "%load_ext itikz" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Par exemple on peut afficher un premier exemple, avant de chercher à les faire bouger :" ] }, { "cell_type": "code", "execution_count": 138, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T20:51:04.363006Z", "start_time": "2021-02-09T20:51:04.008258Z" } }, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", "\n", "\n", "\n", "\n", " \n", "\n", "\n", "\n", "\n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "" ], "text/plain": [ "" ] }, "execution_count": 138, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%itikz --temp-dir --file-prefix simplex-example-\n", "\\documentclass[tikz]{standalone}\n", "\\usepackage{amsfonts}\n", "\\begin{document}\n", "% from http://people.irisa.fr/Francois.Schwarzentruber/algo2/ notes\n", "\\usetikzlibrary{arrows,patterns,topaths,shadows,shapes,positioning}\n", "\\begin{tikzpicture}[scale=0.012, opacity=0.7]\n", "\\tikzstyle{point} = [fill=red, circle, inner sep=0.8mm];\n", "\\draw[->] (0, 0, 0) -- (300, 0, 0) node[right] {a};\n", "\\draw[->] (0, 0, 0) -- (0, 350, 0) node[above] {b};\n", "\\draw[->] (0, 0, 0) -- (0, 0, 300) node[below] {c};\n", "\n", "\\coordinate (O) at (0,0,0);\n", "\\coordinate (D) at (200,0,0);\n", "\\coordinate (E) at (200, 0, 200);\n", "\\coordinate (F) at (0, 0, 200);\n", "\\coordinate (G) at (0, 300,0);\n", "\\coordinate (C) at (200,200,0);\n", "\\coordinate (A) at (100,300, 0);\n", "\\coordinate (B) at (0,300, 100);\n", "\\draw[fill=blue!20] (O) -- (D) -- (E) -- (F) -- (O) -- cycle;\n", "\\draw[fill=blue!20] (D) -- (C) -- (E) -- cycle;\n", "\\draw[fill=blue!20] (G) -- (B) -- (F) -- (O) -- cycle;\n", "\\draw[fill=blue!20] (B) -- (A) -- (C) --(E) -- cycle;\n", "\\draw[fill=blue!20] (B) -- (F) -- (E) -- cycle;\n", "\\draw[fill=blue!20] (B) -- (A) -- (G) -- cycle;\n", "\\node[point] at (0,0,0) {}; % TODO make this argument of function\n", "\\end{tikzpicture}\n", "\\end{document}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Maintenant on peut chercher à contrôler la position du point objectif actuel :\n", "a,b,c sera $x_1, x_2, x_3$." ] }, { "cell_type": "code", "execution_count": 173, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:02:08.418824Z", "start_time": "2021-02-09T21:02:08.406677Z" } }, "outputs": [], "source": [ "simplex_example_str = \"\"\n", "\n", "def default_cost(a, b, c):\n", " \"\"\"1*{a} + 6*{b} + 13*{c}\"\"\"\n", " return 1*a + 6*b + 13*c\n", "\n", "def show_tikz_figure_with_point(a=0, b=0, c=0, cost=default_cost):\n", " # TODO generate nice LaTeX equations\n", " if cost:\n", " current_cost = cost(a, b, c)\n", " cost_doc = cost.__doc__.format(a=a, b=b, c=c)\n", " print(f\"Coût = {cost_doc} = {current_cost}\")\n", " equation_latex = f\"\"\"\\\n", "Cout $f(a,b,c) = {cost_doc} = {current_cost}$.\\\n", "\"\"\"\n", " display(Latex(equation_latex))\n", " # now tikz\n", " global simplex_example_str\n", " simplex_example_str = r\"\"\"\n", "\\documentclass[tikz]{standalone}\n", "\\begin{document}\n", "% from http://people.irisa.fr/Francois.Schwarzentruber/algo2/ notes\n", "\\usetikzlibrary{arrows,patterns,topaths,shadows,shapes,positioning}\n", "\\begin{tikzpicture}[scale=0.016, opacity=0.7]\n", "\\tikzstyle{point} = [fill=red, circle, inner sep=0.8mm];\n", "\\draw[->] (0, 0, 0) -- (300, 0, 0) node[right] {a};\n", "\\draw[->] (0, 0, 0) -- (0, 350, 0) node[above] {b};\n", "\\draw[->] (0, 0, 0) -- (0, 0, 300) node[below] {c};\n", "\n", "\\coordinate (O) at (0,0,0);\n", "\\coordinate (D) at (200,0,0);\n", "\\coordinate (E) at (200, 0, 200);\n", "\\coordinate (F) at (0, 0, 200);\n", "\\coordinate (G) at (0, 300,0);\n", "\\coordinate (C) at (200,200,0);\n", "\\coordinate (A) at (100,300, 0);\n", "\\coordinate (B) at (0,300, 100);\n", "\\draw[fill=blue!20] (O) -- (D) -- (E) -- (F) -- (O) -- cycle;\n", "\\draw[fill=blue!20] (D) -- (C) -- (E) -- cycle;\n", "\\draw[fill=blue!20] (G) -- (B) -- (F) -- (O) -- cycle;\n", "\\draw[fill=blue!20] (B) -- (A) -- (C) --(E) -- cycle;\n", "\\draw[fill=blue!20] (B) -- (F) -- (E) -- cycle;\n", "\\draw[fill=blue!20] (B) -- (A) -- (G) -- cycle;\n", "\\node[point] at (\"\"\" + f\"{a}, {b}, {c}\" + \"\"\") {};\n", "\\end{tikzpicture}\n", "\\end{document}\n", "\"\"\"\n", " #print(simplex_example_str)\n", " # TODO: run this from this function?\n", " #%itikz --temp-dir --file-prefix simplex-example- simplex_example_str\n", " return get_ipython().run_line_magic(\n", " \"itikz\", \"--temp-dir --file-prefix simplex-example- simplex_example_str\"\n", " )" ] }, { "cell_type": "code", "execution_count": 175, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:02:24.001402Z", "start_time": "2021-02-09T21:02:23.986926Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Coût = 1*0 + 6*0 + 13*0 = 0\n" ] }, { "data": { "text/latex": [ "Cout $f(a,b,c) = 1*0 + 6*0 + 13*0 = 0$." ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", "\n", "\n", "\n", "\n", " \n", "\n", "\n", "\n", "\n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "" ], "text/plain": [ "" ] }, "execution_count": 175, "metadata": {}, "output_type": "execute_result" } ], "source": [ "show_tikz_figure_with_point(0, 0, 0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Et en rendant cela interactif, on peut jouer avec ça.\n", "\n", "ATTENTION : même si les widgets sont présents dans une version statique de cette page (au format HTML ou sur [nbviewer.jupyter.org](https://nbviewer.jupyter.org/), la figure ne peut pas être modifée. Si vous souhaitez expérimenter de votre côté, il faut exécuter le notebook localement depuis votre propre Jupyter, ou avec MyBinder en cliquant sur un des boutons suivants :\n", "\n", "[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/Naereen/notebooks/master?filepath=Une_exploration_visuelle_de_l_algorithme_du_Simplexe_en_3D_avec_Python.ipynb)\n", "[![MyBinder v2](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/Naereen/notebooks/master)" ] }, { "cell_type": "code", "execution_count": 177, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T21:09:10.872688Z", "start_time": "2021-02-09T21:09:10.786630Z" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "2d681b937da845fcaac5b2fb87de91d7", "version_major": 2, "version_minor": 0 }, "text/plain": [ "interactive(children=(IntSlider(value=0, description='a', max=300, min=-100, step=10), IntSlider(value=0, desc…" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ ")>" ] }, "execution_count": 177, "metadata": {}, "output_type": "execute_result" } ], "source": [ "interact(\n", " show_tikz_figure_with_point,\n", " a = (-100, 300, 10),\n", " b = (-100, 300, 10),\n", " c = (-100, 300, 10),\n", " cost = fixed(default_cost)\n", ")" ] }, { "cell_type": "code", "execution_count": 151, "metadata": { "ExecuteTime": { "end_time": "2021-02-09T20:56:12.559221Z", "start_time": "2021-02-09T20:56:12.532999Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "- Itération #0, phase 1 :\n", " Valeur objectif = 0\n", " Variables d'écart = [200, 300, 400, 600]\n", " Variables objectif = [0, 0, 0]\n", "\n", "- Itération #1, phase 1 :\n", " Valeur objectif = -2600\n", " Variables d'écart = [200, 300, 200, 0]\n", " Variables objectif = [0, 0, 200]\n", "\n", "- Itération #2, phase 1 :\n", " Valeur objectif = -2800\n", " Variables d'écart = [0, 300, 0, 0]\n", " Variables objectif = [200, 0, 200]\n", "\n", "- Itération #3, phase 1 :\n", " Valeur objectif = -2800\n", " Variables d'écart = [0, 300, 0, 0]\n", " Variables objectif = [200, 0, 200]\n", "\n", "- Itération #4, phase 1 :\n", " Valeur objectif = -3100\n", " Variables d'écart = [200, 0, 0, 0]\n", " Variables objectif = [0, 300, 100]\n", "\n", "- Itération #5, phase 1 :\n", " Valeur objectif = -3100\n", " Variables d'écart = [200, 0, 0, 0]\n", " Variables objectif = [0, 300, 100]\n", "\n", "- Itération #5, phase 2 :\n", " Valeur objectif = -3100\n", " Variables d'écart = [200, 0, 0, 0]\n", " Variables objectif = [0, 300, 100]\n" ] }, { "data": { "text/plain": [ " con: array([], dtype=float64)\n", " fun: -3100.0\n", " message: 'Optimization terminated successfully.'\n", " nit: 5\n", " slack: array([2.00000000e+02, 5.68434189e-14, 0.00000000e+00, 0.00000000e+00])\n", " status: 0\n", " success: True\n", " x: array([ 0., 300., 100.])" ] }, "execution_count": 151, "metadata": {}, "output_type": "execute_result" } ], "source": [ "linprog_wrapper(problem2, callback=dummy_callback)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Conclusion\n", "\n", "C'était amusant.\n", "\n", "> Voir [d'autres notebooks](https://github.com/Naereen/notebooks/)." ] } ], "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.6.9" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": { "height": "65.7833px", "left": "544.35px", "top": "193.7px", "width": "212px" }, "toc_section_display": true, "toc_window_display": true }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { "0013df4fa6bf40328e5c7f1122568189": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "b", "layout": "IPY_MODEL_1303a08fc65640fc861e2d786208036d", "max": 300, "min": -100, "step": 10, "style": "IPY_MODEL_8ff9440daffd481e96aef4681432006a" } }, "0728e221f4e44717b2f4f8d3ce08df14": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "07687316f22045d788fc04ae1dcab927": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "a", "layout": "IPY_MODEL_2e540d56f9044300a25b1b826038479a", "max": 300, "min": -100, "step": 10, "style": "IPY_MODEL_b6e26016f1944db5bea35f17f047adfe", "value": 200 } }, "07ed157521b34a55b146cfd9724c4ce1": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "layout": "IPY_MODEL_de19a02ca0354ea785fe24a17a8147d1", "outputs": [ { "name": "stdout", "output_type": "stream", "text": "Coût = 1*0 + 6*0 + 13*200 = 2600\n" }, { "data": { "image/svg+xml": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n \n\n\n\n\n \n\n\n\n\n\n\n\n\n\n", "text/plain": "" }, "metadata": {}, "output_type": "display_data" } ] } }, "08fe912f6d284dd8aef2a10bb57cc788": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "_dom_classes": [ "widget-interact" ], "children": [ "IPY_MODEL_c9d24498844b47eb90895a44b14d9766", "IPY_MODEL_6e8ba0fe94dd4bef9b4f196bc1fe8d32", "IPY_MODEL_88dda621b3604f569c1164f165b0e52e", "IPY_MODEL_2d2e0ccc138b41fc94e494d5698aa5ef" ], "layout": "IPY_MODEL_92b3417dd99e464ebe3bec9b9df3bc30" } }, "0dbc208ff42545508c86482b03667c11": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "101e990cd49547b3813da5276f501aa0": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "11fa196405a0486094a3699374a58379": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "1303a08fc65640fc861e2d786208036d": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "13441c8ca7414e18a6dec3ac6e319184": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "14c62a4e46eb47f48024bacf5079d706": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "1750411dd580415dbf7de8d04d431e01": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "layout": "IPY_MODEL_850b64933a6f40a6a68e000f7e826d55", "outputs": [ { "name": "stdout", "output_type": "stream", "text": "Coût = 1*200 + 6*160 + 13*110 = 2590\n" }, { "data": { "text/latex": "Cout $f(a,b,c) = 1*200 + 6*160 + 13*110 = 2590$.", "text/plain": "" }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n \n\n\n\n\n \n\n\n\n\n\n\n\n\n\n", "text/plain": "" }, "metadata": {}, "output_type": "display_data" } ] } }, "185b306982d24fa58d968fca6abd5809": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "layout": "IPY_MODEL_ccaa6aa48f34466998e53e00bf842323", "outputs": [ { "data": { "image/svg+xml": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n \n\n\n\n\n \n\n\n\n\n\n\n\n\n\n", "text/plain": "" }, "metadata": {}, "output_type": "display_data" } ] } }, "18f5c92358b3467f9f02db26cb7e92c7": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "1a33de3320f04f148a51aa0ebe6a3fe4": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "1efae46f99964624a5016a469c236b09": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "a", "layout": "IPY_MODEL_6a72b8e739644c0da471761b2e7d607a", "max": 300, "min": -100, "step": 10, "style": "IPY_MODEL_73a5b030ed2740abb2ae37a159037f23" } }, "2010a12203a6442aadff6a1395d7d5ca": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "227659d081ed4d15b315913c055ee8ef": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "22aece595a8d43d88ffdc12a28b4e284": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "c", "layout": "IPY_MODEL_47d80db208744d3fabbe03559f06f49f", "max": 300, "min": -100, "step": 10, "style": "IPY_MODEL_fb197948e178435da9e8b6f2e137f4d9" } }, "246745891e9a4dbcb5aec50633dbc818": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "255cddbef201431897f6bec599596c5c": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "287cee1551d64a52aaa2e12f6d201280": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "2934a6cfce214065a9d0828bd3ebb9fa": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "_dom_classes": [ "widget-interact" ], "children": [ "IPY_MODEL_7af14dc2de8e435ca1a3f935b1c9840c", "IPY_MODEL_afb9960e6f4b4bcf8c17a3f6724674c5", "IPY_MODEL_6d3545f866c3418dbc6fb2c05319cf19", "IPY_MODEL_185b306982d24fa58d968fca6abd5809" ], "layout": "IPY_MODEL_1a33de3320f04f148a51aa0ebe6a3fe4" } }, "297518126b324814876d5c8ba9bed05d": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "2bb0d920eb0c48fda1668bfda389143f": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "2c339a695d0f445aaa50cd55301c2fe8": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "2d2e0ccc138b41fc94e494d5698aa5ef": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "layout": "IPY_MODEL_b005c649cf334004a33568a43c524f83", "outputs": [ { "data": { "image/svg+xml": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n \n\n\n\n\n \n\n\n\n\n\n\n\n\n\n", "text/plain": "" }, "metadata": {}, "output_type": "display_data" } ] } }, "2d681b937da845fcaac5b2fb87de91d7": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "_dom_classes": [ "widget-interact" ], "children": [ "IPY_MODEL_704627424e814110b54a59a6f2a3163c", "IPY_MODEL_c8a35410828149568bfbbc02454008b5", "IPY_MODEL_45b51b4cceb9481ca47e0acc8cdd71da", "IPY_MODEL_1750411dd580415dbf7de8d04d431e01" ], "layout": "IPY_MODEL_39922298906748699063a3ffd28f184f" } }, "2e540d56f9044300a25b1b826038479a": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "2f613336c27c47878af98378cac1b4a2": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "32ff674bbf5d45b8b314e3a5bf321cff": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "38dfd1ee95a945b399a388623c7d99bf": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "z", "layout": "IPY_MODEL_0728e221f4e44717b2f4f8d3ce08df14", "max": 300, "step": 50, "style": "IPY_MODEL_13441c8ca7414e18a6dec3ac6e319184" } }, "39922298906748699063a3ffd28f184f": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "39a8dc5510b342f798a58bffc7dee746": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "41acaf6fb8da4fdea98d6f9029051e6a": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "45b51b4cceb9481ca47e0acc8cdd71da": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "c", "layout": "IPY_MODEL_b893a4e6ca6747aca5ec9fb84f2b916d", "max": 300, "min": -100, "step": 10, "style": "IPY_MODEL_255cddbef201431897f6bec599596c5c", "value": 110 } }, "4691b678c1fa46b18106fa14aff0f86b": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "47d80db208744d3fabbe03559f06f49f": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "48109e46a3424e2da9e6e9d1f5b4f23c": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "4dab81c846c840efae7b60519a24786a": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "4e32de3affb646ecb582a9d702cbc4dc": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "500292032e2e4a8895071940a1c0a5aa": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "531f7e63338941d28d2b2bf515845b61": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "b", "layout": "IPY_MODEL_686b7a3cf0d741f69fc054f68ba1ef52", "max": 300, "min": -100, "step": 10, "style": "IPY_MODEL_2bb0d920eb0c48fda1668bfda389143f" } }, "5a8758b6f09247ee8c5c3c29ee900fee": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "c", "layout": "IPY_MODEL_4691b678c1fa46b18106fa14aff0f86b", "max": 300, "min": -100, "step": 10, "style": "IPY_MODEL_18f5c92358b3467f9f02db26cb7e92c7", "value": 200 } }, "5d7f849470ef40d9a39c5c78b962c4d3": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "5da730a76c1548dfbdcab70f7aba8e29": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "x", "layout": "IPY_MODEL_287cee1551d64a52aaa2e12f6d201280", "max": 200, "step": 50, "style": "IPY_MODEL_2f613336c27c47878af98378cac1b4a2", "value": 200 } }, "5f60e1e4d73743399c230f6f4d8afc75": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "61972fbb6aee4c6a9b0949421cba5003": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "644b9c2778de4b1091e5d87d3a1555f6": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "64d16847060e490bab43f6296a275987": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "x", "layout": "IPY_MODEL_11fa196405a0486094a3699374a58379", "max": 300, "step": 50, "style": "IPY_MODEL_4e32de3affb646ecb582a9d702cbc4dc", "value": 100 } }, "67132e890a524f82b218178268f1773e": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "b", "layout": "IPY_MODEL_4dab81c846c840efae7b60519a24786a", "max": 300, "min": -100, "step": 10, "style": "IPY_MODEL_d8dad505f1ef4124987198ab73e45125" } }, "686b7a3cf0d741f69fc054f68ba1ef52": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "6a72b8e739644c0da471761b2e7d607a": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "6b49f415ff2d4b049fbbbda0920bcb94": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "6d3545f866c3418dbc6fb2c05319cf19": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "c", "layout": "IPY_MODEL_d53bc888234b4f7e8eb56ef8971b49b2", "max": 300, "step": 50, "style": "IPY_MODEL_c4ad8d775a1b469691f76990b9a4cfbd" } }, "6e8ba0fe94dd4bef9b4f196bc1fe8d32": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "b", "layout": "IPY_MODEL_297518126b324814876d5c8ba9bed05d", "max": 300, "min": -100, "step": 10, "style": "IPY_MODEL_2010a12203a6442aadff6a1395d7d5ca" } }, "6ee8d68a153544328dbd5000b221bfc4": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "layout": "IPY_MODEL_e314ab6920714200b69e151575e935bd", "outputs": [ { "data": { "image/svg+xml": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n \n\n\n\n\n \n\n\n \n\n\n\n\n \n\n\n \n\n\n\n\n\n\n\n\n\n", "text/plain": "" }, "metadata": {}, "output_type": "display_data" } ] } }, "704627424e814110b54a59a6f2a3163c": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "a", "layout": "IPY_MODEL_d94dd714b5594690992b58bbb0aa9199", "max": 300, "min": -100, "step": 10, "style": "IPY_MODEL_9ac9298a1782439a8888a21462480cf6", "value": 200 } }, "7328211680b544fb97f47b643a677038": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "73a5b030ed2740abb2ae37a159037f23": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "7780a7c71f434ecca780926d47f6a230": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "y", "layout": "IPY_MODEL_7df05740c858422da60301aafe659822", "max": 300, "step": 50, "style": "IPY_MODEL_644b9c2778de4b1091e5d87d3a1555f6", "value": 150 } }, "7af14dc2de8e435ca1a3f935b1c9840c": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "a", "layout": "IPY_MODEL_61972fbb6aee4c6a9b0949421cba5003", "max": 300, "step": 50, "style": "IPY_MODEL_48109e46a3424e2da9e6e9d1f5b4f23c", "value": 300 } }, "7b303ac30fc948f9bd18f6442dbd8c51": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "x", "layout": "IPY_MODEL_500292032e2e4a8895071940a1c0a5aa", "max": 300, "step": 50, "style": "IPY_MODEL_a2ec5a39228d45aa9b3f042ed68e24fa" } }, "7d2905d70b19470887bfa2e1f7923dbb": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "layout": "IPY_MODEL_f4f01045d9584c778fdfc62f23b8e12b", "outputs": [ { "name": "stdout", "output_type": "stream", "text": "Coût = 1*200 + 6*0 + 13*0 = 200\n" }, { "data": { "text/latex": "Cout $f(a,b,c) = 1*200 + 6*0 + 13*0 = 200$.", "text/plain": "" }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/svg+xml": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n \n\n\n\n\n \n\n\n\n\n\n\n\n\n\n", "text/plain": "" }, "metadata": {}, "output_type": "display_data" } ] } }, "7dccb64990d14b6caec0f9894a786143": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "_dom_classes": [ "widget-interact" ], "layout": "IPY_MODEL_934f56c88f634584ab12bec236f10aea" } }, "7df05740c858422da60301aafe659822": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "850b64933a6f40a6a68e000f7e826d55": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "88dda621b3604f569c1164f165b0e52e": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "c", "layout": "IPY_MODEL_32ff674bbf5d45b8b314e3a5bf321cff", "max": 300, "min": -100, "step": 10, "style": "IPY_MODEL_39a8dc5510b342f798a58bffc7dee746" } }, "8ee6519ee169459ca16c6addd30ceeb1": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "c", "layout": "IPY_MODEL_227659d081ed4d15b315913c055ee8ef", "max": 300, "min": -100, "step": 10, "style": "IPY_MODEL_0dbc208ff42545508c86482b03667c11" } }, "8ff9440daffd481e96aef4681432006a": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "92b3417dd99e464ebe3bec9b9df3bc30": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "934f56c88f634584ab12bec236f10aea": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "9904c60daa624f5f8b4d5336dddf2ccf": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "_dom_classes": [ "widget-interact" ], "children": [ "IPY_MODEL_5da730a76c1548dfbdcab70f7aba8e29", "IPY_MODEL_6ee8d68a153544328dbd5000b221bfc4" ], "layout": "IPY_MODEL_246745891e9a4dbcb5aec50633dbc818" } }, "99e27b1d093d47b9a95d6263bcee73ce": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "9ac9298a1782439a8888a21462480cf6": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "9bcbd875c57a4e4abb266f3a814fcc0b": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "_dom_classes": [ "widget-interact" ], "children": [ "IPY_MODEL_64d16847060e490bab43f6296a275987", "IPY_MODEL_7780a7c71f434ecca780926d47f6a230", "IPY_MODEL_38dfd1ee95a945b399a388623c7d99bf", "IPY_MODEL_f5d3f7486960453da80677f1c883f5f8" ], "layout": "IPY_MODEL_5d7f849470ef40d9a39c5c78b962c4d3" } }, "a2ec5a39228d45aa9b3f042ed68e24fa": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "a62c44ec669642d6b23d18189a5c14e1": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "aa1ba02c6f8f483587c70ce4807bcc87": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "_dom_classes": [ "widget-interact" ], "children": [ "IPY_MODEL_1efae46f99964624a5016a469c236b09", "IPY_MODEL_0013df4fa6bf40328e5c7f1122568189", "IPY_MODEL_5a8758b6f09247ee8c5c3c29ee900fee", "IPY_MODEL_07ed157521b34a55b146cfd9724c4ce1" ], "layout": "IPY_MODEL_5f60e1e4d73743399c230f6f4d8afc75" } }, "aec567f969e440d1b86166c2a296d13c": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "_dom_classes": [ "widget-interact" ], "children": [ "IPY_MODEL_07687316f22045d788fc04ae1dcab927", "IPY_MODEL_67132e890a524f82b218178268f1773e", "IPY_MODEL_22aece595a8d43d88ffdc12a28b4e284", "IPY_MODEL_7d2905d70b19470887bfa2e1f7923dbb" ], "layout": "IPY_MODEL_bb343487b22f4d0a93460c93bdd6826b" } }, "afb9960e6f4b4bcf8c17a3f6724674c5": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "b", "layout": "IPY_MODEL_b759afe9096645a192ef9fdca3d48a12", "max": 300, "step": 50, "style": "IPY_MODEL_2c339a695d0f445aaa50cd55301c2fe8" } }, "b005c649cf334004a33568a43c524f83": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "b6e26016f1944db5bea35f17f047adfe": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "b759afe9096645a192ef9fdca3d48a12": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "b893a4e6ca6747aca5ec9fb84f2b916d": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "bb343487b22f4d0a93460c93bdd6826b": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "bd940a794d694fcc8662123bb2afca69": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "layout": "IPY_MODEL_7328211680b544fb97f47b643a677038", "outputs": [ { "data": { "image/svg+xml": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n \n\n\n\n\n \n\n\n \n\n\n\n\n \n\n\n \n\n\n\n\n\n\n\n\n\n", "text/plain": "" }, "metadata": {}, "output_type": "display_data" } ] } }, "c4ad8d775a1b469691f76990b9a4cfbd": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "c53b919e52a84508a6bace773e00416c": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "c8a35410828149568bfbbc02454008b5": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "b", "layout": "IPY_MODEL_99e27b1d093d47b9a95d6263bcee73ce", "max": 300, "min": -100, "step": 10, "style": "IPY_MODEL_a62c44ec669642d6b23d18189a5c14e1", "value": 160 } }, "c9d24498844b47eb90895a44b14d9766": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "a", "layout": "IPY_MODEL_6b49f415ff2d4b049fbbbda0920bcb94", "max": 300, "min": -100, "step": 10, "style": "IPY_MODEL_ef9d5bd7238a40daabb94fa3d45ee792", "value": -50 } }, "ccaa6aa48f34466998e53e00bf842323": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "d53bc888234b4f7e8eb56ef8971b49b2": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "d8dad505f1ef4124987198ab73e45125": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "d94dd714b5594690992b58bbb0aa9199": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "de19a02ca0354ea785fe24a17a8147d1": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "e1223394717b4ffb8584895663a3baca": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "_dom_classes": [ "widget-interact" ], "children": [ "IPY_MODEL_7b303ac30fc948f9bd18f6442dbd8c51", "IPY_MODEL_bd940a794d694fcc8662123bb2afca69" ], "layout": "IPY_MODEL_c53b919e52a84508a6bace773e00416c" } }, "e314ab6920714200b69e151575e935bd": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "e31f9d600c4c4c6da32be47bd2cf6809": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "a", "layout": "IPY_MODEL_41acaf6fb8da4fdea98d6f9029051e6a", "max": 300, "min": -100, "step": 10, "style": "IPY_MODEL_101e990cd49547b3813da5276f501aa0" } }, "ef9d5bd7238a40daabb94fa3d45ee792": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "f4f01045d9584c778fdfc62f23b8e12b": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "f5d3f7486960453da80677f1c883f5f8": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "layout": "IPY_MODEL_14c62a4e46eb47f48024bacf5079d706", "outputs": [ { "data": { "image/svg+xml": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n \n\n\n\n\n \n\n\n \n\n\n\n\n \n\n\n \n\n\n\n\n\n\n\n\n\n", "text/plain": "" }, "metadata": {}, "output_type": "display_data" } ] } }, "fb197948e178435da9e8b6f2e137f4d9": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } } }, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 4 }