2016-07-13 98 views
0

我試圖做一個線性規劃問題的模擬。該模型具有obj函數和一些約束。在這種情況下,我引入了從正態分佈隨機抽取的2個值。循環槽R中的一組項目

我然後使用for-loop模擬10.000次優化模型。我知道使用for-loop是不好的做法,但在這種情況下速度並不是我所關心的。

#List of 10000 random, normally distributed observations: 
Demand = rnorm(10000, mean=5, sd=2.5) 
Demand 

Performance = rnorm(10000, mean=100, sd=6) 
Performance 

Optimas = NULL 

#combined_list = c(Demand, Performance) 

for (i in Performance){ 
    op <- OP(objective = c(2.5, 4, i),    #Performance value[i]: works fine 
      L_constraint(L = matrix(c(1, 0, 0,  #LHS 
             0, 1, 0,  
             0, 0, 1),  
             ncol=3, nrow = 3, 
             byrow = TRUE), 
          dir = c("<=", "<=", "<="), 
          rhs = c(50, 70, Demand)), #Demand value[i]: should go here 
       maximum = TRUE, 
       types = c("B", "I", "I")) 

    Optima <- ROI_solve(op, solver = "glpk") #solve 
    print(Optima) 
    print(i) 
    Optimas = rbind(Optimas, Optima) 
} 


Optimas <- as.data.frame(Optimas) 
Optimas$objval <- as.numeric(Optimas$objval) 
hist(Optimas$objval) 

從上面可以看出,我的循環就只能走線槽一個變量(性能),在這裏我想在需求矢量在行(i)需求值將被放入模型中,在同一時間,行(i)在性能向量中的性能值。

總體目標是對LP模型進行10.000次模擬,其中性能值和需求值都只出現一次(因爲我已有的另一個循環之外的循環將生成笛卡兒積兩個清單)。

任何幫助將不勝感激。

回答

1

請注意,您的PerformanceDemand向量包含完全相同數量的元素。因此,您可以簡單地遍歷矢量索引並使用各自的索引值來提取相關元素。

我無法運行您的示例代碼,因爲我不確定您的OP函數使用哪種優化包。作爲一個例子,我將定義一個簡單dummyFunction,需要一個性能和需求值作爲輸入,如下:

dummyFunction <- function(perf, dem){ return (perf+dem)} 

在您的具體使用情況下,dummyFunction將包含優化邏輯。接下來,您可以獲取所需的解決方案如下,通過循環矢量指數:

Optimas = vector(mode="numeric", length=length(Performance)) 
for(idx in 1:length(Performance)){ 
    Optimas[idx] <- dummyFunction(Performance[idx], Demand[idx]) 
} 

或者,你可以只是把你的優化邏輯for循環中避免函數定義。 對於更「像解R」考慮sapply/lapply型函數的用法:

Optimas <- sapply(1:length(Performance), function(idx) dummyFunction(Performance[idx], Demand[idx])) 

注意,在這個特殊的例子,你也可以只做到以下幾點:

Optimas <- dummyFunction(Performance, Demand) 

最後,如果性能成爲問題,請考慮使用foreachdoparallel程序包同時在多個內核上運行優化:

library(doParallel) 
library(foreach) 
nrCores <- detectCores() 
cl <- makeCluster(nrCores); registerDoParallel(cl) 
clusterExport(cl,c("Demand", "Performance", "dummyFunction"), envir=environment()) 
Optimas <- foreach(idx=1:length(Performance), .combine="rbind") %dopar%{ 
    dummyFunction(Performance[idx], Demand[idx]) 
} 
stopCluster(cl) 
+0

感謝您的回答:-)使用ROI包進行優化 – MikeR

0

考慮一種mapply()方法,apply函數在多個傳遞相應元素的列表/向量上進行迭代。首先將所有操作包裝在一個函數中,然後在mapply()中爲矢量傳遞兩個參數。最後,使用lapply()轉置爲與do.call(rbind...)行綁定的數據幀的長列表。

Performance = rnorm(10000, mean=100, sd=6) 
Demand = rnorm(10000, mean=5, sd=2.5) 

optimizefct <- function(p, d){ 
    op <- OP(objective = c(2.5, 4, p),    # Performance 
      L_constraint(L = matrix(c(1, 0, 0,  # LHS 
            0, 1, 0,  
            0, 0, 1),  
            ncol=3, nrow = 3, 
            byrow = TRUE), 
         dir = c("<=", "<=", "<="), 
         rhs = c(50, 70, d)),  # Demand 
      maximum = TRUE, 
      types = c("B", "I", "I")) 

    Optima <- ROI_solve(op, solver = "glpk") #solve 
    print(Optima) 
    print(i) 

    return(Optima) 
} 

# WIDE FORMAT 
dfList <- mapply(optimizefct, Performance, Demand) 

# LONG FORMAT 
dfList <- lapply(1:10000, function(i) data.frame(dfList[,i])) 

# BIND TO FINAL DF 
Optimas <- do.call(rbind, dfList) 
Optimas$objval <- as.numeric(Optimas$objval)