物流路由线路配载前端算法逻辑实现方案
作者 | 京东云开发者-京东物流 柳宏
原文链接:https://my.oschina.net/u/4090830/blog/8652549
1. 前置知识
1.1 基本概念
1.1.1 配载
配载代表着某条线路是否具有发往某个方向(区域、省市县、分拣等)的能力,也可以说是网点(分拣中心)是否具有承载配载所指方向货物的能力。一般网络规划者,在均衡线路间货量时,会通过调整配载来完成。
线路上可允许配载货物的 “产品类型、最终妥投目的地”,通过线路的配载,计算 当前网点 到 目的网点 的 下一个网点 ,线路 绑定的配载代表通过当前线路最终可以到达的目的地 。以下图为例
表示:如果放置在整个路由网络资源中,一个标记 T1 的货物要从北京发往福建,可选的路由有①北京站 - 北京 - 武汉 - 福建 - 福建站;②北京站 - 北京 - 广州 - 福建 - 福建站;之所以剔除了北京站 - 北京 - 上海 - 福建 - 福建站以及北京站 - 北京 - 武汉 - 上海 - 福建 - 福建站,正是因为后两条线路中未包含 T1 的配载代码,只标记了 T2 , 说明这条线路只有配载航空的货物,而没有普通陆运的带货能力。
下图就是用于描述配载的树形结构
1.1.2 班期与生失效日期
班期:指的是发运频率,1234567 代表着每周七天中,这个班次的 “上线时间”,一般来讲,维护时缺失某个值,会造成路由中断的现象。
生失效日期:指的是该配载有效时间范围
1.1.3 配载合并逻辑
网点四级地址的关系以配载树的形式展现,勾选节点添加的配载在右侧的配载列表中展示
当某个节点的子节点没有全部勾选时,展示当前勾选的节点到配载列表中
当某个节点的子节点全部勾选时(在符合相关条件时,这里涉及到的算法逻辑后面详述),展示相应的父节点到配载列表中,这个逻辑是递归的
1.2 现有实现技术
2. 现状问题
2.1 节点合并算法逻辑有误
如果一个父节点下的所有子节点都被维护,即使子节点下的班期不同、生失效日期不重叠,系统都会自动合并到父节点。合并的展示效果为:
班期:对于纯新增配载显示 1234567;对于父节点下有一个子节点,班期显示为已存在配载的班期
生失效时间:统一为该切段线路的生失效日期
例如:X 线路被切割成两段,2022-11-02~2023-01-25 以及 2022-01-26~ 长久有效两段,在线路视图点击 2022-11-02~2023-01-25 这段的配载维护,X 下有 A1(配载时间为 2022-11-02~ 长久有效、班期 12),其父节点为 A,A 下还有子节点 A2、A3。今天是 11.17 日,将 A2、A3 都勾选上(时间任意,班期为 12345),配载会立刻合并为 A(生效时间 2022-11-02~2023-01-25,配载 1234567)
线路X
生效时间 失效时间
2022-11-02 2023-01-25
A(父节点):包含A1、A2、A3三个子节点,当前只存在A1的配载如下:
生效时间 失效时间 班期
A1 2022-11-02 2099-12-31 12
参考日期为11.17日,此时勾选A2+A3后触发A的合并,此时配载列表展示A节点
生效时间 失效时间 班期
A 2022-11-02 2023-01-25 1234567
2.2 配载保存和显示的值不一致
上面操作触发合并,提交后库中保存的配载记录为:
生效时间 失效时间 班期
A1 2022-11-02 2022-11-16 12
A 2022-11-17 2023-01-25 1234567
2.3 本质原因
原有根据 zTree 节点触发合并的算法有问题,不考虑当前节点下其他子节点的配载的班期和生失效日期,而是根据是否同一个父节点直接合并。导致合并逻辑错误,保存与展示的数据不一致。
3. 预期效果
3.1 配载合并班期逻辑
条件:同一个父节点 + 各个子节点班期一致
A(父节点):包含A1、A2、A3三个子节点,其中任意节点的班期不一致都无法合并
3.2 配载生失效日期切断逻辑
新添加节点,生效日期 为 参考日期,失效日期 为 线路失效日期
参考日期选择 大于 当前 同级子节点的某天,当触发合并时
合并后的父节点:生效日期取参考日期,失效时间取 同级子节点列表中失效时间最小的
合并后的子节点:
针对同一个节点的配载生失效日期切断的逻辑,举例
1. 配载A的原始生失效时间为 20221103 - 20221110
2. 配载A在经过同级子节点合并后,生失效时间为 20221105-20221108
3. 那么对于配载A来说,在合并后仍然需要保留两段配载记录
3.1 生失效时间为 20221103-20221104
3.2 生失效时间为 20221109-20221110
3.3 配载合并后保存逻辑
4. 实现逻辑
4.1 整体逻辑
4.2 定义数据结构及初始化
zTree:配载树
treeNode:配载树中的节点
nodeId:节点id
childrenNodes:包含当前节点的所有子节点集合
stowageList:配载列表的Dom结构
originStowageMapTI:原始配载:{key:节点;value:配载数据的dom结构}
newStowageMapTI:新增节点配载:{key:节点id;value:节点}
stowageFrequencyMap:配载节点和班期关系:{key:节点id;value:班期}
stowageTimeMap:配载节点和生失效日期关系:{key:节点id;value:[生效时间,失效时间]}
frequencyTreeMap:班期和节点的关系:{key:班期;value:节点数组}
node.pid:节点的父id
node.id:节点的id
4.3 配载合并班期逻辑
配载树中的网点关系主要是四级,举例说明 C(快递全国) 下面某些节点的level 与 pid 的关系
level=1
pid:C 表示全国
level=2
pid:C-10 表示华南
level=3
pid:C-10-16 表示福建
level=4
pid:C-10-16-1303 表示泉州
算法逻辑:根据pid截取相应的字符串为key,查找是否存在父节点的班期
4.4 配载生失效日期切断逻辑
1. queryTime:参考日期
2. maxDisableTime:最大失效时间
3. enableTime:线路生效时间
4. disableTime:线路失效时间
5. originEnableTime:记录原始生效时间
6. originDisableTime:记录原始失效时间
7. newDisableTime :enableTime - 24 * 60 * 60 * 1000
8. newEnableTime:disableTime + 24 * 60 * 60 * 1000
遍历 originStowageMapTI ,判断历史的配载节点是否需要进行日期切断,分为以下两种情况;然后根据节点 id 删除 originStowageMapTI
如果 originEnableTime < enableTime:添加新的配载记录,生效时间取 originEnableTime, 失效时间取 newDisableTime
如果 originDisableTime > disableTime:添加新的配载记录,生效时间取 newEnableTime, 失效时间取 originDisableTime
遍历 newStowageMapTI ,判断新添加的节点是否需要进行日期切断;然后根据节点 id 删除 newStowageMapTI
如果 originDisableTime > disableTime:添加新的配载记录,生效时间取 newEnableTime, 失效时间取 originDisableTime
5. 总结
END
微软开发快速「结束进程」功能
🌟 活动推荐
2023 年 5 月 27-28 日,GOTC 2023 全球开源技术峰会将在上海张江科学会堂隆重举行。
为期 2 天的开源行业盛会,将以行业展览、主题发言、特别论坛、分论坛、快闪演讲的形式来诠释此次大会主题 ——“Open Source, Into the Future”。与会者将一起探讨元宇宙、3D 与游戏、eBPF、Web3.0、区块链等热门技术主题,以及 OSPO、汽车软件、AIGC、开源教育培训、云原生、信创等热门话题,探讨开源未来,助力开源发展。
长按识别下方二维码立即查看 GOTC 2023 详情/报名。
微信扫码关注该文公众号作者