同状态
SameAsFunction 在所有输入不等式的满足状态相同(要么全部满足,要么全部不满足)时返回 one。
契约
- 输入:非空的
List<LinearInequality<V>>。 constraint = true(默认)会在 solver 模型中强制所有满足标志相等。constraint = false只度量标志是否相等,不强制输入不等式一致。- 输出:二值
resultPolynomial;直接求值在状态一致时为 one,否则为 zero。 epsilon是比较容差,m是每个输入指标可选的 Big-M。
定义与数学模型
令
当 constraint 为 true 时,模型添加
当 constraint 为 false 且
单个输入时,度量模式固定
求解器数学模型
Kotlin 先为每个不等式注册满足指标
在度量模式下,使用二值绝对差约束创建
Rust 较窄的二元函数则对
当前 API
Kotlin
import fuookami.ospf.kotlin.core.solver.value.IntoValue
import fuookami.ospf.kotlin.core.symbol.function.SameAsFunction
import fuookami.ospf.kotlin.math.algebra.number.Flt64
import fuookami.ospf.kotlin.math.symbol.Symbol
import fuookami.ospf.kotlin.math.symbol.inequality.Comparison
import fuookami.ospf.kotlin.math.symbol.inequality.LinearInequality
import fuookami.ospf.kotlin.math.symbol.monomial.LinearMonomial
import fuookami.ospf.kotlin.math.symbol.polynomial.LinearPolynomial
import fuookami.ospf.kotlin.core.variable.RealVar
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 zero = LinearPolynomial<Flt64>(emptyList(), Flt64.zero)
val inequalities = listOf(
LinearInequality(xPoly, zero, Comparison.LE, "x_le_0"),
LinearInequality(yPoly, zero, Comparison.LE, "y_le_0")
)
val same = SameAsFunction(
inequalities = inequalities,
constraint = false,
epsilon = Flt64(1e-6),
m = Flt64(10.0),
converter = IntoValue.Identity,
name = "same"
)
val value = same.evaluate(
mapOf<Symbol, Flt64>(x to Flt64.zero, y to Flt64.one)
)
check(value == Flt64.zero)Rust
Rust 提供 SameAsFunction,但形状比 Kotlin 的不等式列表 API 更窄:
SameAsFunction::new(
id: u64,
name: &str,
first: Linear<V>,
second: Linear<V>,
tolerance: V,
) -> SameAsFunction<V>它在 tolerance 内比较两个线性表达式,创建二值 result_variable(),没有 Rust constraint 开关,也不接收 LinearInequality 列表。因此它是最接近的“两表达式相等” API,并不是 Kotlin“所有不等式状态一致”函数的一一对应实现。
evaluate 与 solver 的差异
直接求值计算每个不等式状态并始终返回度量值 constraint 参数如何。solver 注册不同:constraint = true 将状态相等作为硬约束;constraint = false 将度量结果连接到状态是否相等。等式或严格边界附近,直接比较使用实现的 epsilon 规则,而指标约束使用 Big-M/tolerance。
边界、tolerance 与 Undefined
不等式列表必须非空(init 会强制这一点)。缺少符号时直接求值返回 null。调用方必须提供足够的有限 Big-M,或允许从每个差值多项式推导。该函数不会返回 TruthValue.Undefined;无效注册通过失败 Result 暴露。
示例与测试
import fuookami.ospf.kotlin.core.solver.value.IntoValue
import fuookami.ospf.kotlin.core.symbol.function.SameAsFunction
import fuookami.ospf.kotlin.math.algebra.number.Flt64
import fuookami.ospf.kotlin.math.symbol.Symbol
import fuookami.ospf.kotlin.math.symbol.inequality.Comparison
import fuookami.ospf.kotlin.math.symbol.inequality.LinearInequality
import fuookami.ospf.kotlin.math.symbol.monomial.LinearMonomial
import fuookami.ospf.kotlin.math.symbol.polynomial.LinearPolynomial
import fuookami.ospf.kotlin.core.variable.RealVar
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 zero = LinearPolynomial<Flt64>(emptyList(), Flt64.zero)
val inequalities = listOf(
LinearInequality(xPoly, zero, Comparison.LE, "x_le_0"),
LinearInequality(yPoly, zero, Comparison.LE, "y_le_0")
)
val same = SameAsFunction(
inequalities = inequalities,
constraint = false,
epsilon = Flt64(1e-6),
m = Flt64(10.0),
converter = IntoValue.Identity,
name = "same"
)
val value = same.evaluate(
mapOf<Symbol, Flt64>(x to Flt64.zero, y to Flt64.one)
)
check(value == Flt64.zero)use ospf_rust_core::symbol::flatten::{Linear, LinearMonomial};
use ospf_rust_core::symbol::function::SameAsFunction;
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 same = SameAsFunction::new(1, "same", first, second, 1.0e-6_f64);
let _result = same.result_variable();- Core 测试:
FunctionSymbolSameAsGenericRegistrationTest.kt - 示例目录(当前没有专门的同状态文件):linear_function
Rust 源码:same_as.rs。