1A - Enoncé 15 novembre 2021 - rattrapage#

Links: notebook, html, python, slides, GitHub

Correction de l’examen du 15 novembre 2021.

from jyquickhelper import add_notebook_menu
add_notebook_menu()

Exercice 1 : optimisation de volume#

On cherche à expliquer la forme des briques de lait. On rappelle quelques formules :

  • aire d’une surface : S = longueur x largeur

  • volume d’une brique : V = longueur x largeur x hauteur

Q1 : écrire une fonction qui calcule l’aire d’une surface#

def surface(longueur, largeur):
    return longueur * largeur

surface(3, 4)
12

Q2 : écrire une fonction qui calcule le volume d’une brique#

def volume(longueur, largeur, hauteur):
    return longueur, largeur, hauteur

volume(3, 4, 5)
(3, 4, 5)

On veut connaître les dimensions de la brique idéale d’un litre : son volume est 1 et sa surface (la somme des surfaces de toutes les faces) est minimale. Ceci afin de minimiser l’utilisation de matières premières.

Q3 : écrire une fonction qui retourne la somme des surfaces des faces d’une brique#

def surface_brique(longueur, largeur, hauteur):
    return (surface(longueur, largeur) +
            surface(largeur, hauteur) +
            surface(hauteur, longueur)) * 2

surface_brique(3, 4, 5)
94

Q4 : la brique optimale#

On considère l’ensemble [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1., 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.]. On fait varier plusieurs dimensions dans cet ensemble, on ne garde que celle dont le volume est 1 et la surface minimale. Quelles sont les dimensions optimales ?

import numpy

def brique_optimale(ensemble):
    meilleur = None

    for longueur in ensemble:
        for largeur in ensemble:
            hauteur = 1 / (longueur * largeur)
            surf = surface_brique(longueur, largeur, hauteur)
            if meilleur is None or surf < meilleur:
                meilleur = surf
                solution = longueur, largeur, hauteur
    return meilleur, solution


ensemble = (numpy.arange(20) + 1) / 10
brique_optimale(ensemble)
(6.0, (1.0, 1.0, 1.0))

Q5 : on inclut la surface nécessaire pour coller les extremités#

Pour fermer une brique, il faut pouvoir coller les faces entre elles. La surface additionnelle est égale à une fois la plus petite des faces + la surface d’un carré de côté la plus petite dimension. Modifier la fonction précédente pour en tenir compte.

def brique_optimale_surplus(ensemble):
    meilleur = None

    for longueur in ensemble:
        for largeur in ensemble:
            hauteur = 1 / (longueur * largeur)
            surf = (surface_brique(longueur, largeur, hauteur) +
                    surface(longueur, largeur) + largeur ** 2)
            if meilleur is None or surf < meilleur:
                meilleur = surf
                solution = longueur, largeur, hauteur
    return meilleur, solution


ensemble = (numpy.arange(20) + 1) / 10
brique_optimale_surplus(ensemble)
(7.4471428571428575, (1.0, 0.7, 1.4285714285714286))

Dans cette écriture, le programme suppose implicitement que largeur est le plus petit côté. Ce n’est pas toujours le cas. Quand ce n’est pas le cas, on peut vérifier en permutant longueur et largeur, la surface est plus grande. L’optimisation ne choisira pas cette solution. Si ce n’était pas le cas, il suffirait d’exclure tous les cas où largeur > longueur.

Q6 : une bouteille de deux litres deux fois plus large#

Le producteur souhaite écouler la moitié de sa marchandise avec des bouteilles de lait de deux litres, aussi hautes et longues mais deux fois plus large pour pouvoir les stocker facilement. La surface de cette bouteille est celle-ci :

surface_brique2(longueur, largeur, hauteur) = surface_brique(longueur, largeur, hauteur) - 2 * surface(largeur, hauteur).

Quelles sont les dimensions optimales ?

def brique_optimale_surplus_deux_litres(ensemble):
    meilleur = None

    for longueur in ensemble:
        for largeur in ensemble:
            if largeur > longueur:
                continue
            hauteur = 1 / (longueur * largeur)
            surf1 = (surface_brique(longueur, largeur, hauteur) +
                     surface(longueur, largeur) + largeur ** 2)
            surf2 = surf1 - surface(largeur, hauteur) * 2
            surf = surf1 * 2 / 3 + surf2 / 3  # donc autant de litres de lait dans chacun des contenants
            if meilleur is None or surf < meilleur:
                meilleur = surf
                solution = longueur, largeur, hauteur
    return meilleur, solution


ensemble = (numpy.arange(20) + 1) / 10
brique_optimale_surplus_deux_litres(ensemble)
(6.6938095238095245, (0.8, 0.7, 1.7857142857142858))

Q7 : petite brique en bleue, grosse brique en rouge#

Le producteur se sert d’une rangée de longueur de 10 briques de 1 litre dans laquelle il insère des briques de deux litres pour envoyer des messages codés (en binaire).

Example de message : A A B B A B B A B B A = une bouteille de 1 litre, B = moitié d’une bouteille de deux litres.

Combien y a-t-il de possibilités dans une rangée d’une longueur de 10 briques de 1 litre.

def messages(n):
    possibilites = [1 for i in range(n + 1)]
    for i in range(2, n + 1):
        possibilites[i] = possibilites[i-1] + possibilites[i-2]
    return possibilites

messages(10)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

C’est un problème assez classique, le nombre de possibilités pour n=10 est égale au nombre de possibilités pour n=8 et une bouteille de 2 litres + le nombre de possibilités pour n=9 et une bouteille de 1 litre.