Excel 如何建立矩阵相乘的简单优化模型?

Excel 如何建立矩阵相乘的简单优化模型?,excel,r,optimization,model,Excel,R,Optimization,Model,我已经使用标准解算器在Excel中创建了一个优化模型,现在想在R中创建一个类似的模型,因为这将允许我创建像这样的更大模型。不幸的是,我很难找到好的例子来为我的概念建模。因此,我想问你们是否有人能给我一些关于如何在R中制作类似模型的提示 我已将我的Excel工作表上载到 其基本思想是,通过将E10:L19范围内的最多8个单元更改为1,使单元B3最大化。B3单元包括E10:L19范围内的sumproduct()和许多类似范围 我期待着看到一些关于如何在R中构建类似模型的提示 谢谢! 乔切姆 ====

我已经使用标准解算器在Excel中创建了一个优化模型,现在想在R中创建一个类似的模型,因为这将允许我创建像这样的更大模型。不幸的是,我很难找到好的例子来为我的概念建模。因此,我想问你们是否有人能给我一些关于如何在R中制作类似模型的提示

我已将我的Excel工作表上载到

其基本思想是,通过将E10:L19范围内的最多8个单元更改为1,使单元B3最大化。B3单元包括E10:L19范围内的sumproduct()和许多类似范围

我期待着看到一些关于如何在R中构建类似模型的提示

谢谢! 乔切姆

========

根据Chase的建议更新 我想用一些可还原的R代码来澄清我的问题。这与您将在上面的Excel代码中找到的模型大致相同

初始矩阵集:

A <- as.matrix(structure(list(X0 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), X0.1 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), X0.2 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), X0.3 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), X0.4 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), X0.5 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), X0.6 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), X0.7 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)), .Names = c("X0", "X0.1", "X0.2", "X0.3", "X0.4", "X0.5", "X0.6", "X0.7"), class = "data.frame", row.names = c(NA, -9L)))
B <- as.matrix(structure(list(X1 = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), X1.1 = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), X1.2 = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), X1.3 = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), X.100000 = c(-100000L, -100000L, -100000L, -100000L, 1L, 1L, 1L, 1L, 1L), X.100000.1 = c(-100000L, -100000L, -100000L, -100000L, 1L, 1L, 1L, 1L, 1L), X.100000.2 = c(-100000L, -100000L, -100000L, -100000L, 1L, 1L, 1L, 1L, 1L), X.100000.3 = c(-100000L, -100000L, -100000L, -100000L, 1L, 1L, 1L, 1L, 1L)), .Names = c("X1", "X1.1", "X1.2", "X1.3", "X.100000", "X.100000.1", "X.100000.2", "X.100000.3"), class = "data.frame", row.names = c(NA, -9L)))
C <- as.matrix(structure(list(X1 = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), X1.1 = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), X1.2 = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), X1.3 = c(1L, 1L, 1L, 1L, 1L, -100000L, 1L, 1L, 1L), X1.4 = c(1L, 1L, 1L, 1L, 1L, -100000L, 1L, 1L, 1L), X1.5 = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), X1.6 = c(1L, 1L, 1L, 1L, 1L, -100000L, 1L, 1L, -100000L), X1.7 = c(1L, 1L, 1L, 1L, -100000L, -100000L, 1L, 1L, -100000L)), .Names = c("X1", "X1.1", "X1.2", "X1.3", "X1.4", "X1.5", "X1.6", "X1.7"), class = "data.frame", row.names = c(NA, -9L)))
D <- as.matrix(structure(list(X775 = c(385L, 1233L, 1067L, 5L, 730L, 1123L, 837L, 5L, 3087L), X704 = c(625L, 1338L, 804L, 110L, 659L, 1363L, 942L, -165L, 3350L), X704.1 = c(625L, 1338L, 804L, 110L, 659L, 1363L, 942L, -165L, 3350L), X944 = c(625L, 1263L, 898L, 35L, 899L, 1363L, 867L, -65L, 3110L), X775.1 = c(385L, 1233L, 1067L, 5L, 730L, 1123L, 837L, 5L, 3087L), X775.2 = c(385L, 1233L, 1067L, 5L, 730L, 1123L, 837L, 5L, 3087L), X944.1 = c(625L, 1263L, 898L, 35L, 899L, 1363L, 867L, -65L, 3110L), X944.2 = c(625L, 1263L, 898L, 35L, 899L, 1363L, 867L, -65L, 3110L)), .Names = c("X775", "X704", "X704.1", "X944", "X775.1", "X775.2", "X944.1", "X944.2"), class = "data.frame", row.names = c(NA, -9L)))
我想通过将矩阵A中的值从0更改为1来实现这一点。此外,还应考虑以下约束条件。 1.每行只能包含一个值为1的单元格。 2.每列只能包含一个值为1的单元格;这意味着我们可以在矩阵a中最多放置值1的八倍

有人对如何做到这一点有什么建议吗

您的决策变量(A中的单元格值)是布尔值(0或1),您的目标和约束是这些变量的线性函数,这将您归入一类称为混合整数线性规划的优化问题。例如,可以使用
Rglpk
包解决这些问题。以下是我的解决方案:

n1 <- nrow(A)
n2 <- ncol(A)

# objective coefficients
obj <- as.vector(B*C*D) # objective

# matrix of constraints weights
mat <- matrix(0, n1+n2, n1*n2)
for (i in 1:n1) {
   mat[i, ] <- as.numeric(row(A) == i)
}
for (j in 1:n2) {
   mat[n1+j, ] <- as.numeric(col(A) == j)
}

dir   <- rep("<=", n1+n2) # constraint directions
rhs   <- rep(1, n1+n2)    # constraints upper-bounds
types <- rep("B", n1*n2)  # variable types (boolean)

library(Rglpk)
opt <- Rglpk_solve_LP(obj, mat, dir, rhs, types,
                      max = TRUE, verbose = TRUE)
opt

# $optimum
# [1] 9950

# $solution
#  [1] 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
# [39] 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
# [77] 0 1 0 0

# $status
# [1] 0

opt.A <- matrix(opt$solution, n1, n2)
opt.A

#       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#  [1,]    0    0    0    1    0    0    0    0
#  [2,]    0    0    1    0    0    0    0    0
#  [3,]    0    1    0    0    0    0    0    0
#  [4,]    1    0    0    0    0    0    0    0
#  [5,]    0    0    0    0    0    0    0    0
#  [6,]    0    0    0    0    0    0    1    0
#  [7,]    0    0    0    0    0    1    0    0
#  [8,]    0    0    0    0    0    0    0    1
#  [9,]    0    0    0    0    0    0    0    0
# [10,]    0    0    0    0    1    0    0    0

n1现在没有时间研究这个问题,但我问了一个关于约束优化的问题,您可能会感兴趣。如果没有约束,那么代码应该更直接一些。如果有可能包含一段数据并在问题中显示预期的输出,人们可能会更愿意提供帮助,因为下载xlsm可能会吓到人们。关于可重复问题的好提示@Chase谢谢,我已经更新了一点问题,因此不需要打开Excel文件来回答问题。谢谢你的评论。到目前为止,我还无法根据你在评论中链接的文章得出结论。csv文件和excel表格并不完全相同。但是,我在Excel中重新计算了优化(并上传了新的表单),结果也是9950;计算时间只比R;-)长。无论如何,谢谢你的解决方案!这段代码似乎很管用,我需要多研究一点才能完全理解它!干杯嗨,弗洛德尔,我已经研究了你提供的代码,我很难理解在定义“约束权重矩阵”的地方发生了什么以及为什么会发生。为什么要在一个矩阵中排列行和列?@Jochem:约束以矩阵形式定义,通过
mat
dir
rhs
。以
mat
i
行为例:约束读取
sum(mat[i,]*x)dir[i]rhs[i]
,或
sum(mat[i,]*x)在我上面的注释中,
x
是您要求解的,它是一个布尔变量向量(0或1),对应于矩阵
a
中的值
x
具有长度
n1*n2
;第一个
n1
值用于
A
的第一列,下一个
n1
值用于第二列,以此类推。希望这能让您走上正轨。
n1 <- nrow(A)
n2 <- ncol(A)

# objective coefficients
obj <- as.vector(B*C*D) # objective

# matrix of constraints weights
mat <- matrix(0, n1+n2, n1*n2)
for (i in 1:n1) {
   mat[i, ] <- as.numeric(row(A) == i)
}
for (j in 1:n2) {
   mat[n1+j, ] <- as.numeric(col(A) == j)
}

dir   <- rep("<=", n1+n2) # constraint directions
rhs   <- rep(1, n1+n2)    # constraints upper-bounds
types <- rep("B", n1*n2)  # variable types (boolean)

library(Rglpk)
opt <- Rglpk_solve_LP(obj, mat, dir, rhs, types,
                      max = TRUE, verbose = TRUE)
opt

# $optimum
# [1] 9950

# $solution
#  [1] 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
# [39] 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
# [77] 0 1 0 0

# $status
# [1] 0

opt.A <- matrix(opt$solution, n1, n2)
opt.A

#       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#  [1,]    0    0    0    1    0    0    0    0
#  [2,]    0    0    1    0    0    0    0    0
#  [3,]    0    1    0    0    0    0    0    0
#  [4,]    1    0    0    0    0    0    0    0
#  [5,]    0    0    0    0    0    0    0    0
#  [6,]    0    0    0    0    0    0    1    0
#  [7,]    0    0    0    0    0    1    0    0
#  [8,]    0    0    0    0    0    0    0    1
#  [9,]    0    0    0    0    0    0    0    0
# [10,]    0    0    0    0    1    0    0    0