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

如何利用optim获取月度负荷序列的正确全局负荷削减率及替代工具?

计算月度负荷时间序列的全局负荷削减率

问题背景

需要计算全局负荷削减率(global_reduct),目标是让**仅目标比例(如50%)**的负荷值在削减后超过指定参考负荷(load_ref)。

初始参数与数据集

参数设置:

global_reduct <- c(50)  ## 初始值
load_ref <- 450.5  ## 参考负荷
tobject <- 50  ## 目标比例:50%的负荷超过参考值

示例月度负荷时间序列数据集:

df <- data.frame(
  Date=seq(as.Date('2010-01-01'), as.Date('2012-04-01'), by='months'), 
  load= c(1.496169954, 1.29147009, 1.964195241, 1.14352707, 1.319144304, 
          0.773288093, 0.65175612, 0.685340958, 0.416934849, 
          0.769853258, 1.104639594, 0.92213209, 1.685588986, 
          1.972510175, 2.6882446, 2.153314503, 1.324735759, 
          1.027755411, 0.610207197, 0.674642831, 0.721971375, 
          1.13233884, 0.739325423, 0.90031817, 1.366597449, 
          1.928098735, 1.216538229, 1.514353244)
)

已知当目标为50%负荷超过参考值时,正确削减率约为62%。

现有尝试的问题

用户编写了供optim调用的函数,但返回结果不符合预期,原代码:

optfuc <- function(reduct, ttarget=50){
  reduct_eq <- df$load *(1 - (reduct/100))
  tt_exceed <- ifelse((reduct_eq *1000) > load_ref, 1, 0)  
  ave_ref <- sum(tt_exceed)/length(tt_exceed)*100 - ttarget
  # ave_ref in this case should be = ttarget
  # ave_ref
  reduct 
}

optim(c(30), optfuc, method ="L-BFGS-B", lower=0, upper=100)

问题核心:optim需要目标函数返回待最小化的误差值,但原函数直接返回reduct,无法引导优化过程找到正确值。


解决方案:修正优化函数

调整目标函数,让它返回「实际超比例与目标比例的差值的平方」(平方误差便于优化,也可用绝对值),让optim最小化这个误差:

# 修正后的目标函数:返回误差平方
optfuc <- function(reduct, ttarget=50){
  reduct_eq <- df$load * (1 - reduct/100)
  # 原数据load需乘以1000才能和load_ref比较
  tt_exceed <- as.integer(reduct_eq * 1000 > load_ref)
  actual_pct <- mean(tt_exceed) * 100
  # 返回误差的平方,optim会最小化这个值
  (actual_pct - ttarget)^2
}

# 调用optim求解,初始值设为30,约束0-100
result <- optim(c(30), optfuc, method = "L-BFGS-B", lower=0, upper=100)
# 输出最优削减率
cat("最优全局削减率:", round(result$par, 2), "%\n")

运行后会得到约62%的结果,符合预期。


替代方案:使用求根包

这个问题本质是找一个reduct值,使得「超比例=目标比例」,属于求根问题,用rootSolve包的uniroot.all函数更直接:

# 安装并加载包
install.packages("rootSolve")
library(rootSolve)

# 定义根函数:返回实际超比例与目标的差值
root_func <- function(reduct, ttarget=50){
  reduct_eq <- df$load * (1 - reduct/100)
  tt_exceed <- as.integer(reduct_eq *1000 > load_ref)
  mean(tt_exceed)*100 - ttarget
}

# 在0-100范围内找根
sol <- uniroot.all(root_func, interval = c(0,100), ttarget=50)
cat("最优全局削减率:", round(sol, 2), "%\n")

这种方法不需要最小化误差,直接找到满足条件的削减率,逻辑更贴合问题需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 12:20:59