feat: 优化回路数计算逻辑,提升报表准确性
This commit is contained in:
87
main.py
87
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']} (默认)")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user