Skip to content

二次模型中的区间松弛 ​

QuadraticSlackRangeFunction 精确表示二次表达式到闭区间 [lower,upper] 的距离:

s=max(lower−p(x), p(x)−upper, 0)

构造器要求 lower <= upper。

求解器数学模型 ​

令 a=lower−p(x)、b=p(x)−upper。实现分别对 a、b 注册精确正部函数,并将两者相加。等价地,令 s≥0,z0,z1,z2 为二元选择变量,Mi 为有效上界,则实际约束为

s≥a,s≥b,s≥0,s≤a+M0(1−z0),s≤b+M1(1−z1),s≤M2(1−z2),z0+z1+z2=1.

因此区间内部结果为零,区间外结果为精确的单侧违反量。

Kotlin API ​

Kotlin 提供原生二次符号:

kotlin
val slack = QuadraticSlackRangeFunction(
    input = inputQuadratic,
    lower = Flt64(1.0),
    upper = Flt64(2.0),
    bigM = Flt64(100.0),
    converter = IntoValue.Identity,
    name = "quadratic-slack-range"
)

对于线性表达式,使用 SlackRangeFunction(input, lower, upper, bigM, converter, name);它同样使用精确最大值模型,并公开内部 MaxFunction 的结果多项式。

Rust API ​

rust
let slack = QuadraticSlackRangeFunction::new(
    23, "quadratic_slack_range", input, 1.0_f64, 2.0_f64,
);
assert_eq!(slack.calculate_value(&tokens, false), Some(1.0));

当输入不含二次项时,精确的线性区间距离模型直接使用原始线性输入;真正含二次项的输入会先获得一个有符号线性桥接变量和一条二次桥接等式。with_big_m 可提供显式 Big-M;否则在可用时使用已注册的 token 边界。result_variable() 是连续变量。

Kotlin/Rust 示例 ​

kotlin
import fuookami.ospf.kotlin.core.solver.value.IntoValue
import fuookami.ospf.kotlin.core.symbol.function.QuadraticSlackRangeFunction
import fuookami.ospf.kotlin.math.algebra.number.Flt64

val slack = QuadraticSlackRangeFunction(
    input = inputQuadratic,
    lower = Flt64(1.0),
    upper = Flt64(2.0),
    bigM = Flt64(100.0),
    converter = IntoValue.Identity,
    name = "quadratic-slack-range"
)
check(slack.evaluate(values, null, IntoValue.Identity) == Flt64(1.0))
rust
use ospf_rust_core::symbol::FunctionSymbol;
use ospf_rust_core::symbol::function::QuadraticSlackRangeFunction;

let slack = QuadraticSlackRangeFunction::new(
    23, "quadratic_slack_range", input, 1.0_f64, 2.0_f64,
);
assert_eq!(slack.calculate_value(&tokens, false), Some(1.0));

测试与参考 ​