R中的网络流量平衡约束

时间:2018-12-11 08:24:22

标签: r linear-programming

在R中的最小成本流问题上,我有点迷茫。在我看来,以下限制是“经典”的(输入总和减去输出总和等于需求-供应向量),不应为很难找到-用稀疏符号表示(我想避免像这里的过渡矩阵:Minimum Cost Flow - network optimization in R)。我的问题是,如何在R中实现这种流量平衡限制,或者有一个我忽略的编码示例?

enter image description here

1 个答案:

答案 0 :(得分:2)

这是使用igraph和Rsymphony以及稀疏矩阵(slam软件包)的最低成本流的示例:

给出此输入:

library(igraph)
nodes <- data.frame(name=paste0("N",1:8),
                    supply=c(10,20,0,-5,0,0,-15,-10))

edges <- data.frame(nodefrom = paste0("N",c( 1, 2, 2, 2, 3, 3, 4, 5, 5, 6, 7)),
                    nodeto   = paste0("N",c( 4, 1, 3, 6, 4, 5, 7, 6, 7, 8, 8)),
                    cost     = c( 2, 1, 0, 6, 1, 4, 5, 2, 7, 8, 9),
                    capacity = c(15,10,10,10, 5,10,10,20,15,10,15),
                    name     = paste0("E",1:11))
G <- graph.data.frame(edges)
V(G)$supply <- nodes$supply[match(V(G)$name,nodes$name)]
# plot the graph
set.seed(3)
par(mar=c(0,0,0,0))
plot(G, vertex.size=30,
     vertex.label=paste0(V(G)$name,' (',V(G)$supply,')'),
     vertex.color='lightblue', edge.arrow.size=0.5,
     edge.label=paste0(E(G)$name,' (',E(G)$cost,',',E(G)$capacity,')')
     )

Input Graph

library(Rsymphony)
library(slam)

nVars <- ecount(G)
obj <- E(G)$cost
bounds <- list(upper=list(1:nVars,E(G)$capacity),lower=list(1:nVars,rep(0,nVars)))
types <- rep('C',ecount(G))

mat <- simple_triplet_zero_matrix(nrow=nrow(nodes),ncol=nrow(edges))
colnames(mat) <- E(G)$name
rownames(mat) <- V(G)$name
rhs <- -V(G)$supply
dir <- rep('==',vcount(G))
for(v in V(G)){
  outEdges <- E(G)[from(v)]$name
  inEdges <- E(G)[to(v)]$name
  mat[v,match(inEdges,colnames(mat))] <- 1
  mat[v,match(outEdges,colnames(mat))] <- -1
}

output <- Rsymphony_solve_LP(obj=obj,
                   mat=mat,
                   dir=dir,
                   rhs=rhs,
                   bounds=bounds,
                   types=types,
                   max=FALSE,
                   write_lp = TRUE)

# plot the solution
set.seed(3)
par(mar=c(0,0,0,0))
plot(G, vertex.size=30,
     vertex.label=paste0(V(G)$name,' (',V(G)$supply,')'),
     vertex.color='lightblue', edge.arrow.size=0.5,
     edge.label=paste0(E(G)$name,' flow = ',output$solution))

Output Graph

关于稀疏矩阵,在这里我们使用simple_triplet_zero_matrix创建一个全零的矩阵(并且基本上不占用内存,因为在稀疏矩阵中仅存储非零),其大小为nrow x ncol,然后替换一些具有非零系数的索引。

可能在输入大量信息的情况下,这可能并不是很有效。
使用函数simple_triplet_matrix(i,j,v)可能更有效,其中i,j,v是3个长度相同的向量,表示非零系数;特别是i是行索引,j是列索引,v是位置i,j处的非零系数。