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

连续变量乘积线性化及CPLEX OPL实现咨询:小数价格变量处理

连续变量乘积约束的线性化及CPLEX OPL实现方案

一、处理带4-5位小数的price离散化

因为price最多有5位小数,直接缩放成整数是最实用的办法:

  • 设缩放因子SCALE = 100000(对应5位小数,4位就用10000),把离散化后的price定义为整数变量price_int,连续变量price和它的关系是:price = price_int / SCALE
  • 原约束price * time >= Ub转化为price_int * time >= Ub * SCALE,但这是整数×连续变量的乘积,还得用大M法线性化。

整数×连续乘积的线性化步骤

  1. 先确定price_int的取值范围:根据price的最小/最大值,算出x_low = floor(price_min * SCALE),x_high = ceil(price_max * SCALE)
  2. 引入二进制变量b[k](k从x_low到x_high),保证只有一个b[k]取1,对应选中的price_int值
  3. 添加约束把price_int和b[k]绑定,再把乘积约束拆分成多个线性约束

CPLEX OPL代码示例

// 参数定义
float Ub = ...; // 给定的阈值
float price_min = ...; // price的下限
float price_max = ...; // price的上限
int SCALE = 100000; // 5位小数缩放因子
int x_low = floor(price_min * SCALE);
int x_high = ceil(price_max * SCALE);
float M = ...; // time的上限值(取足够大的合理值)

// 变量定义
dvar int price_int in x_low..x_high;
dvar float time >= 0; // 假设time非负,按需调整范围
dvar boolean b[x_low..x_high];

// 约束集合
subject to {
  // 二进制变量只能选一个
  sum(k in x_low..x_high) b[k] == 1;
  // 绑定整数变量与二进制变量
  price_int == sum(k in x_low..x_high) k * b[k];
  // 线性化乘积约束:当b[k]=1时,k*time >= Ub*SCALE
  forall(k in x_low..x_high) {
    // 跳过k=0的情况(如果price不能为0可直接删)
    if (k != 0) {
      time >= (Ub * SCALE) / k - M * (1 - b[k]);
    } else {
      // 若Ub>0,k=0时约束不可能满足,直接禁止选这个值
      (Ub <= 0) || (b[k] == 0);
    }
  }
  // 如需输出连续price,直接计算:float price = price_int / SCALE;
}

二、正确实现price的floor值

你之前用sum(2^n-1)*p的方式逻辑不对,换缩放+整数变量的方法更直接:

dvar int price_floor_int;
dvar float price;

subject to {
  // 约束price*SCALE落在[price_floor_int, price_floor_int+SCALE-1]区间
  price_floor_int <= price * SCALE <= price_floor_int + SCALE - 1;
  // 得到floor值:float price_floor = price_floor_int / SCALE;
}

这样price_floor就是保留对应小数位数的price向下取整结果。

三、无需离散化price的线性化备选方案

如果不想把price转离散,也可以直接线性化连续×连续的乘积,引入辅助变量z=price*time,用大M法约束:

dvar float price >= price_min, <= price_max;
dvar float time >= time_min, <= time_max;
dvar float z;

subject to {
  z >= Ub;
  // 大M法约束z = price*time的线性近似
  z >= price_min * time + time_min * price - price_min * time_min;
  z >= price_max * time + time_max * price - price_max * time_max;
  z <= price_max * time + time_min * price - price_min * time_min;
  z <= price_min * time + time_max * price - price_max * time_max;
}

这种方法的精度取决于price和time的上下界,界越紧,线性化效果越好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 00:33:34