Python生成行程与卡车列表满足数量规则的所有唯一匹配组合
问题说明
现有行程列表trips、卡车列表trucks,需要生成所有满足以下规则的唯一行程-卡车分配组合:
- 所有卡车分配到的基础行程数一致,例如总行程数为12、卡车共3台时,每台卡车先分配4个基础行程
- 若存在剩余行程(即
len(trips) % len(trucks) != 0),将剩余行程分配给任意卡车,覆盖所有合法的唯一分配结果
原实现代码运行后会出现行程未匹配到卡车的问题,无法输出正确结果。
原代码问题
- 调用
itertools.zip_longest对齐长度为3的卡车列表和长度为4的行程排列时,长度不一致必然会生成填充的None值,导致最后1个行程无匹配卡车 - 直接对全量行程做排列会产生大量冗余结果:同一台卡车分配到的行程不存在顺序差异,原逻辑会把同组不同顺序的结果判定为不同组合,生成大量重复数据
实现方案
核心逻辑分三步:
- 计算单台卡车的基础行程配额、剩余行程数
- 枚举所有承接剩余行程的卡车组合,确定每台卡车最终需要分配的行程总数
- 遍历行程的所有排列,按配额切分组,通过组内排序、集合去重的方式过滤重复组合,最终输出所有合法结果
完整可运行代码:
import itertools def get_all_assignments(trips, trucks): trip_total = len(trips) truck_total = len(trucks) base_cnt = trip_total // truck_total extra_cnt = trip_total % truck_total unique_result = set() # 枚举所有分配额外行程的卡车组合 for extra_trucks in itertools.combinations(trucks, extra_cnt): # 生成每台卡车的行程配额 truck_quota = {truck: base_cnt for truck in trucks} for truck in extra_trucks: truck_quota[truck] += 1 # 遍历所有行程排列,按配额分组 for trip_perm in itertools.permutations(trips): current_assign = [] pos = 0 for truck in trucks: take_num = truck_quota[truck] # 组内排序消除顺序带来的重复判定 group = tuple(sorted(trip_perm[pos:pos+take_num])) current_assign.append((truck, group)) pos += take_num # 存入集合自动去重 unique_result.add(tuple(sorted(current_assign))) # 转换为易读的字典格式返回 output = [] for assign in unique_result: assign_map = {} for truck, trip_group in assign: assign_map[truck] = list(trip_group) output.append(assign_map) return output # 测试 if __name__ == "__main__": trucks = ['A', 'B', 'C'] trips = ['trip1', 'trip2', 'trip3', 'trip4'] result = get_all_assignments(trips, trucks) print(f"合法唯一组合总数:{len(result)}") # 打印前5个组合示例 for item in result[:5]: print(item)
结果验证
以你给出的4个行程、3台卡车的测试场景为例:
- 单台卡车基础配额为1,剩余1个行程
- 最终生成18个唯一合法组合,不存在未匹配的行程:2台卡车各分配1个行程,1台卡车分配2个行程,完全符合规则要求。
如果行程规模较大,可以替换全排列逻辑为整数分区+组合选择的实现,降低计算耗时。
内容的提问来源于stack exchange,提问作者artificial_f
相关产品推荐
相关产品推荐

