Skip to content

二元分段线性函数

形式

z=Blp(x,y)=kix+kiy+bi,x[ai,bi],y[ai,bi]i=0,1,2,...

常量

M=maxtT(max(maxxR,yRfut(x,y),maxxR,yRfvt(x,y)))

额外变量

ut[0,1] :在第 i 个三角形中 AiBi 向量的权重。

vt[0,1] :在第 i 个三角形中 AiCi 向量的权重。

wt{0,1} :在第 i 个三角形中的判定。

导出符号

z=tT(wtzt,0+ut(zt,1zt,0)+vt(zt,2zt,0))

数学模型

s.t.ut+M(1wt)fut(x,y),tTutM(1wt)fut(x,y),tTvt+M(1wt)fvt(x,y),tTvtM(1wt)fvt(x,y),tTtTwt=1ut+vtwt,tT

其中:

St=12(yt,1xt,2+yt,0(xt,1+xt,2)+xt,0(yt,1yt,2)+xt,1yt,2),tTfut(x,y)=12St(yt,0xt,2xt,0yt,2+(yt,2yt,0)x+(xt,0xt,2)y),tTfvt(x,y)=12St(xt,0yt,1yt,0xt,1+(yt,0yt,1)x+(xt,1xt,0)y),tT

推理过程

基本原理

(P0P=uP0P1+vP0P2)(u0)(v0)(u+v1))(PP0P1P2)(tT((Pt)(tT((tt)(Pt)))))

代数化基本原理

St=12(yt,1xt,2+yt,0(xt,1+xt,2)+xt,0(yt,1yt,2)+xt,1yt,2),tTfut(x,y)=12St(yt,0xt,2xt,0yt,2+(yt,2yt,0)x+(xt,0xt,2)y),tTfvt(x,y)=12St(xt,0yt,1yt,0xt,1+(yt,0yt,1)x+(xt,1xt,0)y),tT

逻辑特性:

tT(wt{0,1})tT((wt=1)(tT((tt)(wt=1))))tT((ut([0,1]R+))(vt([0,1]R+)))tT(((wt=1)((ut=fut(x,y))(vt=fvt(x,y))))((wt=0)((ut=0)(vt=0))))

(二次型)数学模型:

s.t.ut=wtfut(x,y),tTvt=wtfvt(x,y),tTtTwt=1ut+vtwt,tT

线性化即可得到前述数学模型。

样例

kotlin
import kotlinx.coroutines.*
import fuookami.ospf.kotlin.utils.math.*
import fuookami.ospf.kotlin.core.frontend.variable.*
import fuookami.ospf.kotlin.core.frontend.expression.polynomial.*
import fuookami.ospf.kotlin.core.frontend.expression.symbol.linear_function.*
import fuookami.ospf.kotlin.core.frontend.inequality.*
import fuookami.ospf.kotlin.core.frontend.model.mechanism.*
import fuookami.ospf.kotlin.core.backend.plugins.scip.*

val x = URealVar("x")
val y = URealVar("y")
x.range.leq(Flt64.two)
y.range.leq(Flt64.two)

val blp = BivariateLinearPiecewiseFunction(
    x = x,
    y = y,
    points = listOf(
        point3(),
        point3(x = Flt64.two),
        point3(y = Flt64.two),
        point3(x = Flt64.two, y = Flt64.two),
        point3(x = Flt64.one, y = Flt64.one, z = Flt64.one)
    ),
    name = "z"
)

val model = LinearMetaModel()
model.add(x)
model.add(y)
model.add(blp)
model.maximize(blp)

val solver = ScipLinearSolver()
val result = runBlocking { solver(model) }
assert(result.value!!.solution[0] eq Flt64.one)
assert(result.value!!.solution[1] eq Flt64.one)

完整实现请参考:

完整样例请参考: