根据可用库存将物料划分为其他ID

时间:2018-09-04 11:51:51

标签: r dplyr data.table

大家好,我面临一个独特的问题。如果特定物料ID所需的数量大于手头上的库存,我想根据条件找出库存转移。我们应该从其他ID转移库存。 例如。 I60项目可用于7个ID。对于E1,E6的可用库存量少于数量,因此我要做的是将多余的库存从E3(即6-2 = 4)转移到E1和E6。因此,E1的传输将是1,E6的传输将是2,E3的剩余SOH将是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 :(得分:1)

看起来像一个整数编程问题,以Updated_SOH作为变量和目标函数,在限制SOH的总和保持恒定的情况下,最大程度地减少了数量与SOH之间的绝对差。

以下是一种启发式方法来解决此优化问题:

1)计算用于对数据集进行排序的差异。

2)以与here类似的方式,但是转移正值和不同的聚合,我们使用这些多余的SOH来抵消前几行中的SOH赤字。

3)最终输出是i)现有数量,ii)任何未实现数量和iii)超额SOH的总和。

start()

输出:

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