2017-07-28 90 views
0

我正在使用LPSolve與R和我的輸入數據是在多個CSV文件的形式,每個文件都有一個表。的表2中提及以下:LPSolve與R - 多個數據集作爲輸入

Production Data

Route Data

說明有關約束的 -

  • 有從每個生產家發起
  • 總流出從生產工藝路線房子=源自它的路線的總和(路線容積)
  • 製作公司合計流出< =生產能力
  • 路線卷本身就是一個決策變量取決於在這個崗位未提到的其他變量

約束的數學表達式如下:

`Production Total Outflow = ∑(Route Volume) where (Production House ID from table_1)==(Originating from Prod House ID from table_2)` 

Production Total Outflow <= Production Capacity

在現實中,我有成千上萬的行。我試圖爲上述2個約束寫下面的代碼。將會有2個約束:

#Reading Data from files 
routeData = read.csv("Route.csv", header = TRUE) 
ProductionData = read.csv("Production.csv", header = TRUE) 

#Fetching variable columns 
routeID = routeData$RouteID 
productionID = ProductionData$ProductionID 
productionCapacity = ProductionData$Supply.Capacity 

numberOfColumns = length(routeID) + length(productionID) #4+2 decision variables 
model <- make.lp(nrow=0, ncol=numberOfColumns, verbose="important") 

for(i in 1:length(productionID)){ 
    add.constraint(model, 1, "<=", productionCapacity[i]) #Something wrong here 
} 
#I haven't attempted to write the other constraint 

我無法繼續編寫約束條件。請幫助傢伙。我還沒有分享這個目標,因爲它也有很多其他限制。

+0

它通常有助於首先寫下數學模型。之後,您可以將其轉換爲代碼。 –

+0

我已編輯帖子並添加了數學表示。另外,我在Gurobi中成功編寫了代碼,但在LPSolve中,我感到困惑,因爲我們必須編寫代碼將值直接放入矩陣中。請幫助。 –

回答

0

這裏是試圖在生產用房均勻分佈路線容積

library(lpSolveAPI) 

prodcap <- setNames(c(50,100), c(1,2)) 
route <- data.frame(rid=1:4, pid_from=rep(1:2, each=2)) 
route_volume <- 125 # example 

nvars <- nrow(route)+1 # example: evenly distribute production house output relative to capacity 
lprec <- make.lp(0, nvars) 

set.objfn(lprec, obj=1, indices=nvars) 

# capacity constraints 
for (i in seq(1, length(prodcap))) { 
    route_ids <- which(route[,"pid_from"]==i) 
    add.constraint(lprec, xt=rep(1, length(route_ids)), type="<=", rhs=prodcap[i], indices=route_ids) 
} 

# total outflow constraint 
add.constraint(lprec, xt=rep(1, nrow(route)), type="=", rhs=route_volume, indices=seq(1, nvars-1)) 

# example: define the last decision variable as maximum flow over each production house 
for (i in seq(1, length(prodcap))) { 
    route_ids <- which(route[,"pid_from"]==i) 
    add.constraint(lprec, xt=c(rep(1/prodcap[i], length(route_ids)), -1), type="<=", rhs=0, indices=c(route_ids, nvars)) 
} 

# solve 
status <- solve(lprec) 
if(status!=0) stop("no solution found, error code=", status) 
get.variables(lprec)[seq(1, nrow(route))] 
#[1] 41.66667 0.00000 83.33333 0.00000 

請注意,如果你有成千上萬的路線/生產用房它可能是更有效的預分配的約束一例make.lp並使用set.row而不是add.constraint。下面是一個示例,並將route_volume作爲附加決策變量,如評論中所要求的那樣:

library(lpSolveAPI) 

prodcap <- setNames(c(50,100), c(1,2)) 
route <- data.frame(rid=1:4, pid_from=rep(1:2, each=2)) 
route_volume <- 125 # example 

# the first nrow(route) vars are the outflows, 
# then 1 variable for maximum flow (relative to capacity) over all production house 
# then 1 last variable for the route volume 
nvars <- nrow(route)+2 
ncons <- 2*length(prodcap)+3 

# pre-allocate the constraints 
lprec <- make.lp(ncons, nvars) 

# set objective: minimize maximum flow relative to capacity (example) 
set.objfn(lprec, obj=1, indices=nvars-1) 

# capacity constraints 
rownum <- 1 
for (i in seq(1, length(prodcap))) { 
    route_ids <- which(route[,"pid_from"]==i) 
    set.row(lprec, row=rownum, xt=rep(1, length(route_ids)), indices=route_ids) 
    set.rhs(lprec, prodcap[i], constraints=rownum) 
    rownum <- rownum + 1 
} 

# total outflow constraint ("=" resolves to two constraints) 
set.row(lprec, row=rownum, xt=c(rep(1, nrow(route)), -1), indices=c(seq(1, nvars-2), nvars)) 
set.rhs(lprec, 0, constraints=rownum) 
rownum <- rownum + 1 
set.row(lprec, row=rownum, xt=c(rep(-1, nrow(route)), 1), indices=c(seq(1, nvars-2), nvars)) 
set.rhs(lprec, 0, constraints=rownum) 
rownum <- rownum + 1 

# additional constraint for route volume 
set.row(lprec, row=rownum, xt=-1, indices=nvars) 
set.rhs(lprec, -125, constraints=rownum) #example: route_volume >= 125 
rownum <- rownum + 1 

# example: define the second last decision variable as maximum flow (relative to capacity) over all production houses 
# rhs is 0, which is preset 
for (i in seq(1, length(prodcap))) { 
    route_ids <- which(route[,"pid_from"]==i) 
    set.row(lprec, row=rownum, xt=c(rep(1/prodcap[i], length(route_ids)), -1), indices=c(route_ids, nvars-1)) 
    set.rhs(lprec, 0, constraints=rownum) 
    rownum <- rownum + 1 
} 

# solve 
status <- solve(lprec) 
if(status!=0) stop("no solution found, error code=", status) 
get.variables(lprec)[seq(1, nrow(route))] 
+0

謝謝。有效。但是,如果我們將route_volume作爲決策變量,而不是您對route_volume < - 125的假設,那麼需要在代碼中更改哪些內容? –

+0

你對route_volume有什麼約束,以便求解器不會建議零route_volume? –

+0

爲此添加了代碼示例,h代表 –