Python笔记之按订单重量与去向进行拼车运输算法

需求

在TMS模块,对同去向不同客户之间的订单进行拼车以节省运输成本。

算法

使用Python的interval、itertools 进行拼车。

python 复制代码
# -*- codeing = utf-8 -*-
# @File : TMS拼车2.py
# @Author : 一起种梧桐吧
# @Version : Python 3.10.0
# @Software : PyCharm
# @Time : 2023年7月31日
# @Purpose : TMS运输管理系统同路线客户拼车

from interval import Interval
from itertools import combinations

XL = ["东", "西", "南", "北"]
KH = {"客户01": ["东", 100],
	  "客户02": ["东", 150],
	  "客户03": ["东", 190],
	  "客户04": ["东", 250],
	  "客户05": ["南", 160],
	  "客户06": ["南", 170],
	  "客户07": ["南", 200]}
ZZ = {"客户01": {"dd01": 12550, "dd02": 300},
	  "客户02": {"dd03": 11020, "dd04": 11000, "dd05": 1180, },
	  "客户03": {"dd06": 11050, "dd07": 1220, "dd08": 110, },
	  "客户04": {"dd09": 6350, "dd10": 5280},
	  "客户05": {"dd11": 3050, "dd12": 3180},
	  "客户06": {"dd13": 3520, "dd14": 3180},
	  "客户07": {"dd15": 5390, "dd16": 3210}}
CL = {"X": 11500, "D": 13500}


def load_1shop1order(shop: str, zzl_min: float, zzl_max: float):
	'''
	单门店-单订单装车
	:param zzl_min: 最小载重量
	:param zzl_max: 最大载重量
	:return: 满足条件的订单ID
	'''
	zzl_interval = Interval(zzl_min, zzl_max)
	for item in sorted(ZZ[shop].items(), key=lambda x: x[1], reverse=True):
		if item[1] in zzl_interval:
			return item[0], item[1]
		elif item[1] < zzl_min:
			return None
		else:
			continue
	else:
		return None


def load_1shop2order(shop: str, zzl_min: float, zzl_max: float):
	'''
	单门店-多订单装车
	:param zzl_min: 最小载重量
	:param zzl_max: 最大载重量
	:return: 满足条件的订单ID
	'''
	zzl_interval = Interval(zzl_min, zzl_max)
	dct_order = ZZ[shop]
	if sum(dct_order.values()) in zzl_interval:
		return tuple(dct_order.keys()), sum(dct_order.values())
	elif sum(dct_order.values()) <= zzl_min:
		return None
	else:
		lst_order = []
		for key, value in dct_order.items():
			if value <= zzl_max:
				lst_order.append(key)
		lst_comb = []
		for i in range(1, len(lst_order) + 1):
			lst_comb.extend(combinations(lst_order, i))
		dct_comb = {}
		for order_comb in lst_comb:
			zl_order_comb = 0
			for order in order_comb:
				zl_order_comb += dct_order[order]
			if zl_order_comb in zzl_interval:
				dct_comb.update({order_comb: zl_order_comb})
		for item in sorted(dct_comb.items(), key=lambda x: x[1], reverse=True):
			if item[1] in zzl_interval:
				return item[0], item[1]
			elif item[1] < zzl_min:
				return None
			else:
				continue
		else:
			return None


def load(truck=CL):
	'''
	根据卡车装载量进行自动装载
	:param truck: 卡车信息
	:return: 满足条件的订单ID
	'''
	zzl_min = truck["X"]
	zzl_max = truck["D"]
	zzl_interval = Interval(zzl_min, zzl_max)
	dct_order = {}
	for item in ZZ.values():
		dct_order.update(item)
	# step_01:尝试单店单订单装载
	lst_order1 = []
	for shop in ZZ.keys():
		res = load_1shop1order(shop, zzl_min, zzl_max)
		if res:
			lst_order1.append(res)
	# print(lst_order1)
	dct_order_load1 = {}
	for item_comb in lst_order1:
		if item_comb:
			dct_order_load1.update({item_comb[0]: item_comb[1]})
	if dct_order_load1:
		for key, value in sorted(dct_order_load1.items(), key=lambda x: x[1], reverse=True):
			# return key, value
			print("step_01", key, value)
	# step_02:尝试单店多订单装载
	lst_order2 = []
	for shop in ZZ.keys():
		res = load_1shop2order(shop, zzl_min, zzl_max)
		if res:
			lst_order2.append(res)
	# print(lst_order2)
	dct_order_load2 = {}
	for item_comb in lst_order2:
		if item_comb:
			dct_order_load2.update({item_comb[0]: item_comb[1]})
	if dct_order_load2:
		for key, value in sorted(dct_order_load2.items(), key=lambda x: x[1], reverse=True):
			# return key, value
			print("step_02", key, value)
	# step_03:尝试2店拼订单装载(由远及近)
	dct_shop_03 = {}
	zzl_interval_03 = Interval(zzl_min * 0.5, zzl_max * 0.75)
	for shop in ZZ.keys():
		zzl_shop = sum(ZZ[shop].values())
		if zzl_shop in zzl_interval_03:
			dct_shop_03[shop] = zzl_shop
	for key03, value03 in sorted(dct_shop_03.items(), key=lambda x: x[1], reverse=True):
		zzl_interval_new_03 = Interval(value03 * 0.33, value03) & Interval(zzl_min - value03, zzl_max - value03)
		if not zzl_interval_new_03:
			continue
		[qx03, yj03] = KH[key03]
		lst_shop_03_02 = []
		for shop03_02, qxyj03_02 in KH.items():
			if (qxyj03_02[0] == qx03) & (yj03 - qxyj03_02[1] in Interval(0, 50, lower_closed=False)):
				lst_shop_03_02.append(shop03_02)
		if not lst_shop_03_02:
			continue
		else:
			lst_order03 = []
			for shop02 in lst_shop_03_02:
				res = load_1shop2order(shop02, zzl_interval_new_03.lower_bound, zzl_interval_new_03.upper_bound)
				if res:
					lst_order03.append(res)
			if not res:
				continue
			dct_order_load03 = {}
			for item_comb in lst_order03:
				if item_comb:
					dct_order_load03.update({item_comb[0]: item_comb[1]})
			if dct_order_load03:
				for key03_02, value03_02 in sorted(dct_order_load03.items(), key=lambda x: x[1], reverse=True):
					lst_order_shop = list(ZZ[key03].keys())
					for order in key03_02:
						lst_order_shop.append(order)
					# return key, value
					print("step_03", tuple(lst_order_shop), value03_02 + value03)
	# step_04:尝试2店拼订单装载(由近到远)
	dct_shop_04 = {}
	zzl_interval_04 = Interval(zzl_min * 0.25, zzl_max * 0.5)
	for shop in ZZ.keys():
		zzl_shop = sum(ZZ[shop].values())
		if zzl_shop in zzl_interval_04:
			dct_shop_04[shop] = zzl_shop
	for key04, value04 in sorted(dct_shop_04.items(), key=lambda x: x[1], reverse=True):
		# print(Interval(value * 0.33, value), Interval(zzl_min - value, zzl_max - value))
		zzl_interval_new_04 = Interval(value04, value04 * 3) & Interval(zzl_min - value04, zzl_max - value04)
		if not zzl_interval_new_04:
			continue
		[qx04, yj04] = KH[key04]
		lst_shop_04 = []
		for shop04_02, qxyj04_02 in KH.items():
			if (qxyj04_02[0] == qx04) & (qxyj04_02[1] - yj04 in Interval(0, 50, lower_closed=False)):
				lst_shop_04.append(shop04_02)
		if not lst_shop_04:
			continue
		else:
			lst_order04 = []
			for shop04_02 in lst_shop_04:
				res = load_1shop2order(shop04_02, zzl_interval_new_04.lower_bound, zzl_interval_new_04.upper_bound)
				if res:
					lst_order04.append(res)
			# print(lst_order04)
			dct_order_load04 = {}
			for item_comb in lst_order04:
				if item_comb:
					dct_order_load04.update({item_comb[0]: item_comb[1]})
			if dct_order_load04:
				for key04_02, value04_02 in sorted(dct_order_load04.items(), key=lambda x: x[1], reverse=True):
					lst_order_shop = list(ZZ[key04].keys())
					for order in key04_02:
						lst_order_shop.append(order)
					# return key, value
					print("step_04", tuple(lst_order_shop), value04_02 + value04)


if __name__ == "__main__":
	load()
相关推荐
橘子编程26 分钟前
Python-Word文档、PPT、PDF以及Pillow处理图像详解
开发语言·python
蓝婷儿42 分钟前
Python 机器学习核心入门与实战进阶 Day 2 - KNN(K-近邻算法)分类实战与调参
python·机器学习·近邻算法
森焱森1 小时前
无人机三轴稳定化控制(1)____飞机的稳定控制逻辑
c语言·单片机·算法·无人机
循环过三天1 小时前
3-1 PID算法改进(积分部分)
笔记·stm32·单片机·学习·算法·pid
闪电麦坤951 小时前
数据结构:二维数组(2D Arrays)
数据结构·算法
之歆1 小时前
Python-封装和解构-set及操作-字典及操作-解析式生成器-内建函数迭代器-学习笔记
笔记·python·学习
凌肖战1 小时前
力扣网C语言编程题:快慢指针来解决 “寻找重复数”
c语言·算法·leetcode
埃菲尔铁塔_CV算法2 小时前
基于 TOF 图像高频信息恢复 RGB 图像的原理、应用与实现
人工智能·深度学习·数码相机·算法·目标检测·计算机视觉
天天爱吃肉82182 小时前
ZigBee通信技术全解析:从协议栈到底层实现,全方位解读物联网核心无线技术
python·嵌入式硬件·物联网·servlet
Allen_LVyingbo3 小时前
Python常用医疗AI库以及案例解析(2025年版、上)
开发语言·人工智能·python·学习·健康医疗