{ "cells": [ { "cell_type": "markdown", "metadata": { "toc": true }, "source": [ "

Table of Contents

\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Une prise en main rapide de Jupyter / Julia / JuMP\n", "\n", "## Qu'est-ce qu'un Jupyter notebook ?\n", "\n", "Un Jupyter notebook est un document qui contient \n", "+ du texte \n", " - que l'on peut formatter à l'aide de Markdown\n", " - qui peut contenir des maths à l'aide de $\\LaTeX$\n", "+ du code\n", " - avec lequel on peut intéragir en ligne\n", " \n", "Un notebook est une succession de cellule, chacune pouvant être soit du code, soit du texte.\n", "Quelques astuces :\n", "+ double-clicker pour voir le contenu et modifier une cellule\n", "+ M / Y pour changer le type de cellule\n", "+ Ctrl-enter pour éxecuter la cellule\n", "+ shift-enter pour éxecuter la cellule et passer à la suivante\n", "+ Alt-enter pour éxecuter la cellule et en ajouter une nouvelle\n", "\n", "Vous pouvez télécharger le fichier .ipynb via l'onglet \"file\" en haut à gauche. Vous pouvez aussi télécharger un pdf." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Qu'est-ce que Julia ?\n", "\n", "Julia est un langage de programmation, comparable à Python. C'est un langage récent, développé pour le calcul scientifique. \n", "\n", "Quelques éléments intéressant :\n", "+ langage open-source\n", "+ langage compilé \"Just-in-time\"\n", "+ langage disposant d'un terminal (comme python)\n", "+ ...\n", "\n", "Faisons nos premiers pas avec Julia. Exécuter les cellules suivantes (shift-enter), n'hésitez pas à modifier pour prendre en main :" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "1+1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = [0 5 10 15]\n", "a[1]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sum(a)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sum(x^2 for x in a)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "length(a)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "exp.(a) .- a #to apply an operation or function componentwise just add . " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "@doc exp # to get documentation on a function" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for i = 1:5\n", " println(\"itération \",i)\n", "end" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "function factorielle(n)\n", " if n == 0\n", " return 1\n", " end\n", " res = 1\n", " for i=1:n\n", " res = res * i\n", " end\n", " return res\n", "end" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "factorielle(5)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "round(1.9453;sigdigits=2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "rand(3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Further info can be found [here](https://learnxinyminutes.com/docs/julia/) or in the [documentation](https://docs.julialang.org/en/v1/)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "## Qu'est-ce que JuMP ?\n", "\n", "JuMP est l'un des packages phare de Julia.\n", "\n", "Il s'agit d'un package de modélisation, qui permet d'écrire un problème d'optimisation de manière simple puis de demander à un Solver de le résoudre.\n", "\n", "Nous allons maintenant faire nos premiers pas avec JuMP.\n", "\n", "Plus d'information sur http://www.juliaopt.org/JuMP.jl/v0.20.0/quickstart/ " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Mise en place\n", "\n", "Avant toute chose il faut installer puis appeler les bibliothèques utiles. \n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "import Pkg; #Cette cellule peu prendre du temps à s'executer.\n", "Pkg.add(\"GLPK\")\n", "Pkg.add(\"Ipopt\")\n", "Pkg.add(\"JuMP\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On peut faire la liste des packages installés et leur version en executant la commande suivante." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Pkg.status()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Nous allons maintenant dire que nous souhaitons utiliser ces packages (comparable à \"from packet import *\" en python) \n", "\n", "[Cette commande peut prendre du temps]" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "using JuMP, Ipopt, GLPK # cette cellule peut prendre du temps à s'éxécuter." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "## Construction d'un premier problème linéaire\n", "\n", "Nous souhaitons résoudre le problème linéaire suivant\n", "$$ \\begin{align*} \n", "\\min_{x,y} \\quad & 2x+3y \\\\\n", "s.c. \\quad & x+y \\geq 1 \\\\\n", "& x \\geq 0, y\\geq 0 \\\\\n", "\\end{align*}$$\n", "\n", "Commençons par construire le problème" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$ x + y \\geq 1.0 $" ], "text/plain": [ "x + y ≥ 1.0" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "OPTIMIZER = GLPK.Optimizer # On définit un optimizer\n", "m = Model(OPTIMIZER) # On construit un problème d'optimisation\n", "\n", "@variable(m,x>=0) # x est une variable réelle positive de m\n", "@variable(m,y>=0) # y est une variable réelle positive de m\n", "\n", "### Remarque les fonctions @variable / @objective / @constraint sont des fonctions spécifiques (des macros) \n", "# qui autorise de donner un argument comme 2*x+3*y sans qu'il soit évalué. \n", "# Ce n'est pas un comportement générique des fonctions julia.\n", "\n", "@objective(m,Min, 2*x+3*y) # l'objectif de m est de Minimiser 2*x+3*y\n", "\n", "@constraint(m,x+y >= 1 ) # m a pour contrainte x+y <=1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On peut vérifier que m est bien ce que l'on souhaite" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Min 2 x + 3 y\n", "Subject to\n", " x + y ≥ 1.0\n", " x ≥ 0.0\n", " y ≥ 0.0\n" ] } ], "source": [ "print(m)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On peut également résoudre m" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "OPTIMAL\n", "FEASIBLE_POINT\n", "FEASIBLE_POINT\n" ] } ], "source": [ "optimize!(m)\n", "println(termination_status(m))\n", "println(primal_status(m))\n", "println(dual_status(m))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Et si on souhaite connaître la valeur optimale du problème ou des solutions optimales on peut les avoir de la manière suivante" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.0\n", "x = 1.0\n", "y = 0.0\n" ] } ], "source": [ "println(JuMP.objective_value(m))\n", "println(\"x = \",JuMP.value(x))\n", "println(\"y = \",JuMP.value(y))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Un second problème linéaire\n", "\n", "Nous allons maintenant construire un problème linéaire plus complexe.\n", "$$\n", "\\begin{align*}\n", "\\min_{x\\in R^n} \\quad & \\sum_{i=1}^n c_i x_i \\\\\n", "s.c. \\quad & \\sum_{i=1}^n x_i \\geq n \\\\\n", "& -1 \\leq x_i \\leq 2 & \\forall i\n", "\\end{align*}\n", "$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m2 = Model(OPTIMIZER)\n", "n = 10 # on choisit n = 10, mais vous pouvez le modifier\n", "c = rand(n) # c est choisi ici de manière aléatoire \n", "\n", "@variable(m2, -1<= x[1:n] <= 2) # x est une variable de m2 contenant n éléments x[1], x[2],...,x[n] tous compris entre -1 et 2\n", "\n", "@objective(m2,Min, sum(c[i]*x[i] for i=1:n) )\n", "\n", "@constraint(m2,sum(x[i] for i=1:n) >= n)\n", " \n", "print(m2) " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "optimize!(m2)\n", "println(termination_status(m2))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "value.(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ajoutons maintenant une série de contraintes de la forme\n", "$$ x_i + x_{i+1} \\leq 1, \\qquad \\forall i \\in 2, \\dots, n-1$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for i = 1 : n-1\n", " @constraint(m2, x[i]+x[i+1] <= 2)\n", "end" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "optimize!(m2)\n", "value.(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Un problème non-linéaire\n", "\n", "Nous allons terminer avec un problème non-linéaire simple.\n", "\n", "$$\n", "\\begin{align*}\n", "\\min_{x \\in R^{n.m}} \\quad & \\sum_{i,j} x_{i,j}^2 \\\\\n", "s.c. \\quad & \\sum_{i=1}^n x_{i,j} = 1 & \\forall j \\in [m] \n", "\\end{align*}\n", "$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "using Ipopt # Solveur de problèmes non-linéaires par point intérieur." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "OPTIMIZER_NL = Ipopt.Optimizer\n", "\n", "m3 = Model(OPTIMIZER_NL)\n", "\n", "N,M = 5,7 \n", "\n", "@variable(m3, x[i=1:N, j=1:M])\n", "\n", "@objective(m3, Max, sum(x[i,j]^2 for i=1:N, j=1:M))\n", "\n", "for j=1:M\n", " @constraint(m3, sum(x[i,j] for i =1:N)==1)\n", "end\n", "\n", "@constraint(m3, x[1,1]^2+x[1,2]^2 <= 0.5) # we can add quadratic constraints\n", "\n", "@NLconstraint(m3, x[2,1]^2 + x[2,2]^3 <= 1) # we can add non-linear constraints" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(m3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "optimize!(m3)\n", "println(objective_value(m3))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "value.(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tested Version :\n", "- JuMP 0.20 / Julia 1.5.2" ] } ], "metadata": { "@webio": { "lastCommId": null, "lastKernelId": null }, "kernelspec": { "display_name": "Julia 1.5.2", "language": "julia", "name": "julia-1.5" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.5.2" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": true, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": true, "toc_position": {}, "toc_section_display": true, "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }