You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PuLP优化电动汽车充电站选址遇不可行问题求助

问题排查与解决

模型不可行的核心原因

你的PuLP模型存在多处逻辑错误,导致与实际可行的全充电站场景冲突,具体如下:

  1. 变量定义错误
    E变量的定义使用了range(len(e)),但代码中从未定义过e这个变量,应该替换为range(n)(n是候选节点数量,等于len(e_c))。

  2. 初始状态约束错误
    未定义S_start变量,且初始约束完全不符合实际流程:实际初始是出发前电量100kWh,行驶到第一个节点后电量才会减少,而不是直接将某个节点的电量设为100。

  3. 电量流转逻辑颠倒
    你的约束E[i+1] == E[i] - e_c[i] + (e_r[i] * X[i])假设先消耗路段电量再充电,但实际流程是到达节点后充电,再消耗电量行驶到下一个节点,逻辑完全相反。

  4. 缺失关键约束
    合理性验证中检查了行驶后电量不能为负,但模型中没有添加“到达节点后的电量≥0”的约束,同时对充电后电量上限的约束位置错误。

修正后的模型实现

重新梳理逻辑

明确变量代表的物理意义:

  • X[i]:二进制变量,1=在节点i建充电站,0=不建
  • E_arrive[i]:到达节点i后的电量(行驶完对应路段后的剩余电量)
  • E_leave[i]:离开节点i时的电量(若充电则为充电后的电量,不超过电池容量)

流程约束:

  1. 初始出发电量100kWh,行驶到第一个节点后电量为100 - e_c[0]
  2. 每个节点到达后电量不能为负
  3. 充电仅在节点i进行,充电后电量不超过100kWh
  4. 离开节点i时的电量必须足够行驶到下一个节点(最后一个节点除外)

修正后的代码

from pulp import * 

# 原参数保持不变
BC = 100 # battery capacity
SOC_in = 1.0 # (%) initial state of charge 
SOC_max = 1.0 #(%) maximum SOC

e_c = [23.5,  4.6,  4.4, 33.8, 89.5,  0. , 24.5,  4.7, 21.5,  0. ,  0. ,
       16.2,  4.8, 20.1,  0. , 62.8,  0.6, 40.8, 41.1,  5.1, 16.7,  0. ,
       39.6,  9.6,  9.8, 23.7,  0. ,  0. , 23.4,  5.3,  8.6, 23.7, 18.6,
        5.8,  9.1,  0.1,  0. ,  0.1,  0. ,  0.3, 19.8,  0. ,  4.9, 23.4,
        7.7,  9.6,  8. ,  1. ,  0. ,  0. ,  0. ,  0. , 28.1,  5.5,  9.3,
        0. ,  0.1, 27.9, 41.3,  2.8, 20.8,  6.4,  5.7, 28.4,  7.7, 35.2,
        2.8, 21. , 11.8,  0.1, 21.6,  7.4, 13.5,  8.6,  7.5,  0. , 12.8,
       10.5,  0.4,  0. ,  0. ,  0.5, 37.2,  5.8, 19. , 10.7, 21.7, 17.1,
        0.9,  0. , 17.1, 12. ,  7.9,  2.4,  0.2, 20.6,  4.9, 21.1]

e_r = [30.7,  64.8,  31.2, 181.2,   2.2,  66.5,  30.3,  52.8,  43.8,
        54.1, 151.1,  33.9,  22.2,  68.3,  66.4,  70.2, 170.5, 260.2,
        32.7,  72.6,  89.1, 138.1,  54.6,  70.2,  24.3,  42.2,  44.4,
        38. ,  38.8,  30.1,  28.7, 179.4,  48.6,  96.6,   0.2,  38.5,
        44.5,   0.4,   0.4,  28.8,  13.5,  25.5,  44.9, 196.8, 269.8,
       215.7,  81.1, 166.6,   0.4,   0.4,   0.1,  22.3, 111.9,  36.9,
        43.3,  38. , 712.2,   9.7,  25.2, 242.3,  24.5,  49.4,  31.6,
       231.6,   0.4,  27.5, 228.6,  31.7, 685.1, 812.4,  84.5,  36.7,
        28.4, 214.7,   0.5,  46. ,  61.3,   0.4,   0.4,  22.4,   0.4,
         0.5,  47.5,  27. ,  43.8, 182.3,  24.2,  76.3,  54. , 748.8,
        72. ,  46. ,  31.3, 113.2,   0.4,  22.7,  70.6,  78.9]

candidate_nodes = range(len(e_c))
n = len(candidate_nodes)

# Define optimization problem
model = LpProblem("EV_charging_optimization", LpMinimize)

### Decision variables
X = LpVariable.dicts("UseLocation", candidate_nodes, cat=LpBinary)
# 到达节点i后的电量
E_arrive = LpVariable.dicts("EnergyArrive", candidate_nodes, lowBound=0, upBound=BC, cat=LpContinuous)
# 离开节点i时的电量
E_leave = LpVariable.dicts("EnergyLeave", candidate_nodes, lowBound=0, upBound=BC, cat=LpContinuous)

### Objective function
model += lpSum(X[i] for i in candidate_nodes)

### Constraints
# 初始约束:出发电量100kWh,行驶到第一个节点后的电量
model += E_arrive[0] == SOC_in * BC - e_c[0]

for i in candidate_nodes:
    # 到达节点后的电量不能为负(已通过lowBound保证,但显式约束更清晰)
    model += E_arrive[i] >= 0
    # 充电逻辑:不充电则离开电量=到达电量;充电则加上e_r[i]
    model += E_leave[i] == E_arrive[i] + X[i] * e_r[i]
    # 充电后电量不超过电池容量
    model += E_leave[i] <= BC * SOC_max

# 行驶到下一个节点的约束(除最后一个节点)
for i in range(n-1):
    # 到达下一个节点的电量 = 离开当前节点的电量 - 下一段路的能耗
    model += E_arrive[i+1] == E_leave[i] - e_c[i+1]
    # 离开当前节点的电量必须足够行驶到下一个节点
    model += E_leave[i] >= e_c[i+1]

# Solve
status = model.solve()

# 输出结果
print(f"求解状态: {LpStatus[status]}")
print(f"最少充电站数量: {int(value(model.objective))}")
# 输出选中的节点
selected_nodes = [i for i in candidate_nodes if value(X[i]) == 1]
print(f"选中的充电站节点: {selected_nodes}")

验证说明

修正后的模型完全匹配你合理性验证的逻辑:全充电站场景下,X[i]全部为1,此时每个节点充电后电量被限制在100kWh,行驶过程中电量不会为负,模型会返回可行解。

内容的提问来源于stack exchange,提问作者llamawithgrass

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 14:42:35