FICO
FICO Xpress Optimization Examples Repository
FICO Optimization Community FICO Xpress Optimization Home
Back to examples browserPrevious exampleNext example

Linearizations and approximations via SOS and piecewise linear (pwlin) expressions

Description
Various examples of using SOS (Special Ordered Sets of type 1 or 2) and piecewise linear expressions to represent nonlinear functions in MIP models implemented with Mosel (files *.mos) or BCL (files *.cxx).
  • approximating a continuous nonlinear function in a single variable via piecewise linear expressions (soslingc.mos) or SOS-1 (soslin.*);
  • approximating a continuous nonlinear function in two variables via SOS-2 (sosquad.*);
  • price breaks: all items discount (non-continuous piecewise linear function) formulated via piecewise linear expressions (pricebrai) or SOS-1 (pricebrai SOS);
  • incremental pricebreaks formulated via piecewise linear expressions (pricebrinc), SOS-2 (pricebrinc SOS), or binary variables (pricebrinc bin).
Further explanation of this example: Whitepaper 'MIP formulations and linearizations', Section Non-linear functions


Source Files
By clicking on a file name, a preview is opened at the bottom of this page.
soslin.cxx[download]
soslin.mos[download]
soslingc.mos[download]
sosquad.cxx[download]
sosquad.mos[download]





soslin.cxx

/********************************************************
  Xpress BCL C++ Example Problems
  ===============================

  file soslin.cxx
  ```````````````
  Using SOS-2 for approximating a function in one variable.
  - Example discussed in mipformref whitepaper -  

  (c) 2009 Fair Isaac Corporation
      author: S.Heipcke, Mar. 2009, rev. Feb. 2022
********************************************************/

#include <iostream>
#include "xprb_cpp.h"

using namespace std;
using namespace ::dashoptimization;

#define I 4

int main(int argc, char **argv)
{
 XPRBprob prob("testsos");
 XPRBvar x, y, w[I];
 XPRBexpr Defx, le, ly;
 double R[] ={1, 2.5, 4.5, 6.5};
 double FR[]={1.5, 6, 3.5, 2.5};
 int i;

// ...assign values to arrays R and F...

// Create the decision variables
 x = prob.newVar("x"); y = prob.newVar("y");
 for(i=0; i<I; i++) w[i] = prob.newVar("w");

// Define the SOS-2 with "reference row" coefficients from R
 for(i=0; i<I; i++) Defx += R[i]*w[i];
 prob.newSos("Defx", XPRB_S2, Defx); 
 for(i=0; i<I; i++) le += w[i];
 prob.newCtr("One", le == 1); 

// The variable and the corresponding function value we want to approximate
 prob.newCtr("Eqx", x == Defx);
 for(i=0; i<I; i++) ly += FR[i]*w[i];
 prob.newCtr("Eqy", y == ly);

// Set a lower bound on x to make the problem more interesting
 x.setLB(2);

// Solve the problem
 prob.setObj(y);
 prob.mipOptimize("");

 int mipstatus = prob.getMIPStat();
 switch (mipstatus) {
  case XPRB_MIP_NOT_LOADED:
  case XPRB_MIP_LP_NOT_OPTIMAL:
    cout << "Solving not started" << endl;
    break;
  case XPRB_MIP_LP_OPTIMAL:
    cout << "Root LP solved" << endl;
    break;
  case XPRB_MIP_UNBOUNDED:
    cout << "LP unbounded" << endl;
    break;
  case XPRB_MIP_NO_SOL_FOUND:
  case XPRB_MIP_INFEAS:
    cout << "MIP search started, no solution" << endl;
    break;
  case XPRB_MIP_SOLUTION:
  case XPRB_MIP_OPTIMAL:
    cout << "MIP solution: " << prob.getObjVal() << endl;
    break;
 }

 cout << x.getName() << ": " << x.getSol() << endl;
}

Back to examples browserPrevious exampleNext example