Mathematical optimization in R [closed]

吃可爱长大的小学妹 提交于 2020-01-07 03:23:07

问题


I have the following data frames:

Required <- data.table( Country=c("AT", "BE", "BG", "CY"),Mat1=c(0,5,0,5),Mat2=c(0,3,2,0),Mat3=c(10,2,0,12))
Supplied <- data.table( Country=c("AT", "BE", "BG", "CY"),Mat1=c(0,4,0,10),Mat2=c(20,20,20,0),Mat3=c(8,10,0,10))

> Required
   Country Mat1 Mat2 Mat3
1:      AT    0    0   10
2:      BE    5    3    2
3:      BG    0    2    0
4:      CY    5    0    2

> Supplied
   Country Mat1 Mat2 Mat3
1:      AT    0   20    8
2:      BE    4   20   10
3:      BG    5   20    0
4:      CY   10    0   10

"Required" shows the requirement of three types of materials to different countries, while "Supplied" shows the supply capacity of these countries. I seek to apply an optimization algorithm by which the "Required" data frame is modified according to the supply capacity. For instance, 5 units of "Mat1" are required to the country "BE", while it can only supply 4 units. The algorithm should look for the less constrained country to supply this material, in this case countries "BG" and "CY" both have 5 units "available". The less constrained country is thus the one that has the most units of material available in absolute terms.

The resulting requirement table "RequiredNew" should thus be:

> Required
       Country Mat1 Mat2 Mat3
    1:      AT    0    0    8
    2:      BE    4    3    3
    3:      BG  0.5    2    0
    4:      CY  5.5    0    3

Any ideas on how to proceed? This is an example and the actual table is quite bigger, so I seek a programatical approach.

Many thanks in advance.


回答1:


This is a little bit convoluted, but it should work:

library(data.table)

Required <- data.table( Country=c("AT", "BE", "BG", "CY"),Mat1=c(0,5,0,5),Mat2=c(0,3,2,0),Mat3=c(10,2,0,2))
Supplied <- data.table( Country=c("AT", "BE", "BG", "CY"),Mat1=c(0,4,5,10),Mat2=c(20,20,20,0),Mat3=c(8,10,0,10))

# I prefer to work with matrices, so here I turn Required and Supplied into matrices
req <- as.matrix(Required[,-1,with=FALSE])
row.names(req) <- Required$Country
sup <- as.matrix(Supplied[,-1,with=FALSE])
row.names(sup) <- Supplied$Country

# create a copy of Required data.table to contain the result (we'll overwrite the values)
RequiredNew <- copy(Required)

# for each material...
for(col in 1:(ncol(req))){

  # for each country we compute the remaining stock and requirement after satisfying itself
  netreq <- req[,col] - sup[,col]
  netreq[netreq < 0] <- 0
  netstk <- sup[,col] - req[,col]
  netstk[netstk < 0] <- 0

  # we loop until we satisfy all the requirements or we finish the stock
  finalreq <- req[,col] - netreq
  while(sum(netreq) > 0 && sum(netstk) > 0){
    maxavailidxs <- which(netstk == max(netstk))
    requiredqty <- min(sum(netreq),sum(netstk[maxavailidxs]))
    deltareq <- (requiredqty * netreq) / sum(netreq)
    deltastk <- rep(0,length(netstk))
    deltastk[maxavailidxs] <- requiredqty / length(netstk[maxavailidxs])

    netreq <- netreq - deltareq
    netstk <- netstk - deltastk

    finalreq <- finalreq + deltastk
  }

  # we set the current material final requirement column into the result data.table
  set(RequiredNew,NULL,col+1L, finalreq)
}

RequiredNew
> RequiredNew
   Country Mat1 Mat2 Mat3
1:      AT  0.0    0    8
2:      BE  4.0    3    3
3:      BG  0.5    2    0
4:      CY  5.5    0    3


来源:https://stackoverflow.com/questions/31923107/mathematical-optimization-in-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!