【问题标题】:Divide Items based on their available stock to other ID根据可用库存将项目划分为其他 ID
【发布时间】:2019-02-09 10:52:50
【问题描述】:

大家好,我正面临一个独特的问题。如果特定项目 ID 所需的数量超过现有库存,我想根据条件找出库存转移。我们应该从其他 ID 转移库存。 例如。 item 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))

应使用 R 代码生成突出显示的列

【问题讨论】:

  • 我不知道您要做什么(我很难理解您的冗长说明)。您能否为您的最小样本数据包括您的预期输出;还清楚地说明(用尽可能少的词和尽可能简洁)创建新列的规则。避免使用特定领域的行话,而是专注于一般规则。
  • @MauritsEvers 我已经对自己的问题进行了更改。我希望你现在能明白了。
  • 好的,我想我明白了。如果一件商品的总库存少于总数量,你想怎么办?
  • @Gregor 如果它小于应该从其他 ID 转移的数量。如果没有 ID 有多余的库存,它应该保持原样。
  • 到目前为止您尝试过什么?看看哪些没有奏效会很有帮助,并使流程更加清晰

标签: r dplyr data.table


【解决方案1】:

看起来像一个整数规划问题,以 Updated_SOH 作为变量,目标函数最小化 Quantity 和 SOH 之间的绝对差值,受限于 SOH 的总和保持不变。

这是解决此优化问题的启发式方法:

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

2) 采用与 here 类似的方法,但移动正值和不同的聚合,我们使用这些多余的 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))

【讨论】:

  • 在此解决方案中遇到问题,需要您的帮助。
  • 例如在第 21 行:- 现有库存为 38,数量为 4。更新的 SOH 应该是 34,但我在上述解决方案中得到的是 SOH 领域的 4。应该是 34 而不是 4。请帮帮我。
  • 我在输出中看到 34
  • 当单个 Item.code 中的许多商品的库存多于数量时,就会出现问题。输出中的所有项目都将 Quantity 显示为更新的 SOH 而不是实际的 SOH,因为不会有任何转移,因为所有项目都有足够的 Stock。希望你能理解
  • 没有数据很难理解
猜你喜欢
  • 1970-01-01
  • 2019-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-25
  • 1970-01-01
相关资源
最近更新 更多