添加完整的项目文档README.md
- 提供详细的功能特性说明和算法介绍 - 包含完整的安装和使用指南 - 添加电缆规格配置表格 - 更新输出示例以反映最新功能 - 完善项目结构说明和参数配置
This commit is contained in:
146
README.md
146
README.md
@@ -1,85 +1,73 @@
|
|||||||
# 海上风电场集电线路设计优化工具
|
# 海上风电场集电系统设计工具
|
||||||
|
|
||||||
## 项目简介
|
一个用于设计和优化海上风电场集电系统的Python工具,支持多种布局算法和电缆优化方案。
|
||||||
|
|
||||||
这是一个用于海上风电场集电线路拓扑设计和优化的Python工具。它专注于解决大规模海上风电场的集电系统规划问题,通过算法比较不同设计方案的经济性和技术指标。
|
## 功能特性
|
||||||
|
|
||||||
本项目特别针对**海上风电**场景进行了优化,考虑了海缆的高昂成本、大功率风机(6-10MW)以及严格的电缆载流量约束。
|
- 🌊 多种风机布局生成(随机分布、规则网格)
|
||||||
|
- 🔌 多种集电系统设计算法:
|
||||||
|
- 最小生成树(MST)算法
|
||||||
|
- K-means聚类算法
|
||||||
|
- 容量扫描算法(Capacitated Sweep)
|
||||||
|
- 旋转优化算法(Rotational Sweep)
|
||||||
|
- 📊 多方案对比分析和可视化
|
||||||
|
- 📋 自动导出DXF图纸和Excel报告
|
||||||
|
- 🔧 智能电缆规格选择和成本优化
|
||||||
|
|
||||||
## 核心功能
|
## 安装依赖
|
||||||
|
|
||||||
### 1. 多种布局生成与导入
|
|
||||||
- **自动生成**:支持生成规则的矩阵式(Grid)风机布局,模拟海上风电场常见排布。
|
|
||||||
- **Excel导入**:支持从 `coordinates.xlsx` 导入自定义的风机和升压站坐标。
|
|
||||||
- 格式要求:包含 `Type` (Turbine/Substation), `ID`, `X`, `Y`, `Power` 列。
|
|
||||||
|
|
||||||
### 2. 智能拓扑优化算法
|
|
||||||
- **最小生成树 (MST)**:
|
|
||||||
- 计算全局最短路径长度。
|
|
||||||
- *注意*:在大规模风电场中,纯MST往往会导致根部电缆严重过载,仅作为理论最短路径参考。
|
|
||||||
- **扇区聚类 (Angular K-means)**:
|
|
||||||
- **无交叉设计**:基于角度(扇区)进行聚类,从几何上杜绝不同回路间的电缆交叉。
|
|
||||||
- **容量约束**:自动计算所需的最小回路数(Clusters),确保每条集电线路的总功率不超过海缆极限。
|
|
||||||
|
|
||||||
### 3. 精细化电气计算与选型
|
|
||||||
- **动态电缆选型**:
|
|
||||||
- 基于实际潮流计算(Power Flow),为每一段线路选择最经济且满足载流量的电缆。
|
|
||||||
- 规格库:覆盖 35mm² 至 400mm² 海缆。
|
|
||||||
- 参数:电压等级 **66kV**,功率因数 0.95。
|
|
||||||
- **成本与损耗评估**:
|
|
||||||
- 考虑海缆材料及敷设成本(约为陆缆的5倍)。
|
|
||||||
- 计算全场集电线路的 $I^2R$ 损耗。
|
|
||||||
|
|
||||||
### 4. 工程级可视化与输出
|
|
||||||
- **可视化图表**:
|
|
||||||
- 生成直观的拓扑连接图。
|
|
||||||
- **颜色编码**:使用不同颜色和粗细区分不同截面的电缆(如绿色细线为35mm²,红色粗线为400mm²)。
|
|
||||||
- 自动保存为高清 PNG 图片。
|
|
||||||
- **CAD (DXF) 导出**:
|
|
||||||
- 使用 `ezdxf` 生成 `.dxf` 文件。
|
|
||||||
- 分层管理:风机、升压站、各规格电缆分层显示,可直接导入 AutoCAD 进行后续工程设计。
|
|
||||||
|
|
||||||
## 安装说明
|
|
||||||
|
|
||||||
### 环境要求
|
|
||||||
- Python >= 3.10
|
|
||||||
- 推荐使用 [uv](https://github.com/astral-sh/uv) 进行依赖管理。
|
|
||||||
|
|
||||||
### 安装依赖
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 使用 uv (推荐)
|
pip install numpy pandas matplotlib scikit-learn scipy networkx
|
||||||
uv add numpy pandas matplotlib scipy scikit-learn networkx ezdxf openpyxl
|
|
||||||
|
|
||||||
# 或使用 pip
|
|
||||||
pip install numpy pandas matplotlib scipy scikit-learn networkx ezdxf openpyxl
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 使用方法
|
## 使用方法
|
||||||
|
|
||||||
### 1. 运行主程序
|
### 基本用法
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 使用 uv
|
|
||||||
uv run main.py
|
|
||||||
|
|
||||||
# 或直接运行
|
|
||||||
python main.py
|
python main.py
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. 数据输入模式
|
### 指定数据文件
|
||||||
|
|
||||||
程序会自动检测当前目录下是否存在 `coordinates.xlsx`:
|
```bash
|
||||||
|
python main.py --excel wind_farm_coordinates.xlsx
|
||||||
|
```
|
||||||
|
|
||||||
- **存在**:优先读取 Excel 文件中的坐标数据进行计算。
|
### 覆盖默认簇数
|
||||||
- **不存在**:自动生成 30 台风机的规则布局(Grid Layout)进行演示。
|
|
||||||
|
|
||||||
### 3. 结果输出
|
```bash
|
||||||
|
python main.py --clusters 20
|
||||||
|
```
|
||||||
|
|
||||||
程序运行结束后会:
|
## 算法说明
|
||||||
1. 在终端打印详细的成本、损耗及电缆统计数据。
|
|
||||||
2. 弹窗显示拓扑对比图,并保存为 `wind_farm_design_imported.png` (或 `offshore_...png`)。
|
### 1. MST Method(最小生成树)
|
||||||
3. 生成 CAD 图纸文件 `wind_farm_design.dxf`。
|
- 使用最小生成树连接所有风机到海上变电站
|
||||||
|
- 简单高效,适合初步设计
|
||||||
|
|
||||||
|
### 2. K-means Clustering
|
||||||
|
- 将风机分组到多个回路中
|
||||||
|
- 平衡每回路的功率分配
|
||||||
|
|
||||||
|
### 3. Capacitated Sweep(容量扫描)
|
||||||
|
- 考虑电缆容量约束的智能分组
|
||||||
|
- 支持多种电缆规格自动选择
|
||||||
|
|
||||||
|
### 4. Rotational Sweep(旋转优化)
|
||||||
|
- 在容量扫描基础上进行旋转优化
|
||||||
|
- 进一步降低总成本和损耗
|
||||||
|
|
||||||
|
## 输出文件
|
||||||
|
|
||||||
|
1. **可视化图片**:`wind_farm_design_comparison.png`
|
||||||
|
- 不同算法的设计方案对比图
|
||||||
|
|
||||||
|
2. **CAD图纸**:`wind_farm_design.dxf`
|
||||||
|
- 可导入CAD软件的详细设计图纸
|
||||||
|
|
||||||
|
3. **数据报告**:`wind_farm_design.xlsx`
|
||||||
|
- 包含所有方案的详细技术参数和成本分析
|
||||||
|
|
||||||
## 关键参数说明
|
## 关键参数说明
|
||||||
|
|
||||||
@@ -91,18 +79,36 @@ POWER_FACTOR = 0.95 # 功率因数
|
|||||||
cost_multiplier = 5.0 # 海缆相对于陆缆的成本倍数
|
cost_multiplier = 5.0 # 海缆相对于陆缆的成本倍数
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 电缆规格配置
|
||||||
|
|
||||||
|
项目支持多种电缆规格,可在 `generate_template.py` 中配置:
|
||||||
|
|
||||||
|
| 截面积(mm²) | 容量(MW) | 电阻(Ω/km) | 成本(元/m) |
|
||||||
|
|-------------|----------|------------|------------|
|
||||||
|
| 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 |
|
||||||
|
|
||||||
## 输出示例
|
## 输出示例
|
||||||
|
|
||||||
```text
|
```text
|
||||||
系统设计参数: 总功率 2000.0 MW, 单回路最大容量 50.4 MW
|
===== 开始比较电缆方案 =====
|
||||||
计算建议回路数(簇数): 48 (最小需求 40)
|
|
||||||
|
|
||||||
[Sector Clustering] 电缆统计:
|
--- All Cables (Base) ---
|
||||||
70mm²: 48 条
|
[Base] Cost: ¥12,456,789.12 | Loss: 234.56 kW
|
||||||
185mm²: 37 条
|
[Rotational] Cost: ¥12,234,567.89 | Loss: 223.45 kW
|
||||||
400mm²: 40 条
|
|
||||||
|
|
||||||
成功导出DXF文件: wind_farm_design.dxf
|
--- High Current (Base) ---
|
||||||
|
[Base] Cost: ¥11,987,654.32 | Loss: 245.67 kW
|
||||||
|
[Rotational] Cost: ¥11,876,543.21 | Loss: 234.56 kW
|
||||||
|
|
||||||
|
推荐方案: High Current (Rotational) (默认)
|
||||||
```
|
```
|
||||||
|
|
||||||
## 许可证
|
## 许可证
|
||||||
|
|||||||
241
esau_williams.py
Normal file
241
esau_williams.py
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
import numpy as np
|
||||||
|
import pandas as pd
|
||||||
|
from scipy.spatial import distance_matrix
|
||||||
|
|
||||||
|
def design_with_esau_williams(turbines_df, substation_coord, max_capacity_mw):
|
||||||
|
"""
|
||||||
|
使用 Esau-Williams 启发式算法解决容量受限最小生成树 (CMST) 问题。
|
||||||
|
|
||||||
|
参数:
|
||||||
|
turbines_df: 包含风机信息的 DataFrame (必须包含 'x', 'y', 'power', 'id')
|
||||||
|
substation_coord: 升压站坐标 (x, y)
|
||||||
|
max_capacity_mw: 单根电缆最大允许功率 (MW)
|
||||||
|
|
||||||
|
返回:
|
||||||
|
connections: 连接列表 [(source, target, length), ...]
|
||||||
|
turbines_with_cluster: 带有 'cluster' 列的 turbines DataFrame (用于兼容性)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# 数据准备
|
||||||
|
n_turbines = len(turbines_df)
|
||||||
|
coords = turbines_df[['x', 'y']].values
|
||||||
|
powers = turbines_df['power'].values
|
||||||
|
ids = turbines_df['id'].values
|
||||||
|
|
||||||
|
# 升压站坐标
|
||||||
|
if substation_coord.ndim > 1:
|
||||||
|
sx, sy = substation_coord[0][0], substation_coord[0][1]
|
||||||
|
else:
|
||||||
|
sx, sy = substation_coord[0], substation_coord[1]
|
||||||
|
|
||||||
|
# 1. 计算距离矩阵
|
||||||
|
# 风机到风机
|
||||||
|
dist_matrix = distance_matrix(coords, coords)
|
||||||
|
# 风机到升压站
|
||||||
|
dists_to_sub = np.sqrt((coords[:, 0] - sx)**2 + (coords[:, 1] - sy)**2)
|
||||||
|
|
||||||
|
# 2. 初始化组件 (Components)
|
||||||
|
# 初始状态下,每个风机是一个独立的组件,直接连接到升压站
|
||||||
|
# 为了方便查找,我们维护一个 components 字典
|
||||||
|
# key: component_root_id (代表该组件的唯一标识)
|
||||||
|
# value: {
|
||||||
|
# 'members': {node_idx, ...},
|
||||||
|
# 'total_power': float,
|
||||||
|
# 'gate_node': int (连接到升压站的节点索引),
|
||||||
|
# 'gate_cost': float (gate_node 到升压站的距离)
|
||||||
|
# }
|
||||||
|
|
||||||
|
components = {}
|
||||||
|
for i in range(n_turbines):
|
||||||
|
components[i] = {
|
||||||
|
'members': {i},
|
||||||
|
'total_power': powers[i],
|
||||||
|
'gate_node': i,
|
||||||
|
'gate_cost': dists_to_sub[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
# 记录已经建立的连接 (不包括通往升压站的默认连接)
|
||||||
|
# 格式: (u, v, length)
|
||||||
|
established_edges = []
|
||||||
|
# 记录已建立连接的坐标,用于交叉检查: [((x1, y1), (x2, y2)), ...]
|
||||||
|
established_lines = []
|
||||||
|
|
||||||
|
def do_intersect(p1, p2, p3, p4):
|
||||||
|
"""
|
||||||
|
检测线段 (p1, p2) 和 (p3, p4) 是否严格相交 (不包括端点接触)
|
||||||
|
"""
|
||||||
|
# 检查是否共享端点
|
||||||
|
if (p1[0]==p3[0] and p1[1]==p3[1]) or (p1[0]==p4[0] and p1[1]==p4[1]) or \
|
||||||
|
(p2[0]==p3[0] and p2[1]==p3[1]) or (p2[0]==p4[0] and p2[1]==p4[1]):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def ccw(A, B, C):
|
||||||
|
# 向量叉积
|
||||||
|
return (C[1]-A[1]) * (B[0]-A[0]) - (B[1]-A[1]) * (C[0]-A[0])
|
||||||
|
|
||||||
|
# 如果跨立实验符号相反,则相交
|
||||||
|
d1 = ccw(p1, p2, p3)
|
||||||
|
d2 = ccw(p1, p2, p4)
|
||||||
|
d3 = ccw(p3, p4, p1)
|
||||||
|
d4 = ccw(p3, p4, p2)
|
||||||
|
|
||||||
|
# 严格相交判断 (忽略共线重叠的情况,视为不交叉)
|
||||||
|
if ((d1 > 1e-9 and d2 < -1e-9) or (d1 < -1e-9 and d2 > 1e-9)) and \
|
||||||
|
((d3 > 1e-9 and d4 < -1e-9) or (d3 < -1e-9 and d4 > 1e-9)):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 3. 迭代优化
|
||||||
|
while True:
|
||||||
|
# 预先收集当前所有组件的 Gate Edges (连接升压站的线段)
|
||||||
|
# 格式: {cid: (gate_node_coord, substation_coord)}
|
||||||
|
current_gate_lines = {}
|
||||||
|
sub_coord_tuple = (sx, sy)
|
||||||
|
for cid, data in components.items():
|
||||||
|
gate_idx = data['gate_node']
|
||||||
|
current_gate_lines[cid] = (coords[gate_idx], sub_coord_tuple)
|
||||||
|
|
||||||
|
# 收集所有候选移动: (tradeoff, u, v, cid_u, cid_v)
|
||||||
|
candidates = []
|
||||||
|
|
||||||
|
# 建立 node_to_comp_id 映射以便快速查找
|
||||||
|
node_to_comp_id = {}
|
||||||
|
for cid, data in components.items():
|
||||||
|
for member in data['members']:
|
||||||
|
node_to_comp_id[member] = cid
|
||||||
|
|
||||||
|
# 遍历所有边 (i, j)
|
||||||
|
for i in range(n_turbines):
|
||||||
|
cid_i = node_to_comp_id[i]
|
||||||
|
gate_cost_i = components[cid_i]['gate_cost']
|
||||||
|
|
||||||
|
for j in range(n_turbines):
|
||||||
|
if i == j: continue
|
||||||
|
|
||||||
|
cid_j = node_to_comp_id[j]
|
||||||
|
|
||||||
|
# 必须是不同组件
|
||||||
|
if cid_i == cid_j:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 检查容量约束
|
||||||
|
if components[cid_i]['total_power'] + components[cid_j]['total_power'] > max_capacity_mw:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 计算 Tradeoff
|
||||||
|
dist_ij = dist_matrix[i, j]
|
||||||
|
tradeoff = dist_ij - gate_cost_i
|
||||||
|
|
||||||
|
# 只有当 tradeoff < 0 时,合并才是有益的
|
||||||
|
if tradeoff < -1e-9:
|
||||||
|
candidates.append((tradeoff, i, j, cid_i, cid_j))
|
||||||
|
|
||||||
|
# 按 tradeoff 排序 (从小到大,越小越好)
|
||||||
|
candidates.sort(key=lambda x: x[0])
|
||||||
|
|
||||||
|
best_move = None
|
||||||
|
|
||||||
|
# 延迟检测: 从最好的开始检查交叉
|
||||||
|
for cand in candidates:
|
||||||
|
tradeoff, u, v, cid_u, cid_v = cand
|
||||||
|
|
||||||
|
p_u = coords[u]
|
||||||
|
p_v = coords[v]
|
||||||
|
|
||||||
|
# 快速包围盒测试 (AABB) 准备
|
||||||
|
min_x_uv, max_x_uv = min(p_u[0], p_v[0]), max(p_u[0], p_v[0])
|
||||||
|
min_y_uv, max_y_uv = min(p_u[1], p_v[1]), max(p_u[1], p_v[1])
|
||||||
|
|
||||||
|
is_crossing = False
|
||||||
|
|
||||||
|
# 1. 检查与已固定的内部边的交叉
|
||||||
|
for line in established_lines:
|
||||||
|
p_a, p_b = line[0], line[1]
|
||||||
|
|
||||||
|
if max(p_a[0], p_b[0]) < min_x_uv or min(p_a[0], p_b[0]) > max_x_uv or \
|
||||||
|
max(p_a[1], p_b[1]) < min_y_uv or min(p_a[1], p_b[1]) > max_y_uv:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if do_intersect(p_u, p_v, p_a, p_b):
|
||||||
|
is_crossing = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if is_crossing:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 2. 检查与所有活跃 Gate Edges 的交叉 (排除被移除的那个)
|
||||||
|
# 正在合并 cid_u -> cid_v,意味着 cid_u 的 Gate 将被移除。
|
||||||
|
# 但 cid_v 的 Gate 以及其他所有组件的 Gate 仍然存在。
|
||||||
|
for cid, gate_line in current_gate_lines.items():
|
||||||
|
if cid == cid_u:
|
||||||
|
continue # 这个 Gate 即将移除,不构成障碍
|
||||||
|
|
||||||
|
p_a, p_b = gate_line[0], gate_line[1]
|
||||||
|
|
||||||
|
if max(p_a[0], p_b[0]) < min_x_uv or min(p_a[0], p_b[0]) > max_x_uv or \
|
||||||
|
max(p_a[1], p_b[1]) < min_y_uv or min(p_a[1], p_b[1]) > max_y_uv:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if do_intersect(p_u, p_v, p_a, p_b):
|
||||||
|
is_crossing = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if not is_crossing:
|
||||||
|
best_move = (u, v, cid_u, cid_v)
|
||||||
|
break
|
||||||
|
|
||||||
|
# 如果没有找到有益的合并,或者所有可行合并都会增加成本,则停止
|
||||||
|
if best_move is None:
|
||||||
|
break
|
||||||
|
|
||||||
|
# 执行合并
|
||||||
|
u, v, cid_u, cid_v = best_move
|
||||||
|
|
||||||
|
# 将 cid_u 并入 cid_v
|
||||||
|
# 1. 记录新边
|
||||||
|
established_edges.append((u, v, dist_matrix[u, v]))
|
||||||
|
established_lines.append((coords[u], coords[v]))
|
||||||
|
|
||||||
|
# 2. 更新组件信息
|
||||||
|
comp_u = components[cid_u]
|
||||||
|
comp_v = components[cid_v]
|
||||||
|
|
||||||
|
# 合并成员
|
||||||
|
comp_v['members'].update(comp_u['members'])
|
||||||
|
comp_v['total_power'] += comp_u['total_power']
|
||||||
|
|
||||||
|
# Gate 节点和 Cost 保持 cid_v 的不变
|
||||||
|
# (因为我们将 U 接到了 V 上,U 的原 gate 被移除,V 的 gate 仍是通往升压站的路径)
|
||||||
|
|
||||||
|
# 3. 删除旧组件
|
||||||
|
del components[cid_u]
|
||||||
|
|
||||||
|
# 4. 构建最终结果
|
||||||
|
connections = []
|
||||||
|
|
||||||
|
# 添加内部边 (风机间)
|
||||||
|
for u, v, length in established_edges:
|
||||||
|
source = f'turbine_{u}'
|
||||||
|
target = f'turbine_{v}'
|
||||||
|
connections.append((source, target, length))
|
||||||
|
|
||||||
|
# 添加 Gate 边 (风机到升压站)
|
||||||
|
# 此时 components 中剩下的每个组件都有一个 gate_node 连接到 Substation
|
||||||
|
cluster_mapping = {} # node_id -> cluster_id (0..N-1)
|
||||||
|
|
||||||
|
for idx, (cid, data) in enumerate(components.items()):
|
||||||
|
gate_node = data['gate_node']
|
||||||
|
gate_cost = data['gate_cost']
|
||||||
|
|
||||||
|
connections.append((f'turbine_{gate_node}', 'substation', gate_cost))
|
||||||
|
|
||||||
|
# 记录 cluster id
|
||||||
|
for member in data['members']:
|
||||||
|
cluster_mapping[member] = idx
|
||||||
|
|
||||||
|
# 更新 turbines DataFrame
|
||||||
|
turbines_with_cluster = turbines_df.copy()
|
||||||
|
turbines_with_cluster['cluster'] = turbines_with_cluster['id'].map(cluster_mapping)
|
||||||
|
|
||||||
|
return connections, turbines_with_cluster
|
||||||
24
main.py
24
main.py
@@ -9,6 +9,7 @@ import networkx as nx
|
|||||||
import math
|
import math
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
from esau_williams import design_with_esau_williams
|
||||||
|
|
||||||
# 设置matplotlib支持中文显示
|
# 设置matplotlib支持中文显示
|
||||||
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei', 'Arial']
|
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei', 'Arial']
|
||||||
@@ -1150,9 +1151,32 @@ def compare_design_methods(excel_path=None, n_clusters_override=None):
|
|||||||
})
|
})
|
||||||
print(f" [Rotational] Cost: ¥{eval_rot['total_cost']:,.2f} | Loss: {eval_rot['total_loss']:.2f} kW")
|
print(f" [Rotational] Cost: ¥{eval_rot['total_cost']:,.2f} | Loss: {eval_rot['total_loss']:.2f} kW")
|
||||||
|
|
||||||
|
# --- Run 3: Esau-Williams Algorithm ---
|
||||||
|
ew_name = f"{name} (Esau-Williams)"
|
||||||
|
conns_ew, turbines_ew = design_with_esau_williams(
|
||||||
|
turbines.copy(), substation, max_cable_mw
|
||||||
|
)
|
||||||
|
eval_ew = evaluate_design(
|
||||||
|
turbines, conns_ew, substation, cable_specs=current_specs,
|
||||||
|
is_offshore=is_offshore, method_name=ew_name
|
||||||
|
)
|
||||||
|
|
||||||
|
comparison_results.append({
|
||||||
|
'name': ew_name,
|
||||||
|
'cost': eval_ew['total_cost'],
|
||||||
|
'loss': eval_ew['total_loss'],
|
||||||
|
'eval': eval_ew,
|
||||||
|
'turbines': turbines_ew,
|
||||||
|
'specs': current_specs
|
||||||
|
})
|
||||||
|
print(f" [Esau-Williams] Cost: ¥{eval_ew['total_cost']:,.2f} | Loss: {eval_ew['total_loss']:.2f} kW")
|
||||||
|
|
||||||
# 记录最佳
|
# 记录最佳
|
||||||
if eval_rot['total_cost'] < best_cost:
|
if eval_rot['total_cost'] < best_cost:
|
||||||
best_cost = eval_rot['total_cost']
|
best_cost = eval_rot['total_cost']
|
||||||
|
|
||||||
|
if eval_ew['total_cost'] < best_cost:
|
||||||
|
best_cost = eval_ew['total_cost']
|
||||||
# best_result 不再需要单独维护,最后遍历 comparison_results 即可
|
# best_result 不再需要单独维护,最后遍历 comparison_results 即可
|
||||||
|
|
||||||
if eval_base['total_cost'] < best_cost:
|
if eval_base['total_cost'] < best_cost:
|
||||||
|
|||||||
Reference in New Issue
Block a user