zoukankan      html  css  js  c++  java
  • 快递、拆分、合并、优选逻辑

      

    需求:

    • 根据规则 分配 物品到不同的包裹里。
    • 有些可以放在同一包裹有一些不能。
    • 可以发同一物流的可以放到一个包裹,不同物流的包裹有不同的重量限制(也有可能没有限制)、某些物品在某些物流渠道有单个包裹同种物品的数量限制。

    比如跨境物流危险品限制:

    危险品类型:配套电、内置电、纯电、移动电源(外置电)、强磁、弱磁、液体、膏体、指甲油、假发、喷雾、粉末、种子、唇彩、唇膏、面膜、指甲胶
    1107 - 飞特泰邮:内置电、膏体(单个包裹不超一个)、粉末(单个包裹不超一个)、种子、唇彩、唇膏、面膜、指甲胶 1106 - 快飞鱼敏感货K邮宝:配套电、液体(单个包裹不超一个)、指甲油(单个包裹不超两个) 1100 - 快飞鱼荷邮敏感货:配套电、纯电、移动电源(外置电)、液体(单个包裹不超四个)、指甲油(单个包裹不超三个)、喷雾(单个包裹不超两个) 1051 - 递四方新加坡小包:内置电、弱磁 1034 - 出口易荷兰小包:内置电、弱磁 1040 - 出口易大陆E邮宝:假发 1029 - 出口易省外E邮宝:假发 1026 - 出口易大陆DHL:假发 3 - DHL:假发 19 - 新加坡DHL:假发

    要求:

    运费最低。(根据物品的重量和订单信息可以预估运费。)

    求 最佳分包。

    思路:

    1、穷举所有规则。

    2、穷举所有适配规则的物品(我叫这个是 成包策略 g2p 策略)

    • 按重量拆分。(也存在一套穷举优选的逻辑在,和策略优选的逻辑差不多)

    3、穷举所有策略组合。

    • 过滤组合中所有物品和订单物品不匹配的组合。

    4、转换为【策略组】组合。(既【策略】组合 变成 【策略组】组合)策略组 指 同渠道的策略。设 策略为 A 、策略组为 B{ A[] } 有 A[]  =>  B[]   其中 All A  In B[]  =  All A in A[] 。

    5、策略组 快递竞价。每一个策略组 计算其中所有物品的重量 ,然后计算运费。

    6、优选【策略组组合】。全部物品总运费最低的 策略组组合。

    7、一个策略组 成一个包。

    穷举所有组合的函数:

    public static List<T[]> GetAllComb<T>(T[] arr, Func<T[], bool> filter)
            {
                var res = new List<T[]>();
                int nCnt = arr.Length;
                //int nBit = (0xFFFFFFFF >>> (32 - nCnt));  
                int nBit = 1 << nCnt;
                for (int i = 1 ; i <= nBit ; i++)
                {
                    var item = new List<T>();
                    for (int j = 0 ; j < nCnt ; j++)
                    {
                        if ((i << (31 - j)) >> 31 == -1)
                        {
                            item.Add(arr[j]);
                        }
                    }
    
                    T[] itemArr = item.ToArray();
                    if (filter != null)
                    {
                        if (filter(itemArr))
                        {
                            res.Add(itemArr);
                        }
                    }
                    else
                    {
                        res.Add(itemArr);
                    }
                }
                return res;
            }

    物品根据重量拆分优选代码:

        //超重拆分生成多个策略。默认的拆分的策略是单包 1900g。
        /// <summary>
        /// 物品超重拆分策略
        /// 默认步长是 1900g
        /// 按最小包裹数优先拆分
        /// </summary>
        public class GoodsOverLoadSpiltStrategy
        {
            private const int SPLITSTEP = 1900;
            private int splitStep;
    
            public GoodsOverLoadSpiltStrategy(int splitStep = SPLITSTEP)
            {
                this.splitStep = splitStep;
            }
    
            internal List<Purchase_Goods[]> Spilt(List<Purchase_Goods> goodsList)
            {
                var newPackage = new List<Purchase_Goods>();
    
                //从所有【物品中】获取所有小于 1900 的组合
                var combs = CombinationAlgorithm.GetAllComb(goodsList.ToArray(), goods =>
                {
                    return goods.Sum(m => m.Weight) <= 1900;
                });
    
                //从所有【1900 组合中】获取等于总物品的组合
                var res = CombinationAlgorithm.GetAllComb(combs.ToArray(), comb =>
                {
                    var list = comb.SelectMany(m => m).ToList();
                    return list.All(goodsList.Contains) && list.Count == goodsList.Count;
                });
    
                //返回最佳组合
                return res.OrderByDescending(m => m.Count()).FirstOrDefault().ToList();
    
            }
    
    
        }

    还有一些其他逻辑不是通用的就不贴了,花了一天时间才写完。。。还没有来及测试。

     参考:背包问题

  • 相关阅读:
    「LuoguP1627 / T36198」 [CQOI2009]中位数
    「LuoguT36048」 Storm in Lover
    「LuoguP3252」 [JLOI2012]树
    「LuoguP2170」 选学霸(01背包
    「LuoguP3191」 [HNOI2007]紧急疏散EVACUATE(最大流
    「网络流24题」「LuoguP2774」方格取数问题(最大流 最小割
    「LuoguP3381」【模板】最小费用最大流
    ACTIVEMQ主题、队列设置用户名密码
    activemq消息生产者与消息消费者简单例子
    ActiveMQ使用线程池实现消息的生产与消费
  • 原文地址:https://www.cnblogs.com/zhuwansu/p/10187051.html
Copyright © 2011-2022 走看看