La connexion SSH n'est actuelle disponible que depuis une petite partie du reseau interne U-PSud. Utilisez de préférence les adresses de dépots en HTTPS pour le moment.

Commit d0738b71 authored by Nicolas M. Thiéry's avatar Nicolas M. Thiéry

Talk given at Edinburgh's nbgrader workshop

parent ddc283b2
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Cours 2: Parcours de graphes"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"## Définitions\n",
"- un *chemin* est une suite de sommets `(v_0, v_1, v_2, ...)` tel qu'il existe une arête entre chaque paire de sommets `v_i` et `v_{i+1}`"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- la *distance* entre deux sommets `u` et `v` est la longueur du plus court chemin entre `u` et `v` (ou la somme des poids des arêtes)."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- Soit $G$ un graphe non orienté. La composante connexe d'un sommet $u$ de $G$ est l'ensemble des sommets atteignables depuis $u$ en suivant un chemin dans $G$."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Exemple de graphe\n",
"<center><img src=\"../exercices/graphe.jpeg\" width=\"50%\"></center>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": [
"%run Graph.py\n",
"G = exemples.cours_1_reseau()\n",
"G.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Parcours de graphe"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"def parcours(G, u):\n",
" \"\"\"\n",
" INPUT:\n",
" - 'G' - un graphe\n",
" - 'u' - un sommet du graphe\n",
" \n",
" OUTPUT: la liste des sommets `v` de `G` tel qu'il existe un chemin de `u` à `v`\n",
" \"\"\"\n",
" # Invariants:\n",
" # - `vus`: l'ensemble des sommets déjà rencontrés\n",
" # - `a_faire`: l'ensemble des sommets déjà rencontrés, mais pas encore traités"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Ensembles définis récursivement \n",
"Définition: soit $E$ un ensemble, $R\\subset E$ un sous ensemble fini, et $f$ une fonction associant à chaque élément de $E$ un sous-ensemble fini de $E$. L'ensemble défini récursivement par $R$ et $f$ est le plus petit sous-ensemble de $E$ contenant $R$ et stable par $f$.\n",
"\n",
"Exemples:\n",
"\n",
"- $E=\\mathbb N$, $R=\\{1\\}$, $f(e) = \\{ e + 2 \\}$\n",
"- $E=\\mathbb N$, $R=\\{1\\}$, $f(e) = \\{ 2e, e+3 \\}$\n",
"- $E$: listes, $R=\\{()\\}$, $f(u)$: rajouter $0$ ou $1$ à la fin du $u$\n",
"- $E$: listes, $R=\\{(1,2,3,2,1)\\}$, $f(u)$: supprimer la première ou dernière lettre de $u$\n",
"- Permutations, ...\n",
"- ..."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## [Parcours en largeur](https://fr.wikipedia.org/wiki/Algorithme_de_parcours_en_largeur) et calcul de distance"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**Objectif**: Calculer la distance entre deux sommets?"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**Approche**: raffiner l'algorithme pour parcourir les sommets par distance croissante"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"def parcours(G, u):\n",
" \"\"\"\n",
" INPUT:\n",
" - 'G' - un graphe\n",
" - 'u' - un sommet du graphe\n",
" \n",
" OUTPUT: un dictionnaire associant à chaque sommet `v` sa distance depuis `u`\n",
" \"\"\"\n",
" # Invariants:\n",
" # - `distances`: un dictionnaire associant à chaque sommet vu sa distance `d_v` depuis `v`\n",
" # - `a_faire`: la liste des sommets déjà rencontrés, mais pas encore traités\n",
" # - `d_v` est croissante sur `a_faire`, variant d'au plus `1`\n",
" # - `d_w <= d_v` pour `w` traité et `v` dans `a_faire`"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"## Parcours en profondeur\n",
"Que se passe-t'il si on utilise une pile pour `a_faire`?\n",
"Essayer sur an arbre"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Plus court chemin, avec poids: Algorithme de Dijkstra\n",
"https://fr.wikipedia.org/wiki/Algorithme_de_Dijkstra\n",
"<!-- By HB (Own work) [GFDL (http://www.gnu.org/copyleft/fdl.html) or CC BY-SA 3.0 (https://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons !-->\n",
"<img src=\"DijkstraBis01.svg\">"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"G = [ (0,1,87), (0,2,217), (0,4,173),\n",
" (1,5,80),\n",
" (2,6,186), (2,7,103),\n",
" (3,7,183),\n",
" (4,9,502),\n",
" (5,8,250),\n",
" (7,9,167),\n",
" (8,9,84) ]"
]
}
],
"metadata": {
"celltoolbar": "Slideshow",
"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.7"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Rush Hour"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "836e0c855b6c4349ab3d4ae43912a781",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"VBox(children=(HBox(children=(Dropdown(options=(('Niveau 1', 1), ('Niveau 3', 3), ('Niveau 7', 7), ('Niveau 8'…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from RushHour import *\n",
"from ipywidgets import Button, Dropdown, VBox, HBox, Textarea\n",
"from bqplot import Figure, LinearScale, Lines, Tooltip\n",
"import time\n",
"\n",
"class Application:\n",
" def __init__(self):\n",
" self.niveau = Dropdown(options=[('Niveau {}'.format(i), i) for i in RushHour.niveaux()])\n",
" self.niveau.observe(lambda widget: self.change_niveau(widget.owner.value))\n",
" \n",
" self.voiture = Dropdown(options=[])\n",
" self.modele = Plateau(1)\n",
" self.vue = Figure(scale_x = LinearScale(min=0, max=self.modele.dimension),\n",
" scale_y = LinearScale(min=self.modele.dimension, max=0))\n",
" self.vue.layout.width=\"75ex\"\n",
" self.vue.layout.width=\"75ex\"\n",
" self.vue.layout.height=self.vue.layout.width;\n",
"\n",
" self.vue.vue_voitures = {}\n",
" for lettre, couleur in couleurs.items():\n",
" vue_voiture = Lines(x=[], y=[],\n",
" scales={'x':self.vue.scale_x,\n",
" 'y':self.vue.scale_y},\n",
" fill='inside',\n",
" colors=[couleurs[lettre]],\n",
" visible=False,\n",
" tooltip=Tooltip(fields=[\"lettre\"],show_labels=False),\n",
" )\n",
" vue_voiture.lettre = lettre\n",
" vue_voiture.on_element_click(lambda vue_voiture, _: self.choix_voiture(vue_voiture.lettre))\n",
" self.vue.vue_voitures[lettre] = vue_voiture\n",
" self.vue.marks = list(self.vue.vue_voitures.values())\n",
"\n",
" boutton_solution = Button(description=\"Solution\")\n",
" boutton_solution.on_click(self.montre_solution)\n",
" self.widget = VBox([HBox([self.niveau, boutton_solution]),\n",
" self.vue,\n",
" self.boutton_direction('U'),\n",
" HBox([self.boutton_direction('L'), self.voiture, self.boutton_direction('R')]),\n",
" self.boutton_direction('D')\n",
" ])\n",
" self.widget.layout.align_items = 'center'\n",
" self.change_niveau(1)\n",
"\n",
" # Vues\n",
" def boutton_direction(self, direction):\n",
" boutton = Button(description=direction)\n",
" boutton.on_click(self.on_click_direction)\n",
" return boutton\n",
"\n",
" # Contrôleurs\n",
" def change_niveau(self, i):\n",
" self.niveau = i\n",
" self.modele = Plateau(i)\n",
" self.voiture.options = self.modele.voitures.keys()\n",
" for letter, vue_voiture in self.vue.vue_voitures.items():\n",
" vue_voiture.visible = letter in self.modele.voitures\n",
" self.mise_a_jour_vue()\n",
" \n",
" def montre_solution(self, boutton):\n",
" self.modele = Plateau(self.niveau)\n",
" self.mise_a_jour_vue()\n",
" boutton.description=\"Calcul en cours ...\"\n",
" solution = RushHour.solution(self.niveau)\n",
" boutton.description=\"Solution\"\n",
" for coup in solution:\n",
" self.modele = self.modele.deplace(coup)\n",
" self.mise_a_jour_vue()\n",
" time.sleep(1)\n",
" \n",
" def on_click_direction(self, boutton):\n",
" plateau = self.modele.deplace(self.voiture.value, boutton.description)\n",
" if plateau is not None:\n",
" self.modele = plateau\n",
" self.mise_a_jour_vue()\n",
" \n",
" def choix_voiture(self, lettre):\n",
" self.voiture.value = lettre\n",
" \n",
" def mise_a_jour_vue(self):\n",
" for lettre,voiture in self.modele.voitures.items():\n",
" cases = voiture.cases()\n",
" xmin = min(case[1] for case in cases)\n",
" xmax = max(case[1] for case in cases) + 1\n",
" ymin = min(case[0] for case in cases)\n",
" ymax = max(case[0] for case in cases) + 1\n",
" vue_voiture = self.vue.vue_voitures[lettre]\n",
" vue_voiture.x = [xmin, xmax, xmax, xmin]\n",
" vue_voiture.y = [ymin, ymin, ymax, ymax],\n",
"\n",
" \n",
" def display(self):\n",
" return self.widget\n",
"\n",
"A = Application()\n",
"A.display()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"celltoolbar": "Aucun(e)",
"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.7"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
This diff is collapsed.
A2R00
X2R21
C2R44
R3R52
O3D05
P3D10
Q3D13
B2D40
X2R21
A2R31
C2R52
O3D23
P3D35
B2D41
A2D01
C2D04
D2D05
E2D13
F2D25
H2D43
B2R02
X2R21
I2R32
A2R03
B2R12
X2R20
F2R30
G2R34
H2R40
P3R43
K2R50
Q3R53
O3D05
C2D14
D2D22
E2D23
I2D42
O3D00
P3D03
B2D32
E2D45
A2R01
X2R21
Q3R33
R3R52
A2R01
B2R03
C2R10
D2R12
X2R22
G2R44
H2R51
I2R53
O3D14
P3D15
Q3D20
R3D21
E2D32
F2D33
A2R00
X2R21
Q3R31
R3R53
B2D02
O3D03
P3D10
A2D00
C2D13
D2D22
R3D25
F2D42
O3R03
B2R11
X2R20
E2R33
G2R43
Q3R53
O3D00
B2D04
C2D11
D2D12
P3D15
E2D33
F2D42
A2R01
X2R23
Q3R30
K2R44
H2R50
I2R53
name: talk
channels:
- conda-forge
dependencies:
- xeus-cling
- notebook
- nbgrader
- rise # for slides
- shapely
- descartes
- matplotlib
- ipywidgets
- ipympl
- bqplot
- tqdm
- pip
- pip:
- ordo
from shapely.affinity import translate, rotate, scale
from shapely.geometry import Point, Polygon, LineString
from shapely.ops import cascaded_union
import descartes
import matplotlib.pyplot as plt
#%matplotlib inline
from ipywidgets import interact, IntSlider
from math import sqrt, sin, cos
import io
def disque(x, y, r):
"""
Renvoie un disque de centre (x,y) et de rayon r.
>>> cercle(0,0,1)
"""
return Point([x,y]).buffer(r)
def cercle(x, y, r):
"""
Renvoie un cercle de centre (x,y) et de rayon r.
>>> cercle(0,0,1)
"""
return disque(x, y, r).boundary
def chevron(largeur=-10, hauteur=10, petite_hauteur=5):
return Polygon([[0,0], [-largeur, hauteur], [0,petite_hauteur], [largeur, hauteur]])
def dessine(*figures, fig=None):
if fig is None:
fig = plt.figure(figsize=(5,5))
else:
fig.clear()
ax = fig.add_subplot(1,1,1)
ax.grid(True)
for figure in figures:
ax.add_patch(descartes.PolygonPatch(figure))
ax.axis([-20,20,-20,20])
return fig
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Compute the area of a rectangle of width 4 and height 5"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"ordo_solution": {
"text/plain": "20\ntype: int"
}
},
"outputs": [
{
"data": {
"text/plain": [
"20\n",
"type: int"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/html": [
"<div class='alert alert-success alert-dismissible ordo_feedback' role='alert'> <button type='button' class='close' data-dismiss='alert'>&times;</button> <strong>Well Done!</strong> That was the correct response. </div>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"4 * 5"
]
}
],
"metadata": {
"celltoolbar": "Aucun(e)",
"kernelspec": {
"display_name": "C++11",
"language": "C++11",
"name": "xcpp11"
},
"language_info": {
"codemirror_mode": "text/x-c++src",
"file_extension": ".cpp",
"mimetype": "text/x-c++src",
"name": "c++",
"version": "-std=c++11"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment