Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

LinkedIn Games Python Package

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-games

Or run the command below if you use uv as your package manager:

uv add linkedin-games

Abstract 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 m and n
The total number of rows and columns on game’s board.
Range sets I and J
The ranges of rows and columns, respectively.
Set S
The set of all squares on game board, which is a cartesian product between ranges I and J.
opt_modeler.py
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
59
from 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.

renderer.py
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
from 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