The LinkedIn Games is a Python Package designed to solve the LinkedIn mini games by using Linear Optimization models and it will be the library to be used along this book.
Dependencies¶
The Linkedin Games package has the following Python dependencies to model, solve and visualize the optimization problems:
- Pyomo
- A powerful and flexible optimization modeling language that allows users to define optimization problems in a clear and concise way. Pyomo supports a wide range of optimization problem types, including linear, integer, and nonlinear programming, and can interface with various solvers.
- NetworkX
- A library for the creation, manipulation, and study of complex networks. It provides tools for working with graphs and networks, which can be useful for modeling and solving optimization problems that involve network structures.
- Matplotlib
- A plotting library for Python that provides a wide range of tools for creating static, animated, and interactive visualizations. It can be used to visualize optimization results, such as the feasible region, the objective function landscape, or the solution itself.
With this three libraries, it’s able to model, solve and visualize the optimization problems we will encounter in this book. But...
How to install¶
To install the LinkedIn Games package, you can use the traditional pip command:
pip install linkedin-gamesOr run the command below if you use uv as your package manager:
uv add linkedin-gamesAbstract Base Classes¶
In order to understand how Pyomo work to build and solve the model before displaying the solution with NetworkX, it will be useful to check out the implementation of some Abstract Base Classes, which share methods and attributes with many other classes.
GameModeler¶
The GameModeler is a builder pattern that sets the Pyomo ConcreteModel’s components of a game. This base class creates the basic components shared with all games, such as:
- Board dimension parameters
mandn - The total number of rows and columns on game’s board.
- Range sets
IandJ - The ranges of rows and columns, respectively.
- Set
S - The set of all squares on game board, which is a cartesian product between ranges
IandJ.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59from abc import ABC, abstractmethod import pyomo.environ as pyo from ...domain.game_grid import GameGrid class OptModeler[G: GameGrid](ABC): def __init__(self) -> None: self.reset() def reset(self) -> None: self._game: G self._model = pyo.ConcreteModel() def _set_board_dimensions(self) -> None: m, n = self._game.dims self._model.m = pyo.Param(initialize=m, domain=pyo.PositiveIntegers) self._model.n = pyo.Param(initialize=n, domain=pyo.PositiveIntegers) @abstractmethod def _set_range_sets(self) -> None: self._model.I = pyo.RangeSet(self._model.m) # Rows self._model.J = pyo.RangeSet(self._model.n) # Columns @abstractmethod def _set_composite_sets(self) -> None: self._model.S = pyo.Set( # Grid Squares initialize=lambda model: [(i,j) for i in model.I for j in model.J] ) @abstractmethod def _set_parameters(self) -> None: ... @abstractmethod def _set_decision_variables(self) -> None: ... def _set_objective_function(self) -> None: self._model.obj = pyo.Objective(expr=0) # feasibility problem @abstractmethod def _set_constraints(self) -> None: ... def build_model(self, game: G) -> pyo.ConcreteModel: self._game = game self._set_board_dimensions() self._set_range_sets() self._set_composite_sets() self._set_parameters() self._set_decision_variables() self._set_objective_function() self._set_constraints() model = self._model self.reset() return model
Program 1:The game modeler’s base class
GameRenderer¶
The GameRenderer is plays the role to display the game’s board by using the NetworkX, to build the graph structure, and Matplotlib, to plot the board as a chart.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27from abc import ABC, abstractmethod import networkx as nx from ...domain.game_grid import GameGrid class GameRenderer[G: GameGrid](ABC): _SCALE_FACTOR = .5 def __init__(self, game: G) -> None: self._game = game m, n = game.dims self._height = m * self._SCALE_FACTOR self._width = n * self._SCALE_FACTOR self._set_grid() @abstractmethod def _set_grid(self) -> None: self._grid = nx.grid_2d_graph(*self._game.dims).to_directed() nx.set_node_attributes(self._grid, name="value", values={(i-1, j-1): k for (i, j), k in self._game.squares.items()} ) @abstractmethod def display(self) -> None: ...
Program 3:The game renderer’s base class