Decision Optimization

Decision Optimization

Delivers prescriptive analytics capabilities and decision intelligence to improve decision-making.

 View Only
  • 1.  How to multiply two decision variables

    Posted Fri June 02, 2017 03:00 AM

    Hi,

    if one of the decision variable is binary you may look at https://www.ibm.com/developerworks/community/forums/html/threadTopic?id=aa9aa3db-4fbc-4209-a767-5b5e54902cbd&ps=25

    But what if not ?

    You may use https://www.ibm.com/support/knowledgecenter/SSSA5P_12.7.1/ilog.odms.cplex.help/CPLEX/UsrMan/topics/cont_optim/qcp/01_QCP_title_synopsis.html

    or you may try to move to CPO. CP supports only integer decision variables. However, it is possible to constrain floating point expressions, or to use them as an objective term. It is also possible to declare floating point expressions with the dexpr keyword.

    Here, I want to help those who want to stay MIP and need to deal with

    dvar float x;
    dvar float y;

    subject to
    {
    x*y<=10;
    }

    What you can do is remember that

    4*x*y=(x+y)*(x+y)-(x-y)(x-y)

    So if you do a variable change X=x+y and Y=x-y

    x*y

    becomes

    1/4*(X*X-Y*Y)

    which is separable.

    And then you are able to interpolate the function x*x by piecewise linear function:

    // 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);
    }

    And then CPLEX will solve

     

    regards

     

     

     


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 2.  Re: How to multiply two decision variables

    Posted Fri December 22, 2017 09:57 AM

    Hi,

    offline bright people asked me to give more details.

    Let me do that.

    Suppose you want to multiply 2 float decision variables.

    With CPO you may write:

    using CP;

    int scale=1000;

    dvar int scalea in 0..10000;
    dvar int scaleb in 0..10000;

    dexpr float a =scalea/scale;
    dexpr float b = scaleb/scale;

    maximize a+b;

    subject to
    {
        a*b<=10;
    }

    with CPLEX you could do

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

     

    regards


    #DecisionOptimization
    #OPLusingCPLEXOptimizer