【问题标题】:How to linearize the product of two float variables如何线性化两个浮点变量的乘积
【发布时间】:2018-08-07 20:25:53
【问题描述】:

我想线性化两个浮点变量的乘积。假设一个模型有乘积 x * y,其中 x 和 y 是浮点数,0

【问题讨论】:

  • 线性化是什么意思?还是线性化了?
  • 另外,什么语言?根据我的理解,Cplex 提供了许多替代方案,而浮点数可能意味着不同的东西。
  • 我正在使用 c++ 在 cplex 上构建数学模型,并且我想对具有两个连续变量乘积的约束进行线性化。我有一个约束 x * y (两个变量的乘积),其中这个变量的域是 0
  • 感谢您的澄清。您是否真的尝试过任何事情或自己进行过任何研究?
  • 我认为你不能完全线性化它。你可以用例如近似它分段线性表达式。

标签: c++ mathematical-optimization cplex


【解决方案1】:

我在 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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-19
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多