2015-08-10 4 views
0

У меня есть следующие кадры данных:Математическая оптимизация в R

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 

«Обязательно» показывает требование трех типов материалов в различных странах, в то время как «Комплект поставки» показывает потенциал поставок из этих стран. Я пытаюсь применить алгоритм оптимизации, с помощью которого кадр данных «Требуется» изменяется в соответствии с мощностью поставки. Например, для страны «BE» требуется 5 единиц «Mat1», в то время как она может поставлять только 4 единицы. Алгоритм должен искать менее ограниченную страну для предоставления этого материала, в этом случае страны «BG» и «CY» имеют 5 единиц «доступных». Таким образом, страна с менее ограниченными правами, которая имеет большинство единиц материала, доступна в абсолютном выражении.

Полученное требование таблица "RequiredNew" должно быть таким образом:

> 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 

Любые идеи о том, как поступить? Это пример, и фактическая таблица значительно больше, поэтому я ищу программный подход.

Большое спасибо заранее.

+1

Итак, вы хотите, чтобы покрыть как можно больше требования с национальными поставки возможно импорт из других стран? Числа должны быть целыми числами или вы можете указать, например, 0,5 в одну страну и 0,5 на другую? – digEmAll

+0

Не могли бы вы уточнить свое определение «менее ограниченное»? Абсолютный избыток CY равен 5, а абсолютный избыток BG также равен 5. Процентное значение CY в процентах составляет 50%, а процентный профицит BG - 100%. Итак, почему вы не выбираете BG, чтобы страна поставляла материал? – rbatt

+0

@digEmAll Числа могут быть десятичными, я исправил свой пример, чтобы исправить ошибку и показать эту возможность. – David

ответ

1

Это немного запутанным, но это должно работать:

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 
+0

Большое вам спасибо, он работает по назначению. Тем не менее, я понял, что упростил этот пример, и теперь я не могу реализовать его в своих реальных данных из-за моих ограниченных знаний в Р. В частности, каждая страна поставляет несколько продуктов, так что «maxavailidxs» должен искать конкретный продукт, а не весь столбец , Я создал новую запись с лучшим примером здесь, так как это приостановлено: http://stackoverflow.com/questions/31938512/conditional-mathematics-optimization-in-r. Надеюсь, вы можете помочь мне с вашим кодом без каких-либо изменений. Еще раз спасибо! – David

Смежные вопросы