By using this site, you agree to the Privacy Policy and Terms of Use.
Accept
World of SoftwareWorld of SoftwareWorld of Software
  • News
  • Software
  • Mobile
  • Computing
  • Gaming
  • Videos
  • More
    • Gadget
    • Web Stories
    • Trending
    • Press Release
Search
  • Privacy
  • Terms
  • Advertise
  • Contact
Copyright © All Rights Reserved. World of Software.
Reading: How Your Layover Time Can Make or Break an Airline’s Profit | HackerNoon
Share
Sign In
Notification Show More
Font ResizerAa
World of SoftwareWorld of Software
Font ResizerAa
  • Software
  • Mobile
  • Computing
  • Gadget
  • Gaming
  • Videos
Search
  • News
  • Software
  • Mobile
  • Computing
  • Gaming
  • Videos
  • More
    • Gadget
    • Web Stories
    • Trending
    • Press Release
Have an existing account? Sign In
Follow US
  • Privacy
  • Terms
  • Advertise
  • Contact
Copyright © All Rights Reserved. World of Software.
World of Software > Computing > How Your Layover Time Can Make or Break an Airline’s Profit | HackerNoon
Computing

How Your Layover Time Can Make or Break an Airline’s Profit | HackerNoon

News Room
Last updated: 2025/07/09 at 8:25 PM
News Room Published 9 July 2025
Share
SHARE

When reality doesn’t match expectations, it’s always unpleasant. It is especially unpleasant if you paid money for the expected reality: you buy a ticket of one airline, but for some reason you are put on a plane of a completely different airline. Then you make a connection, and they put you on a plane of some unknown third airline. What happens? After all, you have a ticket of the airline, which you bought just because you know what to expect from it, but you still fly with airplanes of completely different airlines. You seem to have bought a ticket from a large and well-established airline, but on board it turns out that this airline has regional subsidiaries and branches, which are not so good. The first acquaintance with codeshare flights can be very unpleasant.

Don’t airlines realize that such actions can cause travelers to completely change their preferences? A negative experience quickly builds the skill to take a more thorough approach to evaluating possible alternatives. Passenger flows are like a fluid that flows in greater volume where there are fewer obstacles in its path. In this case, even a small difference in airlines’ and travelers’ assessments of the attractiveness of flights can lead to significant diversion of passenger flows.

A decrease in the attractiveness of a flight of one airline leads to the so-called “bottling up” of part of the passenger flow. Another airline can pick up the spill by offering a more attractive alternative — making a grab. Such a model is called the spill and capture (capture) model of passenger flow and directly relates airline profits to positive traveler experiences. This article focuses on how to make codeshare flights more attractive, and make a good profit on it (without leaving your competitors behind, of course).

Passenger flow distribution

Let’s get straight to the problem. Suppose that there is a small route network of three cities, consisting of only three routes:

  • A→B — flights are operated by A1;
  • B→C — flights are operated by A2 and A3;
  • A→B→C — on the first segment, flights are operated by A1, on the second by A2 и A3 — this is the route that requires evaluating the optimality of the codeshare agreement.

Passenger flows can be represented in two forms — let’s call them H and D:

  • H — elementary passenger traffic between two cities;
  • D — composite passenger traffic between two cities.

For example, on segment A→B, airline A1 can estimate (observe if it is less than capacity) passenger flow D11, which is the sum of two elementary passenger flows:

where the upper index in parentheses corresponds to the airline number. In this case, H1 is the passenger flow of travelers interested in getting from A to B, and H3 is the passenger flow of travelers interested in getting from A to C.

For the B→C segment, things are a little more interesting:

where α can be interpreted as the airline’s share of elementary passenger traffic. In this case, airlines A2 and A3 share passenger traffic H2 — travelers going from B to C, and passenger traffic H3 — travelers going from A to C and connecting at the airport of city B.

The parameter α can also be interpreted as the probability of making a ticket purchase on a particular airline flight, therefore:

α depends on the attractiveness of flights and is determined by the utility function U(R), where R is a vector of flight parameters, based on which travelers decide to buy a ticket. Typically, exponentiated functions are used as the utility function and converted to probabilities using soft-max functions. Is this a good way to do it? It is common and simple. At the same time, sigmoid functions and the Dirichlet distribution function fit much better into the voting paradigm. For example, if there were a traveler survey where you had to rate each flight parameter on a 10-point scale, it would be the beta and Dirichlet distributions that would process the results. This is more complicated, but yields more results.

Impact of codeshare agreements on route attractiveness

Codeshare flights are attractive to travelers because they allow passengers to:

  • Accumulate bonus miles by participating in the airline’s loyalty program, even if the flight is operated by another carrier.
  • Book air tickets for flights with convenient connections, choosing the most suitable option among the offers of different airlines.
  • Receive assistance and support from the airline carrier during the flight regardless of the company from which the ticket was purchased.

However, the main reason why codeshare flights are attractive is that they increase the number of routes — it is much easier to choose a ready-made route than to create it yourself. Some airlines are well aware that the attractiveness of codeshare flights can be increased even further — for example, by convenient time factors, so they coordinate their schedules.

Naturally, codeshare flights can also be unattractive for a number of reasons:

  • inappropriate service levels;
  • different baggage and carry-on rules;
  • the possibility of baggage problems during connections.

Increasing the attractiveness of a codeshare flight can increase passenger traffic:

This seems to be the crux of the matter, but it is a bit more complicated and much more interesting. In theory, codeshare flights can increase total passenger traffic, but to a much greater extent, they simply increase demand.

Adding a codeshare flight puts H3 travelers faced with three alternatives:

  1. Fly from A to C on a codeshare flight with minimal inconvenience.
  2. Fly from A to C via B with a convenient connection to an A2 airline flight.
  3. Fly from A to C via B with an inconvenient connection on airline flight A3.

Suppose this is the case, then H3 can be represented as the following sum:

where H(ch)3 — are travelers who chose a codeshare flight, and H(rem)3 — are travelers who have chosen a self-transfer route. H3 must also be shared in some proportion:

Then the full redistribution of all flows between airlines can be written in the following form:

The fact that the attractiveness of routes can change entire passenger flows may seem rather strange. However, it is important to understand that we are talking about parts of passenger flows, i.e. individual segments of travelers who evaluate and rank possible alternatives differently. For some part of travelers, comfort comes first, for another part — price.

Demand shows how price affects the number of tickets purchased. Attractiveness, on the other hand, shows how this number is influenced by other factors. Attractiveness is often fixed — for example, for scheduled flights that cannot change their arrival or departure times. Once a joint flight with another airline is added to such a flight, the connection time may change, which means that some part of travelers will be guided by more than just price when buying a ticket.

Spill and Capture

We have obtained an expression describing the proportional change in passenger volumes between airlines. It remains to figure out how to calculate the proportions based on α. This may seem very complicated — in this case we always resort to simple approximations. We will make two important assumptions:

  1. We have the data.
  2. We can create data models.

Essentially we are just talking about what we “know how to do in ML (Machine Learning)”.

First, we need to specify random passenger volumes consisting of potential buyers, namely, anyone who is in any way interested in buying a ticket on some of the routes under consideration. The best candidate for the distribution of the number of potential buyers is the Poisson distribution:

  • H1∼Poisson(λ1);
  • H2∼Poisson(λ2);
  • H3∼Poisson(λ3).

Let us consider how the bottling and capturing of passenger traffic occurs using the example of H3, because this passenger traffic is divided among three airlines. Different levels of flight attractiveness generate different levels of attention in different passenger price segments. For example, a codeshare flight will be the most attractive, but for the same reason it will be the most expensive. Meaning that it will be of interest to those who are willing to pay more than usual for a ticket.

Let attractiveness be determined by two factors: codeshare and connection time.

There is some optimal transfer time — let’s denote it by t∗. Let’s assume that t(2) the transfer time for flight A2 is much closer to t∗ than t(3) — the transfer time for flight A3.

We can now determine the attractiveness (utility of the two flights) through a simple bell-shaped function. Let’s consider three options:

  • Δt∗=t∗−t=0 — minimal difference from the ideal transfer time.
  • Δt∗=t∗−t>0 — you have to hurry.
  • Δt∗=t∗−t<0 — you have to wait.

Let’s express the attractions through utility functions: u2=U(Δt2) and u3=U(Δt3), where U can be any unimodal function: in our case U is a Gaussian function.

The attractiveness of flights A2 and A3 can be displayed as follows:

import numpy as np from scipy.stats import norm, gamma, poisson, binom, uniform, bernoulli import matplotlib.pyplot as plt from pylab import rcParams rcParams[‘figure.figsize’] = 7, 4 rcParams[‘figure.dpi’] = 140 %config InlineBackend.figure_format = ‘png’ import seaborn as sns sns.set() dt = np.linspace(-5, 5, 300) u = norm.pdf(dt, loc=0, scale=1.4)

plt.plot(dt, u, ‘C0’)

dt_2 = 1.15 u_2 = norm.pdf(dt_2, loc=0, scale=1.4) plt.plot(dt_2, u_2, ‘C2o’, label=r’$u_{2} =$’ + f'{u_2:.2f}’) plt.vlines(dt_2, 0, u_2, color=’C2′)

dt_3 = 2.5 u_3 = norm.pdf(dt_3, loc=0, scale=1.4) plt.plot(dt_3, u_3, ‘C3o’, label=r’$u_{3} =$’ + f'{u_3:.2f}’) plt.vlines(dt_3, 0, u_3, color=’C3′)

plt.title(‘Attractiveness (usefulness) of flightsn’ + r’of airlines $A_{2}$ and $A_{3}$’) plt.xlabel(r’$Delta t$ (hour)’) plt.ylabel(‘u’, rotation=0) plt.legend() plt.show()

If airline A1 enters into a codeshare agreement with A2, then, in terms of transfer time, the attractiveness of the codeshare flight will be the same as that of A2, since the ideal transfer time — t∗, relative to which all deltas are calculated, has not changed in any way. However, codeshare flights offer a number of advantages: no need to re-check baggage, no need to re-check-in, and for international flights, staying in a clear zone means no additional passport control. The attractiveness of a codeshare flight increases due to the fact that the traveler has less risk to meet the Δt2, and there is also additional time to stretch your legs and rest from the flight. It turns out that the ideal connection time for a codeshare flight, t∗ch, is still different from the ideal connection time for a regular flight.

The ideal connection time should take into account several factors:

  • Minimum connecting time — the time needed to successfully transfer passengers and transfer baggage from one flight to another at the airport.
  • Additional comfort time — necessary to reduce the risks of running to check-in for another flight.
  • Average time of flight delays — there are special statistics for each airline.

The ideal connection time for a codeshare flight will decrease at least due to the fact that the risks of the passenger being late for the flight during the connection are assumed by the airline — it now guarantees that even if the traveler is late, they will still be put on the next flight.

Assuming that t∗ch<t∗, this simply causes the graph of the utility function for codeshare flight A1 to shift to the right:

dt = np.linspace(-5, 5, 300) u = norm.pdf(dt, loc=0, scale=1.4)

plt.plot(dt, u, ‘C0′, label=r’$t^{*} – t$’)

dt = np.linspace(-5, 5, 300) u_ch = norm.pdf(dt, loc=0.8, scale=1.4) plt.plot(dt, u_ch, ‘C0–‘, label=r’$t^{*}_{ch} – t$’)

dt_1 = 1.15 u_1 = norm.pdf(dt_1, loc=0.8, scale=1.4) plt.plot(dt_1, u_1, ‘C1o’, label=r’$u_{1} =$’ + f'{u_1:.2f}’) plt.vlines(dt_1, 0, u_1, color=’C1′, lw=4, alpha=0.5)

dt_2 = 1.15 u_2 = norm.pdf(dt_2, loc=0, scale=1.4) plt.plot(dt_2, u_2, ‘C2o’, label=r’$u_{2} =$’ + f'{u_2:.2f}’) plt.vlines(dt_2, 0, u_2, color=’C2′)

dt_3 = 2.5 u_3 = norm.pdf(dt_3, loc=0, scale=1.4) plt.plot(dt_3, u_3, ‘C3o’, label=r’$u_{3} =$’ + f'{u_3:.2f}’) plt.vlines(dt_3, 0, u_3, color=’C3′)

plt.title(‘Attractiveness (usefulness) of flightsn’ + r’of airlines $A_{2}$ and $A_{3}$’) plt.xlabel(r’$Delta t$ (hour)’) plt.ylabel(‘u’, rotation=0) plt.legend() plt.show()

If previously the difference from the ideal connection time was about 1 hour and 10 minutes, for a codeshare flight this difference will be only 20 minutes. Naturally, the approximation to the ideal connection time is not the only factor affecting the attractiveness (usefulness) of a flight. The transfer time is taken for illustrative purposes only. In reality, the calculation of attractiveness relies on many more factors and is performed by ML tools.

Now we need to understand how these three values divide passenger traffic into price segments — we are clearly talking about some fractions. In order to determine these fractions, we need a profile of potential demand. Let’s assume that for each of the passenger flows it looks as follows:

prices_1 = np.linspace(100, 300, 1000) rvdem_1 = gamma(a=12, loc=100, scale=8) profile_1 = rvdem_1.pdf(prices_1) plt.plot(prices_1, profile_1, label=r’$H_{1}$’)

prices_2 = np.linspace(60, 200, 1000) rvdem_2 = gamma(a=8, loc=60, scale=7) profile_2 = rvdem_2.pdf(prices_2) plt.plot(prices_2, profile_2, label=r’$H_{2}$’)

prices_3 = np.linspace(240, 500, 1000) rvdem_3 = gamma(a=10, loc=230, scale=12) profile_3 = rvdem_3.pdf(prices_3) plt.plot(prices_3, profile_3, label=r’$H_{1}$’)

plt.legend() plt.xlabel(‘Price (c.u.)’) plt.title(‘Passenger flow demand profiles’);

The existence of a demand profile indicates that there is a reliable representation of at what prices the probability of buying a ticket is different from 0 or 1 and how it depends on price. It should be immediately noted that the existence of such price profiles does not allow for rational demonstration of old or suboptimal practices. First, once one is familiar with ML methods, it is quite difficult to imagine how one could do anything differently, much less do it worse. Second, there are at least several methodologies for “predicting” the number of tickets sold at some price. Different airlines may use different ones. Some, usually small airlines may rely entirely on intuition. For now, let’s just assume that in the worst case, the demand profiles would be rough step functions.

The different degrees of attractiveness of the alternatives must somehow divide the passenger flows between airlines, and now we have everything we need to calculate the α for each of them:

The H1 flow between airlines is not shared. Only flows H2 and H3 are divided, and the division depends on the attractiveness of the flights, which affects the probability of choice. The attractiveness can look as follows:

fig, ax = plt.subplots(1, 3, figsize=(12, 3))

dt = np.linspace(-5, 5, 300) u = norm.pdf(dt, loc=0, scale=1.4) ax[0].plot(dt, u, ‘C0’)

dt = np.linspace(-5, 5, 300) u_ch = norm.pdf(dt, loc=0.8, scale=1.4) ax[0].plot(dt, u_ch, ‘C0–‘) ax[1].plot(dt, u_ch, ‘C0–‘)

dt_1 = 1.15 u_1 = norm.pdf(dt_1, loc=0.8, scale=1.4) ax[0].plot(dt_1, u_1, ‘C1o’, label=r’$u_{1} =$’ + f'{u_1:.2f}’) ax[0].vlines(dt_1, 0, u_1, color=’C1′, lw=4, alpha=0.5)

dt_2 = 1.15 u_2 = norm.pdf(dt_2, loc=0, scale=1.4) ax[0].plot(dt_2, u_2, ‘C2o’, label=r’$u_{2} =$’ + f'{u_2:.2f}’) ax[0].vlines(dt_2, 0, u_2, color=’C2′)

dt_3 = 2.5 u_3 = norm.pdf(dt_3, loc=0, scale=1.4) ax[0].plot(dt_3, u_3, ‘C3o’, label=r’$u_{3} =$’ + f'{u_3:.2f}’) ax[0].vlines(dt_3, 0, u_3, color=’C3′)

ax[0].legend(loc=3) ax[0].set_title(‘Attractiveness for $H_3$n(codeshare $A_{1}$ and $A_{2}$)’) ax[0].set_xlabel(r’$Delta t$ (hour)’)

ax[1].plot(dt, u, ‘C0’)

dt_1 = 2.5 u_1 = norm.pdf(dt_1, loc=0.8, scale=1.4) ax[1].plot(dt_1, u_1, ‘C1o’, label=r’$u_{1} =$’ + f'{u_1:.2f}’) ax[1].vlines(dt_1, 0, u_1, color=’C1′, lw=4, alpha=0.5)

dt_2 = 1.15 u_2 = norm.pdf(dt_2, loc=0, scale=1.4) ax[1].plot(dt_2, u_2, ‘C2o’, label=r’$u_{2} =$’ + f'{u_2:.2f}’) ax[1].vlines(dt_2, 0, u_2, color=’C2′)

dt_3 = 2.5 u_3 = norm.pdf(dt_3, loc=0, scale=1.4) ax[1].plot(dt_3, u_3, ‘C3o’, label=r’$u_{3} =$’ + f'{u_3:.2f}’) ax[1].vlines(dt_3, 0, u_3, color=’C3′)

ax[1].legend(loc=3) ax[1].set_title(‘Attractiveness for $H_3$n(codeshare $A_{1}$ and $A_{3}$)’) ax[1].set_xlabel(r’$Delta t$ (hour)’)

dt = np.linspace(-5, 5, 300) u = norm.pdf(dt, loc=0, scale=2.6)

plt.plot(dt, u, ‘C0’)

dt_2 = 1.15 u_2 = norm.pdf(dt_2, loc=0, scale=2.6) ax[2].plot(dt_2, u_2, ‘C2o’, label=r’$u_{2} =$’ + f'{u_2:.2f}’) ax[2].vlines(dt_2, 0, u_2, color=’C2′)

dt_3 = 2.5 u_3 = norm.pdf(dt_3, loc=0, scale=2.6) ax[2].plot(dt_3, u_3, ‘C3o’, label=r’$u_{3} =$’ + f'{u_3:.2f}’) ax[2].vlines(dt_3, 0, u_3, color=’C3′) ax[2].legend(loc=3) ax[2].set_title(‘Attractiveness for $H_2$’) ax[2].set_xlabel(r’$Delta t$ (hour)’);

The simplest way to convert utilities into probabilities is to multiply each of the values by some factor so that the resulting sum equals 1:

For example, if A1 enters into a codeshare agreement with A2, the probabilities of choosing one or the other flight are as follows:

u = np.array([0.28, 0.20, 0.06])

print(u / u.sum()) [0.51851852 0.37037037 0.11111111]

  • P3(Choice=A1|Seg=1)=0.52;
  • P3(Choice=A2|Seg=1)=0.37;
  • P3(Choice=A3|Seg=1)=0.11.

However, the choice is influenced not only by preference, but also by the amount of money available to make it. Knowing the demand profiles, we can determine the probability of buying a ticket at a particular price. Let the prices be as follows:

  • Price(1)1=190
  • Price(1)3=370
  • Price(2)2=135
  • Price(3)2=115

Then the probability of buying a ticket at some price can be defined as follows:

For example, the probability that a ticket for a codeshare flight will be bought at 370 c.u. will be equal to 0.27:

rvdem_3 = gamma(a=10, loc=230, scale=12) print(rvdem_3.sf(370))

0.2727250812333501

Travelers who can afford a ticket at this price see three alternatives in front of them. However, if a person can afford the maximum comfort, it does not mean that he or she will necessarily use it. The availability of cheaper alternatives allows to save money — this is why we calculated the attractiveness of alternatives and determined the probabilities of choice based on them. The total probability of choice will be equal to:

The resulting probabilities of choosing a particular flight for such passengers will be equal:

  • P3(Choice=A1|Seg=1)=0.14;
  • P3(Choice=A2|Seg=1)=0.1;
  • P3(Choice=A3|Seg=1)=0.03.

The result does not look so impressive, because the final probability of buying a ticket for the most comfortable flight is not so high. This is the specifics of bottling and capturing passenger flows — conditional probabilities and conditional distributions come into play.

What happens to those who cannot afford to buy such a ticket? If the amount of the passenger’s means falls within the interval:

he will no longer be able to afford a codeshare flight. In this case, he will have two alternatives available to him: choose a flight with a convenient or a long connection. Based on the available utility, the choice probabilities are as follows:

  • P3(Choice=A2|Seg=2)=0.77;
  • P3(Choice=A3|Seg=2)=0.23.

u = np.array([0.20, 0.06])

print(u / u.sum())

[0.76923077 0.23076923]

The probability of buying a ticket in this case will be:

rvdem_3 = gamma(a=10, loc=230, scale=12) print(rvdem_3.sf(325)- rvdem_3.sf(370)) 0.4541835759677653

Then the resulting choice probabilities for such travelers are as follows:

  • P3(Choice=A2|Seg=2)=0.35;
  • P3(Choice=A3|Seg=2)=0.1.

Travelers whose amount of money is in the range [305,325) can only afford flight A3. The probability of buying a ticket at price 305 for this segment is:

rvdem_3 = gamma(a=10, loc=230, scale=12) print(rvdem_3.sf(305)- rvdem_3.sf(325)) 0.17088396696109864

Ultimately, the probabilities of buying a ticket for a particular flight will be expressed as a simple sum:

Passenger traffic H3

will be divided among the airlines as follows:

  • P3(Choice=A1)=0.14;
  • P3(Choice=A2)=0.1+0.35=0.45;
  • P3(Choice=A3)=0.03+0.1+0.17=0.3.

The probability P(Buy=0) that the ticket will not be bought at all is 0.1, which in sum with the above choice probabilities gives 1. It means that the volume of potential-possible passenger flow is fully taken into account.

Having done the same for passenger flow H2, we obtain the following:

  • P2(Choice=A2)=0.1;
  • P2(Choice=A3)=0.38.

Passenger traffic H1 though not shared between airlines, but due to the price of 190 ue some share of it will be spilled, so we can still introduce the probability of flight choice P1(Choice=A1), which will be determined by the price (the probability of buying a ticket at this price):

rvdem_1 = gamma(a=12, loc=100, scale=8) print(rvdem_1.sf(190))

0.5494501693973257

It would be possible to describe in detail all values of α, but since we have already obtained specific values of fractions, we will write everything in a shorter form:

For an airline, optimizing codeshare agreements is a backpack packing problem with a binary variable equal to one or zero when a potential flight is chosen to be shared or not. The main problems begin when estimating the value of the items stowed in the backpack. In the simple case, an airline may decide that it depends on the brand: if it is attractive, then a codeshare flight will also be attractive. In this naive approach, the value of the item stowed in the backpack simply increases in proportion to some factor.

A more developed approach is to use multiple attractiveness criteria to select an item. Each item is a route that has departure and arrival times, as well as connections that may vary in both duration and type. Consequently, choosing one item changes the value of all the others, both those already in the backpack and those not yet packed. This means that all α must be calculated each time an item is selected. However, by multiplying all H by the corresponding prices, you can get quite reasonable estimates of income, and most importantly, you can figure out with whom and on what terms to enter into an agreement.

The method is rather crude, but it should be noted that it links traveler preferences to the redistribution of passenger traffic. Delta Airlines, one of the pioneers in optimizing codeshare agreements reported that this evaluation of joint routes provided up to $50 million in additional annual revenue. This was not only one of the most outstanding results for the 2000s, but also a direct proof of the importance of traveler preferences. Air Canada later showed that this method delivered up to 80% more weekly revenue than the naive method that only considers brand influence.

This method is bad in that it divides the problem into two parts: first we need to rank the alternatives and calculate the optimal shares of H, and then remember that all H are random and calculate the optimal quotas separately. Dividing the tasks simplifies the computation but does not lead to an optimal result.

Modeling and optimization

Airline A1 needs to find not only the best prices but also quotas: w(1)3 — number of seats reserved for codesharing, and w(1)1 — is the number of seats for those traveling from A to B. If we denote by V the capacity of the airplane, then a simple condition for quotas is satisfied: w(1)1+w(1)3⩽V(1) — the same as for the number of tickets sold q(1)1+q(2)3+q(3)3⩽w(1)1 и q(1)3⩽w(1)3.

Usually, the target function is cost-free and consists only of increasing the revenue generated by selecting a joint flight. However, in addition to revenue, there are also costs that have a significant impact on the profitability of flights. To optimize the profit, we introduce the following costs:

  • Cfix — fixed costs, e.g.: crew pay, airport charges for parking, takeoff and landing, aviation security.
  • Cvar — variable costs, which depend on the number of passengers, for example: fees for the provision of airport terminal complex, baggage handling. This would also include kerosene costs, since its quantity also depends on the number of passengers and luggage, but for simplicity we will refer it to Cfix. Пусть Cvar=cvarQ, for example, cvar may be equal to 25 c.u., the value of which is simply multiplied by the number of passengers — Q.
  • Price(2)ch — costs of seats purchased from the operating carrier for a codeshare flight.

Then the average profit A1 will be the following function:

The second airline’s profits:

One might think that if A1 enters into an agreement with A2, then the profits of A3 should be of no concern. In fact, codesharing has a very interesting consequence: competitive pressure. Therefore, let’s write down the target function for A3 as well:

We know that Hj∼Poisson(λj). Knowing that Pj(Choice=Ai), we could record the number of tickets purchased q(i)j as:

and further approximate the binomial distribution by a normal distribution. Even for small values of Hj, it is standard practice, but travelers from H1 and H3 are a random mixture — there is no such thing as first selling tickets only for those from H1 and then selling out the remaining seats only for those from H3. It should also be noted that if airports A and B are separated by a significant number of time zones, the mix of H2 and H3 will have a different time-dependent composition. For example, if A3 significantly reduces the price at night, then this reduction may be seen first by passengers from H3 because they may have daytime instead of nighttime.

It’s important to remember that data always comes first. Even if we wrote down Hj∼Poisson(λj) is an extremely crude approximation taken just for the sake of example. Instead of the Poisson distribution, there is always a very complex conditional distribution, which is what is derived from the data.

Mixing passenger flows, limited aircraft capacity, quotas, and many other nuances make it impossible to derive the distribution of the number of tickets sold analytically. To get adequate values of q, it is necessary to model the sales process.

Before modeling something, it is necessary to define the basic parameters of the problem.

Suppose that route A→B→C is the Vladivostok-Moscow-Sochi route: VVO→SVO→AER.

Let the flights be operated by the following airplanes:

  • VVO→SVO — is operated by airline A1 on A350 aircraft with a capacity of V=325.
  • SVO→AER — is operated by airline A2 on A320 aircraft with a capacity of V=180.
  • SVO→AER — is operated by airline A3 на on Boeing 737 aircraft with a capacity of V=190.

The fixed costs will be as follows:

  • C(1)fix — 48360 c.u.;
  • C(2)fix — 10270 c.u.;
  • C(2)fix — 9890 c.u.

Variable Costs:

  • c(1)var — 6.8 c.u. / passenger.
  • c(2)var — 5.4 c.u. / passenger.
  • c(2)var — 5.1 c.u. / passenger.

Assume that passenger flows are distributed as follows:

  • H1∼Poisson(λ1=370);
  • H2∼Poisson(λ2=350);
  • H3∼Poisson(λ3=110).

def prob_in_trafic(prices): price_1, price_2, price_3 = prices rvdem_1 = gamma(a=12, loc=100, scale=8) rvdem_2 = gamma(a=8, loc=60, scale=7) rvdem_3 = gamma(a=10, loc=230, scale=12) pb_11 = rvdem_1.sf(price_1) pb_10 = 1 – pb_11

ph_1 = [pb_10, pb_11]

uh_2 = np.array([0.14, 0.1]) pseg_2 = uh_2 / uh_2.sum()

if price_2 > price_3: pbp_22 = rvdem_2.sf(price_2) pbp_23 = rvdem_2.sf(price_3) – rvdem_2.sf(price_2) pb_22 = pbp_22 * pseg_2[0] pb_23 = pbp_22 * pseg_2[1] + pbp_23 else: pbp_22 = rvdem_2.sf(price_2) pbp_23 = rvdem_2.sf(price_3) pb_22 = pbp_22 pb_23 = 0

pb_20 = 1 – pb_22 – pb_23

ph_2 = [pb_20, pb_22, pb_23]

uh_3 = np.array([0.2, 0.06]) pseg_3 = uh_3 / uh_3.sum()

if (price_1 + price_2) > (price_1 + price_3): pbp_32 = rvdem_3.sf(price_1 + price_2) pbp_33 = rvdem_3.sf(price_1 + price_3) – rvdem_3.sf(price_1 + price_2) pb_32 = pbp_32 * pseg_3[0] pb_33 = pbp_32 * pseg_3[1] + pbp_33 else: pbp_32 = rvdem_3.sf(price_1 + price_2) pbp_33 = rvdem_3.sf(price_1 + price_3) pb_32 = pbp_32 pb_33 = 0

pb_30 = 1 – pb_32 – pb_33

ph_3 = [pb_30, pb_32, pb_33]

return ph_1, ph_2, ph_3

def sales(P): h_1 = poisson.rvs(mu=370) h_2 = poisson.rvs(mu=350) h_3 = poisson.rvs(mu=110)

h_all = np.sum([h_1, h_2, h_3]) p_in_h = np.array([h_1, h_2, h_3]) / h_all

v_1, v_2, v_3 = 325, 180, 190 q_1, q_2, q_3 = 0, 0, 0 for iter in range(h_all): pass_in_h = np.random.choice([1, 2, 3], p=p_in_h) if pass_in_h == 1: if np.random.choice([0, 1], p=P[0]): if q_1 < v_1: q_1 += 1

if pass\_in\_h == 2:
a\_i = np.random.choice(\[0, 2, 3\], p=P\[1\])
if a\_i == 2:
if q\_2 < v\_2:
q\_2 += 1
if a\_i == 3:
if q\_3 < v\_3:
q\_3 += 1

if pass\_in\_h == 3:
a\_i = np.random.choice(\[0, 2, 3\], p=P\[2\])
if a\_i == 2:
if q\_2 < v\_2:
q\_2 += 1
if q\_1 < v\_1:
q\_1 += 1
if a\_i == 3:
if q\_3 < v\_3:
q\_3 += 1
if q\_1 < v\_1:
q\_1 += 1

return q_1, q_2, q_3

def profit_a(prices, Q): profit_1 = Q[0] * prices[0] – Q[0] * 6.8 – 48360 profit_2 = Q[1] * prices[1] – Q[1] * 5.4 – 10270 profit_3 = Q[2] * prices[2] – Q[2] * 5.1 – 9890 return profit_1, profit_2, profit_3

def e_profit(prices, n_iter): P = prob_in_trafic(prices) return np.mean([profit_a(prices, sales(P)) for _ in range(n_iter)], axis = 0)

Now we can start modeling and optimization. Questions arise: what and how to optimize? What and what to compare to see if there is an increase in profit?

Ideally, every airline wants to increase its profit, but changes in the price of one airline’s tickets affect all passenger traffic. These changes are noticed by other airlines and they too change the price, which again leads to changes in passenger flows. This means that profit gains cannot be achieved by applying the optimization method just once. Thus, there is only one requirement for the method — it must show a non-negative profit increase for all parameters.

Let us assume that no airlines have entered into codeshare agreements and consider the following prices to be optimal:

  • Price(1)1=185;
  • Price(2)2=114;
  • Price(3)2=110.

Then the distributions of their profits will be as follows:

prices = [185, 114, 110]

q_data = [] profit_data = [] P = prob_in_trafic(prices)

for i in range(1000): Q = sales(P) q_data.append(Q) profit_data.append(profit_a(prices, Q))

q_data = np.array(q_data) profit_data = np.array(profit_data) fig, ax = plt.subplots(1, 3, figsize=(12, 3.5))

sns.kdeplot(profit_data[:, 0], ax=ax[0]) e_pa_1 = np.mean(profit_data[:, 0]) ax[0].axvline(e_pa_1, color=’C3′, label=f'{e_pa_1:.0f} c.u.’) ax[0].legend() ax[0].set_title(r’$A_{1}$’) ax[0].set_xlabel(‘Profit (c.u.)’)

sns.kdeplot(profit_data[:, 1], ax=ax[1]) e_pa_2 = np.mean(profit_data[:, 1]) ax[1].axvline(e_pa_2, color=’C3′, label=f'{e_pa_2:.0f} c.u.’) ax[1].legend() ax[1].set_title(r’$A_{2}$’) ax[1].set_xlabel(‘Profit (c.u.)’)

sns.kdeplot(profit_data[:, 2], ax=ax[2]) e_pa_3 = np.mean(profit_data[:, 2]) ax[2].axvline(e_pa_3, color=’C3′, label=f'{e_pa_3:.0f} c.u.’) ax[2].legend(loc=’upper left’) ax[2].set_title(r’$A_{3}$’) ax[2].set_xlabel(‘Profit (c.u.)’)

plt.suptitle(‘Airline profit distribution’) plt.tight_layout();

For airline A3, the price is clearly not the best price. However, we are now interested in exactly how the average profit of airlines A2 and A3 will change if they enter into a codeshare agreement with each other.

def prob_in_trafic_ch(prices): price_1, price_2, price_3, price_ch = prices[:-1] rvdem_1 = gamma(a=12, loc=100, scale=8) rvdem_2 = gamma(a=8, loc=60, scale=7) rvdem_3 = gamma(a=10, loc=230, scale=12)

pb_11 = rvdem_1.sf(price_1) pb_10 = 1 – pb_11

ph_1 = [pb_10, pb_11]

uh_2 = np.array([0.14, 0.1]) pseg_2 = uh_2 / uh_2.sum()

if price_2 > price_3: pbp_22 = rvdem_2.sf(price_2) pbp_23 = rvdem_2.sf(price_3) – rvdem_2.sf(price_2) pb_22 = pbp_22 * pseg_2[0] pb_23 = pbp_22 * pseg_2[1] + pbp_23 else: pbp_22 = rvdem_2.sf(price_2) pbp_23 = rvdem_2.sf(price_3) pb_22 = pbp_22 pb_23 = 0

pb_20 = 1 – pb_22 – pb_23

ph_2 = [pb_20, pb_22, pb_23]

uh_3_ch = np.array([0.28, 0.2, 0.06]) pseg_3_ch = uh_3_ch / uh_3_ch.sum() uh_3 = np.array([0.2, 0.06]) pseg_3 = uh_3 / uh_3.sum()

if price_ch > (price_1 + price_2) > (price_1 + price_3): pbp_31 = rvdem_3.sf(price_ch) pbp_32 = rvdem_3.sf(price_1 + price_2) – rvdem_3.sf(price_ch) pbp_33 = rvdem_3.sf(price_1 + price_3) – rvdem_3.sf(price_1 + price_2) pb_31 = pbp_31 * pseg_3_ch[0] pb_32 = pbp_31 * pseg_3_ch[1] + pbp_32 * pseg_3[0] pb_33 = pbp_31 * pseg_3_ch[2] + pbp_32 * pseg_3[1] + pbp_33 else: pb_31 = 0 pb_32 = 0 pb_33 = 0

pb_30 = 1 – pb_31 – pb_32 – pb_33

ph_3 = [pb_30, pb_31, pb_32, pb_33]

return ph_1, ph_2, ph_3

def sales_ch(P, w_1): h_1 = poisson.rvs(mu=370) h_2 = poisson.rvs(mu=350) h_3 = poisson.rvs(mu=110)

h_all = np.sum([h_1, h_2, h_3]) p_in_h = np.array([h_1, h_2, h_3]) / h_all

v_1, v_2, v_3 = 325, 180, 190 q_1, q_1_ch, q_2, q_3 = 0, 0, 0, 0

for iter in range(h_all): pass_in_h = np.random.choice([1, 2, 3], p=p_in_h) if pass_in_h == 1: if np.random.choice([0, 1], p=P[0]): if q_1 < v_1 – w_1: q_1 += 1

if pass\_in\_h == 2:
a\_i = np.random.choice(\[0, 2, 3\], p=P\[1\])
if a\_i == 2:
if q\_2 < v\_2 – w\_1:
q\_2 += 1
if a\_i == 3:
if q\_3 < v\_3:
q\_3 += 1

if pass\_in\_h == 3:
a\_i = np.random.choice(\[0, 1, 2, 3\], p=P\[2\])
if a\_i == 1:
if q\_1\_ch < w\_1:
q\_1\_ch += 1
if a\_i == 2:
if q\_2 < v\_2 – w\_1:
q\_2 += 1
if q\_1 < v\_1 – w\_1:
q\_1 += 1
if a\_i == 3:
if q\_3 < v\_3:
q\_3 += 1
if q\_1 < v\_1 – w\_1:
q\_1 += 1

return q_1, q_1_ch, q_2, q_3

def profit_a_ch(prices, Q, w_1): profit_1 = (Q[0] * prices[0] + Q[1] * prices[-2]) – (Q[0] + Q[1]) * 6.8 – w_1 * prices[-1] – 48360 profit_2 = (Q[2] * prices[1] + w_1 * prices[-1]) – (Q[2] + Q[1]) * 5.4 – 10270 profit_3 = Q[3] * prices[2] – Q[3] * 5.1 – 9890 return profit_1, profit_2, profit_3

def e_profit_ch(prices, w_1, n_iter): P = prob_in_trafic_ch(prices) return np.mean([profit_a_ch(prices, sales_ch(P, w_1), w_1) for _ in range(n_iter)], axis = 0)

Let’s look at all values of profit A1 and A2 that are simultaneously greater than zero:

PA_1 = [] PA_2 = [] PA_3 = [] PP = [] for i in range(10000): pra_1 = np.random.randint(150, 270) pra_2 = np.random.randint(111, 170) pra_3 = 110 pra_1_ch = np.random.randint(pra_1 + pra_2 , 500) pay_ch = np.random.randint(pra_2, pra_1_ch) prices = pra_1, pra_2, pra_3, pra_1_ch, pay_ch w_1 = np.random.randint(0, 110) pa = e_profit_ch(prices, w_1, 1) if pa[0] > 0 and pa[1] > 0: PA_1.append(pa[0]) PA_2.append(pa[1]) PA_3.append(pa[2]) PP.append([prices, w_1]) plt.plot(PA_2, PA_1, ‘bo’, ms=3, alpha=0.5)

x = np.linspace(0, 17500) y_1 = -x + 20000 y_2 = -0.8 * x + 20000

plt.plot(x, y_1, ‘C3′, label=’Indifference’) plt.plot(x, y_2, ‘C2′, label=’Interest’)

plt.xlabel(r’$A_{2}$ profit (c.u)’) plt.ylabel(r’$A_{1}$ profit (c.u)’) plt.title(‘Scatter of positive profit values ​​of two airlines’)

plt.legend()

plt.show()

The set of points is bounded from above by some upward convex and monotonically decreasing function, which contains all points of the Pareto-efficient set. If this set were symmetric, then the point of the set that is closest to the line cutting off equal segments from the coordinate axes could be taken as the optimal point. This approach is called an indifferent approach. An efficient set is almost never symmetric, so participants have an interest in making sure that asymmetry is necessarily taken into account when making a joint decision. In this case, the point closest to the line above the set and parallel to the line passing through the points of maximum interest is taken as the optimal point (0,Profit∗1) and (Profit∗2,0).

The construction of such a set for a problem in stochastic form always requires investigation and approximation — it cannot be constructed analytically. Let the points of maximum interest be as follows: (0, 12000) and (17500, 0). As a line parallel to another line passing through the points of maximum interest, let us take the line with the equation y=−0.8x+20000. Then the optimal prices will take the following values:

  • Price(1)1=185;
  • Price(2)2=114;
  • Price(1)ch=345;
  • Price(2)ch=120;
  • w(1)3=29.

After the introduction of codeshare flight, the profit distributions will look like this:

prices_opt = [185, 114, 110, 345, 120] w_opt = 29 P = prob_in_trafic_ch(prices_opt)

q_ch_data = [] profit_ch_data = []

for i in range(1000): Q = sales_ch(P, w_opt) q_ch_data.append(Q) profit_ch_data.append(profit_a_ch(prices_opt, Q, w_opt))

q_ch_data = np.array(q_ch_data) profit_ch_data = np.array(profit_ch_data) prices_opt = [185, 114, 110, 345, 120] w_opt = 29 P = prob_in_trafic_ch(prices_opt)

q_ch_data = [] profit_ch_data = []

for i in range(1000): Q = sales_ch(P, w_opt) q_ch_data.append(Q) profit_ch_data.append(profit_a_ch(prices_opt, Q, w_opt))

q_ch_data = np.array(q_ch_data) profit_ch_data = np.array(profit_ch_data)

In addition to increasing profits, we have quietly solved the negotiation problem. All algorithms for optimizing codeshare agreements optimize the revenue of only one airline. In the end, two airlines (potential partners) using such an algorithm will meet at negotiations with different figures — this means that in the final result everything will depend on how they negotiate. Constructing a Pareto-efficient set not only optimizes the profits of both airlines, but also makes negotiations much easier, opening a more direct and shorter path to game theory — eliminating the human element entirely.

The idea of bottling and capturing passengers is very profound and has “far reaching” implications. How much money can be made from such an idea? Testing on real and simulated data shows that considering travelers’ preferences together with calculating optimal quotas and profits for both airlines yields significant gains over preference-only methods:

The red color shows how much is lost by the airlines that did not enter into an agreement — you can see that, on average, the loss exceeds the gain of the airlines that created a codeshare flight.

Talking about competition as such is not quite appropriate here. The point is that changes in passenger flows affect the entire route network. Negative or positive effects of such changes can affect all participants of the network: partners, competitors and even those who were not taken into account at all.

Airlines also often overestimate the attractiveness of codeshare flights. Sometimes prices are inflated by more than 100 dollars. Travelers really value comfort a lot, but because of the extremely inflated price, they choose less comfortable but much cheaper options.

The fact that the optimization problem is a two-criteria problem deserves special attention. If the operating carrier (the one who actually transports passengers) does not know how to calculate the Pareto-optimal set of solutions, the marketing carrier (the one who sells tickets) can easily take advantage of this and pay less than it should. And after all, all he needs to do is simply track the sales of a potential affiliate.

By the way, in this article only one most common type of free-sale codeshare was considered — when both airlines can publish the other carrier’s flight as their own with little or no restrictions on the number of seats that can be sold (within the capacity of the airplane or the set limits). However, the considered optimization method is also suitable for other types of codeshare, for example, block-space — when the number of seats to be sold by a marketing carrier is fixed. The method is also suitable for optimizing interline agreements, where one airline simply recognizes the carriage documents of another airline. Interline also affects attractiveness, but requires fewer constraints on the part of the airline.

On the one hand, taking into account different agreements makes the task a bit more complicated, but on the other hand, it allows the airline to combine different conditions, optimizing not only profits but also attractiveness for both regular and new passengers due to the vast route network.

In conclusion

A 5% increase in profit just due to codeshare agreements is not a bad result. Can it be more? Of course, yes. This problem can be viewed as an extension of the IFAM fleet assignment problem based on passenger composition modeling and the principle of passenger flow bottleneck/capture. A codeshare flight can be conceptualized as a flight operated by some virtual aircraft. This means that one can use already well-established techniques for further optimization — for example, optimizing at the level of dynamic pricing (subclasses) rather than averaged and rough values. In this case, the profit gains can be even greater.

IFAM considers only one airline, but the innovativeness of this model is precisely in the fact that for the first time it began to take into account the impact of changes in some passenger flows on changes in other passenger flows. It became possible to “spill” in one place and “collect the spill” in another. In IFAM there are no codeshare flights, there is no attraction, and passenger flows are only affected by price.

The difficulty with IFAM expansion is that each potential shared flight would really have to be treated as a separate virtual airplane. There could be more than 100 or even 1,000 such potential airplanes in an airline’s fleet. And that’s not all — the IFAM decision is usually preceded by the task of shaping the schedule, which is designed largely with traveler appeal in mind. When adding codeshare flights, the degree to which the fixed flight schedules of the virtual airplanes are consistent with the fixed schedules on which the airline’s real airplanes fly must be considered. Most importantly, after selecting each virtual airplane and ticket price, the redistribution of passenger flows across the entire route network will have to be calculated.

As it was mentioned at the beginning of the article, the solution of the problem is possible only if there is data — more precisely, a huge amount of data. One way or another, it all comes down to modeling the discrete choices that travelers make. Some airlines, with their large amounts of historical data, do a pretty good job with this, but even they can’t compete with GDS (Global Distribution System). This is due to the fact that airlines have data on passenger flows of only their route networks, while GDS sees the whole picture and is able to analyze a much larger number of both routes and scenarios of changes in passenger flows. However, it must be said that this only applies to the new generation of GDS. Unfortunately, older systems have never dealt with such tasks or dealt with them conditionally.

In reality, no airline will ever be able to assess the redistribution of passenger flows in a timely manner, simply because it requires data from other airlines. In this article we have touched, albeit in passing, on the topic of multi-criteria optimization, which facilitates negotiations, which in turn takes us into game theory. But this theory has repeatedly proved that cooperative strategies are the most profitable and sustainable. In order to achieve this, a new generation of GDS is needed, then any airline would have access to anonymized data on passenger traffic of other airlines. Thanks to this it is possible to achieve a qualitatively new level of optimization not only of codeshare agreements, but also of a number of other tasks: schedules, fleet deployment, etc.

To understand the possibilities of GDS, let us ask a simple question: what would happen if in the considered problem all flights were performed not by three but by one airline? In this case, only the average sum of profits from all flights could be optimized. You get the usual IFAM problem, and the gain in total profits becomes much larger than from the introduction of codeshare flights. The only problem is that the flights are operated by different airlines. Centralized management has many more advantages, but it also has difficulties. Due to insufficient data, airlines cannot do this, but GDS can.

Sign Up For Daily Newsletter

Be keep up! Get the latest breaking news delivered straight to your inbox.
By signing up, you agree to our Terms of Use and acknowledge the data practices in our Privacy Policy. You may unsubscribe at any time.
Share This Article
Facebook Twitter Email Print
Share
What do you think?
Love0
Sad0
Happy0
Sleepy0
Angry0
Dead0
Wink0
Previous Article Sir Fraser Stoddart, pioneer of cell-sized machines, dead at 82: ‘He has changed what’s possible’
Next Article Hamas agrees to release 10 hostages as terror group issues ceasefire red lines
Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Stay Connected

248.1k Like
69.1k Follow
134k Pin
54.3k Follow

Latest News

US divided over AI implications: Gallup
News
When Every Dash Is AI: Why Good Writing Now Feels Illegal | HackerNoon
Computing
Rumor Replay: iPhone 17 Air colors, Apple’s 2026 lineup, and more – 9to5Mac
News
Prime Day Live in 25: We’re Tracking the Deals + Trends
Gadget

You Might also Like

Computing

When Every Dash Is AI: Why Good Writing Now Feels Illegal | HackerNoon

15 Min Read
Computing

The TechBeat: Junior Cybersecurity Roles Are Vanishing—Blame Agentic AI (7/10/2025) | HackerNoon

6 Min Read
Computing

Why Golang Belongs in Your AI Stack—Especially for Preprocessing Pipelines | HackerNoon

8 Min Read
Computing

The Quant Graveyard: What 40 Years of Strategy Testing Really Taught Me | HackerNoon

9 Min Read
//

World of Software is your one-stop website for the latest tech news and updates, follow us now to get the news that matters to you.

Quick Link

  • Privacy Policy
  • Terms of use
  • Advertise
  • Contact

Topics

  • Computing
  • Software
  • Press Release
  • Trending

Sign Up for Our Newsletter

Subscribe to our newsletter to get our newest articles instantly!

World of SoftwareWorld of Software
Follow US
Copyright © All Rights Reserved. World of Software.
Welcome Back!

Sign in to your account

Lost your password?