Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOC: add a tutorial of scipy.optimize.linprog #11847

Merged
merged 40 commits into from Apr 20, 2020
Merged
Changes from 3 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
b5bc96b
Doc: add a tutorial of scipy.optimize.linprog
AtsushiSakai Apr 11, 2020
d08e002
improve example based on review.
AtsushiSakai Apr 12, 2020
351c5e1
Merge branch 'master' of github.com:scipy/scipy into issue_10358_1
AtsushiSakai Apr 14, 2020
911c8e0
fixed minor issues based on review.
AtsushiSakai Apr 14, 2020
0b7c315
fixed issues based on review.
AtsushiSakai Apr 14, 2020
7fa2581
fixed minor issues.
AtsushiSakai Apr 14, 2020
4744b2d
[WIP] fix issues based on review.
AtsushiSakai Apr 15, 2020
44a767d
[WIP] fix issues based on review.
AtsushiSakai Apr 15, 2020
1e13abb
fix issues based on review.
AtsushiSakai Apr 16, 2020
ae2b01d
fix issues based on review.
AtsushiSakai Apr 16, 2020
485efeb
fix issues based on review.
AtsushiSakai Apr 16, 2020
e74e31e
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 17, 2020
70597f6
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 17, 2020
a4f7654
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 17, 2020
5a21369
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 17, 2020
2edff81
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 17, 2020
d80d99d
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 17, 2020
f005dc2
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 17, 2020
46380d0
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 17, 2020
a384480
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 17, 2020
2e55169
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 17, 2020
237523a
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 17, 2020
740ecf9
[WIP] fix tutorial based on review.
AtsushiSakai Apr 17, 2020
697e970
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 17, 2020
c8ac02a
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 17, 2020
efa7b68
[WIP] fix tutorial based on review.
AtsushiSakai Apr 17, 2020
efe89c7
Merge branch 'issue_10358_1' of https://github.com/AtsushiSakai/scipy…
AtsushiSakai Apr 17, 2020
388e1df
[WIP] fix tutorial based on review.
AtsushiSakai Apr 17, 2020
dca299b
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 18, 2020
ae0c6bb
update docstring base on review.
AtsushiSakai Apr 18, 2020
a7ba283
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 19, 2020
28a252f
fix constraint output.
AtsushiSakai Apr 19, 2020
4dc20ff
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 19, 2020
6303c52
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 19, 2020
b2244b7
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 19, 2020
40e89c9
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 19, 2020
b77a274
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 19, 2020
c531c1c
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 19, 2020
849ba17
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 19, 2020
4886777
Update doc/source/tutorial/optimize.rst
AtsushiSakai Apr 19, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
98 changes: 49 additions & 49 deletions doc/source/tutorial/optimize.rst
Expand Up @@ -1355,7 +1355,7 @@ Linear programming (:func:`linprog`)

The function :func:`linprog` can minimize a linear objective function
subject to linear equality and inequality constraints. This kind of
problem is well known as Linear programming. Linear programming solves
problem is well known as linear programming. Linear programming solves
problems of the following form:

.. math::
Expand All @@ -1369,8 +1369,8 @@ where :math:`x` is a vector of decision variables; :math:`c`, :math:`b_{ub}`,
:math:`b_{eq}`, :math:`l`, and :math:`u` are vectors; and :math:`A_{ub}` and
:math:`A_{eq}` are matrices.

In this tutorial, we will try to solve some typical linear programming
problems using :func:`linprog`.
In this tutorial, we will try to solve a typical linear programming
problem using :func:`linprog`.

Linear programming example
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -1384,16 +1384,19 @@ Consider the following simple linear programming problem:
& 2x_1 -3x_2 -7x_3 + 3x_4 \geq 10\\
& 2x_1 + 8x_2 + x_3 = 60\\
& 4x_1 + 4x_2 + x_4 = 60\\
& x_i \geq 0 ,
& 0 \leq x_0\\
& 0 \leq x_1 \leq 5\\
& x_2 \leq 0.5\\
& -3 \leq x_3 \leq 0\\

We need some mathematical deformations to convert the target problem to the form of :func:`linprog`.
We need some mathematical manipulations to convert the target problem to the form accepted by :func:`linprog`.

First of all, let's consider the objective function. The problem has 4 decision variables :math:`x_1, x_2, x_3, x_4`.
AtsushiSakai marked this conversation as resolved.
Show resolved Hide resolved
We define a vector of decision variables :math:`x = [x_1, x_2, x_3, x_4]`. The problem want to maximize the objective
function, but :func:`linprog` can accept a minimization problem. This is easily remedied by converting the maximize
We define a vector of decision variables :math:`x = [x_1, x_2, x_3, x_4]`. We want to maximize the objective
function, but :func:`linprog` can only accept a minimization problem. This is easily remedied by converting the maximize
:math:`29x_1 + 45x_2` to minimizing :math:`-29x_1 -45x_2`. Also, :math:`x_3, x_4` are not shown in the objective
function. That means the weights elements of the objective function for :math:`x_3, x_4` are zeros. So, the objective
function can be converted to:
function. That means the weights corresponding with :math:`x_3, x_4` are zero. So, the objective function can be
converted to:

.. math::
\min_{x_1, x_2, x_3, x_4} \ -29x_1 -45x_2 + 0x_3 + 0x_4
Expand All @@ -1405,13 +1408,15 @@ should be
c = [-29, -45, 0, 0]

Next, let's consider the two inequality constraints. These can be converted by using the "greater than" inequality
constraint to a "less than" inequality constraint by multiplying both sides by a factor of :math:`-1`:
constraint to a "less than" inequality constraint by multiplying both sides by a factor of :math:`-1`. The first
one is the "less than" inequality constraint, however second one is the "greater than" inequality constraint. So, only
second one should be converted to align inequality sign direction:
AtsushiSakai marked this conversation as resolved.
Show resolved Hide resolved

.. math::
x_1 -x_2 -3x_3 + 0x_4 &\leq 5\\
-2x_1 + 3x_2 + 7x_3 - 3x_4 &\leq -10\\

These equations can be converted as matrix form:
These equations can be converted to matrix form:

.. math::
A_{ub} x \leq b_{ub}\\
Expand All @@ -1436,13 +1441,13 @@ where
\end{bmatrix}
\end{equation*}

Next, let's consider the two equality constraints. These can be converted like:
Next, let's consider the two equality constraints. Showing zero weights explicitly, these are:

.. math::
2x_1 + 8x_2 + 1x_3 + 0x_4 &= 60\\
4x_1 + 4x_2 + 0x_3 + 1x_4 &= 60\\

These equations can be converted as matrix form:
These equations can be converted to matrix form:

.. math::
A_{eq} x = b_{eq}\\
Expand All @@ -1467,52 +1472,47 @@ where
\end{bmatrix}
\end{equation*}

The last inequality constraint :math:`x_i \geq 0` is minimum value constraint for all decision variables, which can be
applied as the ``bounds`` argument of :func:`linprog`. As you can see the API doc :func:`linprog`, the default values of
``bound`` argument is ``(0, None)`` that means all decision variables are non-negative. So, we don't need to do anything
the last inequality constraint in this case.
Lastly, let's consider the minimum and maximum inequality constraints for each decision variable, which is known as
"box constraint". These constraints can be applied as the ``bounds`` argument of :func:`linprog`.
As you can see the API doc :func:`linprog`, the default values of ``bounds`` argument is ``(0, None)`` that means
all decision variables are non-negative. Using None indicates that there is no bound. So, we need to set each bound
as ``bounds`` argument in this case.
AtsushiSakai marked this conversation as resolved.
Show resolved Hide resolved

Finally, we can solve the desired problem using the mathematical converts and :func:`linprog`.
Finally, we can solve the transformed problem using :func:`linprog`.

::

from scipy.optimize import linprog
import numpy as np

c = np.array([-29.0, -45.0, 0.0, 0.0])
A_ub = np.array([[1.0, -1.0, -3.0, 0.0],
[-2.0, 3.0, 7.0, -3.0]])
b_ub = np.array([[5.0],
[-10.0]])
A_eq = np.array([[2.0, 8.0, 1.0, 0.0],
[4.0, 4.0, 0.0, 1.0]])
b_eq = np.array([[60.0],
[60.0]])

result = linprog(c, A_ub=A_ub, b_ub=b_ub, A_eq=A_eq, b_eq=b_eq)
>>> from scipy.optimize import linprog
>>> import numpy as np
>>> c = np.array([-29.0, -45.0, 0.0, 0.0])
>>> A_ub = np.array([[1.0, -1.0, -3.0, 0.0],
... [-2.0, 3.0, 7.0, -3.0]])
AtsushiSakai marked this conversation as resolved.
Show resolved Hide resolved
>>> b_ub = np.array([[5.0],
AtsushiSakai marked this conversation as resolved.
Show resolved Hide resolved
... [-10.0]])
>>> A_eq = np.array([[2.0, 8.0, 1.0, 0.0],
... [4.0, 4.0, 0.0, 1.0]])
>>> b_eq = np.array([[60.0],
... [60.0]])
>>> x0_bounds = (0, None)
>>> x1_bounds = (0, 5.0)
>>> x2_bounds = (None, 0.5)
AtsushiSakai marked this conversation as resolved.
Show resolved Hide resolved
>>> x3_bounds = (-3.0, 0)
>>> bounds = [x0_bounds, x1_bounds, x2_bounds, x3_bounds]
>>> result = linprog(c, A_ub=A_ub, b_ub=b_ub, A_eq=A_eq, b_eq=b_eq, bounds=bounds)

The result is

::

>>> print(result)
con: array([3.07489501e-09, 3.19440119e-09])
fun: -500.79999997382595
message: 'Optimization terminated successfully.'
nit: 5
slack: array([ 1.0000000e+00, -1.0003518e-09])
status: 0
success: True
x: array([9.2000000e+00, 5.2000000e+00, 4.3425461e-11, 2.4000000e+00])

::

>>> [print("x_", i, ":", np.round(result.x[i], 2)) for i in range(len(result.x))]
x_ 0 : 9.2
x_ 1 : 5.2
x_ 2 : 0.0
x_ 3 : 2.4

con: array([42.58855175, 45.54023356])
AtsushiSakai marked this conversation as resolved.
Show resolved Hide resolved
fun: -143.26958745795812
AtsushiSakai marked this conversation as resolved.
Show resolved Hide resolved
message: 'The algorithm terminated successfully and determined that the problem is infeasible.'
nit: 4
slack: array([ 2.89860769, -12.11677835])
AtsushiSakai marked this conversation as resolved.
Show resolved Hide resolved
status: 2
success: False
x: array([ 2.41503507, 1.62741268, -0.43792331, -1.71002454])
AtsushiSakai marked this conversation as resolved.
Show resolved Hide resolved


AtsushiSakai marked this conversation as resolved.
Show resolved Hide resolved
.. rubric:: References
Expand Down