Vous êtes sur la page 1sur 6

Université de Tunis

Institut Préparatoire aux Etudes d'Ingénieurs de Tunis

Examen Informatique N°2


Sections : SM & SP Durée : 2h
Date : 04 Mai 2023 Nombre de pages : 6

Documents non autorisés


Les parties I, II et III sont indépendantes
Les fonctions et les méthodes seront implémentées par le langage Python

Les trois parties portent sur la même thématique présentée dans la description qui suit :
Description :
Un centre de contrôle aérien est confronté à un problème de régulation de trafic aérien
impliquant plusieurs avions. En effet, les altitudes de vol en croisière sont normalisées
signifiant que les avions volent à des altitudes prédéterminées dans une plage de hauteurs
dans l'atmosphère. Mais, certains niveaux de vol sont très demandés, ce qui peut engendrer
des conflits potentiels. Pour alléger le travail des contrôleurs et diminuer les risques, le
système de régulation s’autorise à faire voler un avion à un niveau différent de son niveau de
vol souhaité, appelé aussi NVD (Niveau de Vol Demandé). On limite donc le choix aux
niveaux immédiatement supérieur et inférieur au NVD.

Ce problème de régulation est modélisé par un graphe (dont le but est d’imposer des plans de
vol qui réduisent le plus possible le coût total de la résolution des conflits) dans lequel chaque
vol est représenté par trois sommets. Le sommet ‘0’ correspond à l’attribution du NVD, le
sommet ‘+’ au niveau supérieur et le sommet ‘–‘ au niveau inférieur. Chaque conflit potentiel
entre deux vols sera représenté par une arête reliant les deux sommets concernés. Le coût d’un
conflit potentiel sera représenté par une valeur attribuée à l’arête correspondante. Figure 1
présente le graphe de conflits potentiels entre trois vols A, B et C.

Figure 1. Graphe de conflits potentiels entre trois vols

1
Dans la Figure 1:
 Faire voler les trois avions à leur NVD engendre un coût de régulation entre A et B de
100 et un coût de régulation entre B et C de 400, soit un coût total de la régulation de
500 (pas de conflit entre A et C (absence d’arête)).
 Faire voler l’avion A à son NVD et les avions B et C au-dessus de leur NVD engendre
un conflit potentiel de coût 100 entre A et B et 150 entre A et C, soit un coût total de
250 (il n’y a plus de conflit entre B et C).
 Faire voler A et C à leur NVD et B au-dessous de son NVD engendre des solutions de
coût nul (absence d’arêtes reliant les sommets ‘0’, ‘0’ et ‘-‘ des vols B, A et C,
respectivement).

Partie I : Simulation numérique


A- Problématique
Chaque vol étant représenté par trois sommets, le graphe des conflits associé à 𝑛 vols
𝑣 ,𝑣 ,…,𝑣 possède 3𝑛 sommets que nous numéroterons de 0 à 3𝑛 − 1. Nous
conviendrons que pour 0 ≤ 𝑘 < 𝑛 :
− le sommet 3𝑘 représente le vol 𝑣 à son NVD.
− le sommet 3𝑘 + 1 représente le vol 𝑣 au-dessus de son NVD.
− le sommet 3𝑘 + 2 représente le vol 𝑣 au-dessous de son NVD.

Le coût de chaque conflit potentiel est stocké dans une matrice d’entiers d’ordre 3𝑛 (3𝑛×3𝑛)
accessible grâce à la variable globale conflit :
- Si 𝑖 et 𝑗 désignent deux sommets du graphe, alors conflit[i,j] est égal au coût du
conflit potentiel (s’il existe) entre les plans de vol représentés par les sommets 𝑖 et 𝑗.
- S’il n’y a pas de conflit entre ces deux sommets, conflit[i,j] vaut 0. On convient que
conflit[i, j] vaut 0 si les sommets 𝑖 et 𝑗 correspondent au même vol (Figure 2).
On notera que pour tout couple de sommets (𝑖, 𝑗), conflit[i,j] = conflit[j,i]

0 0 0 100 100 0 0 150 0


0 0 0 0 0 50 0 0 0
0 0 0 0 200 0 0 300 50
100 0 0 0 0 0 400 0 0
100 0 200 0 0 0 200 0 100
0 50 0 0 0 0 0 0 0
0 0 0 400 200 0 0 0 0
150 0 300 0 0 0 0 0 0
0 0 50 0 100 0 0 0 0

Figure 2. Matrice des coûts des conflits associés au graphe représenté par la Figure 1

1. Écrire une fonction nb_conflits() sans paramètre qui renvoie le nombre de conflits
potentiels, c’est-à-dire le nombre d’arêtes dont la valeur est non nulle.
2. Exprimer en fonction de 𝑛 la complexité de cette fonction.

B- Régulation
a) Pour un vol 𝑣 on appelle niveau relatif l’entier 𝑟 valant 0, 1 ou 2 tel que :
 𝑟 = 0 représente le vol 𝑣 à son NVD.
 𝑟 = 1 représente le vol 𝑣 au-dessus de son NVD.
 𝑟 = 2 représente le vol 𝑣 au-dessous son NVD.

2
Une régulation sera présentée par une liste d’entiers Lr = [𝑟 , 𝑟 , … , 𝑟 ]. Par exemple, la
régulation [0, 0, …, 0] représente la situation dans laquelle chaque avion vole à son NVD.
Il pourra être utile d’observer que les sommets du graphe des conflits choisis par la régulation
𝑟 portent lesnuméros 3𝑘 + 𝑟 pour 0 ≤ 𝑘 < 𝑛. On remarque également qu’au sommet 𝑠 du
graphe correspond le niveau relatif 𝑟 = 𝑠 % 3 et le vol 𝑣 tel que 𝑘 = 𝑠//3.

Exemple :
En utilisant le sommet s d’indice 7 de la matrice conflit de la figure 2 on a :
 k = 7//3, représentant le vol numéro 2 ;
 𝑟 = 7%3, représentant le niveau relatif 1 pour le vol numéro 2.
Inversement, pour une liste de régulation Lr = [0,0,1], pour déterminer le sommet s
correspondant au vol 𝑣 on a :
 𝑠= 3*2 + Lr[2], représentant le sommet d’indice 7 dans la matrice conflit.

b) On appelle coût d’une régulation la somme des coûts des conflits potentiels que cette
régulation engendre.

3. Écrire une fonction nbvol_niveau_relatif(Lr) qui prend en paramètre une liste


représentant une régulation (liste de 𝑛 entiers) et qui renvoie une liste de 3 entiers
[a, b, c] dans laquelle 𝑎 est le nombre de vols à leurs niveaux NVD, 𝑏 le nombre de
vols au-dessus de leurs niveaux NVD et 𝑐 le nombre de vols au-dessous de leurs
niveaux NVD.
4. Écrire une fonction cout_regulation(Lr) qui prend en paramètre une liste représentant
une régulation et qui renvoie le coût de celle-ci.
5. Évaluer en fonction de 𝑛, la complexité de cette fonction.
6. Écrire une fonction cout_NVD() qui renvoie le coût de la régulation pour laquelle
chaque avion vole à son NVD .

C- Algorithme Minimal

On définit le coût d’un sommet comme la somme des coûts des conflits potentiels dans
lesquels ce sommet intervient. Par exemple, le coût du sommet correspondant au niveau NVD
de l’avion A dans le graphe de la Figure 1 est égal à 100 + 100 + 150 = 350.
L’algorithme Minimal consiste à sélectionner le sommet du graphe de coût minimal ; une fois
ce dernier trouvé, les deux autres niveaux possibles de ce vol sont supprimés du graphe et on
recommence avec ce nouveau graphe jusqu’à avoir attribué un niveau à chaque vol.
Dans la pratique, plutôt que de supprimer effectivement des sommets du graphe, on utilise
une liste etat_s de 3𝑛 entiers tels que :

 etat_s[s] vaut 0 lorsque le sommet 𝑠 a été supprimé du graphe.


 etat_s[s] vaut 1 lorsque le sommet 𝑠 a été choisi dans la régulation.
 etat_s[s] vaut 2 dans les autres cas.

7. Écrire une fonction cout_sommet(s, etat_s) qui prend en paramètres un numéro de


sommet 𝑠 (n’ayant pas été supprimé) ainsi que la liste etat_s et qui renvoie le coût du
sommet 𝑠 dans le graphe défini par la variable globale conflit et le paramètre etat_s.
Exprimer en fonction de 𝑛 sa complexité.

3
8. Écrire une fonction sommet_cout_min(etat_s) qui, parmi les sommets qui n’ont pas
encore été choisis ou supprimés, renvoie le numéro du sommet de coût minimal.
9. Écrire une fonction verif_etat_s(L) qui retourne True si le nombre de la valeur 2 dans
la liste L est inférieur à sa taille, False sinon.
10. Écrire une fonction minimal() qui renvoie la régulation résultant de l’application de
l’algorithme Minimal. Afin de trouver la régulation, nous optons pour les étapes
suivantes :
- Initialiser une liste etat_s à 3n valeurs indiquant qu’aucun vol n’a été traité.(n
étant le nombre de vols)
- Initialiser une liste de régulation à des 0 indiquant que tous les vols sont
initialement assignés à leurs NVD.
- Répéter les étapes ci-dessous jusqu’à ce que tous les vols soient traités :
 Trouver le sommet ayant le coût minimal.
 Déterminer le vol correspondant à ce sommet.
 Mettre à jour etat_s en mettant à 0 les sommets correspondant aux
autres niveaux de ce vol et en mettant à 1 le sommet choisi.
 Mettre à jour la liste de régulation en enregistrant le niveau choisi pour
ce vol.

Partie II : Programmation Orientée Objet


L’objectif de cette partie est d’implémenter les deux classes :
- Vol
- Régulation

Description des classes

A. Classe Vol
Cette classe représente un vol avec un identifiant unique, un niveau de vol demandé et une
liste de conflits potentiels avec d'autres vols. Elle expose une méthode permettant de calculer
le coût d'une affectation de niveau de vol.
Attributs :
- nb_vols : attribut de classe initialisé à 0 et utilisé afin de générer un identifiant unique
pour chaque vol (incrémenté après chaque appel de méthode __init__()).
- id_vol : entier strictement positif représentant l’identifiant unique du vol courant.
- nvd : entier représentant le niveau de vol demandé.
- conflits_potentiels : liste des identifiants des vols qui peuvent potentiellement entrer
en conflit avec le vol courant. Ainsi, au moins aucun et au plus tous les vols
représentés par cette liste peuvent être en conflit avec le vol courant
.
Méthodes :

- __init__(...) : permet de créer une nouvelle instance de la classe Vol à partir des
paramètres nvd et conflits_potentiels.
- __str__(...) : permet de retourner une représentation textuelle du vol sous la forme :
"Volid_vol (NVD: nvd, Conflits Potentiels: conflits_potentiels)". Exemple :
Vol1(NVD : 350, Conflits Potentiels : [2, 3])

4
- cout(...) : qui à partir d’une liste L_nvd représentant des niveaux de vol assignés à
chaque vol, retourne le coût d'une affectation de niveau de vol pour le vol courant.
Ainsi, le coût est représenté par le nombre de vols en conflit potentiel avec le vol en
question.
Exemple : Supposons que nous avons 3 vols :
 Vol1 avec un NVD de 350 et une liste de conflits potentiels [2, 3]
 Vol2 avec un NVD de 310 et une liste de conflits potentiels [1]
 Vol3 avec un NVD de 350 et une liste de conflits potentiels [1, 2]
Pour une liste L_nvd = [350, 310,350], le coût d'une affectation de niveau de vol pour
chaque vol est donné comme suit :

 Vol 1 : 1 (conflit avec Vol 3)


 Vol 2 : 0 (pas de conflit potentiel)
 Vol 3 : 1 (conflit avec Vol 1)

B. Classe Régulation
Cette classe représente une régulation de vols avec une liste de vols et leurs niveaux de vol
assignés. Elle expose des méthodes permettant d'assigner un niveau de vol à un vol donné, de
calculer le coût total de la régulation, de vérifier si un vol a déjà été affecté à un niveau de vol
et si la régulation est complète.

Attributs :
- vols : liste des vols inclus dans la régulation.
- niv_assign: liste des niveaux de vol assignés aux vols, initialisée à une liste de
valeurs None. Cela signifie que pour chaque vol, aucun niveau de vol ne lui a été
assigné initialement.

Méthodes :
- __init__(...) : permet de créer une nouvelle instance de la classe Régulation à partir de
la liste du paramètre vols.
- __str__(...) : permet de retourner une représentation textuelle de la régulation. Un
exemple de représentation d’un objet de la classe Régulation est donné ci-dessous.
Exemple :
Régulation:
Vol1, Niveau Assigné: 280
Vol2, Niveau Assigné: 300
Vol3, Niveau Assigné: 320
- cout(...) : qui retourne le coût total de la régulation en additionnant les coûts de
chaque vol.
- est_assigné(...) : qui à partir d’un paramètre v représentant un objet Vol retourne True
si un vol a déjà été affecté à un niveau de vol, False sinon.
- assigner_niveau(...) : qui à partir des paramètres v et nva représentant
respectivement un objet Vol et un niveau de vol à assigner, permet d'assigner un
niveau de vol à un vol donné.

5
- est_complète(...) : qui retourne True si la régulation est complète (tous les vols ont
été affectés à un niveau de vol), False sinon.
Travail demandé :

1. Construire la classe Vol


2. Construire la classe Régulation

Partie III : Base de données relationnelle


Nous modélisons, de manière très simplifiée, les plans de vol gérés par l’organisation de
navigation aérienne, sous la forme d’une base de données comportant deux tables :

aeroport(id_aero, ville, pays)


vol (id_vol, #depart, #arrivee, jour, heure, niveau)

• id_aero : identifiant de l’aéroport (Clé primaire, chaine de caractères).


• ville : principale ville desservie (chaine de caractères) ;
• pays : pays dans lequel se situe l’aéroport (chaine de caractères).
• id_vol : numéro du vol (chaine de caractères) ;
• depart : identifiant de l’aéroport de départ (Clé étrangère, chaine de caractères) ;
• arrivee : identifiant de l’aéroport d’arrivée (Clé étrangère, chaine de caractères)
• jour : jour du vol (chaine de caractères, affiché au format aaaa-mm-jj)
• heure : heure de décollage souhaitée (chaine de caractères, affichée au format hh:mi)
• niveau : niveau de vol souhaité (entier).

Soit le script python suivant :

import sqlite3 as sq
con = sq.connect(‘BDVOL.db’)
cur = con.cursor()
……
cur.close()
con.close()

Dans la suite, con et cur seront utilisées par les fonctions comme des variables globales.

Travail demandé :

1. Écrire une fonction creer_vol() qui permet de créer la table vol dans la base en
exprimant toutes les contraintes d’intégrité.
2. Écrire une fonction nb_vol(j) qui permet de retourner le nombre de vols qui doivent
décoller dans la journée j avant midi.
3. Écrire une fonction num_vol(v,j) qui permet de retourner la liste des numéros de vols
au départ d’un aéroport desservant la ville v dans la journée j.
4. Certains vols peuvent engendrer des conflits potentiels : c’est par exemple le cas
lorsque deux avions suivent un même trajet, en sens inverse, le même jour et à un
même niveau. Écrire une fonction conflit() qui permet de retourner la liste des couples
(id1, id2) des identifiants des vols dans cette situation

Bon Travail

Vous aimerez peut-être aussi