2017-05-09 60 views
0

我很努力地在R中解决优化问题。对于我来说使用excel求解器很容易,但是我不能在R中做同样的问题。我没有太多的优化经验R 问题在于在特定活动应该在该时间段内完成时进行分配。 A1,A2,...,A12是在一个字段中完成的12个活动。 0代表未分配,1代表分配。从Excel优化到R

约束是 -

  • A2应该发生的完成A1之后,A3应该发生A2完成等
  • A3,A5,A6后 - 只有两个,这些活动都可以在一个特定的发生
  • 每一项活动都应该在一个领域发生(在Excel规划求解的一天,这个约束是通过采取行和定义等于一个

这将是一个很大的帮助,如果任何人都可以在SOLVIN帮助克这个问题。为了更好地理解这个问题,我附上了图片。 另外,请让我知道是否有任何网站或书籍,丰富的例子“如何解决R中的优化问题”。感谢你在期待。

enter image description here

+0

在我看来,就像一个小而直的MIP问题。不明白为什么这会在R. –

+0

中造成问题。回答下面的两个约束。现在我想不出一种优雅的方式去做最后一个(“A2应该发生在A1之后”)。在Excel解决方案中如何以及如何制定? – JanLauGe

+0

@JanLauGe,在excel中,对于这个约束,我将每一行的SUMPRODUCT与时间(我创建了一个序列1,2,...,12)并且差异应该是'> ='1。例如 - SUMPRODUCT(row2,timesequence) - SUMPRODUCT(row1,timesequence)> = 1'。希望,这回答你的问题。谢谢! – honey

回答

3

您可以使用lpSolve包解决您的问题。

您将需要一个成本向量和约束条件信息。在以下结构送入功能限制信息:

  • lhs:系数的“左手侧”矩阵,每一个决策变量
  • dir:a“方向”,即<<===>=>
  • rhs:一个 “右手边” 的数值

要建立您的合作名单nstraints,我觉得可以考虑每个可能作为X的决定(成为lhs表中的一列),并且您希望将每个约束定义为一个单独的等式(成为lhs表中的一行,其中有一个分别dirrhs对应的值)

让我们从所有可能的决定:

library(tidyverse) 
library(stringr) 

# What are the decision variables? ---- 

# Which action to take 
actions <- str_c('A',seq(1:12) %>% formatC(width = 2, flag = '0')) 
actions 
#[1] "A01" "A02" "A03" "A04" "A05" "A06" "A07" "A08" "A09" "A10" "A11" "A12" 

# When to take it 
timings <- str_c('T',seq(1:12) %>% formatC(width = 2, flag = '0')) 
timings 
#[1] "T01" "T02" "T03" "T04" "T05" "T06" "T07" "T08" "T09" "T10" "T11" "T12" 

# List of all possible decisions is this: 
decisions <- expand.grid(actions, timings) 

# Convert it to a vector 
decision_variables <- str_c(decisions[,1], '_', decisions[,2]) 

# You also need a cost vector. 
# We'll use a value increasing as a function of timings, 
# as this will penalize "late" actions? 
cost <- rep(seq(1:length(timings)), length(actions)) %>% sort 

decision_variables每个元素都是一个可能的动作(即在给定的时间采取行动。现在我们可以通过引入限制来缩小解算器可用的选项范围。


第一种类型的约束:每个选项只应采取一次! (这实际上是你的第三位,但我开始用这个,因为它是最简单的一种) 我们制定的是这样的:

# Create a matrix with one column per possible decision 
# and one row per action (for now) 
lhs <- matrix(0, 
    nrow = length(actions), 
    ncol = length(decision_variables), 
    dimnames = list(
    actions, 
    decision_variables)) 

# Each action should only be taken once! 
for (i in 1:length(actions)) { 
    # Which fields does an action occur in? 
    this_action <- str_detect(colnames(lhs), actions[i]) 
    # Set their coefficients to 1 
    lhs[i,this_action] <- 1 
} 
# create corresponding dir and rhs values 
dir <- rep('==', length(actions)) 
rhs <- rep(1, length(actions)) 

你可以看到,我们将所有X的系数(决定)其中包含action1。在我们的最终解决方案中,每个X将采用01的值。如果X为零,则系数将不相关。如果X1,则系数将被添加到lhs的总和中,并使用dirrhs的值进行比较。

这里,我们的约束条件是我们刚刚介绍的每个约束的总和为coefficient * X == 1。对于包含给定动作的所有可能的决定,系数是1。艾尔戈,一个解决方案只有在任何给定的行动只被采取一次是有效的。


第二个限制:只有两个c('A03', 'A05', 'A06')应该在某一天同时出现。

再一次,我们为每个约束生成一行。在这种情况下,我认为我们每天需要一个约束。我们,我们将生成值附加到现有lhsdirrhs变量:

# only one of A3, A5, A6 at any given time. 
# One constraint for each timestep 
for (j in timings) { 
    lhs <- rbind(lhs, ifelse(str_detect(decision_variables, paste0('A0[356]{1}_',j)), 1, 0)) 
    dir <- c(dir, '<=') 
    rhs <- c(rhs, 2) 
} 

占位符的第三个约束


转眼间,我们已经制定了我们的问题。现在让lpSolve紧缩数字! 您可以养活我们的问题转化为算法是这样的:

library(lpSolve) 

# Run lpSolve to find best solution 
solution <- lp(
    # maximise or minimise the objective function? 
    direction = 'min', 
    # coefficients of each variable 
    objective.in = cost, 
    const.mat = lhs, 
    const.dir = dir, 
    const.rhs = rhs) 

# Extract the values of X for the best solution: 
print(solution$solution) 

# Convert it into ta matrix of the format you are familiar with 
matrix(solution$solution, 
     nrow = length(timings), 
     ncol = length(actions), 
     dimnames = list(actions, timings)) 

这是不是你所需要的?

有任何问题吗?

+0

非常感谢您的回答。 'print'解决方案为我提供了一个输出。如果你能帮助我阅读输出结果会很好。我正在寻找的解决方案 - 在决策矩阵中分配0,1(如图所示)。在Excel中,我的目标函数是colSums(decision_matrix)* seq(1,12)'。如果你能解释,如果你正在考虑这些事情,那将是非常好的。再一次感谢你! – honey

+0

'decision_variables'的每个值都对应于Excel表中的一个字段(12乘12表= 144字段)。解决方案向量为每个字段提供“0”或“1”。将其转换为您习惯使用的格式的矩阵,现在将其添加到答案中。 – JanLauGe

+0

至于你的目标功能,你似乎会在后几个月处罚,以便尽早采取行动。我们可以通过使'成本'向量在时间上增加一个数字向量来实现。还补充说。 – JanLauGe