Está en la página 1de 2

Examen d’informatique

(CPP Grenoble – 1re année)

Thierno Barry, Frederic Devernay, Julie Dumas, Matthieu Moy


avril 2016

1 Aucun document n’est autorisé, en dehors de l’aide-mémoire distribué avec le sujet. Les calculatrices sont
également interdites.
2 Vous pouvez utiliser les ordinateurs pour expérimenter ou faire des calculs, mais rendez toutes vos
réponses sur la copie papier. Le contenu du compte informatique est effacé à la fin de l’examen.
3 Il y a 9 questions, compter au plus 5mn par question.
4 La plupart des questions sont indépendantes. Si vous n’arrivez pas à implémenter une fonction, vous
pouvez tout de même utiliser cette fonction pour les questions suivantes.

1 Problème du voyageur de commerce


On considère un ensemble de n villes réparties dans le plan (cf. figure 1.(a)). Le problème du voyageur de
commerce consiste à trouver le plus court chemin qui passe une (et une seule) fois par chaque ville, en revenant
au point de départ. On néglige pla courbure de la terre et on considère donc la distance usuelle entre deux points
(x1 , y1 ) et (x2 , y2 ) comme : (x − x1 )2 + 2
√ (y2 − y1 ) . Par exemple, l’itinéraire 1 proposé figure 1.(b) a une
√ √ √ 2
longueur √ de √ 9+1+ √ 2 + 1 + 9 + 2 + 2 ≈ 11.15, alors que l’itinéraire 2 de la figure 1.(c) a une longueur
de 2 + 2 + 2 2 + 2 + 2 ≈ 9.65 (sur cet exemple, c’est l’itinéraire optimal).
Ce problème est bien connu en informatique, et il n’existe pas aujourd’hui d’algorithme de complexité
polynomiale pour le résoudre : le pire cas est exponentiel en fonction du nombre de villes. Nous allons ici utiliser
un algorithme probabiliste pour chercher une solution : choisir k itinéraires au hasard, et renvoyer le plus court
d’entre eux. Plus k est grand, plus on a de chance d’obtenir une solution proche de l’optimal 1 .

(a) Ensemble de villes (b) Itinéraire 1 (c) Itinéraire 2

Figure 1 – Itinéraires entre villes

1.1 Définition du problème en Python


Une instance du problème peut être définie par une liste de villes, chaque ville étant définie par ses coor-
données, elles-mêmes définies par une liste de deux éléments (abscisse et ordonnée). L’exemple de la figure 1 est
représenté en Python par :
1. On pourrait montrer que la probabilité d’obtenir la solution optimale tend vers 1 quand k tends vers +∞

1
VILLES = [
[1 , 1] ,
[3 , 1] ,
[2 , 2] ,
[4 , 2] ,
[2 , 4]
]
N = len ( VILLES )
Dans la suite de l’exercice, on suppose que VILLES et N sont définies en variable globale.
La première ville est VILLES[0] et se trouve aux coordonnées (1, 1). La seconde, VILLES[1] aux coordonnées
(3, 1), etc. On a donc VILLES[1][0] == 3, VILLES[1][1] == 1...
On définit un itinéraire entre villes comme une liste d’indices i ∈ [0, n − 1] de villes, tel que chaque indice ap-
paraît une et une seule fois dans la liste. L’itinéraire de la figure 1.(b) est représenté par la liste [0, 3, 1, 4, 2]
et celui de la figure 1.(c) par [0, 1, 3, 4, 2]. Le fait que l’itinéraire soit cyclique est implicite : on ne fait pas
apparaître deux fois l’indice de la ville de départ. On peut remarquer que les dessins des figures 1.(b) et 1.(c)
peuvent être représentées par plusieurs listes (selon le sens de parcours et le choix de la ville de départ).

1.2 Algorithme probabiliste de résolution


Nous allons dans un premier temps écrire une fonction choisir_itineraire() qui choisit un itinéraire au
hasard. Cette fonction va choisir les villes une par une (n choix pour la première ville, puis n − 1 choix parmi les
villes restantes, puis n − 2 ...). Choisir un entier dans l’intervalle [0, n] se fait en Python avec randint(0, n)
(randint se trouve dans le module Python random). Il nous reste à implémenter la fonction « choisir une ville
parmi les villes non encore visitées ».

Question 1 (1.5 points) Écrire une fonction choisir_ville(itineraire) qui renvoie une ville (un entier
dans [0, n−1]) qui n’apparaît pas dans itineraire. La ville doit être choisie aléatoirement avec une distribution
uniforme sur les villes non-visitées.

Question 2 (1 point) Quelle est la complexité en pire cas de la fonction choisir_ville(itineraire)


que vous venez d’écrire ? On demande une notation du type O(. . .), et une justification du résultat.

Question 3 (1 point) Écrire une fonction choisir_itineraire() qui construit et renvoie une liste de n
villes différentes choisies aléatoirement.

Question 4 (0.5 point) Écrire une fonction distance(n1, n2) qui renvoie la distance entre la ville
d’indice n1 et celle d’indice n2. Sur notre exemple, distance(0, 1) doit renvoyer 2.

Question 5 (1.5 points) Écrire une fonction longueur_itineraire(itineraire) qui prend en paramètre
un itinéraire et renvoie la longueur de l’itinéraire (i.e. la somme des distances entre les villes apparaissant dans
l’itinéraire, sans oublier la distance à parcourir pour revenir au point de départ).

Question 6 (2 points) Écrire une fonction voyageur(k) qui tire k itinéraires aléatoirement et renvoie
l’itinéraire le plus court parmi ceux-ci.

Question 7 (1 point) Quelle est la complexité de la fonction voyageur que vous venez d’écrire (attention,
la complexité est fonction de plusieurs variables). Justifiez votre réponse.

Question 8 (1 point) Écrire une fonction affiche_itineraire(itineraire) qui prend en argument un


itinéraire et affiche les coordonnées des villes à parcourir.
Par exemple, affiche_itineraire([0, 3, 1, 4, 2]) doit afficher :
[1 , 1]
[4 , 2]
[2 , 2]
[2 , 4]
[3 , 1]

Question 9 (0.5 point) Écrire le code Python qui calcule et affiche l’itinéraire le plus court parmi 1000
tirages aléatoires.

También podría gustarte