Разделите элементы на основе их имеющихся запасов на другой идентификатор - PullRequest
0 голосов
/ 04 сентября 2018

Привет Всем, я сталкиваюсь с уникальной проблемой. Я хочу выяснить передачу запаса на основе условия, если количество, требуемое для конкретного идентификатора элемента, превышает запас на складе. мы должны перенести инвентарь с другого удостоверения личности. Например. Элемент I60 доступен для 7 идентификаторов. Для E1 доступный запас E6 меньше количества, поэтому я хочу перевести избыточный запас из E3 (т.е. 6-2 = 4) в E1 и E6. Таким образом, перевод для E1 будет 1, а E6 будет 2, а оставшийся SOH от E3 будет 3. Я надеюсь, что все могут это понять.

structure(list(ID = structure(c(1L, 6L, 7L, 3L, 5L, 2L, 4L, 8L, 
1L, 7L, 3L, 5L, 2L, 9L, 8L, 1L, 7L, 3L, 5L, 2L, 9L, 8L, 1L, 7L, 
3L, 5L, 2L, 9L, 8L, 1L, 7L, 3L, 5L, 2L, 9L, 8L, 1L, 7L, 3L, 5L, 
2L, 9L, 8L, 1L, 7L, 3L, 5L, 2L, 9L), .Label = c("E1", "E2", "E3", 
"E4", "E5", "E6", "E7", "E8", "E9"), class = "factor"), Item.Code = structure(c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 
5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L
), .Label = c("I60", "I67", "I68", "I69", "I70", "I71", "I72"
), class = "factor"), Quantity = c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 4L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), Stock_on_hand = c(1L, 
0L, 2L, 6L, 2L, 2L, 2L, 0L, 6L, 3L, -1L, 1L, 2L, 9L, 1L, 5L, 
-1L, 9L, 3L, 38L, 5L, 10L, 2L, 3L, 2L, 2L, 1L, 8L, 0L, 2L, 2L, 
4L, 2L, 1L, 5L, 1L, -1L, 4L, 3L, 1L, 2L, 11L, 1L, 2L, 0L, 3L, 
1L, 4L, 1L), Transfer = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 4L, 0L, 
0L, 0L, 0L, 0L, 0L, 3L, 0L, 7L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 6L, 0L, 0L, 0L, 0L, 0L, 0L, 3L, 0L, 0L, 2L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 1L, 0L, 2L, 0L, 0L)), class = "data.frame", row.names = c(NA, 
-49L))

highlighted columns should be generated with R code.

выделенные столбцы должны генерироваться с кодом R

1 Ответ

0 голосов
/ 05 сентября 2018

Выглядит как задача целочисленного программирования, так как Updated_SOH - переменная и целевая функция, минимизирующая абсолютную разницу между количеством и SOH с учетом ограничения, что общая сумма SOH остается постоянной.

Вот эвристический подход к решению этой проблемы оптимизации:

1) Рассчитайте разницу, которая будет использоваться для сортировки набора данных.

2) При подходе, аналогичном здесь , но смещая положительные значения и другую агрегацию, мы используем эти избыточные значения SOH, чтобы компенсировать дефицит SOH в предыдущих строках.

3) Окончательный результат представляет собой сумму i) существующего количества, ii) любого невыполненного количества и iii) избытка SOH.

setDT(df)    
df[, Diff := Stock_on_hand - Quantity]
setorder(df, Item.Code, Diff)

df[, Updated_SOH := {
    posVal <- replace(Diff, Diff<0, 0)
    negVal <- replace(Diff, Diff>0, 0)
    n <- 1L
    while (any(negVal < 0) && n < .N) {
        negVal <- replace(negVal, negVal>0, 0) + 
            shift(posVal, 1L, type="lead", fill=0) +
            c(posVal[1L], rep(0, .N-1L)) #for case where there are more Quantity than SOH
        posVal <- replace(negVal, negVal<0, 0)
        n <- n + 1L
    }

    excess <- negVal[negVal > 0]

    Quantity +                                           #existing Quantity
        replace(negVal, negVal>0, 0) +                   #unfulfilled Quantity
        c(rep(0, .N - length(excess)), excess) #shifting back down excess SOH
}, by=.(Item.Code)]

выход:

    ID Item.Code Quantity Stock_on_hand Transfer Diff Updated_SOH
 1: E6       I60        2             0        0   -2           2
 2: E1       I60        2             1        0   -1           2
 3: E7       I60        2             2        0    0           2
 4: E5       I60        2             2        0    0           2
 5: E2       I60        2             2        0    0           2
 6: E4       I60        2             2        0    0           2
 7: E3       I60        2             6        0    4           3
 8: E3       I67        2            -1        0   -3           2
 9: E8       I67        2             0        4   -2           2
10: E5       I67        2             1        0   -1           2
11: E2       I67        2             2        0    0           2
12: E7       I67        2             3        0    1           2
13: E1       I67        2             6        0    4           2
14: E9       I67        2             9        0    7           8
15: E7       I68        2            -1        7   -3           2
16: E8       I68        2             1        3   -1           2
17: E5       I68        2             3        0    1           2
18: E1       I68        2             5        0    3           2
19: E9       I68        2             5        0    3           5
20: E3       I68        2             9        0    7           9
21: E2       I68        4            38        0   34          38
22: E2       I69        2             1        6   -1           2
23: E1       I69        2             2        0    0           2
24: E3       I69        2             2        0    0           2
25: E5       I69        2             2        0    0           2
26: E7       I69        2             3        0    1           2
27: E9       I69        2             8        0    6           8
28: E8       I69        2            10        0    8          10
29: E8       I70        2             0        0   -2           2
30: E2       I70        2             1        3   -1           2
31: E1       I70        2             2        0    0           2
32: E7       I70        2             2        0    0           2
33: E5       I70        2             2        0    0           2
34: E3       I70        2             4        0    2           2
35: E9       I70        2             5        0    3           4
36: E1       I71        2            -1        2   -3           2
37: E8       I71        2             1        0   -1           2
38: E5       I71        2             1        0   -1           2
39: E2       I71        2             2        0    0           2
40: E3       I71        2             3        0    1           2
41: E7       I71        2             4        0    2           2
42: E9       I71        2            11        0    9           9
43: E7       I72        2             0        1   -2           0
44: E8       I72        2             1        0   -1           2
45: E5       I72        2             1        2   -1           2
46: E9       I72        2             1        0   -1           2
47: E1       I72        2             2        0    0           2
48: E3       I72        2             3        0    1           2
49: E2       I72        2             4        0    2           2
    ID Item.Code Quantity Stock_on_hand Transfer Diff Updated_SOH

данные:

library(data.table)
df <- structure(list(ID = structure(c(1L, 6L, 7L, 3L, 5L, 2L, 4L, 8L, 
    1L, 7L, 3L, 5L, 2L, 9L, 8L, 1L, 7L, 3L, 5L, 2L, 9L, 8L, 1L, 7L, 
    3L, 5L, 2L, 9L, 8L, 1L, 7L, 3L, 5L, 2L, 9L, 8L, 1L, 7L, 3L, 5L, 
    2L, 9L, 8L, 1L, 7L, 3L, 5L, 2L, 9L), .Label = c("E1", "E2", "E3", 
        "E4", "E5", "E6", "E7", "E8", "E9"), class = "factor"), Item.Code = structure(c(1L, 
            1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 
            3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 
            5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L
        ), .Label = c("I60", "I67", "I68", "I69", "I70", "I71", "I72"
        ), class = "factor"), Quantity = c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 
            2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 4L, 2L, 2L, 2L, 
            2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
            2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), Stock_on_hand = c(1L, 
                0L, 2L, 6L, 2L, 2L, 2L, 0L, 6L, 3L, -1L, 1L, 2L, 9L, 1L, 5L, 
                -1L, 9L, 3L, 38L, 5L, 10L, 2L, 3L, 2L, 2L, 1L, 8L, 0L, 2L, 2L, 
                4L, 2L, 1L, 5L, 1L, -1L, 4L, 3L, 1L, 2L, 11L, 1L, 2L, 0L, 3L, 
                1L, 4L, 1L), Transfer = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 4L, 0L, 
                    0L, 0L, 0L, 0L, 0L, 3L, 0L, 7L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
                    0L, 6L, 0L, 0L, 0L, 0L, 0L, 0L, 3L, 0L, 0L, 2L, 0L, 0L, 0L, 0L, 
                    0L, 0L, 0L, 1L, 0L, 2L, 0L, 0L)), class = "data.frame", row.names = c(NA, 
                        -49L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...