I am trying to implement a "Minimum Cost Network Flow" transportation problem solution in R
.
I understand that this could be implemented from scratch using something like lpSolve
. However, I see that there is a convenient igraph
implementation for "Maximum Flow". Such a pre-existing solution would be a lot more convenient, but I can't find an equivalent function for Minimum Cost.
Is there an igraph
function that calculates Minimum Cost Network Flow solutions, or is there a way to apply the igraph::max_flow
function to a Minimum Cost problem?
igraph
network example:
library(tidyverse)
library(igraph)
edgelist <- data.frame(
from = c(1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8),
to = c(2, 3, 4, 5, 6, 4, 5, 6, 7, 8, 7, 8, 7, 8, 9, 9),
capacity = c(20, 30, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99),
cost = c(0, 0, 1, 2, 3, 4, 3, 2, 3, 2, 3, 4, 5, 6, 0, 0))
g <- graph_from_edgelist(as.matrix(edgelist[,c('from','to')]))
E(g)$capacity <- edgelist$capacity
E(g)$cost <- edgelist$cost
plot(g, edge.label = E(g)$capacity)
plot(g, edge.label = E(g)$cost)
This is a network with directional edges, a "source node" (1), and a "sink node" (9). Each edge has a "capacity" (here often put as 99 for unlimited) and a "cost" (the cost of one unit flowing through this edge). I want to find the integer vector of flows (x, length = 9) that minimises the cost while transmitting a pre-defined flow through the network (let's say 50 units, from node 1 into node 9).
Disclaimer: this post asked a similar question, but did not result in a satisfying answer and is rather dated (2012).
In case of interest, here is how I ended up solving this problem. I used an edge dataframe with
to
nodes,from
nodes,cost
property andcapacity
property for each edge to create a constraint matrix. Subsequently, I fed this into a linear optimisation using thelpSolve
package. Step-by-step below.Start with the edgelist dataframe from my example above
Looks like this:
Create constraints matrix
Should result in something like this
Feed constraints to
lpSolve
for the ideal solutionNow we can convert our edges to a graph object and plot the solution
Hope it's interesting / useful :)
I was looking for a function but didn't success. The original function calls another:
res <- .Call("R_igraph_maxflow", graph, source - 1, target - 1, capacity, PACKAGE = "igraph")
And I don't know how to deal with it.
For the moment I inverted the cost path values in order to use the same function in oposite direction:
I draw in paper the graph and my code agree with manual solution This method should be tested with real know values, as I mentioned in the comment