Upload
others
View
5
Download
0
Embed Size (px)
Citation preview
Travail d'étude et de recherche
Julien GUEPET
11 mai 2011
1
Table des matières
1 Introduction 3
2 Segmentation de la clientèle 3
2.1 Cas d'un seul vol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2 Cas d'un réseau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.3 Etude d'un cas particulier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3.1 Programme linéaire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3.2 Méthode probabiliste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3.3 Méthode mixte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3 Dynamic Princing 8
3.1 Modèle de la demande . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.1.1 Elasticité de la demande . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.1.2 Inverser la fonction demande . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.1.3 Etude de la fonction de revenu . . . . . . . . . . . . . . . . . . . . . . . . 10
3.1.4 Revenu marginal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.2 Méthode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.3 Méthode de programmation dynamique . . . . . . . . . . . . . . . . . . . . . . . 12
3.3.1 Algorithme récursif naïf . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.3.2 Algorithme récursif avec marquage . . . . . . . . . . . . . . . . . . . . . . 13
3.3.3 Adaptation à la variabilité de la demande . . . . . . . . . . . . . . . . . . 14
3.3.4 Simulations et comparaison . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4 Conclusion 15
5 Bibliographie 16
6 Annexe 16
6.1 Processus_Poisson.R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
6.2 Prog_Lin.R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
6.3 Methode_Probabiliste.R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
6.4 Prog_Lin_Modif.R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
6.5 Dynamic_Pricing.R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
6.6 Dynamic_Princing_Aleatoire.R . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2
1 Introduction
J'ai eectué mon travail d'étude et de recherche au laboratoire G-Scop. Ce laboratoire s'inter-
esse aux domaines de la conception, de l'optimisation et la production. Cette pluridisciplinarité le
divise en deux pôles, eux-mêmes divisés en trois domaines de compétences chacun. J'ai travaillé
dans le pôle "Optimisation et système de production", dans le domaine de compétence intit-
ulé "Optimisation Combinatoire". Ce dernier à pour but de résoudre des problèmes théoriques
d'optimisation discrète. L'équipe dans laquelle j'ai travaillé est composée de 9 chercheurs et 5
doctorants. J'ai été encadré par M. Bienia. M. Bienia étant le seul de son équipe à s'être interéssé
au Yield Management, mes recherches ne m'ont amené à ne travailler qu'avec lui. J'ai eu assez
peu de contacts avec les autres membres de l'équipe (j'ai assisté à quelques conférences). L'axe
principal de mon travail d'étude et de recherche a été la lecture et la compréhension d'une thèse
sur le Yield Management, le but étant de se familiariser avec les méthodes et les principes déjà
existants. Je me suis intéréssé plus particulièrement au cas de l'industrie du transport aérien
car ces méthodes sont largement utilisées dans ce domaine. Pour la plupart, elles en sont même
issues. Avant cela, j'ai étudié deux livres traitant d'optimisation pour consolider mes connais-
sances dans ce domaine, an de faciliter la compréhension de la thèse.
Pour résumer le Yield Management en quelques mots, cette discipline a pour but de répondre
à la problématique suivante : vendre le bon produit au bon client, au bon moment et au bon
prix. Par "bon" il faut bien sûr entendre "bon pour la compagnie aérienne", l'ensemble de ces
méthodes servant à un but nal : maximiser le revenu. En eet, la démarche habituelle pour aug-
menter le bénéce est de baisser les coûts de production en optimisant la chaine de production.
Ce principe est assez mal adapté à l'industrie du transport aérien, c'est pourquoi les méthodes
développées consistent à jouer sur le prix de vente des billets an d'augmenter le chire d'aaire
sans engendrer de coût supplémentaire. An de répondre à cette problématique on ne peut plus
vaste, il existe trois techniques majeures :
la segmentation de la clientèle, qui revient à créer plusieurs classes de clients et à vendre
les billets à des prix diérents.
la surréservation, qui revient à vendre plus de billets que le nombre de place de l'avion.
Ceci se justie par le fait que tous les clients ne se présentent pas le jour du départ.
la variation du prix en fonction du temps, ou Dynamic Pricing, qui revient à faire varier
le prix en fonction du temps.
Pour ce qui est de la surréservation (overbooking), la littérature regorge de méthodes prob-
abilistes ou d'approches plus typiques de la recherche opérationnelle. Pour ce qui est de la
segmentation et du Dynamic Pricing, on trouve relativement peu d'articles ou de livres à ce
sujet, car elles ont été développées par les compagnies elles-mêmes (recherche privée) qui les
gardent secrètes an de battre leur concurrents. C'est pourquoi j'ai choisi de me pencher plus
particulièrement sur ces deux derniers points. Nous étudierons dans un premier temps la segmen-
tation de la clientèle à travers un exemple. Nous présenterons ensuite une méthode de Dynamic
pricing.
2 Segmentation de la clientèle
La segmentation de la clientèle est basée sur la constatation suivante : tous les clients ne sont
pas prêts à mettre le même prix dans un billet d'avion et n'exigent pas les mêmes services. Il est
alors intéressant de segmenter la clientèle an de pouvoir vendre certains billets plus cher. La
question qui se pose alors est combien de places il faut réserver pour chaque classe dans l'avion.
3
2.1 Cas d'un seul vol
Dans cette partie, nous ne considérons qu'un seul vol et nous cherchons à découper la clientèle
en n classes. Un billet en classe i a pour prix pi, on suppose que p1 > p2 > .. > pn. Nous supposonsaussi que la compagnie observe une demande Di aléatoire pour la classe i.On introduit Vi(x), la fonction de revenu à l'étage i pour une capacité restante de x places.
On cherche alors à déterminer uj la répartition optimale pour l'étage i. On peut remarquer que
ui ≤ min(Di, x). On peut alors formuler notre problème comme un programme dynamique. En
eet, l'équation de Bellman suivante correspond au revenu maximal attendu :
Vi(x) = E
[max
0≤u≤min(Di,x)(piu+ Vj−1(x− u)
]En pratique, il est impossible de résoudre exactement cette équation car on ne connait pas
exactement la demande. C'est pourquoi on cherche à approcher la fonction d'évaluation V .
L'approximation qui est souvent faite est la suivante :
Vi(x) = max0≤u≤min(E[Di],x)
(piu+ Vj−1(x− u))
Ce qui revient à rendre déterministe le problème en approchant la demande par la demande
moyenne.
2.2 Cas d'un réseau
Dans cette partie, notre but est de généraliser le raisonnement précédent au cas d'un réseau
de vols. Pour modéliser notre problème, nous dénissons la matrice d'incidence A de terme
général (aij) où :
aij =
1 si le vol i est utilisé par le produit j
0 sinon
Par exemple, on considère le résau suivant :
Figure 1 : Exemple de réseau de vols.
Où il y a trois produits possibles :
un vol de A à C
4
un vol de C à B
un vol de A à B avec escale en C
La matrice d'incidence est alors :
A =
(1 0 10 1 1
)La demande est représentée par un vecteur aléatoire ~D = (D1, .., Dn) et les prix sont représentéssous forme vectorielle ~p = (p1, ..pn). Comme dans le cas d'un seul vol, en pratique il est impossible
de faire des calculs exacts car on ne connaît pas susamment la demande.
La méthode que propose l'auteur pour résoudre ce problème est de déterminer les prix seuils,
i.e. les prix minima qu'il faut vendre chaque billet an d'obtenir un bénéce optimal. An de
calculer les prix seuils, nous formulons notre problème par un programme linéaire :
max ~pT~y
sous A~y ≤ ~x
0 ≤ ~y ≤ ~µ
Les prix seuils sont obtenus par résolution du dual
min ~ΠT~x+ ~λT ~µ
sous ~ΠTA+ ~λ ≤ ~p
~λ ≥ 0
~Π ≥ 0
La solution ~Π∗ du problème dual nous donne les prix seuils. Par le principe de dualité, xer les
prix aux prix seuils revient à eectuer une segmentation ~y∗ optimale. Elle peut être interprétée
comme suit : si Πi <= pi alors il faut vendre la place, sinon il ne faut pas la vendre.
2.3 Etude d'un cas particulier
Dans cette sous-partie, nous allons tenter de résoudre notre problème sur le réseau de la
gure 1. Dans un premier temps, nous testerons une implémentation de la méthode proposée
par l'auteur. Nous n'utiliserons pas la solution duale mais la résolution du primal par le simplexe.
Nous proposerons ensuite une méthode basée sur les probabilités et nous nirons par proposer
une méthode mixte. Pour la suite, tous les algorithmes proposés ont été implémentés en R.
Pour tester ces algorithmes, nous avons modélisé la demande par un processus de Poisson. Le
chier Processus_Poisson.R (Annexe 6.1) nous permet de simuler ce processus. Nous utiliserons
désormais les notations suivantes :
λXY est l'intensité du processus de Poisson modélisant la demande pour le vol allant de
X à Y.
pXY est le prix du vol allant de X à Y.
nXY est le nombre de places réservées pour le vol allant de X à Y.
dXY est la demande pour le vol allant de X à Y.
Pour alléger les notations, nous supposerons que tous les avions ont la même capacité que
l'on notera C. T est la durée de la vente.
Dans tous les tests eectués, on prendra C = 300, pAB = 500, pAC = 300, pCB = 300 et
T = 30.
5
2.3.1 Programme linéaire
On reprend le programme linéaire de la section précédente, adapté à notre cas particulier :
max nAB ∗ pAB + nAC ∗ pAC + nCB ∗ pCB
sous nAB + nAC ≤ cAC
nAB + nCB ≤ cCB
nAB ≤ dAB
nAC ≤ dAC
nCB ≤ dCB
nAB, nAC , nCB ≥ 0
Le principe de la méthode est de résoudre le programme linéaire et d'utiliser la solution
optimale pour gérer la demande. L'algorithme a été implémenté dans le chier Prog_Lin.R
(Annexe 6.2). Remarquons juste que si la demande est trop faible, notre algorithme peut refuser
des ventes à tort. En eet, si la demande excède la prévision, il y aura rejet alors qu'il reste des
places dans l'avion, car la somme des nXY sera inférieure à C. Pour remédier à ce problème, il
sut de renormaliser la sortie du programme linéaire.
An de tester notre algorithme, nous comparons les résultats à une méthode naïve, qui
consiste à accepter toutes les demandes tant qu'il reste de la place dans l'avion. Nous tirons
aléatoirement les valeurs des λXY an de faire un test général. Nous avons eectué 1000 tirages
aléatoires. A chaque tirage, nous eectuons 100 tests an d'obtenir le comportement moyen de
notre algorithme. Nous estimons la demande par la moyenne.
Cette méthode permet d'augmenter en moyenne de 4.45% le revenu. Ce pourcentage peut sembler
petit, mais quand la demande est faible (i.e. quand on ne remplit pas les avions), segmenter la
clientèle ne sert à rien, car cela ne crée aucune restriction. Dans ce cas, le résultat est donc le
même qu'avec la méthode naïve et l'augmentation est de 0%, ce qui fait baisser le pourcentage
global.
Le problème de cette méthode est qu'elle fait une résolution en supposant que la demande
est déterministe (une fois l'approximation faite) et ne s'adapte pas du tout au cours de la vente.
Nous allons maintenant proposer une méthode qui en tient compte.
2.3.2 Méthode probabiliste
Le but de cette partie est de trouver une méthode qui tient compte de l'aléa et qui est capable
de s'adapter au cours de la vente. Nous proposons un algorithme qui répond positivement ou
négativement à une demande. Il est basé sur le principe suivant : on vend le billet si on ne
compte pas gagner plus en vendant la place plus tard à quelqu'un d'autre. Pour formaliser ce
principe, on introduit les fonctions PXY qui correspondent à la probabilité de vendre la place
pour le vol XY. Par exemple pour une demande AB, on vendra la place si :
pAB ≥ pACPAC + pCBPCB
En eet, si on ne vend pas la place en AB, on peut espérer en vendre une en AC et une en CB.
On a aussi :
pAC ≥ pABPAB − pCBPCB
En eet, si on ne vend pas la place en AC, on peut espérer en vendre une en AB mais on en
vendra alors une de moins en CB. Il faut alors enlever le revenu que l'on pensait gagner avec
cette dernière. Pour les mêmes raisons, on a :
pCB ≥ pABPAB − pACPAC
6
Le problème consiste maintenant à calculer les PXY . Il est logique que ces probabilités dépendent
du temps : si on est proche de la n de la vente, il est moins probable de réussir à vendre la
place. Elles dépendent aussi du nombre de places restantes dans le vol XY : si il reste peu de
places, il est plus probable de réussir à vendre cette place que s'il en reste beaucoup. De plus,
on ne peut pas vendre cette place plus tard si on a déjà vendu toutes les places. On a donc :
PXY (t) = P (NXY (T − t) > n)
où NXY est le processus aléatoire modélisant la demande en XY et n le nombre de places
restantes dans le vol XY. On peut maintenant les calculer de la manière suivante :
P (N(t) > n) = 1− P (N(t) ≤ n) = 1−n∑
k=0
P (N(t) = k) = 1−n∑
k=0
(λt)k
k!e−λt
dans le cas du processus de Poisson.
On peut donc écrire l'algorithme suivant :
traiterDemande(Demande d)
. Si (d = AB)
. Si (il reste des places dans les vols AC et CB)
. retourne pAB ≥ PAC .pAC + PCB.pCB
. Sinon
. retourne non
. Fin Si
. Sinon si (d = AC)
. Si (il reste des places dans le vol AC)
. Si (il reste des places dans le vol CB)
. retourne pAC ≥ PAB.pAB − PCB.pCB
. Sinon
. retourne oui
. Fin si
. Sinon
. retourne non
. Fin Si
. Sinon //d = CB
. Si (il reste des places dans le vol CB)
. Si (il reste des places dans le vol AC)
. retourne pCB ≥ PAB.pAB − PAC .pAC
. Sinon
. retourne oui
. Fin si
. Sinon
. retourne non
. Fin Si
. Fin Si
Cet algorithme a été implémenté dans le chier Methode_Probabiliste.R (Annexe 6.3).
Nous eectuons le même test que dans la partie précédente an de le tester. Nous obtenons une
7
augmentation du bénéce de 3.64%.
Cette méthode présente certains avantages. Elle est en apparence assez lente car le calcul de
toutes les probabilités est assez long. Cependant, ce calcul est eectué à chaque demande, il y a
assez peu de calculs pour chaque demande, elle est donc applicable en temps réel. De plus, au lieu
de refuser la demande, il est interéssant de l'accepter à un prix plus élevé. En eet, le terme de
droite de l'inégalité générant le refus peut servir de prix seuil, il s'agit bien du prix limite au delà
duquel il est interéssant de vendre la place. Elle peut donc servir pour construire un algorithme
de dynamic pricing. Cette méthode a cependant certaines limites. Nous avons pu eectuer les
calculs de probabilités de manière explicite car nous utilisons le processus de Poisson, on connait
donc la loi du processus. Cependant dans le cas général, on ne connait pas cette loi. De plus,
l'utilisation du processus de Poisson peut être remis en cause car cela implique que la demande
est uniforme au cours de la vente (par la propriété de perte de mémoire du processus de Poisson).
En pratique, la demande est souvent plus forte vers la n de la période de vente qu'au début,
la modélisation par le processus de Poisson semble donc incorrecte. Aussi cette méthode parait
dicile à généraliser car elle regarde trop en détail la demande, il faut réécrire un algorithme
similaire pour chaque cas particulier, ce qui est irréalisable en pratique. De plus, nos tests
semblent montrer que la méthode est moins ecace que la précédente. Cependant, nous avons
remarqué que notre algorithme a tendance à rejeter trop de demandes (l'avion part non plein), il
est probablement possible d'améliorer les résultats de cette méthode en travaillant davantage sur
les probabilités (notre raisonnement paraît trop simple). Nous n'avons pas spécialement cherché
à le faire car cette méthode est de toute façon inutilisable. Il semble donc pertinent d'introduire
les probabilités an de s'adapter au cours de la vente. Pour gagner en généralité, on peut penser
à la demande de manière plus globale, comme par exemple en travaillant sur des moyennes. C'est
ce que nous tentons de faire dans la partie suivante.
2.3.3 Méthode mixte
Nous allons tenter de modier l'algorithme basé sur le programme linéaire an de s'adapter
à la variation de la demande. L'idée est la suivante :
on résout le programme linéaire et on commence la vente en suivant les bornes ainsi
obtenues.
une fois une borne atteinte, on regarde s'il est interéssant de changer cette borne en fonction
de l'avancement de la vente.
Le but est de ne pas refuser de ventes alors que l'avion part non plein. An de calculer s'il est
interéssant de vendre tout de même la place, on compare simplement l'espérance de vente dans
le temps restant et le nombre de places restantes dans l'avion. Si l'espérance est plus faible, on
vend la place.
Cet algorithme a été implémentée dans le chier Prog_Lin_Modif.R (Annexe 6.4). Nous com-
parons cette méthode avec la méthode basée sur le programme linéaire avec la même procédure
de test que précédemment. Nous obtenons un augmentation du chire d'aaire de 0.30%. Cette
amélioration est faible, cependant sur le chire d'aaire annuel d'une compagnie aérienne, cela
représente une somme non négligeable. Cette méthode est plus facilement généralisable que la
méthode précédente puisque nous n'utilisons que l'espérance qui est plus facile à estimer que les
probabilités.
3 Dynamic Princing
Le dynamic pricing est motivé par les constatations suivantes :
plus un client a besoin d'un produit, plus il est prêt à le payer cher.
8
plus un client achète une place tôt, plus il a de chance de l'annuler avant le jour du départ.
Ainsi, si un client achète un billet à une date proche de la n de la vente, il est fortement interéssé
par ce billet et il a de fortes chances de partir. Il est donc prêt à payé son billet plus cher qu'un
client qui l'achète au début de la vente. Ce dernier est succeptible d'être interéssé par un autre
vol avant la n de la vente et il n'est donc pas prêt à le payer cher. L'avantage de faire varier le
prix en fonction du temps permet d'avoir plus de chances de remplir l'avion tout en vendant les
billets à un prix élevé. On peut illustrer ceci par les deux courbes suivantes :
A gauche, on utilise une méthode sans variation de prix, le revenu réalisé correspond à l'aire
sous le rectangle. L'idée du dynamic pricing est d'utiliser diérents prix an de réaliser plusieurs
rectangles et ainsi augmenter le revenu. Dans un premier temps, nous énoncerons les résultats
présentés dans la thèse. Pour cela, nous avons besoin de quelques notions de la théorie de l'ore
et de la demande. Enn, nous étudierons une méthode qui ne s'appuie pas sur la théorie de
l'ore, gagnant ainsi en généralité.
3.1 Modèle de la demande
L'étude de la demande revient à mettre en relation la quantité voulue d'un produit et les
diérents facteurs qui inuent sur cette quantité. Nous allons étudier ici comment la demande
varie face à une modication du prix. Nous supposerons donc que la demande ne dépend que
du prix. On dénit Ωp comme l'ensemble des prix possibles. Enn, les hypothèses suivantes sont
faites sur la demande :
Hypothèse 1 Nous supposons que la fonction demande d(p) doit être régulière i.e. :
d est de classe C1 sur Ωp.
d est strictement décroissante sur Ωp.
d est positive sur Ωp.
Pour des prix susamment hauts, la demande est nulle i.e. :
infp∈Ωp
d(p) = 0
La fonction de revenu est nie pour tout prix i.e. :
∀p ∈ Ωpr(p, d(p)) = pd(p) < +∞
La fonction de revenu admet un maximum p∗ ∈ Ωp.
3.1.1 Elasticité de la demande
Déntion 1 L'élasticité de la demande est dénie comme le pourcentage de variation de la
quantité de demande divisé par le pourcentage de variation de prix i.e. :
ε(p) =%devariationdedemande
%devariationdeprix=
∂dd∂pp
=p∂d
d∂p
9
On peut remarquer que sous l'hypothèse de décroissance de la demande en fonction du prix, εsera toujours négatif.
Par exemple si ε(p) = −1.2 une hausse du prix de 20% provoque une hausse de la demande de
0.2 ∗ (−1.2) = −24% c'est à dire une baisse de 24%. En analyse économique, on distingue alors
3 cas :
|ε(p)| < 1 la demande est dite inélastique, ce qui signie qu'elle est relativement insensible
au changement de prix.
|ε(p)| = 1 la demande est dite unitairement élastique, ce qui signie qu'une hasse du prix
provoque une baisse égale de la demande.
|ε(p)| > 1 la demande est dite élastique, ce qui signie que tout changement de prix
provoque une réaction plus grande sur la demande.
On peut également distinguer les cas limites :
ε(p) = 0 la demande est dite parfaitement inélastique, ce qui signie qu'un changement
du prix n'a aucune répercussion sur la demande.
ε(p) = −∞ la demande est dite parfaitement élastique,ce qui signie que le moindre
changement de prix entraine un très grand changement de la demande.
La connaissance de l'élasticité de la demande permet d'augmenter le revenu. En eet, nous
savons que si le prix augmente, la demande baisse, le revenu varie donc. Si la demande est
élastique, une petite baisse des prix implique une forte augmentation de la demande et le revenu
ainsi généré est plus grand. Au contraire, si la demande est inélastique, une forte hausse des prix
implique une faible baisse de la demande, là aussi le revenu généré est plus grand.
3.1.2 Inverser la fonction demande
Intuitivement, si la demande dépend du prix, il est logique que le prix dépende de la demande.
Déntion 2 L'inverse de la fonction demande p(d) est le prix le plus haut généré par une
demande d i.e. :
p(d) = max∈Ωp
p|d(p) >= d
Ceci est particulièrement utile pour un vol de A vers B avec une seule classe et une capacité
limitée : il est interéssant de connaître le prix maximum tel que la demande soit au moins égale
à la capacité.
Les hypothèses faites sur la fonction demande impliquent que son inverse est bien déni et C1
sur Ωd = x|x = d(p), p ∈ Ωp.
3.1.3 Etude de la fonction de revenu
Déntion 3 La fonction de revenu peut être dénie de deux façons équivalentes.
La fonction de revenu est égale au produit du prix par la fonction de demande i.e. :
r(p) = pd(p)
La fonction de revenu est égale au produit de la demande par la fonction de prix (inverse de la
fonction demande) i.e. :
r(d) = dp(d)
10
3.1.4 Revenu marginal
Déntion 4 On dénit le revenu marginal comme le gain ou la perte produit par la poduction
et la vente d'une unité de produit supplémentaire. Comme pour le revenu, le revenu marginal
peut être déni de deux façons équivalentes :
J(d) =∂r
∂d(d) = p(d) + dp′(d)
J(p) =∂r
∂p(p) = p+ d(p)
1
d′(p)
L'hypothèse que la fonction de revenu admet un maximum implique que J(p) est strictement
concave. J(p) permet de déterminer directement p∗. En eet, si J(p) est positive alors on a
intérêt à augmenter les prix, car une augmentation des prix générerait une augmentation du
revenu. Au contraire si J(p) est négative, on a intérêt à baisser les prix.
3.2 Méthode
Nous supposons que la fonctin de demande vérie les hypothèses de régularité de la partie
précédente. Nous supposons dans cette partie que la demande est déterministe et qu'elle est
donnée par la fonction de demande d(t,p). Rappelons que le revenu à une date t est déni par
le produit de la demande et du prix, ce qui, en utilisant l'inverse de la fonction de demande se
traduit par :
r(t, d(t)) = d(t).p(t, d(t))
Le but du vendeur est bien sur de maximiser le revenu, on peut donc formuler notre problème
par le problème d'optimisation suivant :
maxd(1),..d(T )
∑Tt=1 r(t, d(t))
sous∑T
t=1 d(t) ≤ C
d(t) ≥ 0 pour tout t = 1..T
Ce problème peut sembler être formulé à l'envers car on cherche à déterminer la demande
optimale pour chaque période. Cependant, en supposant qu'on connaisse la demande optimale, il
est possible de retrouver le prix optimal correspondant grâce à la fonction inverse de la demande
p(t, d(t)).En utilisant la méthode des multiplicateurs de Lagrange, et l'inverse de la fonctoin de demande,
on trouve que le vecteur de prix optimalep∗ = (p(1), .., p(T )) doit vérier le système suivant :
p∗(t)− λ∗
p∗=
1
|ε(t, p∗)∀t = 1..T
λ∗
(C −
T∑t=1
d(t)∗
)= 0
λ∗ ≥ 0
où λ∗ est le multiplicateur de Lagrange optimal sur la contrainte de capacité.
11
Ce système étant dicile à résoudre en général, l'algorithme glouton suivant est proposé
pour approcher la solution du problème précédent.
Pour cela, on divise la capacité C en M unités de taille ρ tel que C = Mρ.
.Algorithme_Glouton
.debut
. Initialisation : d(t) = 0 ∀t = 1, .., T
. pour k de 1 à M faire
. si maxtr(t, d(t) + ρ)− r(t, d(t)) > 0 alors
. soit t∗ la période qui maximise l'augmentation de revenu.
. d(t∗) = d(t∗) + ρ
. sinon
. STOP
. fin si
. fin pour
.fin
On peut montrer que le choix ρ = 1 est optimal.
3.3 Méthode de programmation dynamique
Le but de cette partie est de construire un algorithme ecace pour déterminer les prix
optimaux des billets en fonction du temps sans utiliser la théorie de la demande. Cela permet de
ne pas faire ces hypothèses, notamment celle de décroissance de la demande en fonction du prix.
Cette hypothèse, bien qu'a priori logique, peut être remise en question. Par exemple si un client
trouve le prix d'un produit anormalement bas, il ne va pas avoir conance en ce produit et ne
l'achetera pas. Cela se produit fréquemment dans l'industrie pharmaceutique ou dans l'industrie
informatique, des domaines où les clients ne sont souvent pas compétents et jugent la qualité du
produit uniquement en fonction de son prix. Il en est de même pour le domaine du transport
aérien : beaucoup de personnes n'ont pas conance en les vols dits charters et préfèrent payer
plus cher pour avoir une compagnie sans se soucier si la qualité du service est meilleure. L'étude
que nous allons faire n'utilise donc pas ces hypthèses.
Hypothèse 2 Voici le cadre d'application de cette méthode :
La dimension du temps est discrétisée en T périodes non nécéssairement égales i.e. t =1..T .
L'ensemble des prix possibles est lui aussi discret i.e. Ωp = pi > 0, i = 1..N. On notera
pt le prix choisi pour la période t.
On notera C la capacité de l'avion. On supposera que la demande ne dépend que du temps et
du prix. Ainsi la demande peut être représentée par une matrice TxN dont tous les coecients
sont a priori indépendants.
Cette modélisation de la demande permet d'utiliser des méthodes statistiques pour l'évaluer.
De cette manière, nous pouvons eectuer une prédiction de la demande sans faire d'hypothèse
sur sa loi de probabilité (en utilisant par exemple la régression linéaire multidimensionnelle).
Commençons par résoudre le cas où la demande est déterministe.
Le revenu sur chaque période est alors déni par
r(t, pt) = ptd(t, pt)
12
et le revenu total par
r =
T∑t=1
r(t, pt)
. Rappelons que notre but est de trouver un vecteur p = (p1, .., pT ) qui maximise le revenu. On
peut alors écrire notre problème comme le problème d'optimisation suivant :
maxp=(p1,..pT )
∑Tt=1 ptd(t, pt)
sous∑T
t=1 d(t, pt) ≤ C
Nous pouvons écrire ce problème d'optimisation sous la forme d'un programme dynamique :
V (t, c) = maxp∈Ωp
maxi=0,..,lt
(V (t− 1, c− i) + ip) où lt = min(c, d(t, p))
Avec V (1, c) = maxp∈Ωp
p.min(c, d(1, p))
3.3.1 Algorithme récursif naïf
.AlgorithmeNaïf(t,c)
.debut
. V=0
. pour p dans Ωp faire
. si t==1
. V[1,c] = max(V[1,c],p*min(c,d(t,p)))
. sinon
. pour i de 0 à min(c,d(t,p)) faire
. V = max(V,AlgortihmeNaïf(t-1,c-i) + i*p)
. fin pour
. fin si
. fin pour
. retourner V
.fin
Calculons la complexité de ce programme dynamique si on applique une méthode naïve.
Remarquons qu'elle dépend de quatre paramêtres : T, N, C et la demande. En eet, lt implique
que le nombre d'appels récursifs dépend de la demande pour chaque période et pour chaque
prix. Pour simplier les calculs, on appelle d la demande moyenne. On note C(t) la complexité
pour eectuer le calcul au temps t. On a alors :
C(t) = N.d.C(t− 1) = (Nd)t−1C(1) avec C(1) = O(N).Donc C(T ) = O((Nd)T ).
3.3.2 Algorithme récursif avec marquage
.Initialiser une matrice V de taille TxN à -1
.AlgorithmeMarquage(t,c)
.debut
. si V[t,c] == -1
. pour p dans Ωp faire
13
. si t==1
. V[1,c] = max(V[1,c],p*min(c,d(t,p)))
. sinon
. pour i de 0 à min(c,d(t,p)) faire
. V[t,c] = max(V[t,c],AlgorithmeMarquage(t-1,c-i)+i*p)
. fin pour
. fin si
. fin pour
. fin si
. retourner V[t,c]
.fin
Un tel algorithme est en O(T.N.d).En utilisant un marquage pour se rappeler quels sont les choix faits lors de la récursion, on
obtient ainsi le nombre de places à vendre et le prix de vente optimal pour chaque période. Nous
avons implémenté cet algorithme en se rappelant des choix dans le chier Dynamic_Princing.R
(Annexe 6.5).
3.3.3 Adaptation à la variabilité de la demande
Nous savons désormais résoudre notre problème de façon ecace si la demande est déter-
ministe. Nous allons voir comment résoudre de façon ecace le cas d'une demande aléatoire.
Supposons que la matrice d est une réalisation d'une variable aléaoire D, et que nous connais-
sons susamment de réalisations de la variable D an d'avoir une méthode statistique correcte
pour évaluer D. En pratique, cela signie juste utiliser les précédentes ventes similaires de la
compagnie aérienne, cette hypothèse est donc peu réstrictive. Il nous sut alors de prédire la
demande et d'appliquer l'algorithme précédent.
Cependant, bien que cette méthode soit en moyenne correcte, la prévision sera bien sûr erronée
et le résultat ainsi obtenu ne sera pas optimal. En particulier, il est fort probable que l'avion ne
parte pas plein. Par exemple, si on avait prévu 15 places pour la première période à un prix p1mais qu'en réalité il y a eu seulement 13 demandes, avec la méthode que nous utilisons actuelle-
ment, ces deux places seront perdues. An de remédier à ceci, il sut de corriger les prévisions
à la n de chaque période de vente. Ceci peut être fait simplement : après chaque période de
vente, on relance l'algorithme avec une période de moins et il faut enlever à la capacité de l'avion
le nombre de places déjà vendues. Cela permet de récupérer les places qui n'ont pas été vendues
lors de la première période. On obtient donc l'algorithme suivant :
.AlgorithmeAl\'eaoire
.debut
. pour t de 1 à T faire
. d = di..dn
. Initialiser V de taille (T-t)xN à -1
. AlgorithmeMarquage(T-t,C)
. Attendre les résultat de la période t
. C = C - nombre de places vendues à la période t
. fin pour
.fin
où d = di..dn signie qu'il ne faut prendre les n− i dernières colonnes de d.
14
Le coût d'un tel algorithme est en O(T 2.N.d), car on eectue T fois l'algorithme avec marquage
(∑T
t=1 T.N.d = O(T 2.N.d)), ce qui reste ecace. Cependant le coût est réparti sur toute la
période de la vente car il faut attendre les résultats de chaque période avant de faire appel à
l'algorithme de marquage suivant.
On arrive ainsi à s'adapter à la variation de la demande à chaque période de manière ecace.
Nous avons implémenté cet algorithme dans le chier Dynamic_Princing_Aleatoire.R (Annexe
6.6).
3.3.4 Simulations et comparaison
Comme nous ne disposons pas de données an de construire un modèle statistique, nous
avons modélisé la demande aléatoire par des lois binomiales de paramêtres n variable suivant
les prix (voir tableau ci-dessous) et p = 0.5. Nous eectuons les tests sur 4 périodes, avec 3 prix
(100 200 et 400) et une capacité de 100 places.
n p1 = 100 p2 = 200 p3 = 400
t1 70 30 0
t2 60 40 10
t3 30 50 20
t4 20 40 30
Nous eectuons les comparaisons suivantes en eectuant 10000 simulations.
Comparaison entre une méthode sans dynamic pricing et une méthode avec :
La méthode sans dynamic pricing consiste à prendre le revenu optimal si on suppose qu'on
ne peut pas changer le prix entre deux périodes (i.e.maxp(p∗∑T
t=1 d(t, p))). Nous obtenonsune augmentation du bénéce d'environ 10%. Ce pourcentage a peu de sens car il est facile
de construire une simulation engendrant un gros pourcentage d'augmentation. Cependant,
j'ai essayé de faire une simulation honnête, le principal étant qu'il est bien sur interéssant
de faire du dynamic pricing.
Comparaison entre la méthode de dynamic pricing sans calcul entre chaque période et celle
avec : Nous obtenons une amélioration du revenu d'environ 4%, ce qui est satisfaisant. Nous
sommes donc parvenus à une méthode ecace, générale et avec de bons résultats.
4 Conclusion
Au cours de mon travail d'étude et de recherche, j'ai étudié diverses méthodes de segmenta-
tion de la clientèle et de dynamic pricing. J'en ai moi-même proposé deux en segmentation, une
basée sur les statistiques qui s'est révélée ne pas être utilisable, et une heuristique d'améliora-
tion de la méthode classique basée sur la résolution d'un programme linéaire, qui s'est révélée
être sensiblement meilleure. J'ai également proposé une méthode en dynamic pricing, qui se
révèle être générale (on peut même l'utiliser dans d'autres domaines que l'industrie du transport
aérien), et ecace. A propos de la segmentation de la clientèle, l'auteur avance à un moment
qu'il obtient des résultats sensiblement meilleurs en tirant aléatoirement la demande (en faisant
une moyenne sur 100 tirages) plutôt qu'en utilisant l'espérance. Si j'avais eu plus de temps,
j'aurais voulu avoir le temps d'étudier ce résultat car il ne me semble pas intuitif. J'aurais aussi
voulu étudier l'utilisation simultanée de la segmentation de la clientèle et du dynamic pricing.
En particulier, on peut se poser la question suivante : faut-il d'abord segmenter la clientèle et
ensuite déterminer les prix ou bien faire les deux en même temps ? Ceci me parait réalisable en
modiant ma méthode de dynamic pricing.
15
5 Bibliographie
M. SAKAROVITCH. Optimisation combinatoire. HERMANN, 1984.
J.-C. CULIOLI : Introduction à l'optimisation, Ellipses, Paris, 1994.
R.KEACH : Pricing and Revenue Management, Thèse, 2004.
6 Annexe
6.1 Processus_Poisson.R
Voici le chier Processus_Poisson.R, il contient deux fonctions, une pour simuler un pro-
cessus, une deuxième qui construit l'échantillon à partir des simulations. Le résultat est une
matrice à deux lignes, la première ligne contient les temps d'arrivée des clients, la deuxième
contient 1 si le cient i demande AB, 2 si AC, 3 si CB.
## Fonction qui simule un processus de Poisson d'intensité l sur une durée T
Poisson<-function(l,T)
t<-0; res<-c()
while (t < T)
t <- t + rexp(1,l)
if (t < T)
res<-c(res,t)
return (res);
## Fonction qui fait une simulation d'arrivée des clients
Echantillon<-function(lAB,lAC,lCB,T)
# On commence par tirer l'arriver des clients
AB<-Poisson(lAB,T); AC<-Poisson(lAC,T); CB<-Poisson(lCB,T)
# On definit les longeurs de chaque echantillon de clientèle
lgAB<-length(AB); lgAC<-length(AC); lgCB<-length(CB)
# On définit un indice par clientèle
iAB<-1; iAC<-1; iCB<-1
i<-1 # indice dans la matrice
Echantillon<-matrix(nrow=2,ncol=(lgAB+lgAC+lgCB))
# Il ne reste plus qu'à recopier dans la matrice de résultat dans le bon ordre
while (i<=lgAB+lgAC+lgCB)
if (iAB<=lgAB)
valAB<-AB[iAB]
else
valAB<-T+1
if (iAC<=lgAC)
valAC<-AC[iAC]
else
valAC<-T+1
if (iCB<=lgCB)
16
valCB<-CB[iCB]
else
valCB<-T+1
if (valAB < valAC)
if (valAB < valCB)
Echantillon[1,i]<-valAB
Echantillon[2,i]<-1
iAB<-iAB+1
else
Echantillon[1,i]<-valCB
Echantillon[2,i]<-3
iCB<-iCB+1
else
if (valAC < valCB)
Echantillon[1,i]<-valAC
Echantillon[2,i]<-2
iAC<-iAC+1
else
Echantillon[1,i]<-valCB
Echantillon[2,i]<-3
iCB<-iCB+1
i<-i+1
return (Echantillon)
6.2 Prog_Lin.R
Voici le contenu du chier Prog_Lin.R, les lXY sont les valeurs des lambda, T la période de
vente et Ech une simulation de demande.
source("Processus_Poisson.R")
library(boot)
Prog_Lin<-function(lAB,lAC,lCB,Ech,T)
# Definition des constantes
C<-300
pAB <- 500; pAC <- 300; pCB <- 300
## Fonction qui resout le programme linéaire
Solve_Prog_Lin<-function(dAB,dAC,dCB)
a<-c(pAB,pAC,pCB)
A<-matrix(c(1,1,1,0,0,1,0,0,1,0,0,1,0,0,1),nrow=5)
b<-c(C,C,dAB,dAC,dCB)
res<-simplex(a,A,b,maxi=T)
x<-unlist(res[1])
17
# Renormalisation de x
if (x[1]+x[2] >= C && x[1]+x[3] >= C)
return (x)
else if (x[1]+x[2] >= C)
return (c(x[1],x[2],C-x[1]))
else if (x[1]+x[3] >= C)
return (c(x[1],C-x[1],x[3]))
else
return ( c( min(C*x[1]/(x[1]+x[2]),C*x[1]/(x[1]+x[3])),
C*x[2]/(x[1]+x[2]),
C*x[3]/(x[1]+x[3]) ) )
## Algorithme de résolution par programmation linéaire
Algo_Prog_Lin<-function(lAB,lAC,lCB,Ech,T)
nAB <- 0; nAC <- 0; nCB <- 0;
capa <- Solve_Prog_Lin(T*lAB,T*lAC,T*lCB)
for (i in 1:ncol(Ech))
if (Ech[2,i] == 1)
if (nAB < capa[1])
nAB <- nAB + 1
else if (Ech[2,i] == 2)
if (nAC < capa[2])
nAC <- nAC +1
else
if (nCB < capa[3])
nCB <- nCB +1
return (nAB*pAB + nAC*pAC + nCB*pCB)
return (Algo_Prog_Lin(lAB,lAC,lCB,Ech,T))
6.3 Methode_Probabiliste.R
Voici le contenu du chier Methode_Probabiliste.R, les lXY sont les valeurs des lambda,
T la période de vente et Ech une simulation de demande.
Methode_Probabiliste<-function(lAB,lAC,lCB,T,Ech)
# On fixe les constantes du problème
C<- 300
pAB<- 500; pAC<- 300; pCB<- 300
# Fonction de répartition de la loi de Poisson
18
SumExp<-function(l,n)
res<-exp(-l); facto <-1
for (i in 1:n)
facto<-facto*i
if (l**i!=Inf) # Pour eviter la division par 0 du à l'arrondi machine
res<-res + l**i/facto*exp(-l)
return (res)
# On définit les fonctions de probabilités de notre problème
Pab<-function(t,nAB,nAC,nCB)
return (1-SumExp((T-t)*lAB,max(min(C-nAB-nAC,C-nAB-nCB), 0) ))
Pac<-function(t,nAB,nAC)
return (1-SumExp((T-t)*lAC,C-nAC-nAB))
Pcb<-function(t,nAB,nCB)
return (1-SumExp((T-t)*lCB,C-nAB-nCB))
## Fonction qui effectue un traitement des clients selon l'algorithme de probabilitées
# Retourne le revenu généré
AlgoProba<-function(Ech)
nAB<-0; nAC<-0; nCB<-0
for (i in 1:ncol(Ech))
if (Ech[2,i] == 1)
if (nAC+nAB < C && nCB+nAB < C && (pAB >= pAC*Pac(Ech[1,i],nAB,nAC)
+ pCB*Pcb(Ech[1,i],nAB,nCB)))
nAB <- nAB + 1
else if (Ech[2,i] == 2)
if (nAC+nAB < C)
if (nCB+nAB == C || (pAC >= pAB*Pab(Ech[1,i],nAB,nAC,nCB)
- pCB*Pcb(Ech[1,i],nAB,nCB)))
nAC <- nAC + 1
else
if (nCB+nAB < C)
if (nAC+nAB == C || (pCB >= pAB*Pab(Ech[1,i],nAB,nAC,nCB)
- pAC*Pac(Ech[1,i],nAB,nAC)))
nCB<-nCB + 1
19
return(pAB*nAB + pAC*nAC + pCB*nCB)
return (AlgoProba(Ech))
6.4 Prog_Lin_Modif.R
Voici le contenu du chier Prog_Lin_Modif.R, les lXY sont les valeurs des lambda, T la
période de vente et Ech une simulation de demande.
source("Processus_Poisson.R")
library(boot)
Prog_Lin_Modif<-function(Ech,T,lAB,lAC,lCB)
# Definition des constantes
C<-300
pAB<- 500; pAC<- 300; pCB<- 300
## Fonction qui resout le programme linéaire
Solve_Prog_Lin<-function(dAB,dAC,dCB)
a<-c(pAB,pAC,pCB)
A<-matrix(c(1,1,1,0,0,1,0,0,1,0,0,1,0,0,1),nrow=5)
b<-c(C,C,dAB,dAC,dCB)
res<-simplex(a,A,b,maxi=T)
x<-unlist(res[1])
# Renormalisation de x
if (x[1]+x[2] >= C && x[1]+x[3] >= C)
return (x)
else if (x[1]+x[2] >= C)
return (c(x[1],x[2],C-x[1]))
else if (x[1]+x[3] >= C)
return (c(x[1],C-x[1],x[3]))
else
return ( c( min(C*x[1]/(x[1]+x[2]),C*x[1]/(x[1]+x[3])),
C*x[2]/(x[1]+x[2]),
C*x[3]/(x[1]+x[3]) ) )
## Fonction qui calcul l'espérance
Esperance<-function(l,t,T)
return (l*(T-t))
## Algorithme de résolution par programmation linéaire
Algo_Prog_Lin_Modif<-function(Ech,T,lAB,lAC,lCB)
nAB <- 0; nAC <- 0; nCB <- 0;
20
capa <- Solve_Prog_Lin(T*lAB,T*lAC,T*lCB)
for (i in 1:ncol(Ech))
if (Ech[2,i] == 1)
if (nAB < capa[1])
nAB <- nAB + 1
else if (Esperance(lAC,Ech[1,i],T) < capa[2]-nAC
|| Esperance(lCB,Ech[1,i],T) < capa[3]-nCB)
nAB <- nAB +1
capa[1]<-capa[1]+1; capa[2]<- capa[2]-1; capa[3]<- capa[3]-1;
else if (Ech[2,i] == 2)
if (nAC < capa[2])
nAC <- nAC +1
else if ( Esperance(lAB,Ech[1,i],T) < capa[1]-nAB
|| Esperance(lCB,Ech[1,i],T) > capa[3]-nCB+1)
nAC<-nAC+1
capa[2]<-capa[2]+1; capa[3]<-capa[3]+1; capa[1]<- capa[1] -1
else
if (nCB < capa[3])
nCB <- nCB +1
else if (Esperance(lAB,Ech[1,i],T) < capa[1]-nAB
|| Esperance(lAC,Ech[1,i],T) > capa[2]-nAC+1
nCB<-nCB+1
capa[2]<-capa[2]+1; capa[3]<-capa[3]+1; capa[1]<- capa[1] -1
return (nAB*pAB + nAC*pAC + nCB*pCB)
return (Algo_Prog_Lin_Modif(Ech,T,lAB,lAC,lCB))
6.5 Dynamic_Pricing.R
Voici le contenu du chier Dynamic_Princing.R.
## Fonction principale du dynamic princing elle calcul le revenu optimal
# selon la demand d, les prix P et la capacité C
Dynamic_Pricing<-function(d,P,C)
T<-length(d[1,]); N<-length(P)
# Initialisation de la matrice des marques
V<-matrix(nrow=C,ncol=T)
for (i in 1:C)
for (j in 1:T)
V[i,j]=-1
21
# Definition des matrices de marquage
rep<-matrix(nrow=C,ncol=T) # permet de stocker la répartition choisi
pred<-matrix(nrow=C,ncol = T) # permet de stocker l'indice de l'où on vient
prix<-matrix(nrow=C,ncol = T) # prix permet de stocker les prix choisi
## Fonction qui calcul récursivement le revenu optimale avec marquage
Algo_Rec<-function(t,c)
# Si il n'y a plus de place libre dans l'avion on arrête la
if (c == 0)
return (0)
else if (V[c,t] == -1)
for (p in 1:N)
if (t == 1)
comp<-P[p]*min(c,d[p,t])
if (V[c,t] < comp)
V[c,t] <<- comp
rep[c,t] <<- c
prix[c,t] <<- p
else
for (i in 0:min(c,d[p,t]))
comp <- Algo_Rec(t-1,c-i)
if (V[c,t] < comp + i*P[p])
V[c,t] <<- comp + i*P[p]
rep[c,t] <<- i
pred[c,t] <<- c-i
prix[c,t] <<- p
return (V[c,t]);
# La suite sert juste a construire la matrice contenant le résultat à retourner
## Fonction qui retourne un vecteur contenant l'indice du prix choisis dans p
getChemin<-function()
chemin<-c(C)
if (T != 1)
for (i in 0:(T-2))
chemin<-c(pred[chemin[1],T-i],chemin)
return (chemin);
Algo_Rec(T,C)
22
chemin<-getChemin();
# On crée la matrice contenant le résultat
res<-matrix(nrow=2, ncol=T)
for (i in 1:T)
res[1,i] <- prix[chemin[i],i]
res[2,i] <- rep[chemin[i],i]
return (res)
6.6 Dynamic_Princing_Aleatoire.R
Voici le contenu du chier Dynamic_Princing_Aleatoire.R.
source("Dynamic_Pricing.R")
## Fonction principale du dynamic princing aléatoire
# dPred une matrice de taille TxN
# dPred une matrice de taille TxN
# P est un vecteur de prix de taille N
# C est la capacité de l'avion
Dynamic_Pricing_Aleatoire<-function(P,C,dPred,dReel)
T<-length(dPred[1,])
N<-length(P)
res<-matrix(nrow=2, ncol=T)
for (i in 1:T)
if (C > 0)
# Appel de l'algorithme avec marquage avec les bonnes valeurs de d
d<-dPred[,c(i:T)]
if (i == T) # si i vaut 1 R considére d comme un vecteur,
d<-matrix(d,ncol=1) # on le force donc à le considerer comme une matrice
# On stock le résultat
tmp <- Dynamic_Pricing(d,P,C)
res[1,i] <- tmp[1,1]
res[2,i] <- tmp[2,1]
# On met à jour la capacité :
# on enlève le minimum entre la demande prévu et la demande réelle
C <- C - min(res[2,i],dReel[res[1,i],i])
return (res)
23