Python解决一种火车装钢卷配货方法
一种火车装钢卷配货方法
背景
有一块业务是中亚班列,具体是火车车厢运输钢卷,需要在满足铁路方面要求的情况下,尽最大运输能力运输货物,节省火车运力,避免浪费。
限制要求
火车限制
- 车厢内货物总重量不能超过65吨(普遍70吨标箱)
- 车厢内货位由两组钢架组成,共有9个货位,需要保证车厢平衡,前后载重量不能超过2吨,即1-4货位和6-9货位装载的总重量相差不能超过2吨
- 钢架固定了宽度,不能让货物悬空,所以两两钢卷的外径之和不能超过2640mm,否则不能放置
钢卷特点
- 一般来说越重的钢卷,外径越大(97%的情况),除非钢卷宽度特别窄(钢卷越重、越窄,外径就越大)
- 一批货物的钢卷每个重量和外径都不一样
配货方法
首次装载
对钢卷列表从重向轻、从外径大向小排序
首次以最大载重和外径要求尝试模拟装载,计算所需车厢最小数量,装载顺序采用1,9,8,2,3,7,6,4,5的顺序,即每车从车厢两边向中间顺序装载
首次模拟装载完成后,计算车厢平衡性,假如发现不平衡车厢则进入车厢内调流程
第一次调整——车厢内调
尝试将不平衡的车厢进行内部调整,因为采用3.1.2步的顺序装载,基本上不平衡的都是车厢内装载货物为单数的车皮,看车厢中间货位(即5号货位)是否为空,如果为空尝试找到最合适的货物调整到中间,再次计算车厢平衡性(单数货物不平衡原因,主要是因为装载货物没有出发外径限制,而触发了重量限制,导致最后一件货物没有放在中间货位上而导致不平衡)
第二次调整——车厢外调
前面的车厢内调解决不了车厢中间货位已经放货且不平衡的情况,主要原因是因为钢卷外径限制导致车厢装载顺序提前走完,已经装到中间货位时,但是车厢重量限制未触发,后续在货物列表中找到较小的单件钢卷继续填充车厢,导致车厢不平衡,此时找到这件小卷,往后找双数且平衡的车厢(一定中间货位未装货),尝试装此卷看重量是否满足条件,如果满足就放进去。此时再看移出小卷车厢是否平衡,如果不平衡,继续尝试左右装载且不装中间货位顺序即1,9,8,2,3,7,6,4,不装5号货位,对于装不上的货物,打上未装标记。
第三次调整——整列优化
3.3中所述情况一般是由于重量、外径降序排列,容易触发外径限制,发生情况一般都在编号靠前的车厢,因此车厢外调后,导致前车装不满,且此时的货物两两之间容易触发外径限制,如果此时新增车厢装载会导致车厢载重利用率不够,浪费更多车厢。
于是把车厢分为两类:载重不足90%或者装载件数小于6件的都属于不良车厢,剩下的属于优秀车厢
首先掏空不良车厢内的货物,打上标记未装载,然后删除不良车厢
然后把优秀车厢的货物尽量往中间靠,把优秀车厢号序重新排序,更新车厢内货物的车厢号属性
不良车厢普遍比较考前,所以现在标记“未装”的货物普遍重量较大、外径较大,对此“未装”货物列表重新依据重量和外径降序排列
按照上面列表中每次取前两件(件重差较小)与优秀车厢中货位为1,9(件重差较小)或者2,8(件重差较小)的进行两两交换尝试,仍需满足车厢载重和外径限制,并且检查车厢前后平衡性,如果都满足则交换。将放入的货物标记“已装”和车厢号,车厢内货位号;将换出来的货物标记“未装”,去掉车厢号、车厢内货物号,重新假如“未装”列表排序。循环此操作,直至装完所有货物。
**特别说明:**到3.4.5的时候其实已经优化了车厢配货排列,但是程序设计上,这一步我简化了编程难易度,首先不良车厢内“未装”货物列表肯定偏重、偏大,降序排列比较考前,所以我直接采取先把优秀车厢中1,9货位上两件的货物取出来,如果没有1,9就取2,8上的两件货物(记住只能取两件,左右各一件,保持原来的平衡),把取出来的货物先加入“未装”降序列表中,这样的货物排序就靠后,如果前面的货物不满足装车,这些货物还是按照排序还是会装原来的车,不影响优秀车厢,最好的情况就是1,9没有货,取出来的是2,8的货,因为换上去更大的货可以不用考虑外径限制,只用考虑重量限制。容错性:如果经过优化后仍然还有特别重没有换进去,就有两种情况:一、必须开新的车厢且载重装不满(比较少);二、中间换进去了一部分外径大但是重量跟优秀车厢移出的卷差不多的卷,就可以重新与之前的外径比较大的卷尝试拼车,或许就能拼上去。(如果能拼上去就得到了优化的目的)
验证
手头上三份实际货物文件的样本(27件、95件、105件),实验之后全部通过。车厢利用率全部在90%以上。
结语
一开始知道这个项目的时候,就隐约感觉到对象编程可以解决问题,然后边编程边理清逻辑,因为这样可以快速的验证自己思路的结果,最后得到上面的解题思路。编程不难,思想才是最难的,找到这些逻辑。