transport | R Documentation |
Given two objects a
and b
that specify distributions of mass and an object that specifies (a way to compute) costs,
find the transport plan for going from a
to b
that minimizes the total cost.
transport(a, b, ...)
## Default S3 method:
transport(a, b, costm, method = c("networkflow", "shortsimplex", "revsimplex",
"primaldual"), fullreturn=FALSE, control = list(), threads=1, ...)
## S3 method for class 'pgrid'
transport(a, b, p = NULL, method = c("auto", "networkflow", "revsimplex", "shortsimplex",
"shielding", "aha", "primaldual"), fullreturn=FALSE,
control = list(), threads=1,...)
## S3 method for class 'pp'
transport(a, b, p = 1, method = c("auction", "auctionbf", "networkflow", "shortsimplex",
"revsimplex", "primaldual"), fullreturn=FALSE, control = list(), threads=1, ...)
## S3 method for class 'wpp'
transport(a, b, p = 1, method = c("networkflow", "revsimplex", "shortsimplex",
"primaldual"), fullreturn=FALSE, control = list(), threads=1, ...)
a , b |
two objects that describe mass distributions, between which the optimal transport map is to be computed. For the default
method these are vectors of non-negative values. For the other three methods these are objects of the respective classes.
It is also possible to have |
costm |
for the default method a |
p |
for the three specialized methods the power |
method |
the name of the algorithm to use. See details below. |
fullreturn |
A boolean specifying whether the output of the function should also include the dual solution, the optimal transport cost between a and b and the transport plan in matrix form should be returned as well. |
control |
a named list of parameters for the chosen method or the result of a call to |
threads |
An Integer specifying the number of threads used in parallel computing. Currently only available for the method "networkflow". |
... |
currently without effect. |
There is a number of algorithms that are currently implemented and more will be added in future versions of the package. The following is a brief description of each key word used. Much more details can be found in the cited references and in a forthcoming package vignette.
aha
: The Aurenhammer–Hoffmann–Aronov (1998) method with the multiscale approach presented in Mérigot (2011). The original theory was limited to p=2
. We refer by aha
also to the extension of the same idea for p=1
as presented in Hartmann and Schuhmacher (2017) and for more general p
(currently not implemented).
auction
: The auction algorithm by Bertsekas (1988) with epsilon-scaling, see Bertsekas (1992).
auctionbf
: A refined auction algorithm that combines forward and revers auction, see Bertsekas (1992).
networkflow
: The fast implementation of the network simplex algorithm by Nicolas Bonneel based on the LEMON Library (see citations below).
primaldual
: The primal-dual algorithm as described in Luenberger (2003, Section 5.9).
revsimplex
: The revised simplex algorithm as described in Luenberger and Ye (2008, Section 6.4) with various speed improvements, including a multiscale approach.
shielding
: The shielding (or shortcut) method, as described in Schmitzer (2016).
shortsimplex
: The shortlist method based an a revised simplex algorithm, as described in Gottschlich and Schuhmacher (2014).
The order of the default key words specified for the argument method
gives a rough idea of the relative efficiency of the algorithms for the corresponding class of objects. For a given a
and b
the actual computation times may deviate significantly from this order.
For class pgrid
the default method is "auto"
, which resolves to "revsimplex"
if p
is not 2 or the problem is very small, and to "shielding"
otherwise.
The following table gives information about the applicability of the various algorithms (or sometimes rather their current implementations).
default | pgrid | pp | wpp | |
aha (p=1 or 2!) | - | + | - | @ |
auction | - | - | + | - |
auctionbf | - | - | + | - |
networkflow | + | + | + | + |
primaldual | * | * | * | + |
revsimplex | + | + | * | + |
shielding (p=2!) | - | + | - | - |
shortsimplex | + | + | * | + |
where: + recommended, * applicable (may be slow), - no implementation planned or combination does not make sense; @ indicates that the aha algorithm is available in the special combination where a
is a pgrid
object and b
is a wpp
object (and p
is 2). For more details on this combination see the function semidiscrete
.
Each algorithm has certain parameters supplied by the control
argument. The following table gives an overview of parameter names and
their applicability.
start | multiscale | individual parameters | |
aha (p=2 !) | - | + | factr , maxit |
auction | - | - | lasteps , epsfac |
auctionbf | - | - | lasteps , epsfac |
networkflow | - | - | |
primaldual | - | - | |
revsimplex | + | + | |
shielding (p=2 !) | - | + | |
shortsimplex | - | - | slength , kfound , psearched |
start
specifies the algorithm for computing a starting solution (if needed). Currently the Modified Row Minimum Rule
(start="modrowmin"
), the North-West Corner Rule (start="nwcorner"
) and the method by Russell (1969) (start="russell"
)
are implemented. When start="auto"
(the default) the ModRowMin Rule is chosen. However,
for transport.pgrid
and p
larger than 1, there are two cases where an automatic multiscale procedure is also performed, i.e. the optimal transport is first computed on coarser grids and information from these solutions is then used for the finer girds.
This happens for
method = "revsimplex"
, where a single coarsening at factor scmult=2
is performed, and for method = "shielding"
, where a number of coarsenings adapted to the dimensions of the array is performed.
For p=1
and method="revsimplex"
, as well as p=2
and method="aha"
there are multiscale versions of
the corresponding algorithms that allows for finer control via the parameters
nscales
, scmult
and returncoarse
. The default value of nscales=1
suppresses
the multiscale version. For larger problems it is advisable to use the multiscale version, which currently is only implemented for
square pgrids in two dimensions. The algorithm proceeds then by coarsening the pgrid nscales-1
times, summarizing
each time scmult^2
pixels into one larger pixels, and then solving the various transport problems starting from the coarsest and
using each previous problem to compute a starting solution to the next finer problem. If returncoarse
is TRUE
, the coarser
problems and their solutions are returned as well (revsimplex
only).
factr
, maxit
are the corresponding components of the control
argument in the optim
L-BFGS-B method.
lasteps
, epsfac
are parameters used for epsilon scaling in the auction algortihm. The algorithm starts with a “transaction cost” per bid of epsfac^k * lasteps
for some reasonable k
generating finer and finer approximate solutions as the k
counts down to zero. Note that in order for the procedure to make sense, epsfac
should be larger than one (typically two- to three-digit) and in order for the final solution to be exact lasteps
should be smaller than 1/n
, where n
is the total number of points in either of the point patterns.
slength
, kfound
, psearched
are the shortlist length, the number of pivot candidates needed, and the percentage of
shortlists searched, respectively.
A data frame with columns from
, to
and mass
that specifies from which element of a
to which element of b
what amount of mass is sent in the optimal transport plan. For class pgrid
elements are specified as vector indices in terms of the usual column major enumeration of the matrices a$mass
and b$mass
. There are plot
methods for the classes pgrid
and pp
, which can plot this solution.
If returncoarse
is TRUE
for the revsimplex
method, a list with components sol
and prob
giving the solutions and problems on the various scales considered. The solution on the finest scale (i.e. the output we obtain when setting returncoarse
to FALSE
) is in sol[[1]]
.
If a
is of class pgrid
and b
of class wpp
(and p=2
), an object of class power_diagram
as described in the help for the function semidiscrete
. The plot
method for class pgrid
can plot this solution.
The combination of the shielding-method with the CPLEX numerical solver outperforms the other algorithms by an order of magnitude for large problems (only applicable for p=2
and objects of class "pgrid"
). If a local installation of CPLEX is available, the transport package can be linked against it during installation. See the file src/Makevars in the source package for instructions.
The combination of the aha-method with p=1
requires the use of CGAL (the Computational Geometry Algorithms Library) for dealing with Apollonius diagrams. If you require this functionality, install it from https://www.cgal.org/download.html and adapt the file src/Makevars of this package according to the instructions given in that file. Then re-install 'transport' from source as usual.
Dominic Schuhmacher schuhmacher@math.uni-goettingen.de
Björn Bähre bjobae@gmail.com (code for aha
-method for p=2
)
Nicolas Bonneel nicolas.bonneel@liris.cnrs.fr
(adaption of LEMON code for fast networkflow
method)
Carsten Gottschlich gottschlich@math.uni-goettingen.de
(original java code for shortlist
and revsimplex
methods)
Valentin Hartmann valentin.hartmann@epfl.ch (code for aha
method for p=1
)
Florian Heinemann florian.heinemann@uni-goettingen.de
(integration of networkflow
method)
Bernhard Schmitzer schmitzer@uni-muenster.de (code for shielding
-method)
F. Aurenhammer, F. Hoffmann and B. Aronov (1998). Minkowski-type theorems and least-squares clustering. Algorithmica 20(1), 61–76.
D. P. Bertsekas (1988). The auction algorithm: a distributed relaxation method for the assignment problem. Annals of Operations Research 14(1), 105–123.
D. P. Bertsekas (1992). Auction algorithms for network flow problems: a tutorial introduction. Computational Optimization and Applications 1, 7–66.
N. Bonneel (2018). Fast Network Simplex for Optimal Transport. Github repository, nbonneel/network_simplex.
N. Bonneel, M. van de Panne, S. Paris and W. Heidrich (2011). Displacement interpolation using Lagrangian mass transport. ACM Transactions on Graphics (SIGGRAPH ASIA 2011) 30(6).
Egervary Research Group on Combinatorial Optimization, EGRES (2014). LEMON Graph Library v1.3.1. lemon.cs.elte.hu/trac/lemon.
C. Gottschlich and D. Schuhmacher (2014). The shortlist method for fast computation of the earth mover's distance and finding optimal solutions to transportation problems. PLOS ONE 9(10), e110214. \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1371/journal.pone.0110214")}
V. Hartmann and D. Schuhmacher (2020). Semi-discrete optimal transport: a solution procedure for the unsquared Euclidean distance case, Mathematical Methods of Operations Research 92, 133–163. \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1007/s00186-020-00703-z")}
D.G. Luenberger (2003). Linear and nonlinear programming, 2nd ed. Kluwer.
D.G. Luenberger and Y. Ye (2008). Linear and nonlinear programming, 3rd ed. Springer.
Q. Mérigot (2011). A multiscale approach to optimal transport. Computer Graphics Forum 30(5), 1583–1592. \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1111/j.1467-8659.2011.02032.x")}
B. Schmitzer (2016). A sparse multiscale algorithm for dense optimal transport. J. Math. Imaging Vision 56(2), 238–259. https://arxiv.org/abs/1510.05466
plot
,
wasserstein
,
unbalanced
.
#
# example for the default method
#
a <- c(100, 200, 80, 150, 50, 140, 170, 30, 10, 70)
b <- c(60, 120, 150, 110, 40, 90, 160, 120, 70, 80)
set.seed(24)
costm <- matrix(sample(1:20, 100, replace=TRUE), 10, 10)
res <- transport(a,b,costm)
# pretty-print solution in matrix form for very small problems:
transp <- matrix(0,10,10)
transp[cbind(res$from,res$to)] <- res$mass
rownames(transp) <- paste(ifelse(nchar(a)==2," ",""),a,sep="")
colnames(transp) <- paste(ifelse(nchar(b)==2," ",""),b,sep="")
print(transp)
#
# example for class 'pgrid'
#
dev.new(width=9, height=4.5)
par(mfrow=c(1,2), mai=rep(0.1,4))
image(random32a$mass, col = grey(0:200/200), axes=FALSE)
image(random32b$mass, col = grey(0:200/200), axes=FALSE)
res <- transport(random32a,random32b)
dev.new()
par(mai=rep(0,4))
plot(random32a,random32b,res,lwd=1)
#
# example for class 'pp'
#
set.seed(27)
x <- pp(matrix(runif(400),200,2))
y <- pp(matrix(runif(400),200,2))
res <- transport(x,y)
dev.new()
par(mai=rep(0.02,4))
plot(x,y,res)
#
# example for class 'wpp'
#
set.seed(30)
m <- 30
n <- 60
massx <- rexp(m)
massx <- massx/sum(massx)
massy <- rexp(n)
massy <- massy/sum(massy)
x <- wpp(matrix(runif(2*m),m,2),massx)
y <- wpp(matrix(runif(2*n),n,2),massy)
res <- transport(x,y,method="revsimplex")
plot(x,y,res)
#
# example for semidiscrete transport between class
# 'pgrid' and class 'wpp' (p=2)
#
set.seed(33)
n <- 100
massb <- rexp(n)
massb <- massb/sum(massb)*1e5
b <- wpp(matrix(runif(2*n),n,2),massb)
res <- transport(random32a,b,p=2)
plot(random32a,b,res)
#
# example for semidiscrete transport between class
# 'pgrid' and class 'wpp' (p=1)
#
if (transport:::cgal_present()) {
set.seed(33)
n <- 30
massb <- rexp(n)
massb <- massb/sum(massb)*1e5
b <- wpp(matrix(runif(2*n),n,2),massb)
res <- transport(random32a,b,p=1)
plot(random32a,b,res)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.