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

基于二进制变量的线性优化结果异常问询(R语言lpSolveAPI)

我来帮你拆解一下这个问题——你的模型没输出那个更优解,核心是约束条件的逻辑没写对,没有准确还原你设定的产量调整规则。咱们一步步梳理:

问题背景回顾

你研究的是一家分4个时段生产的企业,核心目标是最小化产量与平均销量S0=90的差值,初始产量固定为110,调整规则是:

  • 若前一时段产量≥100,下一时段可增减10
  • 若前一时段产量<100,下一时段仅可增减5

你用lpSolveAPI实现的模型得到的解是[110,100,100,90],误差为10,但理论上[110,100,90,85]的误差更小(6.25),却没被模型识别到。

核心问题:约束条件的逻辑偏差

你的代码里试图用二进制变量(第7-10位)标记时段产量是否≥100,但约束的写法没有正确关联「前一时段产量状态」和「当前时段调整幅度」的关系,具体问题如下:

1. 产量调整幅度的约束逻辑混乱

你写的这段调整幅度约束:

#maximum increase
for (i in 1:3){
  for (j in 7:10){
    x[i+1]=1
    x[i]=-1
    x[j]=-5
    add.constraint(error, x, "<=", 5)
    x[i]=0
    x[i+1]=0
    x[j]=0
  }
}
#maximum decrease
for (i in 1:3){
  for (j in 7:10){
    x[i]=-1
    x[i+1]=1
    x[j]=5
    add.constraint(error, x, ">=", -5)
    x[i]=0
    x[i+1]=0
    x[j]=0
  }
}

这段代码没有把二进制变量和前一时段的产量状态绑定。你想表达的是「前一时段产量≥100时,当前时段可±10;否则仅可±5」,但当前约束反而给调整幅度加了错误的限制,导致模型无法生成90→85的调整(这个调整需要前一时段产量<100时允许减5,但你的约束没正确放开这个规则)。

2. 二进制变量与产量状态的约束缺失

你写了这段代码试图关联产量和二进制变量:

for (i in 1:3){
  for (j in 7:10){
    x[i]=1
    x[j]=-100
    add.constraint(error, x, ">=", 0)
    x[i]=0
    x[j]=0
  }
}

这个约束的逻辑是p_i ≥ 100*b_i(如果二进制变量b_i=1,则p_i≥100),但缺少反向约束:如果p_i≥100,则对应的二进制变量b_i必须为1。没有这个反向约束,二进制变量就无法准确标记产量状态,调整幅度的约束自然无法生效。

3. 目标函数的定义可能存在歧义

你的目标函数是set.objfn(error,x),其中x=c(0,0,0,0,0,1,0,0,0,0,0),看起来是把第6个变量作为误差项,但你需要确认这个误差项是否准确代表了「产量与销量的差值」——比如是所有时段产量与S0的绝对差之和?还是平均产量与S0的差值?如果目标函数定义不对,也会导致模型找到的不是你想要的最优解。

修正建议

要正确实现你的规则,需要重新梳理约束逻辑:

  1. 明确变量定义

    • p1,p2,p3,p4:4个时段的产量(对应代码前4个变量)
    • b1,b2,b3,b4:二进制变量,b_i=1当且仅当p_i≥100(对应代码第7-10位变量)
    • e:误差项,需准确代表你要最小化的目标(比如所有时段产量与S0的绝对差之和,或平均差值)
  2. 补充二进制变量与产量的双向约束
    给每个时段添加双向约束,让二进制变量准确标记产量状态:

    M <- 200 # 足够大的常数
    for (i in 1:4) {
      # 若b_i=1,则p_i≥100
      add.constraint(error, c(rep(0,i-1),1,rep(0,4-i),0,0,rep(0,i-1),-100,rep(0,4-i)), ">=",0)
      # 若b_i=0,则p_i<100(线性化处理为p_i ≤99 + M*b_i)
      add.constraint(error, c(rep(0,i-1),1,rep(0,4-i),0,0,rep(0,i-1),M,rep(0,4-i)), "<=",99+M)
    }
    
  3. 正确定义产量调整幅度的约束
    关联前一时段的二进制变量和当前时段的调整幅度:

    for (i in 1:3) {
      # 调整上限:前一时段≥100时允许+10,否则允许+5
      add.constraint(error, c(rep(0,i-1),-1,1,rep(0,3-i),0,0,rep(0,i-1),5,rep(0,3-i)), "<=",5)
      # 调整下限:前一时段≥100时允许-10,否则允许-5
      add.constraint(error, c(rep(0,i-1),-1,1,rep(0,3-i),0,0,rep(0,i-1),5,rep(0,3-i)), ">=",-5)
    }
    
  4. 修正目标函数
    如果要最小化所有时段产量与S0的绝对差之和,需要线性化处理绝对差:

    # 添加4个绝对差变量e1-e4(可扩展变量数量)
    # 目标函数设为最小化e1+e2+e3+e4
    # 给每个时段添加约束:
    # p_i - S0 ≤ e_i
    # S0 - p_i ≤ e_i
    # e_i ≥0
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:56:41