R中多个约束的优化

时间:2015-08-03 18:57:34

标签: r constraints mathematical-optimization

我有一个问题,即使用一些约束来优化建筑物中多个房间的程序使用。 我的问题是如何根据数据和约束同时要求所有4个教室中的最佳课程?

以下是我的数据的一小部分样本。

Program                 sf    101   201 301 401 
(1) Offices             120    6     6   5   5
(2) Gallery             1000   5     5   4   4
(3) Reception / Greeter 300    6     6   5   7
(4) Studio / Classroom  800    6     6   5   5

101,201,301和401代表建筑物中的4个房间 程序是潜在的房间使用 sf表示预期程序的最大平方英尺(一个约束) 数据表示预期程序与每个房间的属性匹配的标准数量(这是我想要最大化的数字)。

我还想提出一些约束条件,这些约束条件允许我说我只想要建筑物中的一定数量的办公室,画廊等。

例如,我想要1个接待/接待员和2个办公室,最后一个房间可以填写最佳匹配。 101室的最大sf为150,201室的最大sf为250平方英尺,301室的最大sf为1500,而401室的最大sf为500(这些约束不在我的数据框中,因为我无法'想到一个好方法,包括他们。)  此示例应返回101 =办公室,201 =办公室,301 =三个中的一个,不包括图库,401 =接收/接收。

更新: 目标应该是这样的(我希望它们都最大化):

obj <- data$101, data$201, data$301, data$401 (and probably data$sf too) 

然后我不确定如何编写约束,但它们就是这样:

数据$ 101
数据$ sf&lt; = 150
此列中的解决方案数量应为1

数据$ 201
数据$ sf&lt; = 250
此列中的解决方案数量应为1

...

数据$ 401
数据$ sf&lt; = 500
此列中的解决方案数量应为1

然后最终以某种方式限制“办公室”,“画廊”,“接待/接待”,“工作室/教室”的数量。

可能是这样的:

as.numeric(data$Program %in% c("(1) Offices") == 1

希望这能澄清一些事情。

1 个答案:

答案 0 :(得分:1)

听起来您正在将程序(data中的行)分配给房间(data中的列),以便最大化分配的值。如果房间足够大,您只能将一个程序分配给一个房间,并且您只能将一个程序分配给一个房间,尽管可以将同一个程序分配给多个房间(例如,您可以将“办公室”分配给101和201室)。因此,您的数据实际上包括程序大小,房间大小和目标值:

program.size <- c(120, 1000, 300, 800)
room.size <- c(150, 250, 1500, 500)
(obj.vals <- matrix(c(6, 5, 6, 6, 6, 5, 6, 6, 5, 4, 5, 5, 5, 4, 7, 5), nrow=4))
#      [,1] [,2] [,3] [,4]
# [1,]    6    6    5    5
# [2,]    5    5    4    4
# [3,]    6    6    5    7
# [4,]    6    6    5    5

阻止将程序分配给太小的房间的简单方法是将这样的分配的目标值设置为较低的值(我将在这里使用0):

(obj.adj <- obj.vals * outer(program.size, room.size, "<="))
#      [,1] [,2] [,3] [,4]
# [1,]    6    6    5    5
# [2,]    0    0    4    0
# [3,]    0    0    5    7
# [4,]    0    0    5    0

现在,您可以使用整数编程来解决此问题,定义一个变量x_pr,如果将程序p分配给房间r,则取值为1,否则为0。您可以使用R:

中的lpSolve包非常轻松地编写目标和约束
# Convenience variables
nr <- nrow(obj.adj)
nc <- ncol(obj.adj)

# Model
library(lpSolve)
mod <- lp("max",
          as.vector(obj.adj),
          t(1*sapply(1:nc, function(x) rep(1:nc == x, each=nr))),
          rep("<=", nc),
          rep(1, nc),
          all.bin=TRUE)
matrix(mod$solution, nrow=nr)
#      [,1] [,2] [,3] [,4]
# [1,]    1    1    0    0
# [2,]    0    0    0    0
# [3,]    0    0    0    1
# [4,]    0    0    1    0

现在我们已将“办公室”分配到101和201室,“工作室/教室”分配到301室,“接待/招待”分配到401室。

值得注意的是,通过选择obj.adj中每个房间最大值的程序,可以轻松解决此程序,因此只有在您拥有更复杂的约束时才能使用lpSolve问题中提到的那些。