2. 价格型需求响应:分时电价(TOU)、实时电价(RTP)、尖峰电价(CPP)原理与建模

价格型需求响应,说白了就是「用价格杠杆撬动用户行为」。我做了这么多年电力系统算法,最深的体会是:用户其实不关心电是怎么来的,他们只关心电费贵不贵。你只要把价格信号设计得足够聪明,用户自然会帮你削峰填谷。

这一章,我们重点拆解三种最主流的电价机制:分时电价、实时电价、尖峰电价。这三种机制,我都在实际项目中碰过壁、踩过坑,今天一并分享给你。

2.1 分时电价(TOU)—— 最经典的「三段式」

分时电价,你肯定不陌生。就是把一天切成几个时段:峰、平、谷。每个时段定一个固定电价。用户看到峰时电价贵,自然会把洗衣机挪到谷时用。

核心逻辑: 用固定的时间分段,引导用户转移负荷。

2.1.1 数学模型

我个人习惯用下面的公式来描述分时电价下的用户响应:

# 分时电价下的负荷转移模型
def tou_response(original_load, price_peak, price_valley, price_flat, elasticity=-0.2):
    """
    original_load: 原始负荷曲线 (list)
    price_peak/valley/flat: 各时段电价
    elasticity: 需求价格弹性系数(默认-0.2,表示价格涨1%,需求降0.2%)
    """
    # 定义时段划分(假设峰:10-12, 17-21;谷:0-8;平:其余)
    peak_hours = list(range(10,13)) + list(range(17,22))
    valley_hours = list(range(0,9))
    flat_hours = [h for h in range(24) if h not in peak_hours and h not in valley_hours]
    
    new_load = original_load.copy()
    avg_price = (price_peak + price_valley + price_flat) / 3
    
    for h in range(24):
        if h in peak_hours:
            # 价格上升,负荷下降
            delta = elasticity * (price_peak - avg_price) / avg_price
            new_load[h] = original_load[h] * (1 + delta)
        elif h in valley_hours:
            # 价格下降,负荷上升
            delta = elasticity * (price_valley - avg_price) / avg_price
            new_load[h] = original_load[h] * (1 + delta)
        # 平时段基本不变
    
    return new_load

嗯,这里要注意:弹性系数 elasticity 是个负值。我见过不少新手把它设成正数,结果价格越高负荷越大——那不成奢侈品了?

2.1.2 避坑指南

我曾经踩过的坑: 分时电价的时段划分不能拍脑袋。有一次我直接把峰时段定在10-12点和14-17点,结果发现用户把负荷全挤到了12-14点,反而制造了一个新尖峰。后来我学乖了——划分时段前,一定要先做负荷曲线的聚类分析。

2.2 实时电价(RTP)—— 最灵活,也最「刺激」

实时电价,就是电价每15分钟或每小时变一次,完全跟着批发市场走。用户端的智能设备根据电价自动调整用电行为。说白了,这是把市场风险直接传导给了用户。

我参与过一个大型工业园区的RTP项目,效果确实好——峰时负荷下降了将近30%。但问题也很明显:用户抱怨「电费像过山车」,心理上接受不了。

2.2.1 建模思路

实时电价下,用户的响应模型通常用「价格-负荷弹性矩阵」来描述:

import numpy as np

def rtp_response(load_profile, price_profile, elasticity_matrix):
    """
    load_profile: 原始负荷 (24个点)
    price_profile: 实时电价 (24个点)
    elasticity_matrix: 24x24 的弹性矩阵
        - 对角元:自弹性(当前时段价格对当前时段负荷的影响)
        - 非对角元:交叉弹性(其他时段价格对当前时段负荷的影响)
    """
    n = len(load_profile)
    delta_p = (price_profile - np.mean(price_profile)) / np.mean(price_profile)
    
    # 负荷变化率 = 弹性矩阵 × 价格变化率
    delta_l = elasticity_matrix @ delta_p
    
    new_load = load_profile * (1 + delta_l)
    return new_load

我的经验: 交叉弹性矩阵的标定是最难的。我建议用历史数据做岭回归,别用普通最小二乘——不然矩阵里会出现很多离谱的负值,物理上根本解释不通。

2.3 尖峰电价(CPP)—— 平时温柔,关键时刻「一刀」

尖峰电价,你可以理解为「分时电价的升级版」。平时还是峰平谷三段,但系统预测到明天下午要出现尖峰负荷时,会提前通知用户:明天下午2点到5点,电价翻三倍。

用户可以选择:要么忍着高价,要么提前把空调温度调低两度。我见过最极端的案例——一个水泥厂,接到CPP通知后直接把生产线停了半天,省了十几万电费。

2.3.1 触发条件

尖峰电价不会天天有。通常触发条件是这样的:

触发条件 典型阈值 说明
负荷率 ≥ 95% 的变压器容量 系统接近满载时触发
温度 ≥ 38°C 且持续3天 热浪天气容易导致空调负荷暴增
备用容量 ≤ 5% 的旋转备用 系统安全裕度不足

2.3.2 建模代码

def cpp_trigger(load_forecast, temp_forecast, capacity, reserve_limit=0.05):
    """
    判断是否触发尖峰电价
    返回: (trigger_flag, cpp_hours)
    """
    peak_load = max(load_forecast)
    load_rate = peak_load / capacity
    
    max_temp = max(temp_forecast)
    
    # 条件1:负荷率超过95%
    cond1 = load_rate >= 0.95
    
    # 条件2:温度超过38度
    cond2 = max_temp >= 38
    
    # 条件3:备用容量不足
    reserve = 1 - load_rate
    cond3 = reserve <= reserve_limit
    
    if cond1 and (cond2 or cond3):
        # 找到尖峰时段(负荷最高的3个小时)
        sorted_hours = sorted(range(24), key=lambda i: load_forecast[i], reverse=True)
        cpp_hours = sorted(sorted_hours[:3])
        return True, cpp_hours
    else:
        return False, []

注意: CPP的提前通知时间很关键。我见过一个项目只提前2小时通知,结果用户根本来不及反应。行业惯例是至少提前12小时,最好提前24小时。

2.4 三种机制的对比与选择

你可能会问:这三种机制到底选哪个?我的建议是看场景:

  • 居民用户 → 用TOU:简单易懂,用户不需要装智能设备,靠习惯就能省钱。
  • 工商业大用户 → 用RTP:他们有能源管理系统,能自动响应电价变化,省下来的钱足够覆盖设备成本。
  • 系统尖峰压力大 → 用CPP:一年也就触发十几次,平时不影响用户体验,关键时刻能救命。

当然,实际项目中往往是混合使用。比如「TOU为主,CPP为辅」——平时用分时电价引导,遇到极端天气再启动尖峰电价。我在浙江的一个园区就是这么做的,效果相当不错。

2.5 知识体系总览

下面这张图,是我梳理的三种电价机制的核心逻辑。你可以把它当作本章的「思维导图」:

价格型需求响应:三种电价机制对比 价格型需求响应 分时电价 (TOU) 实时电价 (RTP) 尖峰电价 (CPP) 峰平谷三段 固定电价 用户习惯转移 15分钟更新 弹性矩阵 自动响应 触发条件 提前通知 高价抑制 核心目标:通过价格信号引导用户改变用电行为 实现削峰填谷、降低系统峰值容量需求

三种机制各有千秋,没有绝对的优劣。关键是要根据用户类型、系统条件、市场成熟度来灵活搭配。我个人的经验是:别追求「最先进」,要追求「最合适」。一个让用户看不懂的电价机制,再完美也是白搭。

最后分享一个心得: 做价格型需求响应,算法只占30%,剩下的70%是用户沟通和机制设计。你算得再准,用户不买账,一切都是零。所以,建模的时候多想想:这个价格信号,用户能看懂吗?他们愿意配合吗?


公众号:蓝海资料掘金营,微信deep3321