@@ -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
88kernelspec :
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,
38382 . the [ linprog_simplex] ( https://quanteconpy.readthedocs.io/en/latest/optimize/linprog_simplex.html ) solver from QuantEcon and
39393 . the simplex-based solvers included in the [ Python Optimal Transport] ( https://pythonot.github.io/ ) package.
4040
41-
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```
4947
5048Let's start with some imports.
@@ -59,11 +57,6 @@ from scipy.stats import binom, betabinom
5957import networkx as nx
6058```
6159
62-
63-
64-
65-
66-
6760## The Optimal Transport Problem
6861
6962Suppose that $m$ factories produce goods that must be sent to $n$ locations.
@@ -356,7 +349,7 @@ A = np.vstack([A1, A2])
356349b = np.hstack([p, q])
357350
358351# 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)
360353
361354# Print results
362355print("message:", res.message)
@@ -405,15 +398,15 @@ However, we find a different transportation plan.
405398Though it is a different plan, it attains the same cost!
406399
407400```{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```
410403
411404```{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```
414407
415408```{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```
418411
419412Evidently, it is slightly quicker to work with the system that removed a redundant constraint.
@@ -438,7 +431,7 @@ cost = []
438431for i in range(1000):
439432
440433 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])
442435
443436 # if find a new solution
444437 sol = tuple(res_shuffle.x)
@@ -460,7 +453,7 @@ These are the same two plans computed earlier.
460453Next, we show that leaving out the first constraint "accidentally" leads to the initial plan that we computed.
461454
462455```{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```
465458
466459Let'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
481474
482475We 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`.
484477
485478While 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
523516
524517```{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```
528521
529522```{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
583576res_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))
585578
586579#Print results
587580print("message:", res_dual.message)
@@ -610,7 +603,7 @@ res_dual.x
610603We can compare computational times from using our two tools.
611604
612605```{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```
615608
616609```{code-cell} ipython3
@@ -625,14 +618,14 @@ Try first leaving out the first constraint:
625618
626619```{code-cell} ipython3
627620linprog(-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```
630623
631624Not let's instead leave out the last constraint:
632625
633626```{code-cell} ipython3
634627linprog(-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```
637630
638631### Interpretation of dual problem
687680
688681Sure enough, we have the same solution and the same cost
689682
690-
691683```{code-cell} ipython3
692684total_cost = np.sum(X * C)
693685total_cost
@@ -725,8 +717,6 @@ It allocates to the nodes it creates their location, mass, and group.
725717
726718Locations are assigned randomly.
727719
728-
729-
730720```{code-cell} ipython3
731721def 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):
753743Now we build two lists of nodes, each one containing one type (factories or
754744 locations)
755745
756-
757746```{code-cell} ipython3
758747n_p = 32
759748n_q = 32
@@ -836,8 +825,8 @@ nx.draw_networkx_edges(g,
836825 connectionstyle='arc3,rad=0.1',
837826 alpha=0.6)
838827plt.show()
839-
840828```
841829
830+ ```{code-cell} ipython3
842831
843-
832+ ```
0 commit comments