我想最小化以下等式:
F=SUM{u 1:20}sum{w 1:10} Quw(ruw-yuw)
具有以下约束:
yuw >= yu,w+1
yuw >= yu-1,w
y20,0 >= 100
y0,10 >= 0
我有一个20 * 10 ruw和20 * 10 quw矩阵,我现在需要生成一个符合约束条件的yuw矩阵。我在R编码,熟悉lpsolve和optimx包,但不知道如何使用它们来解决这个问题。
答案 0 :(得分:3)
由于Quw
和ruw
都是数据,因此yuw
决策变量中的所有约束和目标都是线性的。因此,这是一个线性编程问题,lpSolve
包可以解决这个问题。
为了抽象出来,我们假设R=20
和C=10
描述了输入矩阵的维数。然后有R*C
个决策变量,我们可以为它们分配顺序y11, y21, ... yR1, y12, y22, ... yR2, ..., y1C, y2C, ..., yRC
,读取变量矩阵的列。
目标中每个yuw
变量的系数为-Quw
;请注意,求和中的Quw*ruw
项是常量(也不受我们为决策变量选择的值的影响),因此不会输入到线性编程求解器。有趣的是,这意味着ruw
实际上对优化模型解决方案没有影响。
第一个R*(C-1)
约束对应yuw >= yu,w+1
约束,下一个(R-1)*C
约束对应yuw >= yu-1,w
约束。最后两个约束对应于y20,1 >= 100
和y1,10 >= 0
约束。
我们可以使用以下R命令将此模型输入到lpsolve
包中,将每个条目为-1的简单Q矩阵作为输入(所得到的解决方案应将所有决策变量设置为0,除了底部左角,应该是100):
# Sample data
Quw <- matrix(-1, nrow=20, ncol=10)
R <- nrow(Quw)
C <- ncol(Quw)
# Build constraint matrix
part1 <- matrix(0, nrow=R*(C-1), ncol=R*C)
part1[cbind(1:(R*C-R), 1:(R*C-R))] <- 1
part1[cbind(1:(R*C-R), (R+1):(R*C))] <- -1
part2 <- matrix(0, nrow=(R-1)*C, ncol=R*C)
pos2 <- as.vector(sapply(2:R, function(r) r+seq(0, R*(C-1), by=R)))
part2[cbind(1:nrow(part2), pos2)] <- 1
part2[cbind(1:nrow(part2), pos2-1)] <- -1
part3 <- rep(0, R*C)
part3[R] <- 1
part4 <- rep(0, R*C)
part4[(C-1)*R + 1] <- 1
const.mat <- rbind(part1, part2, part3, part4)
library(lpSolve)
mod <- lp(direction = "min",
objective.in = as.vector(-Quw),
const.mat = const.mat,
const.dir = rep(">=", nrow(const.mat)),
const.rhs = c(rep(0, nrow(const.mat)-2), 100, 0))
我们现在可以访问模型解决方案:
mod
# Success: the objective function is 100
matrix(mod$solution, nrow=R)
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 0 0 0 0 0 0 0 0 0 0
# [2,] 0 0 0 0 0 0 0 0 0 0
# [3,] 0 0 0 0 0 0 0 0 0 0
# [4,] 0 0 0 0 0 0 0 0 0 0
# [5,] 0 0 0 0 0 0 0 0 0 0
# [6,] 0 0 0 0 0 0 0 0 0 0
# [7,] 0 0 0 0 0 0 0 0 0 0
# [8,] 0 0 0 0 0 0 0 0 0 0
# [9,] 0 0 0 0 0 0 0 0 0 0
# [10,] 0 0 0 0 0 0 0 0 0 0
# [11,] 0 0 0 0 0 0 0 0 0 0
# [12,] 0 0 0 0 0 0 0 0 0 0
# [13,] 0 0 0 0 0 0 0 0 0 0
# [14,] 0 0 0 0 0 0 0 0 0 0
# [15,] 0 0 0 0 0 0 0 0 0 0
# [16,] 0 0 0 0 0 0 0 0 0 0
# [17,] 0 0 0 0 0 0 0 0 0 0
# [18,] 0 0 0 0 0 0 0 0 0 0
# [19,] 0 0 0 0 0 0 0 0 0 0
# [20,] 100 0 0 0 0 0 0 0 0 0
请注意,如果更改Quw
,您的模型很容易变得不可行(例如,如果我们用1填充而不是-1)。在这些情况下,模型将退出状态3(您可以通过运行mod
或mod$status
来查看此内容。