WMS关于出库分配库存凑数凑整相关的几点策略-递归方法

一、业务背景种类:

(1)单托数量差别小,出库固定托数,分配总数控制误差范围

A客户,标准托盘,产品单一不混托,单托数量基本固定,略有误差,例如单托2.5t ± 0.5t

出库方式:集装箱装货,每个集装箱装货11托产品,需要要求出库总重27.5t ± 0.3t,需WMS自动分配库存,并可以人工手动调整分配结果(人工调整这里不进行代码展示)

相关策略详见:代码展示   第(1)条

(2)不固定托数,分配总数控制误差范围

B客户,单据出库总数50t,需WMS自动分配托数,使其总数满足  [50-5 ,  50] t   的区间之内

相关策略详见:代码展示   第(2)条

(3)凑整出库,减少分拣返库,每托数量较为规律,差异不太大

A物料每托的数量可能是10,12,15,18......,其中数量为10有x托,数量为12的有y托,以此类推;假设客户需要出库30,需要WMS自动分配出库托盘,如果库内托盘存在数量相加正好等于30,就不要多出,减少分拣返库。

相关策略详见:代码展示   第(3)条

(4)凑整出库,减少分拣返库,每托数量完全为无规律——本方法仅适用于执行样本量小或者出库托数不多的项目

A物料每托的数量可能是10,12,15,18......,很少出现两个托盘数量完全一样的,客户需要要出库30,需要WMS自动分配出库托盘,如果库内托盘存在数量相加正好等于30,就不要多出,减少分拣返库。

相关策略详见:代码展示   第(4)条

二、代码说明

    本人刚从房地产成本转行WMS开发一年多时间,代码用的C#,本次分享完全为个人实战总结,有不足之处欢迎指正,混托分配/入库策略等以后分享。

三、代码展示

(1)业务场景(1)代码实现:

 public void getjiList(List<UnitLoadItem> yangben//库存样本, List<UnitLoadItem> jieguo//分配返回的结果, decimal star//范围下限, decimal end//范围上限, int rongliang//托数, List<UnitLoadItem> zuhe = null)
        {
            foreach (var item in yangben)
            {
                if (jieguo.Count > 0)
                {
                    return;
                }
                if (zuhe == null)
                {
                    zuhe = new List<UnitLoadItem>();
                }
                List<UnitLoadItem> newzuhe = zuhe.ToList();
                newzuhe.Add(item);
                if (newzuhe.Count == rongliang)
                {
                    decimal sum = newzuhe.Sum(x => x.Quantity.Number);
                    if (sum >= star && sum <= end)
                    {
                        jieguo.AddRange(newzuhe);
                    }
                    return;
                }
                List<UnitLoadItem> newyangben = yangben.Where(x => x != item).OrderBy(x => x.UnitLoad.CreatedAt).ToList();
                if (newyangben.Count > 0)
                {
                    getjiList(newyangben, jieguo, star, end, rongliang, newzuhe);
                }
            }

        }

(2)业务场景(2)代码实现:

 public void getziList(List<UnitLoadItem> yangben//库存样本, List<UnitLoadItem> jieguo//返回分配的结果, decimal total//出库总数, decimal wucha//误差 List<UnitLoadItem> zuhe = null)
        {
            foreach (var item in yangben)
            {
                if (jieguo.Count > 0)
                {
                    return;
                }
                if (zuhe == null)
                {
                    zuhe = new List<UnitLoadItem>();
                }
                List<UnitLoadItem> newzuhe = zuhe.ToList();
                newzuhe.Add(item);

                decimal sum = newzuhe.Sum(x => x.Quantity.Number);
                if (sum >= total - wucha && sum <= total)
                {
                    jieguo.AddRange(newzuhe);
                    return;
                }
                List<UnitLoadItem> newyangben = yangben.Where(x => x != item).OrderBy(x => x.UnitLoad.CreatedAt).ToList();
                if (newyangben.Count > 0)
                {
                    getziList(newyangben, jieguo, total, wucha, newzuhe);
                }
            }

        }

(3)业务场景(3)代码实现:

设计思路:有点类似于栈的概念:后如先出,可以兼顾一点先进先出的要求

public void getList2(List<UnitLoadItem> zong//库存样本, List<UnitLoadItem> fen//待分配样本, List<decimal> groupList//样本按数量分组后的KEY集合, List<UnitLoadItem> jieguo//返回的分配结果, decimal xz//迭代用的, decimal total//出库总数, List<UnitLoadItem> zuhe = null)
        {
            foreach (var item in fen)
            {
                if (jieguo.Count > 0)
                {
                    return;
                }
                if (zuhe == null)
                {
                    zuhe = new List<UnitLoadItem>();
                }
                List<UnitLoadItem> newzuhe = zuhe.ToList();

                decimal sum = newzuhe.Sum(x => x.Quantity.Number) + item.Quantity.Number;
                if (sum > total)
                {
                    var index = newzuhe.Count - 1;
                    for (var i = index; i >= 0; i--)
                    {
                        if (newzuhe[i].Quantity.Number != xz)
                        {
                            return;
                        }
                        newzuhe.RemoveAt(i);
                        var newxzzu = groupList.Where(x => x > xz).ToList();
                        if (newxzzu.Count > 0)
                        {
                            var newxz = newxzzu.OrderBy(x => x).FirstOrDefault();
                            var newfen = zong.Where(x => x.Quantity.Number == newxz).OrderBy(x => x.UnitLoad.CreatedAt).ToList();
                            getList2(zong, newfen, groupList, jieguo, newxz, total, zuhe);
                            if (jieguo.Count > 0)
                            {
                                return;
                            }
                        }

                    }

                }
                else if (sum == total)
                {
                    newzuhe.Add(item);
                    jieguo.AddRange(newzuhe);
                    return;
                }
                else
                {
                    zuhe.Add(item);
                }

            }

        }

(4)业务场景(4)代码实现:

提醒:看似最灵活的设计,实际样本量稍微有点大,CPU就完犊子了

 public void getList(List<UnitLoadItem> yangben, List<UnitLoadItem> jieguo, decimal total, List<UnitLoadItem> zuhe = null)
        {
            foreach (var item in yangben)
            {
                if (jieguo.Count > 0)
                {
                    return;
                }
                if (zuhe == null)
                {
                    zuhe = new List<UnitLoadItem>();
                }
                List<UnitLoadItem> newzuhe = zuhe.ToList();
                newzuhe.Add(item);

                decimal sum = newzuhe.Sum(x => x.Quantity.Number);
                if (sum > total)
                {
                    return;
                }
                if (sum == total)
                {
                    jieguo.AddRange(newzuhe);
                    return;
                }
                List<UnitLoadItem> newyangben = yangben.Where(x => x != item).ToList();
                if (newyangben.Count > 0)
                {
                    getList(newyangben, jieguo, total, newzuhe);
                }
            }

        }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值