diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..bea26b7 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python Debugger: Current File with Arguments", + "type": "debugpy", + "request": "launch", + "program": "main.py", + "console": "integratedTerminal", + "args": "--excel abc.xlsx" + }, + ] +} diff --git a/gui.py b/gui.py index 75564af..33848e6 100644 --- a/gui.py +++ b/gui.py @@ -781,8 +781,12 @@ def index(): total_length_m = sum(d["length"] for d in res["eval"]["details"]) total_length_km = total_length_m / 1000 + # 获取回路数 (通过统计从升压站发出的连接) + n_circuits = sum(1 for d in res["eval"]["details"] if d["source"] == "substation" or d["target"] == "substation") + row_dict = { "name": name_display, + "n_circuits": n_circuits, "cost_wan": f"{res['cost'] / 10000:.2f}", "loss_kw": f"{res['loss']:.2f}", "total_length": f"{total_length_km:.2f}", @@ -938,6 +942,12 @@ def index(): "required": True, "align": "left", }, + { + "name": "n_circuits", + "label": "回路数", + "field": "n_circuits", + "sortable": True, + }, { "name": "cost_wan", "label": "总投资 (万元)", diff --git a/main.py b/main.py index dd3cb34..69403df 100644 --- a/main.py +++ b/main.py @@ -655,38 +655,20 @@ def design_with_rotational_sweep( return final_connections, turbines -def get_max_cable_capacity_mw( - cable_specs=None, voltage=VOLTAGE_LEVEL, power_factor=POWER_FACTOR -): +# 4. 获取电缆最大容量(MW) +def get_max_cable_capacity_mw(cable_specs, voltage=VOLTAGE_LEVEL, power_factor=POWER_FACTOR): """ - 计算给定电缆规格中能够承载的最大功率 (单位: MW)。 - - 基于提供的电缆规格列表,选取最大载流量,结合系统电压和功率因数计算理论最大传输功率。 - - 参数: - cable_specs (list, optional): 电缆规格列表。每个元素应包含 (截面积, 额定电流, 单价, 损耗系数)。 - voltage (float): 系统电压 (V), 默认 66000 - power_factor (float): 功率因数, 默认 0.95 - - 返回: - float: 最大功率承载能力 (MW)。 - - 异常: - Exception: 当未提供 cable_specs 时抛出,提示截面不满足。 + 根据电缆规格计算最大承载功率 + :param cable_specs: 电缆规格列表 list of tuples,或者直接是最大功率数值(MW) """ - if cable_specs is None: - # Default cable specs if not provided (same as in evaluate_design) - cable_specs = [ - (35, 150, 0.524, 80), - (70, 215, 0.268, 120), - (95, 260, 0.193, 150), - (120, 295, 0.153, 180), - (150, 330, 0.124, 220), - (185, 370, 0.0991, 270), - (240, 425, 0.0754, 350), - (300, 500, 0.0601, 450), - (400, 580, 0.0470, 600), - ] + # 如果传入的已经是数值,直接返回 + if isinstance(cable_specs, (int, float, np.number)): + return float(cable_specs) + + # 兼容性检查:如果列表为空 + if not cable_specs: + print("Warning: 没有可用的电缆规格,使用默认最大容量 100MW") + return 100.0 # 从所有电缆规格中找到最大的额定电流容量 max_current_capacity = max(spec[1] for spec in cable_specs) @@ -1009,10 +991,12 @@ def export_to_excel(connections_details, filename): df = pd.DataFrame(data) # 汇总统计 + n_circuits = sum(1 for conn in connections_details if conn["source"] == "substation" or conn["target"] == "substation") summary = { "Total Cost (¥)": df["Cost (¥)"].sum(), "Total Effective Length (m)": df["Effective Length (m)"].sum(), "Total Vertical Length (m)": df["Vertical Length (m)"].sum(), + "Number of Circuits": n_circuits, } summary_df = pd.DataFrame([summary]) @@ -1038,15 +1022,14 @@ def export_all_scenarios_to_excel(results, filename): # 1. 总览 Sheet summary_data = [] for res in results: - # 获取回路数 - n_circuits = 0 - if "turbines" in res and "cluster" in res["turbines"].columns: - n_circuits = res["turbines"]["cluster"].nunique() + # 获取回路数 (通过统计从升压站发出的连接) + n_circuits = sum(1 for conn in res["eval"]["details"] if conn["source"] == "substation" or conn["target"] == "substation") summary_data.append( { "Scenario": res["name"], "Total Cost (¥)": res["cost"], + "总费用(万元)": res.get("total_cost_npv", res["cost"]) / 10000, "Total Loss (kW)": res["loss"], "Num Circuits": n_circuits, # 计算电缆统计 @@ -1413,14 +1396,10 @@ def compare_design_methods( print(f" 最大电缆容量: {max_cable_mw:.2f} MW") - # --- Run 1: Base Algorithm (Capacitated Sweep) --- + # --- Run 1: Base Sector Sweep --- base_name = f"{name} (Base)" conns_base, turbines_base = design_with_capacitated_sweep( - turbines.copy(), - substation, - cable_specs=current_specs, - voltage=voltage, - power_factor=power_factor, + turbines.copy(), substation, max_cable_mw, voltage=voltage ) eval_base = evaluate_design( turbines, @@ -1432,7 +1411,7 @@ def compare_design_methods( voltage=voltage, power_factor=power_factor, ) - + n_circuits_base = sum(1 for d in eval_base["details"] if d["source"] == "substation" or d["target"] == "substation") comparison_results.append( { "name": base_name, @@ -1444,17 +1423,13 @@ def compare_design_methods( } ) print( - f" [Base] Cost: ¥{eval_base['total_cost']:,.2f} | Loss: {eval_base['total_loss']:.2f} kW" + f" [Base] Cost: ¥{eval_base['total_cost']:,.2f} | Loss: {eval_base['total_loss']:.2f} kW | Circuits: {n_circuits_base}" ) - # --- Run 2: Rotational Algorithm (Optimization) --- + # --- Run 2: Rotational Sweep (Optimization) --- rot_name = f"{name} (Rotational)" conns_rot, turbines_rot = design_with_rotational_sweep( - turbines.copy(), - substation, - cable_specs=current_specs, - voltage=voltage, - power_factor=power_factor, + turbines.copy(), substation, max_cable_mw, voltage=voltage ) eval_rot = evaluate_design( turbines, @@ -1466,7 +1441,7 @@ def compare_design_methods( voltage=voltage, power_factor=power_factor, ) - + n_circuits_rot = sum(1 for d in eval_rot["details"] if d["source"] == "substation" or d["target"] == "substation") comparison_results.append( { "name": rot_name, @@ -1478,7 +1453,7 @@ def compare_design_methods( } ) print( - f" [Rotational] Cost: ¥{eval_rot['total_cost']:,.2f} | Loss: {eval_rot['total_loss']:.2f} kW" + f" [Rotational] Cost: ¥{eval_rot['total_cost']:,.2f} | Loss: {eval_rot['total_loss']:.2f} kW | Circuits: {n_circuits_rot}" ) # --- Run 3: Esau-Williams Algorithm --- @@ -1496,7 +1471,7 @@ def compare_design_methods( voltage=voltage, power_factor=power_factor, ) - + n_circuits_ew = sum(1 for d in eval_ew["details"] if d["source"] == "substation" or d["target"] == "substation") comparison_results.append( { "name": ew_name, @@ -1508,7 +1483,7 @@ def compare_design_methods( } ) print( - f" [Esau-Williams] Cost: ¥{eval_ew['total_cost']:,.2f} | Loss: {eval_ew['total_loss']:.2f} kW" + f" [Esau-Williams] Cost: ¥{eval_ew['total_cost']:,.2f} | Loss: {eval_ew['total_loss']:.2f} kW | Circuits: {n_circuits_ew}" ) # 记录最佳 @@ -1525,7 +1500,7 @@ def compare_design_methods( # 可视化 (只画 Base 版本) ax_idx = i + 1 if plot_results and ax_idx < 4: - n_circuits = turbines_base["cluster"].nunique() + n_circuits = sum(1 for d in eval_base["details"] if d["source"] == "substation" or d["target"] == "substation") title = f"{base_name} ({n_circuits} circuits)\nCost: ¥{eval_base['total_cost'] / 10000:.2f}万" visualize_design( turbines_base, substation, eval_base["details"], title, ax=axes[ax_idx] @@ -1565,7 +1540,11 @@ def compare_design_methods( for i, res in enumerate(comparison_results): if res["cost"] < comparison_results[best_idx]["cost"]: best_idx = i - print(f" {i + 1}. {res['name']} - Cost: ¥{res['cost']:,.2f}") + + # 获取回路数 (通过统计从升压站发出的连接) + n_circuits = sum(1 for conn in res["eval"]["details"] if conn["source"] == "substation" or conn["target"] == "substation") + + print(f" {i + 1}. {res['name']} - Cost: ¥{res['cost']:,.2f} | Circuits: {n_circuits}") print(f"推荐方案: {comparison_results[best_idx]['name']} (默认)")