04 Airport game
Airport game or airport problem is another famous example of cooperative games, where Shapley values can be easily computed.
In the airport game, several companies seek to build an airport runway. Each company has a different aircraft type which requires a different different runway length. To accommodate everybody the longest possible runway needs to be built. The question is how to assign the "fair" value for each air carrier.
Example from Wikipedia
An airport needs to build a runway for 4 different aircraft types. The building cost associated with each aircraft is 8, 11, 13, 18 for aircraft A, B, C, D. We would come up with the following cost table based on Shapley value:
Aircraft |
Adding A |
Adding B |
Adding C |
Adding D |
Shapley value |
|---|---|---|---|---|---|
Marginal Cost |
8 |
3 |
2 |
5 |
|
Cost to A |
2 |
2 |
|||
Cost to B |
2 |
1 |
3 |
||
Cost to C |
2 |
1 |
1 |
4 |
|
Cost to D |
2 |
1 |
1 |
5 |
9 |
Total |
18 |
Implement with shapley-numba
Let’s consider implementation with shapley-numba. The package allows to encapsulate the internal parameters in a single object. We will encapsulate the length requirements for each aircraft type.
Next, we need to implement that method value. The parameter to value method is subset - an array of zeros and ones. For efficiency, we will multiply the length requirements by subset array and take the maximum of the result.
import numba
from shapley_numba import numba_game
airport_game_spec = [('length_requirements', numba.float64[:])]
@numba_game(airport_game_spec)
class AirPortGame:
def __init__(self, length_requirements):
self.length_requirements = length_requirements
def value(self, subset):
return max(self.length_requirements * subset)
import numpy as np
game = AirPortGame(np.array([8, 11, 13, 18], dtype=np.float64))
Numba gotchas:
Since numba requires strict typing neither of the following two work:
game = AirPortGame([8, 11, 13,18])
This is because numba can’t work with heterogeneous python list when expecting a numba array.
game = AirPortGame(np.array([8, 11, 13,18]))
This also doesn’t work because the create numpy array assumes dtype of int32, while the game spec wants float64
from shapley_numba.shapley import shapley
shapley(game, num_players=4)
array([2., 3., 4., 9.])