如何用Python将电力负载列表分配为三组,实现总和近似均衡?
三相负载最优分配算法(支持任意长度列表)
针对三相负载平衡问题,普通贪心算法只关注当前每相的最小总和,容易在大负载后分配时导致全局失衡。下面提供两种实用方案,适配现场任意长度的负载列表:
方案一:排序+回溯剪枝(适合中小规模负载)
核心思路:先把负载从大到小排序,优先分配大负载(避免最后大负载无法合理放置),再通过回溯尝试所有可能的分配方式,同时用剪枝跳过明显不可能更优的分支,保证效率。
代码实现
def three_phase_balance(loads): # 按负载从大到小排序,优先处理大负载 sorted_loads = sorted(loads, reverse=True) total = sum(sorted_loads) ideal = total / 3 # 理想每相功率 best_diff = float('inf') # 记录最优的三相最大差 best_assignment = [[], [], []] # 记录最优分配结果 def backtrack(index, phases): nonlocal best_diff, best_assignment # 所有负载分配完成,计算当前偏差 if index == len(sorted_loads): sums = [sum(p) for p in phases] current_diff = max(sums) - min(sums) # 更新最优解 if current_diff < best_diff: best_diff = current_diff best_assignment = [p.copy() for p in phases] return current_load = sorted_loads[index] # 遍历三个相,尝试分配当前负载 for i in range(3): # 剪枝:当前相加负载后与理想值的差距过大,直接跳过 if sum(phases[i]) + current_load - ideal > best_diff / 2: continue # 去重优化:相邻两相总和相同,跳过重复分配 if i > 0 and sum(phases[i]) == sum(phases[i-1]): continue # 分配负载并递归 phases[i].append(current_load) backtrack(index + 1, phases) phases[i].pop() # 初始化三相,开始回溯 backtrack(0, [[], [], []]) phase_sums = [sum(p) for p in best_assignment] return { "R相": {"负载列表": best_assignment[0], "总功率": phase_sums[0]}, "S相": {"负载列表": best_assignment[1], "总功率": phase_sums[1]}, "T相": {"负载列表": best_assignment[2], "总功率": phase_sums[2]}, "最小偏差": best_diff, "理想每相功率": round(ideal, 2) } # 测试示例负载 loads = [2000, 2500, 1500, 1700, 5500, 3000, 1200, 1300, 1600, 2700] result = three_phase_balance(loads) print("分配结果:") for phase, data in result.items(): if isinstance(data, dict): print(f"{phase}:") print(f" 负载列表: {data['负载列表']}") print(f" 总功率: {data['总功率']}W") else: print(f"{phase}: {data}")
代码说明
- 排序优先:先处理大负载,避免最后大负载只能加到某一相导致失衡。
- 剪枝逻辑:跳过明显无法缩小偏差的分配路径,大幅减少计算量。
- 去重优化:避免重复计算相同分配逻辑的分支,提升效率。
方案二:改进版贪心(适合大规模负载)
如果负载数量很大(比如上百个),回溯法效率太低,可以用改进版贪心:
- 先把负载从大到小排序。
- 每次将当前负载分配到与理想值差距最大的相(而非当前总和最小的相),优先补充欠载的相。
代码实现
def improved_greedy_three_phase(loads): sorted_loads = sorted(loads, reverse=True) total = sum(sorted_loads) ideal = total / 3 phases = [[], [], []] for load in sorted_loads: # 计算每个相与理想值的差距,差距越大越需要补充负载 gaps = [ideal - sum(p) for p in phases] # 找到最需要补充的相 target_phase = gaps.index(max(gaps)) phases[target_phase].append(load) phase_sums = [sum(p) for p in phases] return { "R相": {"负载列表": phases[0], "总功率": phase_sums[0]}, "S相": {"负载列表": phases[1], "总功率": phase_sums[1]}, "T相": {"负载列表": phases[2], "总功率": phase_sums[2]}, "偏差": max(phase_sums) - min(phase_sums), "理想每相功率": round(ideal, 2) } # 测试示例 loads = [2000, 2500, 1500, 1700, 5500, 3000, 1200, 1300, 1600, 2700] result = improved_greedy_three_phase(loads) print("\n改进版贪心分配结果:") for phase, data in result.items(): if isinstance(data, dict): print(f"{phase}:") print(f" 负载列表: {data['负载列表']}") print(f" 总功率: {data['总功率']}W") else: print(f"{phase}: {data}")
总结
- 中小规模负载(≤30个):用排序+回溯剪枝,能找到最优解。
- 大规模负载:用改进版贪心,效率高,结果接近最优。
内容的提问来源于stack exchange,提问作者Adrian Cabrera Duarte
相关产品推荐
相关产品推荐

