2017-05-09 37 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