我想线性化两个浮点变量的乘积,假设一个模型有x * y的乘积,其中x和y是浮点变量,0〈= x〈= 1,0〈= y〈= 1,如何线性化这个乘积?
gcuhipw91#
我在OPL/CPLEX here中给出了一个例子,你要做的就是记住
4*x*y=(x+y)*(x+y)-(x-y)(x-y)
如果你做一个变量改变X=x+y和Y=x-y
x*y
变成
1/4*(X*X-Y*Y)
其是可分离的。然后你就可以用分段线性函数来插值函数x*x:
// y=x*x interpolation int sampleSize=10000; float s=0; float e=100; float x[i in 0..sampleSize]=s+(e-s)*i/sampleSize; int nbSegments=20; float x2[i in 0..nbSegments]=(s)+(e-s)*i/nbSegments; float y2[i in 0..nbSegments]=x2[i]*x2[i]; float firstSlope=0; float lastSlope=0; tuple breakpoint // y=f(x) { key float x; float y; } sorted { breakpoint } breakpoints={<x2[i],y2[i]> | i in 0..nbSegments}; float slopesBeforeBreakpoint[b in breakpoints]= (b.x==first(breakpoints).x) ?firstSlope :(b.y-prev(breakpoints,b).y)/(b.x-prev(breakpoints,b).x); pwlFunction f=piecewise(b in breakpoints) { slopesBeforeBreakpoint[b]->b.x; lastSlope } (first(breakpoints).x, first(breakpoints).y); assert forall(b in breakpoints) f(b.x)==b.y; float maxError=max (i in 0..sampleSize) abs(x[i]*x[i]-f(x[i])); float averageError=1/(sampleSize+1)*sum (i in 0..sampleSize) abs(x[i]*x[i]-f(x[i])); execute { writeln("maxError = ",maxError); writeln("averageError = ",averageError); } dvar float a in 0..10; dvar float b in 0..10; dvar float squareaplusb; dvar float squareaminusb; maximize a+b; dvar float ab; subject to { ab<=10; ab==1/4*(squareaplusb-squareaminusb); squareaplusb==f(a+b); squareaminusb==f(a-b); }
1条答案
按热度按时间gcuhipw91#
我在OPL/CPLEX here中给出了一个例子,你要做的就是记住
如果你做一个变量改变X=x+y和Y=x-y
变成
其是可分离的。
然后你就可以用分段线性函数来插值函数x*x: