最小值
MinFunction 表示一个或多个线性多项式的最小值:
契约
- 输入:非空的
List<LinearPolynomial<V>>(n >= 1)。 - 输出:
resultVar,其类型为有符号RealVar,并通过resultPolynomial暴露。 evaluate求值每个输入并返回最小值;缺少符号值时返回null。V必须实现RealNumber<V>与NumberField<V>,并传入匹配的IntoValue<V>转换器。
数学定义
实现使用二进制 selectorVars
当某个候选对应的选择变量为 0 时,该候选被强制等于结果;其余不等式则强制结果不大于每个候选。
适用域与边界
solver 结果是有符号的 RealVar;当每个候选都有有限界时,结果范围会收紧到候选范围,因此可以表示负的最小值。推导 Big-M 需要候选有限界;否则当前回退值为 bigM 必须覆盖所有候选差距。推导边界时,每个候选的 Big-M 等于该候选上界减去所有候选中最小的下界。
当前 API
Kotlin
MinFunction 与 MaxFunction 声明在同一个源码文件中(不存在独立实现文件):Max.kt(MinFunction)
MinFunction(
polynomials: List<LinearPolynomial<V>>,
bigM: V? = null,
converter: IntoValue<V>,
name: String = "min",
displayName: String? = null
)伴生工厂还提供 fromSymbols,面向 LinearIntermediateSymbol<V> 候选。
Rust
Rust 在 MinFunction 中使用 flatten::Linear<V>:
MinFunction::new(id: u64, name: &str, polynomials: Vec<Linear<V>>, exact: bool) -> MinFunction<V>exact = true 为每个候选创建一个二值选择器并注册精确选择模型;exact = false 只保留不等式包络。与 Kotlin 不同,Rust 构造器没有 bigM 或 converter 参数,结果通过 result_variable() 暴露。
求解器数学模型
令结果为 exact = true 实际传入
被选候选的 exact = false 只保留
evaluate 与 solver 的差异
evaluate 直接折叠候选值,不执行 solver 侧的结果范围收紧。solver 注册会把结果范围收紧到候选范围,并依赖有效的 Big-M;Big-M 过小时可能排除真正的最小值。
示例与测试
import fuookami.ospf.kotlin.core.solver.value.IntoValue
import fuookami.ospf.kotlin.core.symbol.function.MinFunction
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 min = MinFunction(
polynomials = listOf(xPoly, yPoly),
bigM = Flt64(10.0),
converter = IntoValue.Identity,
name = "min"
)
val value = min.evaluate(mapOf<Symbol, Flt64>(x to Flt64.two, y to Flt64(5.0)))
check(value != null && (value eq Flt64.two))use ospf_rust_core::symbol::flatten::{Linear, LinearMonomial};
use ospf_rust_core::symbol::function::MinFunction;
let x = Linear::new(vec![LinearMonomial::new(1.0, 0)], 0.0);
let y = Linear::new(vec![LinearMonomial::new(1.0, 1)], 0.0);
let min = MinFunction::new(1, "min", vec![x, y], true);
assert!(min.exact());
let _result = min.result_variable();完整示例:MinTest.kt
Core 验证:MaxAndMaskingFunctionGenericEvaluateTest.kt
Rust 源码与跨语言回归覆盖:max.rs 和 gurobi_linear_function_kotlin_parity.rs。
MinMaxFunction 与 MaxMinFunction
虽然名称容易引起误解,MinMaxFunction 实际通过委托给内部 MaxFunction 来计算最大值,并转发求值、辅助变量和约束注册。MaxMinFunction 通过委托给内部 MinFunction 来计算最小值。名称描述的是优化语境下的解释,而不是另一种聚合算法。两个包装器都接收相同的 polynomials、可选 bigM、converter、name 和可选 displayName 参数。它们的 fromSymbols 工厂接收 List<LinearIntermediateSymbol<V>>,返回 LinearFunctionSymbolAdapter;该适配器仅用于衔接中间符号 API。
源码:MinMax.kt(MinMaxFunction 与 MaxMinFunction)
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"
)