#r #optimization #ompr
#r #оптимизация #ompr
Вопрос:
Я пытаюсь решить проблему оптимизации сети поставок MILP, используя OMPR-пакет R. Мне нужно определить 3D-двоичную переменную (x[i, j, q]) в модели, чтобы сопоставить клиентов (i) с DC (j) по каждому артикулу (q). Кто-нибудь знает, как я могу это сделать?
С моим текущим кодом я получаю
Error - in as.data.frame.default(x[[i]], optional = TRUE) :
cannot coerce class ‘structure("LinearVariableCollection", package = "ompr")’ to a data.frame
Я больше не получаю эту ошибку, но модель не выдает правильный результат (проверено с помощью открытого решателя Excel). Кажется, есть какая-то проблема с ограничением # 4. Похоже, что умножение между VCustDemand и переменной x [i, j, q] происходит не в правильном порядке.
model <- MILPModel() %>%
add_variable(y[j], j = 1:n, type = "binary")%>% #1: if warehouse j is opened
add_variable(x[i, j, q], i = 1:m, j =1:n, q=1:r , type = "binary")%>% #2: if i gets assigned to warehouse j for Product q
add_variable(z[p, j], p = 1:o, j = 1:n, type = "binary") %>% # 3 for selection of DC of a specific size
add_variable(aa[l,j,q], l = 1:k, j =1:n, q=1:r, type = "integer",lb = 0, ub = 500000) %>% # 4 for plant getting mapped to a warehouse for product q
set_objective(
sum_expr(colwise(Vsec_log[i (j-1)*m*r (q-1)*m]) * x[i, j, q] * colwise(VCustDemand[i (q-1)*32]) , i = 1:m ,j = 1:n, q=1:r) #Secondary shipments total
sum_expr(colwise(Vfix_fac[p o*(j-1)]) * z[p, j] , p = 1:o, j = 1:n ) #DC Fixed costs
sum_expr(colwise(VCustDemand[i (q-1)*32]) * x[i,j,q] * colwise(Vvar_fac_storage[q (j-1)*r]), i = 1:m , j = 1:n, q=1:r ) #Varilable storage costs
sum_expr(colwise(VCustDemand[i (q-1)*32]) * x[i,j,q] * colwise(Vvar_fac_handling[q (j-1)*r]), i = 1:m , j = 1:n, q=1:r ) #DC Variable handling costs
sum_expr(colwise(Vprimary_log[l (j-1)*k*r (q-1)*k]) * aa[l,j,q] , l = 1:k, j = 1:n, q=1:r), # #Primary logistics costs
# sum_expr(aa[l,j,q]*colwise(Vplant_var[l (q-1)*k]) , l = 1:k, j = 1:n, q = 1:r), #Plant variable costs
sense = "min") %>%
add_constraint(sum_expr(y[j] , j = 1:n) == 6)%>% #1. No. of open DCs
add_constraint(sum_expr(x[i, j, q], j = 1:n) == 1, i = 1:m, q=1:r) %>% #2. Each Customer is mapped to one DCs for 1 SKU
add_constraint((sum_expr(x[i, j, q], i = 1:m, q=1:r)/999) <= y[j], j = 1:n) %>% #3. Grouping constraint connecting #1 amp; #2
add_constraint(aa[l,j,q] >= 0, l = 1:k, j = 1:n, q = 1:r) %>% #4. Positive outflow from Plant s
add_constraint(sum_expr(aa[l,j,q], l = 1:k) == sum_expr(colwise(VCustDemand[i (q-1)*32]) * x[i,j,q], i = 1:m), j = 1:n, q = 1:r)%>% #4 plant outflow should be equal to DC inflow for each SKU
add_constraint(sum_expr(aa[l,j,q], j = 1:n) <= Vtbl_plant_capacity[l (q-1)*k], l = 1:k, q = 1:r) %>% ##5 Constraint on plant capacity for every SKU
add_constraint(sum_expr(aa[l,j,q], j = 1:n, q = 1:r) <= Vtbl_Total_plant_capacity[l], l = 1:k) %>%##6 Constraint on overall plant capacity across SKUs
add_constraint(sum_expr(z[p,j], p = 1:o) == y[j], j = 1:n) %>% #7. Select one facility per capacity size
add_constraint(sum_expr(colwise(Vfix_fac_cap[p]) * z[p,j], p = 1:o ) >=
sum_expr(colwise(VCustDemand[1:(m*r)]) * x[i,j,q], i = 1:m, q =1:r), j = 1:n) #8. Total DC outflow should be <= Total DC capacity
'''
If I replace the constraint by
add_constraint(sum_expr(aa[l,j,q], l = 1:2) == sum_expr(colwise(VCustDemand[i (1-1)*32]) * x[i,j,q], i = 1:m), j = 1:n, q = 1) %>%
add_constraint(sum_expr(aa[l,j,q], l = 1:2) == sum_expr(colwise(VCustDemand[i (2-1)*32]) * x[i,j,q], i = 1:m), j = 1:n, q = 2) %>%
add_constraint(sum_expr(aa[l,j,q], l = 1:2) == sum_expr(colwise(VCustDemand[i (3-1)*32]) * x[i,j,q], i = 1:m), j = 1:n, q = 3) %>%
'''
The code seems to work
VCustDemand is a 2D data containing customer demand in the following format -
ProductLine CustomerCity Demand
SKU1 Agra 1755
SKU1 Ahemdabad 7279
SKU1 Delhi 1830
SKU2 Agra 1408
SKU2 Ahemdabad 9111
SKU2 Delhi 4970
SKU3 Agra 1469
SKU3 Ahemdabad 414
SKU3 Delhi 229
Комментарии:
1. Добро пожаловать в Stack Overflow. Не могли бы вы, пожалуйста, включить код и образец данных? Следующий код сгенерирует фрагмент кода с 10 случайными записями, которые вы можете вставить в свой исходный пост: dput(dplyr::sample_n(YourDatasetsNameGoesHere, 10)). Чтобы использовать мой код, вам может потребоваться установить dplyr с помощью: install.packages(«dplyr»)