math spé option info TP4 La guerre des étoiles (calcul d`un

Transcription

math spé option info TP4 La guerre des étoiles (calcul d`un
math spé option info TP4
La guerre des étoiles (calcul d’un couplage maximal dans un graphe biparti)
d’après un sujet de TP de l’ENS Cachan
Année scolaire 2016-2017
Dans une galaxie lointaine, très lointaine, les humains des forces de l’alliance ont développé une technologie
leur permettant d’emporter une victoire définitive contre les races extra-terrestres. Cette nouvelle technologie
leur permet de produire d’énormes vaisseaux de combat et de puissance équivalente aux redoutables bases de
défense extra-terrestres. Les forces de l’alliance contrôlent un certain nombre de planètes alors que d’autres
sont sous le contrôle des aliens. La production de chaque vaisseau nécessite une certaine quantité de temps
constante au cours du temps et propre à chaque planète. Le taux de production de la planète de l’alliance Pi
est noté αi (en nombre de vaisseaux par année) et chaque planète dispose initialement d’un certain nombre
vi de vaisseaux. Chaque planète commence à produire des vaisseaux à l’instant t = 0. Ainsi, au temps t, la
planète Pi dispose de vi + tαi vaisseaux. De même, chaque planète extra-terrestre Qj dispose initialement
d’un certain nombre bj de bases et en produit βj par an.
Lors d’un affrontement entre les vaisseaux de l’alliance et les bases extra-terrestres, l’armée en supériorité
numérique emporte le combat. En cas de victoire de l’alliance, cette dernière prend le contrôle de la planète.
En cas d’égalité des forces en présence, c’est l’alliance qui emporte la victoire.
Bol, le général en chef de l’alliance, a décidé que pour profiter de l’effet de surprise tous les vaisseaux des
forces de l’alliance partiraient à la même date T . Il a également décidé de la stratégie suivante : pour chaque
planète extra-terrestre Qj , il choisit une planète de l’alliance Pi qui produira des vaisseaux jusqu’à la date
T et qui seront tous envoyés vers la planète Qj . Une planète extra-terrestre ne peut donc être envahie que
par au plus une planète de l’alliance et aucune planète de l’alliance n’envoie ses vaisseaux vers deux planètes
extra-terrestres différentes. Une des difficulté tient au fait qu’il faut un temps δi,j (parfois infini en raison
de l’inexistence de voie inter-galactique) pour se rendre de la planète Pi à la planète Qj . Et pendant ce
temps, les planètes extra-terrestres continuent de produire leurs bases de défense. Notre objectif est d’aider
le général Bol à prendre le contrôle de chaque planète extra-terrestre le plus tôt possible.
1 - Génération aléatoire de galaxies
Une galaxie G représente les forces en présence et correspond donc à la donnée de :
• n le nombre de bases de l’alliance, m le nombre de bases extra-terrestres et p le nombre de routes intergalactiques,
• les listes de couples (vi , αi )0≤i<n et (bj , βj )0≤j<m
• la liste de p triplets (i, j, δi,j ) représentant les voies inter-galactiques.
Choisissez un u0 strictement positif et inférieur ou égal à 64006. Votre suite d’entiers (uk )k≥0 est alors définie
par :
!
"
∀ k ≥ 1, uk = 15091 × uk−1 mod 64007
Définition 1) On note G(n, m, p) la galaxie comportant n planètes de l’alliance, m planètes extra-terrestres
et telle que :
• la planète de l’alliance Pi (pour 0 ≤ i < n) dispose de vi = u2i mod 21 vaisseaux au temps t = 0 et a un
taux de production αi = u2i+1 mod 21,
• la planète extra-terrestre Qj (pour 0 ≤ j < m) dispose de bj = u2(j+n) mod 7 bases au temps t = 0 et a
un taux de production βj = u2(j+n)+1 mod 7,
• la planète Pu2(n+m)+3k mod n est à (u2(n+m)+3k+1 mod 50) années de la planète Qu2(n+m)+3k+2 mod m pour
0 ≤ k < p.
Si plusieurs voies inter-galactiques connectent deux planètes, on supprimera évidemment les doublons pour
ne retenir que celle dont la durée est la plus courte.
Une galaxie G sera représentée par un enregistrement :
type galaxie = {alliance: (int*int) vect; alien: (int*int) vect; routes: int vect vect}
avec G.alliance.(i) = (vi , αi ), G.alien.(j) = (bj , βj ) et G.routes.(i).(j) = δi,j .
Par convention, δi,j sera égal à 50 s’il n’existe pas de chemin inter-galactique de Pi à Qj .
Question 1) Écrire une fonction gal : int -> int -> int -> galaxie telle que l’appel gal n m p renvoie la galaxie G(n, m, p) (on commencera par créer une table contenant les valeurs ui utiles).
Indiquer si la première planète de l’alliance est reliée à la première planète extra-terrestre (et si oui indiquer
le nombre d’années requises pour s’y rendre) dans les galaxies suivantes :
a) G(20, 10, 40)
b) G(20, 10, 200)
c) G(100, 50, 300)
Pour une date de départ t donnée (non nécessairement entière), la planète Pi vaincra la planète Qj si et
seulement si le nombre (non nécessairement entier) de vaisseaux partant de Pi au temps t est supérieur ou
égal au nombre de bases en Qj au temps t + δi,j .
Définition 2) On note Gt (m, n, p) le graphe sur l’ensemble {P0 , P1 , . . . , Pn−1 , Q0 , Q1 , . . . , Qm−1 } comportant une arête entre Pi et Qj si et seulement si la planète de l’alliance Pi vainc la planète extra-terrestre Qj
en partant au temps t. Un tel graphe sera représenté par un vecteur de longueur m dont l’entrée d’indice j
contient la liste des i tels qu’il y ait une arête de Pi à Qj dans Gt (m, n, p).
Question 2) Écrire une fonction graphe : galaxie -> float -> int list vect qui, appliquée à une
galaxie G(n, m, p) et à un nombre réel t renvoie le graphe Gt (n, m, p). Calculer le nombre d’arêtes, ainsi que
le degré 1 minimal et maximal des sommets représentant les planètes extra-terrestres, dans les graphes
a) G3 (20, 10, 40)
b) G30 (20, 10, 200)
c) G50 (100, 50, 300)
Le graphe Gt (n, m, p) varie avec t mais le nombre de dates (strictement positives) où ce graphe change est
fini : ces dates sont appelées instants critiques.
Question 3) Écrire une fonction instants_critiques : galaxie -> float list qui calcule la liste croissante des instants critiques d’une galaxie. Indiquer le nombre d’instants critiques, ainsi que le premier de ces
instants, pour les galaxies suivantes :
a) G(20, 10, 40)
b) G(20, 10, 200)
c) G(100, 50, 300)
2 - Plan de bataille
On appelle couplage d’un graphe un ensemble d’arêtes du graphe ne contenant aucun couple d’arêtes ayant un
sommet commun. La recherche d’un ensemble maximal d’arêtes ayant cette propriété s’appelle un problème
de couplage maximal. Il est aisé de voir que l’Alliance remportera une victoire définitive en lançant ses
vaisseaux au temps t si et seulement s’il existe un couplage du graphe Gt de cardinal m. Pour construire un
couplage maximal, on peut générer systématiquement tous les couplages et choisir le meilleur. Cependant
cet algorithme naïf a pour inconvénient d’avoir une complexité exponentielle en le nombre de routes intergalactiques, ce qui risque de ne plaire au général Bol. L’objet de cette partie est de concevoir un algorithme
plus efficace afin d’éviter son courroux. Un couplage C sera représenté par un vecteur d’entiers de longueur
n, C.(i) contenant l’unique j (s’il existe) tel que l’arête (Pi , Qj ) appartienne à C, et la valeur m si un tel j
n’existe pas.
Définition 3) On dira qu’un arête e = {Pi , Qj } est inférieure à une arête e$ = {Pi$ , Q$j } si et seulement
si (i, j) est inférieur à (i$ , j $ ) pour l’ordre lexicographique. On note Et (n, m, p) l’ensemble trié des arêtes de
Gt (n, m, p) et Ct (n, m, p) l’ensemble trié d’arêtes extrait de Et (n, m, p) en en sélectionnant une sur dix.
1. le degré d’un sommet est le nombre d’arêtes qui en partent.
2
Question 4) Modifier la fonction graphe : galaxie -> float -> (int*int) list pour qu’elle renvoie
la liste croissante Et (n, m, p).
Question 5) Écrire une fonction qui extrait un élément sur 10 d’une liste et une fonction est_couplage
qui teste si une liste d’arêtes triées est un couplage. Donner la première arête de Ct (n, m, p) et indiquer si
Ct (n, m, p) est un couplage ou non pour les ensembles suivants :
a) C3 (20, 10, 40)
b) C30 (20, 10, 200)
c) C50 (100, 50, 300)
Soit C un couplage ; un sommet est dit saturé si c’est l’extrémité d’une arête de C (on dira sinon qu’il est
insaturé). Une chaîne améliorante de longueur 2p + 1 est une suite de sommets (x0 , x1 , . . . , x2p+1 ) telle que :
•
•
•
•
x0 est une planète insaturée de l’alliance ;
x2p+1 est une planète allien insaturés ;
{x0 , x1 }, {x1 , x2 }, . . ., {xp−1 , xp } sont des arêtes du graphe ;
{x1 , x2 }, {x3 , x4 }, . . . , {x2p−1 , x2p } ∈ C.
Une chaîne (x0 , x1 , . . . , xp ) sera représentée par la liste [|x0 ; x1 ; . . . ; xp |].
Étant donnés un couplage C et une chaîne améliorante CA , il est toujours possible de construire un couplage
C $ de cardinalité supérieure en considérant la différence symétrique de C et de CA , comme dans l’exemple
ci-dessous, où les arêtes de CA n’appartenant pas à C sont représentées par des tirets :
P0
P1
P2
P3
P4
P5
P6
P7
Q0
Q1
Q2
Q3
Q4
Q5
Q6
Q7
P0
P1
P2
P3
P4
P5
P6
P7
Q0
Q1
Q2
Q3
Q4
Q5
Q6
Q7
P8
C et CA
P8
C$
Question 6) Écrire une fonction amelioration : int -> int vect -> int list qui calcule C $ en fonction de m, C et CA.
Si C est un couplage, nous cherchons une chaîne améliorante de la façon suivante : nous partons d’un sommet
Qj insaturé ; s’il existe une arête {Pi , Qj } avec Pi insaturé, (Pi , Qj ) est une chaîne améliorante ; sinon, nous
choisissons une arrête {Pi , Qj } (s’il en existe) : le sommet Pi est donc saturé et il existe un unique j1 tel
que {Pi , Qj1 } ∈ C ; nous reprenons le calcul précédent en remplaçant Qj par Qj1 . La difficulté est qu’en cas
d’échec, il est nécessaire de revenir en arrière pour explorer d’autres choix, jusqu’à obtenir une solution (s’il
en existe une). Pour cela, nous utiliserons la méthode suivante :
3
• pour chaque j ∈ {0, 1, . . . , m − 1}, nous calculons les choix possibles depuis le sommet Qj ; s’il existe une
arête {Pi , Qj } avec Pi insaturé, le sommet Qj sera dit gagnant ; sinon, nous calculons la liste (éventuellement vide) des i tels que {Pi , Qj } soit une arête du graphe. Pour différencier ces deux cas, nous utiliserons
le type :
type choix = GAGNE of int | LISTE of int list ;;
Le premier pas consistera donc à calculer le vecteur Choix de longueur m dont l’entrée d’indice j donnera
les choix associés au sommet Qj ;
• nous initialisons ensuite une pile L contenant les couples (j, []) où j décrit l’ensemble des indices des
sommets Qj insaturés. Cette pile contient tous les débuts possibles de chaînes améliorantes ; tant que L
est non vide, on récupère la tête (j, l) de L (en supprimant (j, l) de L : si Qj est un sommet gagnant,
associé au sommet Pi , la liste i :: j :: l est une chaîne améliorante et on termine le calcul en vidant la pile
L ; sinon, on ajoute à L tous les couples (j1 , i1 :: j :: l) pour i1 choix possible de j et {Pi1 , Qj1 } ∈ C.
• pour ne pas boucler indéfiniment, il est nécessaire de n’étudier qu’au plus une fois chaque sommet Pi :
nous utiliserons donc un vecteur deja_vu de longueur n initialisé à la valeur [|f alse; f alse; . . . ; f alse|] et
nous n’ajouterons (j1 , i1 :: j :: l) à L que lorsque le sommet Pi1 n’a pas encore été rencontré.
Question 7) Écrire une fonction init_choix: int liste -> int list vect -> choix vect qui, appliqué à un couplage et à un graphe, renvoie un vecteur représentant les choix des sommets Qj . Par exemple,
avec le couplage C et le graphe représenté ci-dessous (les arêtes du graphe n’appartenant pas au couplage
sont représentées en gris)
P0
P1
P2
P3
P4
P5
P6
P7
Q0
Q1
Q2
Q3
Q4
Q5
Q6
Q7
P8
la fonction pourra renvoyer le vecteur
[| GAGNE(1) ; LISTE([1 ;6]) ; LISTE([0]) ; GAGNE(3) ; GAGNE(5) ; GAGNE(4) ; LISTE([6 ;8]) ; GAGNE(5) |]
Question 8) Écrire une fonction chaine_ameliorante: int liste -> int list vect -> int list qui,
appliquée à un couplage et à un graphe, renvoie une chaîne améliorante ; si une telle chaîne n’existe pas, la
fonction renverra la liste vide. Si l’ensemble C défini à la question 6 est un couplage, construire une chaîne
améliorante pour les graphes suivants :
a) G3 (20, 10, 40)
b) G30 (20, 10, 200)
c) G50 (100, 50, 300)
On admettra qu’un couplage est de cardinal maximal si et seulement s’il n’accepte aucune
chaîne améliorante.
Question 9) Écrire une fonction couplage_optimal: int liste -> int list vect -> unit qui, appliquée à un couplage C et à un graphe, transforme C en un couplage optimal. Calculer le cardinal d’un
couplage optimal pour les graphes suivants :
a) G3 (20, 10, 40)
b) G30 (20, 10, 200)
c) G50 (100, 50, 300)
Question 10) Écrire une fonction solution: int -> int -> int -> float*(int vect) qui, appliquée à
trois entiers n, m et p, renvoie (s’il existe) le premier instant et le plan de bataille permettant aux planètes de
l’alliance de vaincre les planètes extra-terrestres dans la galaxie G(n, m, p). À quel instant l’attaque doit-elle
être lancée dans les galaxie :
a) G(20, 10, 40)
b) G(20, 10, 200)
c) G(100, 50, 300)
4