使用线性编程的图表最长路径

时间:2015-10-08 21:37:50

标签: optimization graph linear-programming lpsolve longest-path

我有一个加权有向图,其中没有周期,我希望定义约束,以便我可以用线性编程来解决路径权重的最大化。但是,我无法理解如何做到这一点。

为此,我希望使用LPSolve工具。我想过制作一个邻接矩阵,但我不知道如何用LPSolve来完成它。

如何使用约束定义每个节点的可能路径,并使其足够通用,以便适应其他图形?

1 个答案:

答案 0 :(得分:1)

由于您有加权有向图,因此为每个边x_e定义二进制变量e并添加指定源节点具有流量平衡1的约束就足够了(还有一个选择的输出边缘比输入边缘更多,目标节点的流量平衡为-1(输入边缘比选择的输出边缘多一个),并且每个其他节点的流量平衡为0(选择了相同数量的输出和输入边缘) 。由于您的图形没有循环,这将导致从源到目标的路径(假设存在一个)。您可以最大化所选边的权重。

我将继续使用lpSolve包在R中进行展示。考虑具有以下边缘的图表:

(edges <- data.frame(source=c(1, 1, 2, 3), dest=c(2, 3, 4, 4), weight=c(2, 7, 3, -4)))
#   source dest weight
# 1      1    2      2
# 2      1    3      7
# 3      2    4      3
# 4      3    4     -4

从1到4的最短路径为1 -> 2 -> 4,权重为5(1 -> 3 -> 4的权重为3)。

我们需要四个节点中每个节点的流量平衡约束:

source <- 1
dest <- 4
(nodes <- unique(c(edges$source, edges$dest)))
# [1] 1 2 3 4
(constr <- t(sapply(nodes, function(n) (edges$source == n) - (edges$dest == n))))
#      [,1] [,2] [,3] [,4]
# [1,]    1    1    0    0
# [2,]   -1    0    1    0
# [3,]    0   -1    0    1
# [4,]    0    0   -1   -1
(rhs <- ifelse(nodes == source, 1, ifelse(nodes == dest, -1, 0)))
# [1]  1  0  0 -1

现在我们可以将所有内容放在我们的模型中并解决:

library(lpSolve)
mod <- lp(direction = "max", 
          objective.in = edges$weight,
          const.mat = constr,
          const.dir = rep("=", length(nodes)),
          const.rhs = rhs,
          all.bin = TRUE)
edges[mod$solution > 0.999,]
#   source dest weight
# 1      1    2      2
# 3      2    4      3
mod$objval
# [1] 5