Cara menggunakan vector optimization python

Linear programming is a set of techniques used in mathematical programming, sometimes called mathematical optimization, to solve systems of linear equations and inequalities while maximizing or minimizing some linear function. It’s important in fields like scientific computing, economics, technical sciences, manufacturing, transportation, military, management, energy, and so on.

The Python ecosystem offers several comprehensive and powerful tools for linear programming. You can choose between simple and complex tools as well as between free and commercial ones. It all depends on your needs.

In this tutorial, you’ll learn:

  • What linear programming is and why it’s important
  • Which Python tools are suitable for linear programming
  • How to build a linear programming model in Python
  • How to solve a linear programming problem with Python

You’ll first learn about the fundamentals of linear programming. Then you’ll explore how to implement linear programming techniques in Python. Finally, you’ll look at resources and libraries to help further your linear programming journey.

Free Bonus: 5 Thoughts On Python Mastery, a free course for Python developers that shows you the roadmap and the mindset you’ll need to take your Python skills to the next level.

Linear Programming Explanation

In this section, you’ll learn the basics of linear programming and a related discipline, mixed-integer linear programming. In the , you’ll see some practical linear programming examples. Later, you’ll solve linear programming and mixed-integer linear programming problems with Python.

Remove ads

What Is Linear Programming?

Imagine that you have a system of linear equations and inequalities. Such systems often have many possible solutions. Linear programming is a set of mathematical and computational tools that allows you to find a particular solution to this system that corresponds to the maximum or minimum of some other linear function.

What Is Mixed-Integer Linear Programming?

Mixed-integer linear programming is an extension of linear programming. It handles problems in which at least one variable takes a discrete integer rather than a continuous value. Although mixed-integer problems look similar to continuous variable problems at first sight, they offer significant advantages in terms of flexibility and precision.

Integer variables are important for properly representing quantities naturally expressed with integers, like the number of airplanes produced or the number of customers served.

A particularly important kind of integer variable is the binary variable. It can take only the values zero or one and is useful in making yes-or-no decisions, such as whether a plant should be built or if a machine should be turned on or off. You can also use them to mimic logical constraints.

Why Is Linear Programming Important?

Linear programming is a fundamental optimization technique that’s been used for decades in science- and math-intensive fields. It’s precise, relatively fast, and suitable for a range of practical applications.

Mixed-integer linear programming allows you to overcome many of the limitations of linear programming. You can approximate non-linear functions with piecewise linear functions, use semi-continuous variables, model logical constraints, and more. It’s a computationally intensive tool, but the advances in computer hardware and software make it more applicable every day.

Often, when people try to formulate and solve an optimization problem, the first question is whether they can apply linear programming or mixed-integer linear programming.

Some use cases of linear programming and mixed-integer linear programming are illustrated in the following articles:

  • Gurobi Optimization Case Studies
  • Five Areas of Application for Linear Programming Techniques

The importance of linear programming, and especially mixed-integer linear programming, has increased over time as computers have gotten more capable, algorithms have improved, and more user-friendly software solutions have become available.

Linear Programming With Python

The basic method for solving linear programming problems is called the simplex method, which has several variants. Another popular approach is the interior-point method.

Mixed-integer linear programming problems are solved with more complex and computationally intensive methods like the branch-and-bound method, which uses linear programming under the hood. Some variants of this method are the branch-and-cut method, which involves the use of cutting planes, and the branch-and-price method.

There are several suitable and well-known Python tools for linear programming and mixed-integer linear programming. Some of them are open source, while others are proprietary. Whether you need a free or paid tool depends on the size and complexity of your problem as well as on the need for speed and flexibility.

It’s worth mentioning that almost all widely used linear programming and mixed-integer linear programming libraries are native to and written in Fortran or C or C++. This is because linear programming requires computationally intensive work with (often large) matrices. Such libraries are called solvers. The Python tools are just wrappers around the solvers.

Python is suitable for building wrappers around native libraries because it works well with C/C++. You’re not going to need any C/C++ (or Fortran) for this tutorial, but if you want to learn more about this cool feature, then check out the following resources:

  • Building a Python C Extension Module
  • CPython Internals
  • Extending Python with C or C++

Basically, when you define and solve a model, you use Python functions or methods to call a low-level library that does the actual optimization job and returns the solution to your Python object.

Several free Python libraries are specialized to interact with linear or mixed-integer linear programming solvers:

  • SciPy Optimization and Root Finding
  • PuLP

In this tutorial, you’ll use SciPy and PuLP to define and solve linear programming problems.

Remove ads

Linear Programming Examples

In this section, you’ll see two examples of linear programming problems:

  1. A small problem that illustrates what linear programming is
  2. A practical problem related to resource allocation that illustrates linear programming concepts in a real-world scenario

You’ll use Python to solve these two problems in the .

Small Linear Programming Problem

Consider the following linear programming problem:

Cara menggunakan vector optimization python

You need to find x and y such that the red, blue, and yellow inequalities, as well as the inequalities x ≥ 0 and y ≥ 0, are satisfied. At the same time, your solution must correspond to the largest possible value of z.

The independent variables you need to find—in this case x and y—are called the decision variables. The function of the decision variables to be maximized or minimized—in this case z—is called the objective function, the cost function, or just the goal. The inequalities you need to satisfy are called the inequality constraints. You can also have equations among the constraints called equality constraints.

This is how you can visualize the problem:

Cara menggunakan vector optimization python

The red line represents the function 2x + y = 20, and the red area above it shows where the red inequality is not satisfied. Similarly, the blue line is the function −4x + 5y = 10, and the blue area is forbidden because it violates the blue inequality. The yellow line is −x + 2y = −2, and the yellow area below it is where the yellow inequality isn’t valid.

If you disregard the red, blue, and yellow areas, only the gray area remains. Each point of the gray area satisfies all constraints and is a potential solution to the problem. This area is called the feasible region, and its points are feasible solutions. In this case, there’s an infinite number of feasible solutions.

You want to maximize z. The feasible solution that corresponds to maximal z is the optimal solution. If you were trying to minimize the objective function instead, then the optimal solution would correspond to its feasible minimum.

Note that z is linear. You can imagine it as a plane in three-dimensional space. This is why the optimal solution must be on a vertex, or corner, of the feasible region. In this case, the optimal solution is the point where the red and blue lines intersect, as you’ll see .

Sometimes a whole edge of the feasible region, or even the entire region, can correspond to the same value of z. In that case, you have many optimal solutions.

You’re now ready to expand the problem with the additional equality constraint shown in green:

Cara menggunakan vector optimization python

The equation −x + 5y = 15, written in green, is new. It’s an equality constraint. You can visualize it by adding a corresponding green line to the previous image:

Cara menggunakan vector optimization python

The solution now must satisfy the green equality, so the feasible region isn’t the entire gray area anymore. It’s the part of the green line passing through the gray area from the intersection point with the blue line to the intersection point with the red line. The latter point is the solution.

If you insert the demand that all values of x must be integers, then you’ll get a mixed-integer linear programming problem, and the set of feasible solutions will change once again:

Cara menggunakan vector optimization python

You no longer have the green line, only the points along the line where the value of x is an integer. The feasible solutions are the green points on the gray background, and the optimal one in this case is nearest to the red line.

These three examples illustrate feasible linear programming problems because they have bounded feasible regions and finite solutions.

Remove ads

Infeasible Linear Programming Problem

A linear programming problem is infeasible if it doesn’t have a solution. This usually happens when no solution can satisfy all constraints at once.

For example, consider what would happen if you added the constraint x + y ≤ −1. Then at least one of the decision variables (x or y) would have to be negative. This is in conflict with the given constraints x ≥ 0 and y ≥ 0. Such a system doesn’t have a feasible solution, so it’s called infeasible.

Another example would be adding a second equality constraint parallel to the green line. These two lines wouldn’t have a point in common, so there wouldn’t be a solution that satisfies both constraints.

Unbounded Linear Programming Problem

A linear programming problem is unbounded if its feasible region isn’t bounded and the solution is not finite. This means that at least one of your variables isn’t constrained and can reach to positive or negative infinity, making the objective infinite as well.

For example, say you take the initial problem above and drop the red and yellow constraints. Dropping constraints out of a problem is called relaxing the problem. In such a case, x and y wouldn’t be bounded on the positive side. You’d be able to increase them toward positive infinity, yielding an infinitely large z value.

Resource Allocation Problem

In the previous sections, you looked at an abstract linear programming problem that wasn’t tied to any real-world application. In this subsection, you’ll find a more concrete and practical optimization problem related to resource allocation in manufacturing.

Say that a factory produces four different products, and that the daily produced amount of the first product is x₁, the amount produced of the second product is x₂, and so on. The goal is to determine the profit-maximizing daily production amount for each product, bearing in mind the following conditions:

  1. The profit per unit of product is $20, $12, $40, and $25 for the first, second, third, and fourth product, respectively.

  2. Due to manpower constraints, the total number of units produced per day can’t exceed fifty.

  3. For each unit of the first product, three units of the raw material A are consumed. Each unit of the second product requires two units of the raw material A and one unit of the raw material B. Each unit of the third product needs one unit of A and two units of B. Finally, each unit of the fourth product requires three units of B.

  4. Due to the transportation and storage constraints, the factory can consume up to one hundred units of the raw material A and ninety units of B per day.

The mathematical model can be defined like this:

Cara menggunakan vector optimization python

The objective function (profit) is defined in condition 1. The manpower constraint follows from condition 2. The constraints on the raw materials A and B can be derived from conditions 3 and 4 by summing the raw material requirements for each product.

Finally, the product amounts can’t be negative, so all decision variables must be greater than or equal to zero.

Unlike the previous example, you can’t conveniently visualize this one because it has four decision variables. However, the principles remain the same regardless of the dimensionality of the problem.

Linear Programming Python Implementation

In this tutorial, you’ll use two Python packages to solve the linear programming problem described above:

  1. SciPy is a general-purpose package for scientific computing with Python.
  2. PuLP is a Python linear programming API for defining problems and invoking external solvers.

SciPy is straightforward to set up. Once you install it, you’ll have everything you need to start. Its subpackage

$ sudo apt install glpk glpk-utils
7 can be used for both linear and nonlinear optimization.

PuLP allows you to choose solvers and formulate problems in a more natural way. The default solver used by PuLP is the COIN-OR Branch and Cut Solver (CBC). It’s connected to the COIN-OR Linear Programming Solver (CLP) for linear relaxations and the COIN-OR Cut Generator Library (CGL) for cuts generation.

Another great open source solver is the GNU Linear Programming Kit (GLPK). Some well-known and very powerful commercial and proprietary solutions are Gurobi, CPLEX, and XPRESS.

Besides offering flexibility when defining problems and the ability to run various solvers, PuLP is less complicated to use than alternatives like Pyomo or CVXOPT, which require more time and effort to master.

Remove ads

Installing SciPy and PuLP

To follow this tutorial, you’ll need to install SciPy and PuLP. The examples below use version 1.4.1 of SciPy and version 2.1 of PuLP.

You can install both using

$ sudo apt install glpk glpk-utils
8:

$ python -m pip install -U "scipy==1.4.*" "pulp==2.1"

You might need to run

$ sudo apt install glpk glpk-utils
9 or
$ sudo dnf install glpk-utils
0 to enable the default solvers for PuLP, especially if you’re using Linux or Mac:

$ pulptest

Optionally, you can download, install, and use GLPK. It’s free and open source and works on Windows, MacOS, and Linux. You’ll see how to use GLPK (in addition to CBC) with PuLP later in this tutorial.

On Windows, you can and run the installation files.

On MacOS, you can use Homebrew:

$ brew install glpk

On Debian and Ubuntu, use

$ sudo dnf install glpk-utils
1 to install
$ sudo dnf install glpk-utils
2 and
$ sudo dnf install glpk-utils
3:

$ sudo apt install glpk glpk-utils

On Fedora, use

$ sudo dnf install glpk-utils
4 with
$ sudo dnf install glpk-utils
3:

$ sudo dnf install glpk-utils

You might also find conda useful for installing GLPK:

$ conda install -c conda-forge glpk

After completing the installation, you can check the version of GLPK:

$ glpsol --version

See GLPK’s tutorials on installing with Windows executables and Linux packages for more information.

Using SciPy

In this section, you’ll learn how to use the SciPy optimization and root-finding library for linear programming.

To define and solve optimization problems with SciPy, you need to import

$ sudo dnf install glpk-utils
6:

>>>

>>> from scipy.optimize import linprog

Now that you have

$ sudo dnf install glpk-utils
7 imported, you can start optimizing.

Example 1

Let’s first solve the linear programming problem from above:

Cara menggunakan vector optimization python

$ sudo dnf install glpk-utils
7 solves only minimization (not maximization) problems and doesn’t allow inequality constraints with the greater than or equal to sign (≥). To work around these issues, you need to modify your problem before starting optimization:

  • Instead of maximizing z = x + 2y, you can minimize its negative(−z = −x − 2y).
  • Instead of having the greater than or equal to sign, you can multiply the yellow inequality by −1 and get the opposite less than or equal to sign (≤).

After introducing these changes, you get a new system:

Cara menggunakan vector optimization python

This system is equivalent to the original and will have the same solution. The only reason to apply these changes is to overcome the limitations of SciPy related to the problem formulation.

The next step is to define the input values:

>>>

>>> obj = [-1, -2]
>>> #      ─┬  ─┬
>>> #       │   └┤ Coefficient for y
>>> #       └────┤ Coefficient for x

>>> lhs_ineq = [[ 2,  1],  # Red constraint left side
...             [-4,  5],  # Blue constraint left side
...             [ 1, -2]]  # Yellow constraint left side

>>> rhs_ineq = [20,  # Red constraint right side
...             10,  # Blue constraint right side
...              2]  # Yellow constraint right side

>>> lhs_eq = [[-1, 5]]  # Green constraint left side
>>> rhs_eq = [15]       # Green constraint right side

You put the values from the system above into the appropriate lists, tuples, or NumPy arrays:

  • $ sudo dnf install glpk-utils
    
    9 holds the coefficients from the objective function.
  • $ conda install -c conda-forge glpk
    
    0 holds the left-side coefficients from the inequality (red, blue, and yellow) constraints.
  • $ conda install -c conda-forge glpk
    
    1 holds the right-side coefficients from the inequality (red, blue, and yellow) constraints.
  • $ conda install -c conda-forge glpk
    
    2 holds the left-side coefficients from the equality (green) constraint.
  • $ conda install -c conda-forge glpk
    
    3 holds the right-side coefficients from the equality (green) constraint.

Note: Please, be careful with the order of rows and columns!

The order of the rows for the left and right sides of the constraints must be the same. Each row represents one constraint.

The order of the coefficients from the objective function and left sides of the constraints must match. Each column corresponds to a single decision variable.

The next step is to define the bounds for each variable in the same order as the coefficients. In this case, they’re both between zero and positive infinity:

>>>

>>> bnd = [(0, float("inf")),  # Bounds of x
...        (0, float("inf"))]  # Bounds of y

This statement is redundant because

$ sudo dnf install glpk-utils
7 takes these bounds (zero to positive infinity) by default.

Note: Instead of , you can use , , or

$ conda install -c conda-forge glpk
8.

Finally, it’s time to optimize and solve your problem of interest. You can do that with

$ sudo dnf install glpk-utils
7:

>>>

$ pulptest
0

The parameter

$ glpsol --version
0 refers to the coefficients from the objective function.
$ glpsol --version
1 and
$ glpsol --version
2 are related to the coefficients from the left and right sides of the inequality constraints, respectively. Similarly,
$ glpsol --version
3 and
$ glpsol --version
4 refer to equality constraints. You can use
$ glpsol --version
5 to provide the lower and upper bounds on the decision variables.

You can use the parameter

$ glpsol --version
6 to define the linear programming method that you want to use. There are three options:

  1. $ glpsol --version
    
    7 selects the interior-point method. This option is set by default.
  2. $ glpsol --version
    
    8 selects the revised two-phase simplex method.
  3. $ glpsol --version
    
    9 selects the legacy two-phase simplex method.

$ sudo dnf install glpk-utils
7 returns a data structure with these attributes:

  • >>> from scipy.optimize import linprog
    
    1 is the equality constraints residuals.

  • >>> from scipy.optimize import linprog
    
    2 is the objective function value at the optimum (if found).

  • >>> from scipy.optimize import linprog
    
    3 is the status of the solution.

  • >>> from scipy.optimize import linprog
    
    4 is the number of iterations needed to finish the calculation.

  • >>> from scipy.optimize import linprog
    
    5 is the values of the slack variables, or the differences between the values of the left and right sides of the constraints.

  • >>> from scipy.optimize import linprog
    
    6 is an integer between
    >>> from scipy.optimize import linprog
    
    7 and
    >>> from scipy.optimize import linprog
    
    8 that shows the status of the solution, such as
    >>> from scipy.optimize import linprog
    
    7 for when the optimal solution has been found.

  • >>> obj = [-1, -2]
    >>> #      ─┬  ─┬
    >>> #       │   └┤ Coefficient for y
    >>> #       └────┤ Coefficient for x
    
    >>> lhs_ineq = [[ 2,  1],  # Red constraint left side
    ...             [-4,  5],  # Blue constraint left side
    ...             [ 1, -2]]  # Yellow constraint left side
    
    >>> rhs_ineq = [20,  # Red constraint right side
    ...             10,  # Blue constraint right side
    ...              2]  # Yellow constraint right side
    
    >>> lhs_eq = [[-1, 5]]  # Green constraint left side
    >>> rhs_eq = [15]       # Green constraint right side
    
    0 is a Boolean that shows whether the optimal solution has been found.

  • >>> obj = [-1, -2]
    >>> #      ─┬  ─┬
    >>> #       │   └┤ Coefficient for y
    >>> #       └────┤ Coefficient for x
    
    >>> lhs_ineq = [[ 2,  1],  # Red constraint left side
    ...             [-4,  5],  # Blue constraint left side
    ...             [ 1, -2]]  # Yellow constraint left side
    
    >>> rhs_ineq = [20,  # Red constraint right side
    ...             10,  # Blue constraint right side
    ...              2]  # Yellow constraint right side
    
    >>> lhs_eq = [[-1, 5]]  # Green constraint left side
    >>> rhs_eq = [15]       # Green constraint right side
    
    1 is a NumPy array holding the optimal values of the decision variables.

You can access these values separately:

>>>

$ pulptest
1

That’s how you get the results of optimization. You can also show them graphically:

Cara menggunakan vector optimization python

As discussed earlier, the optimal solutions to linear programming problems lie at the vertices of the feasible regions. In this case, the feasible region is just the portion of the green line between the blue and red lines. The optimal solution is the green square that represents the point of intersection between the green and red lines.

If you want to exclude the equality (green) constraint, just drop the parameters

$ glpsol --version
3 and
$ glpsol --version
4 from the
$ sudo dnf install glpk-utils
7 call:

>>>

$ pulptest
2

The solution is different from the previous case. You can see it on the chart:

Cara menggunakan vector optimization python

In this example, the optimal solution is the purple vertex of the feasible (gray) region where the red and blue constraints intersect. Other vertices, like the yellow one, have higher values for the objective function.

Example 2

You can use SciPy to solve the resource allocation problem stated in the :

Cara menggunakan vector optimization python

As in the previous example, you need to extract the necessary vectors and matrix from the problem above, pass them as the arguments to

>>> obj = [-1, -2]
>>> #      ─┬  ─┬
>>> #       │   └┤ Coefficient for y
>>> #       └────┤ Coefficient for x

>>> lhs_ineq = [[ 2,  1],  # Red constraint left side
...             [-4,  5],  # Blue constraint left side
...             [ 1, -2]]  # Yellow constraint left side

>>> rhs_ineq = [20,  # Red constraint right side
...             10,  # Blue constraint right side
...              2]  # Yellow constraint right side

>>> lhs_eq = [[-1, 5]]  # Green constraint left side
>>> rhs_eq = [15]       # Green constraint right side
5, and get the results:

>>>

$ pulptest
3

The result tells you that the maximal profit is

>>> obj = [-1, -2]
>>> #      ─┬  ─┬
>>> #       │   └┤ Coefficient for y
>>> #       └────┤ Coefficient for x

>>> lhs_ineq = [[ 2,  1],  # Red constraint left side
...             [-4,  5],  # Blue constraint left side
...             [ 1, -2]]  # Yellow constraint left side

>>> rhs_ineq = [20,  # Red constraint right side
...             10,  # Blue constraint right side
...              2]  # Yellow constraint right side

>>> lhs_eq = [[-1, 5]]  # Green constraint left side
>>> rhs_eq = [15]       # Green constraint right side
6 and corresponds to x₁ = 5 and x₃ = 45. It’s not profitable to produce the second and fourth products under the given conditions. You can draw several interesting conclusions here:

  1. The third product brings the largest profit per unit, so the factory will produce it the most.

  2. The first slack is

    >>> from scipy.optimize import linprog
    
    7, which means that the values of the left and right sides of the manpower (first) constraint are the same. The factory produces
    >>> obj = [-1, -2]
    >>> #      ─┬  ─┬
    >>> #       │   └┤ Coefficient for y
    >>> #       └────┤ Coefficient for x
    
    >>> lhs_ineq = [[ 2,  1],  # Red constraint left side
    ...             [-4,  5],  # Blue constraint left side
    ...             [ 1, -2]]  # Yellow constraint left side
    
    >>> rhs_ineq = [20,  # Red constraint right side
    ...             10,  # Blue constraint right side
    ...              2]  # Yellow constraint right side
    
    >>> lhs_eq = [[-1, 5]]  # Green constraint left side
    >>> rhs_eq = [15]       # Green constraint right side
    
    8 units per day, and that’s its full capacity.

  3. The second slack is

    >>> obj = [-1, -2]
    >>> #      ─┬  ─┬
    >>> #       │   └┤ Coefficient for y
    >>> #       └────┤ Coefficient for x
    
    >>> lhs_ineq = [[ 2,  1],  # Red constraint left side
    ...             [-4,  5],  # Blue constraint left side
    ...             [ 1, -2]]  # Yellow constraint left side
    
    >>> rhs_ineq = [20,  # Red constraint right side
    ...             10,  # Blue constraint right side
    ...              2]  # Yellow constraint right side
    
    >>> lhs_eq = [[-1, 5]]  # Green constraint left side
    >>> rhs_eq = [15]       # Green constraint right side
    
    9 because the factory consumes 60 units of raw material A (15 units for the first product plus 45 for the third) out of a potential
    >>> bnd = [(0, float("inf")),  # Bounds of x
    ...        (0, float("inf"))]  # Bounds of y
    
    0 units.

  4. The third slack is

    >>> from scipy.optimize import linprog
    
    7, which means that the factory consumes all
    >>> bnd = [(0, float("inf")),  # Bounds of x
    ...        (0, float("inf"))]  # Bounds of y
    
    2 units of the raw material B. This entire amount is consumed for the third product. That’s why the factory can’t produce the second or fourth product at all and can’t produce more than
    >>> bnd = [(0, float("inf")),  # Bounds of x
    ...        (0, float("inf"))]  # Bounds of y
    
    3 units of the third product. It lacks the raw material B.

>>> bnd = [(0, float("inf")),  # Bounds of x
...        (0, float("inf"))]  # Bounds of y
4 is
>>> from scipy.optimize import linprog
7 and
>>> bnd = [(0, float("inf")),  # Bounds of x
...        (0, float("inf"))]  # Bounds of y
6 is
>>> bnd = [(0, float("inf")),  # Bounds of x
...        (0, float("inf"))]  # Bounds of y
7, indicating that the optimization problem was successfully solved with the optimal feasible solution.

SciPy’s linear programming capabilities are useful mainly for smaller problems. For larger and more complex problems, you might find other libraries more suitable for the following reasons:

  • SciPy can’t run various external solvers.

  • SciPy can’t work with integer decision variables.

  • SciPy doesn’t provide classes or functions that facilitate model building. You have to define arrays and matrices, which might be a tedious and error-prone task for large problems.

  • SciPy doesn’t allow you to define maximization problems directly. You must convert them to minimization problems.

  • SciPy doesn’t allow you to define constraints using the greater-than-or-equal-to sign directly. You must use the less-than-or-equal-to instead.

Fortunately, the Python ecosystem offers several alternative solutions for linear programming that are very useful for larger problems. One of them is PuLP, which you’ll see in action in the next section.

Remove ads

Using PuLP

PuLP has a more convenient linear programming API than SciPy. You don’t have to mathematically modify your problem or use vectors and matrices. Everything is cleaner and less prone to errors.

As usual, you start by importing what you need:

$ pulptest
4

Now that you have PuLP imported, you can solve your problems.

Example 1

You’ll now solve this system with PuLP:

Cara menggunakan vector optimization python

The first step is to initialize an instance of to represent your model:

$ pulptest
5

You use the

>>> bnd = [(0, float("inf")),  # Bounds of x
...        (0, float("inf"))]  # Bounds of y
9 parameter to choose whether to perform minimization ( or
$ pulptest
01, which is the default) or maximization ( or
$ pulptest
03). This choice will affect the result of your problem.

Once that you have the model, you can define the decision variables as instances of the class:

$ pulptest
6

You need to provide a lower bound with

$ pulptest
05 because the default value is negative infinity. The parameter
$ pulptest
06 defines the upper bound, but you can omit it here because it defaults to positive infinity.

The optional parameter

$ pulptest
07 defines the category of a decision variable. If you’re working with continuous variables, then you can use the default value
$ pulptest
08.

You can use the variables

$ pulptest
09 and
$ pulptest
10 to create other PuLP objects that represent linear expressions and constraints:

>>>

$ pulptest
7

When you multiply a decision variable with a scalar or build a linear combination of multiple decision variables, you get an instance of that represents a linear expression.

Note: You can add or subtract variables or expressions, and you can multiply them with constants because PuLP classes implement some of the that like , , and . These methods are used to customize the behavior of operators like

$ pulptest
15,
$ pulptest
16, and
$ pulptest
17.

Similarly, you can combine linear expressions, variables, and scalars with the operators

$ pulptest
18,
$ pulptest
19, or
$ pulptest
20 to get instances of that represent the linear constraints of your model.

Note: It’s also possible to build constraints with the rich comparison methods , , and that define the behavior of the operators

$ pulptest
18,
$ pulptest
19, and
$ pulptest
20.

Having this in mind, the next step is to create the constraints and objective function as well as to assign them to your model. You don’t need to create lists or matrices. Just write Python expressions and use the

$ pulptest
27 operator to append them to the model:

$ pulptest
8

In the above code, you define tuples that hold the constraints and their names.

>>> bnd = [(0, float("inf")),  # Bounds of x
...        (0, float("inf"))]  # Bounds of y
8 allows you to add constraints to a model by specifying them as tuples. The first element is a
$ pulptest
29 instance. The second element is a human-readable name for that constraint.

Setting the objective function is very similar:

$ pulptest
9

Alternatively, you can use a shorter notation:

$ brew install glpk
0

Now you have the objective function added and the model defined.

Note: You can append a constraint or objective to the model with the operator

$ pulptest
27 because its class,
>>> bnd = [(0, float("inf")),  # Bounds of x
...        (0, float("inf"))]  # Bounds of y
8, implements the special method , which is used to specify the behavior of
$ pulptest
27.

For larger problems, it’s often more convenient to use with a list or other sequence than to repeat the

$ pulptest
15 operator. For example, you could add the objective function to the model with this statement:

$ brew install glpk
1

It produces the same result as the previous statement.

You can now see the full definition of this model:

>>>

$ brew install glpk
2

The string representation of the model contains all relevant data: the variables, constraints, objective, and their names.

Note: String representations are built by defining the special method . For more details about

$ pulptest
36, check out Pythonic OOP String Conversion:
$ pulptest
38 vs
$ pulptest
39.

Finally, you’re ready to solve the problem. You can do that by calling on your model object. If you want to use the default solver (CBC), then you don’t need to pass any arguments:

$ brew install glpk
3

$ pulptest
40 calls the underlying solver, modifies the
$ pulptest
42 object, and returns the integer status of the solution, which will be
$ pulptest
01 if the optimum is found. For the rest of the status codes, see .

You can get the optimization results as the attributes of

$ pulptest
42. The function and the corresponding method
$ pulptest
47 return the actual values of the attributes:

>>>

$ brew install glpk
4

$ pulptest
48 holds the value of the objective function,
$ pulptest
49 contains the values of the slack variables, and the objects
$ pulptest
09 and
$ pulptest
10 have the optimal values of the decision variables.
$ pulptest
52 returns a list with the decision variables:

>>>

$ brew install glpk
5

As you can see, this list contains the exact objects that are created with the constructor of

$ pulptest
04.

The results are approximately the same as the ones you got with SciPy.

Note: Be careful with the method

$ pulptest
40—it changes the state of the objects
$ pulptest
09 and
$ pulptest
10!

You can see which solver was used by calling

$ pulptest
57:

>>>

$ brew install glpk
6

The output informs you that the solver is CBC. You didn’t specify a solver, so PuLP called the default one.

If you want to run a different solver, then you can specify it as an argument of

$ pulptest
40. For example, if you want to use GLPK and already have it installed, then you can use
$ pulptest
59 in the last line. Keep in mind that you’ll also need to import it:

$ brew install glpk
7

Now that you have GLPK imported, you can use it inside

$ pulptest
40:

$ brew install glpk
8

The

$ pulptest
61 parameter is used to display information from the solver.
$ pulptest
62 disables showing this information. If you want to include the information, then just omit
$ pulptest
61 or set
$ pulptest
64.

Your model is defined and solved, so you can inspect the results the same way you did in the previous case:

>>>

$ brew install glpk
9

You got practically the same result with GLPK as you did with SciPy and CBC.

Let’s peek and see which solver was used this time:

>>>

$ sudo apt install glpk glpk-utils
0

As you defined above with the highlighted statement

$ pulptest
65, the solver is GLPK.

You can also use PuLP to solve mixed-integer linear programming problems. To define an integer or binary variable, just pass

$ pulptest
66 or
$ pulptest
67 to
$ pulptest
04. Everything else remains the same:

$ sudo apt install glpk glpk-utils
1

In this example, you have one integer variable and get different results from before:

>>>

$ sudo apt install glpk glpk-utils
2

Now

$ pulptest
09 is an integer, as specified in the model. (Technically it holds a value with zero after the decimal point.) This fact changes the whole solution. Let’s show this on the graph:

Cara menggunakan vector optimization python

As you can see, the optimal solution is the rightmost green point on the gray background. This is the feasible solution with the largest values of both

$ pulptest
09 and
$ pulptest
10, giving it the maximal objective function value.

GLPK is capable of solving such problems as well.

Example 2

Now you can use PuLP to solve the resource allocation problem from above:

Cara menggunakan vector optimization python

The approach for defining and solving the problem is the same as in the previous example:

$ sudo apt install glpk glpk-utils
3

In this case, you use the dictionary

$ pulptest
09 to store all decision variables. This approach is convenient because dictionaries can store the names or indices of decision variables as keys and the corresponding
$ pulptest
04 objects as values. Lists or tuples of
$ pulptest
04 instances can be useful as well.

The code above produces the following result:

$ sudo apt install glpk glpk-utils
4

As you can see, the solution is consistent with the one obtained using SciPy. The most profitable solution is to produce

$ pulptest
75 units of the first product and
$ pulptest
76 units of the third product per day.

Let’s make this problem more complicated and interesting. Say the factory can’t produce the first and third products in parallel due to a machinery issue. What’s the most profitable solution in this case?

Now you have another logical constraint: if x₁ is positive, then x₃ must be zero and vice versa. This is where binary decision variables are very useful. You’ll use two binary decision variables, y₁ and y₃, that’ll denote if the first or third products are generated at all:

$ sudo apt install glpk glpk-utils
5

The code is very similar to the previous example except for the highlighted lines. Here are the differences:

  • Line 5 defines the binary decision variables

    $ pulptest
    
    77 and
    $ pulptest
    
    78 held in the dictionary
    $ pulptest
    
    10.

  • Line 12 defines an arbitrarily large number

    $ pulptest
    
    80. The value
    >>> bnd = [(0, float("inf")),  # Bounds of x
    ...        (0, float("inf"))]  # Bounds of y
    
    0 is large enough in this case because you can’t have more than
    >>> bnd = [(0, float("inf")),  # Bounds of x
    ...        (0, float("inf"))]  # Bounds of y
    
    0 units per day.

  • Line 13 says that if

    $ pulptest
    
    77 is zero, then
    $ pulptest
    
    84 must be zero, else it can be any non-negative number.

  • Line 14 says that if

    $ pulptest
    
    78 is zero, then
    $ pulptest
    
    86 must be zero, else it can be any non-negative number.

  • Line 15 says that either

    $ pulptest
    
    77 or
    $ pulptest
    
    78 is zero (or both are), so either
    $ pulptest
    
    84 or
    $ pulptest
    
    86 must be zero as well.

Here’s the solution:

$ sudo apt install glpk glpk-utils
6

It turns out that the optimal approach is to exclude the first product and to produce only the third one.

Remove ads

Linear Programming Resources

Linear programming and mixed-integer linear programming are very important topics. If you want to learn more about them—and there’s much more to learn than what you saw here—then you can find plenty of resources. Here are a few to get started with:

  • Wikipedia Linear Programming Article
  • Wikipedia Integer Programming Article
  • MIT Introduction to Mathematical Programming Course
  • Brilliant.org Linear Programming Article
  • CalcWorkshop What Is Linear Programming?
  • BYJU’S Linear Programming Article

Gurobi Optimization is a company that offers a very fast commercial solver with a Python API. It also provides valuable resources on linear programming and mixed-integer linear programming, including the following:

  • Linear Programming (LP) – A Primer on the Basics
  • Mixed-Integer Programming (MIP) – A Primer on the Basics
  • Tutorials
  • Choosing a Math Programming Solver

If you’re in the mood to learn optimization theory, then there’s plenty of math books out there. Here are a few popular choices:

  • Linear Programming: Foundations and Extensions
  • Convex Optimization
  • Model Building in Mathematical Programming
  • Engineering Optimization: Theory and Practice

This is just a part of what’s available. Linear programming and mixed-integer linear programming are popular and widely used techniques, so you can find countless resources to help deepen your understanding.

Linear Programming Solvers

Just like there are many resources to help you learn linear programming and mixed-integer linear programming, there’s also a wide range of solvers that have Python wrappers available. Here’s a partial list:

  • GLPK
  • LP Solve
  • CLP
  • CBC
  • CVXOPT
  • SciPy
  • SCIP with PySCIPOpt
  • Gurobi Optimizer
  • CPLEX
  • XPRESS
  • MOSEK

Some of these libraries, like Gurobi, include their own Python wrappers. Others use external wrappers. For example, you saw that you can access CBC and GLPK with PuLP.

Conclusion

You now know what linear programming is and how to use Python to solve linear programming problems. You also learned that Python linear programming libraries are just wrappers around native solvers. When the solver finishes its job, the wrapper returns the solution status, the decision variable values, the slack variables, the objective function, and so on.

In this tutorial, you learned how to:

  • Define a model that represents your problem
  • Create a Python program for optimization
  • Run the optimization program to find the solution to the problem
  • Retrieve the result of optimization

You used SciPy with its own solver as well as PuLP with CBC and GLPK, but you also learned that there are many other linear programming solvers and Python wrappers. You’re now ready to dive into the world of linear programming!

If you have any questions or comments, then please put them in the comments section below.

Mark as Completed

🐍 Python Tricks 💌

Get a short & sweet Python Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

Cara menggunakan vector optimization python

Send Me Python Tricks »

About Mirko Stojiljković

Cara menggunakan vector optimization python
Cara menggunakan vector optimization python

Mirko has a Ph.D. in Mechanical Engineering and works as a university professor. He is a Pythonista who applies hybrid optimization and machine learning methods to support decision making in the energy sector.

» More about Mirko


Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:

Cara menggunakan vector optimization python

Aldren

Cara menggunakan vector optimization python

Brad

Cara menggunakan vector optimization python

Geir Arne

Cara menggunakan vector optimization python

Joanna

Cara menggunakan vector optimization python

Jacob

Master Real-World Python Skills With Unlimited Access to Real Python

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

Master Real-World Python Skills
With Unlimited Access to Real Python

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

What Do You Think?

Rate this article:

Tweet Share Share Email

What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.

Commenting Tips: The most useful comments are those written with the goal of learning from or helping out other students. and get answers to common questions in our support portal.