GitHub

@@ -4,9 +4,9 @@ jupytext:

44

extension: .md

55

format_name: myst

66

format_version: 0.13

7-

jupytext_version: 1.10.3

7+

jupytext_version: 1.14.4

88

kernelspec:

9-

display_name: Python 3

9+

display_name: Python 3 (ipykernel)

1010

language: python

1111

name: python3

1212

---

@@ -38,13 +38,11 @@ several implementations of linear programming, including, in order,

3838

2. the [linprog_simplex](https://quanteconpy.readthedocs.io/en/latest/optimize/linprog_simplex.html) solver from QuantEcon and

3939

3. the simplex-based solvers included in the [Python Optimal Transport](https://pythonot.github.io/) package.

404041-42-43-4441

```{code-cell} ipython3

4542

:tags: [hide-output]

43+4644

!pip install --upgrade quantecon

47-

!pip install --upgrade POT jax jaxlib

45+

!pip install --upgrade POT

4846

```

49475048

Let's start with some imports.

@@ -59,11 +57,6 @@ from scipy.stats import binom, betabinom

5957

import networkx as nx

6058

```

615962-63-64-65-66-6760

## The Optimal Transport Problem

68616962

Suppose that $m$ factories produce goods that must be sent to $n$ locations.

@@ -356,7 +349,7 @@ A = np.vstack([A1, A2])

356349

b = np.hstack([p, q])

357350358351

# Solve the primal problem

359-

res = linprog(C_vec, A_eq=A, b_eq=b, method='Revised simplex')

352+

res = linprog(C_vec, A_eq=A, b_eq=b)

360353361354

# Print results

362355

print("message:", res.message)

@@ -405,15 +398,15 @@ However, we find a different transportation plan.

405398

Though it is a different plan, it attains the same cost!

406399407400

```{code-cell} ipython3

408-

linprog(C_vec, A_eq=A[:-1], b_eq=b[:-1], method='Revised simplex')

401+

linprog(C_vec, A_eq=A[:-1], b_eq=b[:-1])

409402

```

410403411404

```{code-cell} ipython3

412-

%time linprog(C_vec, A_eq=A[:-1], b_eq=b[:-1], method='Revised simplex')

405+

%time linprog(C_vec, A_eq=A[:-1], b_eq=b[:-1])

413406

```

414407415408

```{code-cell} ipython3

416-

%time linprog(C_vec, A_eq=A, b_eq=b, method='Revised simplex')

409+

%time linprog(C_vec, A_eq=A, b_eq=b)

417410

```

418411419412

Evidently, it is slightly quicker to work with the system that removed a redundant constraint.

@@ -438,7 +431,7 @@ cost = []

438431

for i in range(1000):

439432440433

np.random.shuffle(arr)

441-

res_shuffle = linprog(C_vec, A_eq=A[arr], b_eq=b[arr], method='Revised simplex')

434+

res_shuffle = linprog(C_vec, A_eq=A[arr], b_eq=b[arr])

442435443436

# if find a new solution

444437

sol = tuple(res_shuffle.x)

@@ -460,7 +453,7 @@ These are the same two plans computed earlier.

460453

Next, we show that leaving out the first constraint "accidentally" leads to the initial plan that we computed.

461454462455

```{code-cell} ipython3

463-

linprog(C_vec, A_eq=A[1:], b_eq=b[1:], method='Revised simplex')

456+

linprog(C_vec, A_eq=A[1:], b_eq=b[1:])

464457

```

465458466459

Let's compare this transport plan with

@@ -480,7 +473,7 @@ The minimized cost from the optimal transport plan is given by the $fun$ variabl

480473

### Using a Just-in-Time Compiler

481474482475

We can also solve optimal transportation problems using a powerful tool from

483-

QuantEcon, namely,`quantecon.optimize.linprog_simplex`.

476+

QuantEcon, namely, `quantecon.optimize.linprog_simplex`.

484477485478

While this routine uses the same simplex algorithm as

486479

`scipy.optimize.linprog`, the code is accelerated by using a just-in-time

@@ -523,7 +516,7 @@ Let's do a speed comparison between `scipy.optimize.linprog` and `quantecon.opti

523516524517

```{code-cell} ipython3

525518

# scipy.optimize.linprog

526-

%time res = linprog(C_vec, A_eq=A[:-1, :], b_eq=b[:-1], method='Revised simplex')

519+

%time res = linprog(C_vec, A_eq=A[:-1, :], b_eq=b[:-1])

527520

```

528521529522

```{code-cell} ipython3

@@ -581,7 +574,7 @@ For the same numerical example described above, let's solve the dual problem.

581574

```{code-cell} ipython3

582575

# Solve the dual problem

583576

res_dual = linprog(-b, A_ub=A.T, b_ub=C_vec,

584-

bounds=[(None, None)]*(m+n), method='Revised simplex')

577+

bounds=[(None, None)]*(m+n))

585578586579

#Print results

587580

print("message:", res_dual.message)

@@ -610,7 +603,7 @@ res_dual.x

610603

We can compare computational times from using our two tools.

611604612605

```{code-cell} ipython3

613-

%time linprog(-b, A_ub=A.T, b_ub=C_vec, bounds=[(None, None)]*(m+n), method='Revised simplex')

606+

%time linprog(-b, A_ub=A.T, b_ub=C_vec, bounds=[(None, None)]*(m+n))

614607

```

615608616609

```{code-cell} ipython3

@@ -625,14 +618,14 @@ Try first leaving out the first constraint:

625618626619

```{code-cell} ipython3

627620

linprog(-b[1:], A_ub=A[1:].T, b_ub=C_vec,

628-

bounds=[(None, None)]*(m+n-1), method='Revised simplex')

621+

bounds=[(None, None)]*(m+n-1))

629622

```

630623631624

Not let's instead leave out the last constraint:

632625633626

```{code-cell} ipython3

634627

linprog(-b[:-1], A_ub=A[:-1].T, b_ub=C_vec,

635-

bounds=[(None, None)]*(m+n-1), method='Revised simplex')

628+

bounds=[(None, None)]*(m+n-1))

636629

```

637630638631

### Interpretation of dual problem

@@ -687,7 +680,6 @@ X

687680688681

Sure enough, we have the same solution and the same cost

689682690-691683

```{code-cell} ipython3

692684

total_cost = np.sum(X * C)

693685

total_cost

@@ -725,8 +717,6 @@ It allocates to the nodes it creates their location, mass, and group.

725717726718

Locations are assigned randomly.

727719728-729-730720

```{code-cell} ipython3

731721

def build_nodes_of_one_type(group='p', n=100, seed=123):

732722

@@ -753,7 +743,6 @@ def build_nodes_of_one_type(group='p', n=100, seed=123):

753743

Now we build two lists of nodes, each one containing one type (factories or

754744

locations)

755745756-757746

```{code-cell} ipython3

758747

n_p = 32

759748

n_q = 32

@@ -836,8 +825,8 @@ nx.draw_networkx_edges(g,

836825

connectionstyle='arc3,rad=0.1',

837826

alpha=0.6)

838827

plt.show()

839-840828

```

841829830+

```{code-cell} ipython3

842831843-832+

```

Read the original on github.com ↗