Skip to content

最大值 ​

MaxFunction 表示一个或多个线性多项式的最大值:

y=max(p1,p2,…,pn).

契约 ​

  • 输入:非空的 List<LinearPolynomial<V>>(n >= 1)。
  • 输出:resultVar,其类型为 RealVar,并通过 resultPolynomial 暴露。
  • evaluate 求值每个输入并返回最大值;缺少符号值时返回 null。
  • V 必须实现 RealNumber<V> 与 NumberField<V>,并传入匹配的 IntoValue<V> 转换器。

数学定义 ​

精确选择模型使用二进制 selectorVars si:

y≥pi(i=1,…,n),y−pi+Misi≤Mi,∑i=1nsi=1.

当某个候选对应的选择变量为 1 时,该候选被强制等于结果;其余不等式则强制结果不小于每个候选。

适用域与边界 ​

当前结果变量为有符号的 RealVar。当每个候选都有有限范围时,结果变量的范围会被收紧到 [miniloweri, maxiupperi],因此可以表示负的最大值。未传入 bigM 时,实现会尽可能使用每个候选的有限范围(每个候选取“最宽候选上界减其自身下界”);否则当前 Big-M 回退值为 106。显式值必须足以覆盖所有候选差距。

当前 API ​

Kotlin ​

源码:Max.kt(MaxFunction)

kotlin
MaxFunction(
    polynomials: List<LinearPolynomial<V>>,
    bigM: V? = null,
    converter: IntoValue<V>,
    name: String = "max",
    displayName: String? = null
)

伴生工厂还提供 fromSymbols,用于 LinearIntermediateSymbol<V> 列表。当候选已经是 LinearPolynomial<V> 时,普通构造器最直观。

Rust ​

Rust 对平展后的 Linear<V> 表达式暴露 MaxFunction:

rust
MaxFunction::new(
    id: u64,
    name: &str,
    polynomials: Vec<Linear<V>>,
    exact: bool,
) -> MaxFunction<V>

exact = true 为每个候选创建二值选择器,并注册恰好一个选择器的模型。exact = false 时,Rust 只注册 result >= p_i 下界;此时需要目标函数或其他上界才能让结果等于最大值。result_variable()、polynomials() 和 exact() 暴露内部状态。Rust 结果是连续变量;若模型有边界要求,调用方必须提供合适的变量范围。Rust 的 MinMaxFunction 和 MaxMinFunction 是对应的包装符号,但没有 exact 参数。

求解器数学模型 ​

令结果为 y、候选为 pi、选择变量 si∈{0,1}。Kotlin 与 Rust 的 exact = true 实际传入

y−pi≥0(1≤i≤n),y−pi+Misi≤Mi(1≤i≤n),∑i=1nsi=1.

Rust 的 exact = false 只注册 y−pi≥0;此时必须通过最小化或其他上界使结果等于最大值。Kotlin 始终注册精确选择模型。

evaluate 与 solver 的差异 ​

evaluate 直接折叠所有候选值,不产生 Big-M 或变量域副作用。solver 注册选择模型,并在每个候选都有有限范围时把结果域收紧到候选范围;Big-M 过小时,solver 可能不可行,而直接求值仍能成功。

示例与测试 ​

kotlin
import fuookami.ospf.kotlin.core.solver.value.IntoValue
import fuookami.ospf.kotlin.core.symbol.function.MaxFunction
import fuookami.ospf.kotlin.core.variable.RealVar
import fuookami.ospf.kotlin.math.algebra.number.Flt64
import fuookami.ospf.kotlin.math.symbol.Symbol
import fuookami.ospf.kotlin.math.symbol.inequality.eq
import fuookami.ospf.kotlin.math.symbol.monomial.LinearMonomial
import fuookami.ospf.kotlin.math.symbol.polynomial.LinearPolynomial

val x = RealVar("x")
val y = RealVar("y")
val xPoly = LinearPolynomial(listOf(LinearMonomial(Flt64.one, x)), Flt64.zero)
val yPoly = LinearPolynomial(listOf(LinearMonomial(Flt64.one, y)), Flt64.zero)
val max = MaxFunction(
    polynomials = listOf(xPoly, yPoly),
    bigM = Flt64(10.0),
    converter = IntoValue.Identity,
    name = "max"
)
val value = max.evaluate(mapOf<Symbol, Flt64>(x to Flt64.two, y to Flt64(5.0)))
check(value != null && (value eq Flt64(5.0)))
rust
use ospf_rust_core::symbol::flatten::{Linear, LinearMonomial};
use ospf_rust_core::symbol::function::MaxFunction;

let first = Linear::new(vec![LinearMonomial::new(1.0, 0)], 0.0);
let second = Linear::new(vec![LinearMonomial::new(1.0, 1)], 0.0);
let max = MaxFunction::new(1, "max", vec![first, second], true);
assert!(max.exact());
let _result = max.result_variable();

完整示例:MaxTest.kt

Core 验证:MaxAndMaskingFunctionGenericEvaluateTest.kt

Rust 源码与 parity 覆盖:max.rs 和 gurobi_linear_function_kotlin_parity.rs。

MinMaxFunction 与 MaxMinFunction ​

MinMax(p1,…,pn)=maxipi,MaxMin(p1,…,pn)=minipi.

虽然名称容易引起误解,MinMaxFunction 实际通过委托给内部 MaxFunction 来计算最大值,并转发求值、辅助变量和约束注册。MaxMinFunction 通过委托给内部 MinFunction 来计算最小值。名称描述的是优化语境下的解释,而不是另一种聚合算法。两个包装器都接收相同的 polynomials、可选 bigM、converter、name 和可选 displayName 参数。它们的 fromSymbols 工厂接收 List<LinearIntermediateSymbol<V>>,返回 LinearFunctionSymbolAdapter;该适配器仅用于衔接中间符号 API。

源码:MinMax.kt(MinMaxFunction 与 MaxMinFunction)

kotlin
val minMax = MinMaxFunction(
    polynomials = listOf(xPoly, yPoly),
    bigM = Flt64(10.0),
    converter = IntoValue.Identity,
    name = "min_max"
)
val maxMin = MaxMinFunction(
    polynomials = listOf(xPoly, yPoly),
    bigM = Flt64(10.0),
    converter = IntoValue.Identity,
    name = "max_min"
)

相关页面 ​

  • min:对应的最小值运算。
  • masking:二进制选择一个多项式或零。