【C++/Cplex/Benders】vs2015调用cplex自带benders algorithm

原文链接: https://blog.csdn.net/flora_zhl/article/details/79502777

【benders strategy】

OFF -1 默认分支定界求解

AUTO 0

USER 1 完全按照用户设定的annotation

WORKERS 2 先按照用户的annotation,再自动优化

FULL 3 自动确定主问题(整数变量部分)和子问题(连续型变量部分)

【key】

IloCplex::LongAnnotation bendersdec = _solver.newLongAnnotation(IloCplex::BendersAnnotation,0);
for (int i = 0; i < MFUtil::scnNum; i++)
{
	for (int j = 0; j < _legList.size(); j++)
	{
		_solver.setAnnotation(bendersdec, _z_si[i][j], i+1);
	}
}

_solver.setParam(IloCplex::Param::Benders::Strategy,
	IloCplex::BendersUser);

【…\cplex\examples\src\cpp\ilobenders.cpp】

(默认:C:\Program Files\IBM\ILOG\CPLEX_Studio127\cplex\examples\src)

model和ann文件均读入,cplex全自动模式(FULL)

// Example:
// ilobenders UFL_30_120_1.mps.gz UFL_30_120_1.ann
//

#include
ILOSTLBEGIN

static void usage (const char *progname);

int
main (int argc, char **argv)
{
IloEnv env;
try {
IloModel model(env);
IloCplex cpx(env);
bool hasannofile = false;

  // Check the arguments.
  if ( argc == 3 ) {
 hasannofile = true;
  }
  else if ( argc != 2 ) {
     usage (argv[0]);
     throw(-1);
  }

  IloObjective   obj;
  IloNumVarArray var(env);
  IloRangeArray  rng(env);

  // Read the problem file.
  cpx.importModel(model, argv[1], obj, var, rng);

  // Extract the model.
  cpx.extract(model);

  // If provided, read the annotation file.
  if ( hasannofile ) {
 cpx.readAnnotations(argv[2]);
  }
  else {
 // Set benders strategy to auto-generate a decomposition.
 cpx.setParam(IloCplex::Param::Benders::Strategy,
	      IloCplex::BendersFull);

 // Write out the auto-generated annotation.
 cpx.writeBendersAnnotation("benders.ann");
  }

  // Solve the problem using Benders' decomposition.
  if ( !cpx.solve() ) {
     env.error() << "Failed to optimize." << endl;
     throw(-1);
  }

  IloAlgorithm::Status status = cpx.getStatus();
  double bestObjValue = cpx.getBestObjValue();
  double objValue = cpx.getObjValue();
  env.out() << "Solution status: " << status << endl;
  env.out() << "Best bound:      " << bestObjValue << endl;
  env.out() << "Best integer:    " << objValue << endl;

}
catch (IloException& e) {
cerr << "Concert exception caught: " << e << endl;
throw;
}
catch (…) {
cerr << “Unknown exception caught” << endl;
throw;
}

env.end();
return 0;
} // END main

static void usage (const char *progname)
{
cerr << “Usage: " << progname << " filename [annofile]” << endl;
cerr << " where filename is a file with extension " << endl;
cerr << " MPS, SAV, or LP (lower case is allowed)" << endl;
cerr << " and annofile is an optional .ann file with model annotations" << endl;
cerr << " Exiting…" << endl;
} // END usage

【…\cplex\examples\src\cpp\facility.cpp】选址问题举例

#include

ILOSTLBEGIN

typedef IloArray FloatMatrix;
typedef IloArray NumVarMatrix;

static void usage(const char *progname);
int
main(int argc, char **argv)
{
IloEnv env;
try {
IloInt i, j;

  IloNumArray capacity(env), fixedCost(env);
  FloatMatrix cost(env);
  IloInt      nbLocations;
  IloInt      nbClients;
  int         doBenders = false;

  const char* filename  = "../../../examples/data/facility.dat";
  for (i = 1; i < argc; i++) {
     if ( argv[i][0] != '-' )
        break;
     switch ( argv[i][1] ) {
     case 'a':
        doBenders = 2;
        break;
     case 'b':
        doBenders = true;
        break;
     case 'd':
        break;
     default:
        usage (argv[0]);
     }
  }
  if (i < argc) 
     filename = argv[i];
  ifstream file(filename);
  if (!file) {
     cerr << "ERROR: could not open file '" << filename
          << "' for reading" << endl;
     usage (argv[0]);
     throw(-1);
  }

  file >> capacity >> fixedCost >> cost;
  nbLocations = capacity.getSize();
  nbClients   = cost.getSize(); 

  IloBool consistentData = (fixedCost.getSize() == nbLocations);
  for(i = 0; consistentData && (i < nbClients); i++)
     consistentData = (cost[i].getSize() == nbLocations);
  if (!consistentData) {
     cerr << "ERROR: data file '" 
          << filename << "' contains inconsistent data" << endl;
     throw(-1);
  }

  IloNumVarArray open(env, nbLocations, 0, 1, ILOINT);
  NumVarMatrix supply(env, nbClients);
  for(i = 0; i < nbClients; i++)
     supply[i] = IloNumVarArray(env, nbLocations, 0, 1, ILOFLOAT);

  IloModel model(env);
  for(i = 0; i < nbClients; i++)
     model.add(IloSum(supply[i]) == 1);
  for(j = 0; j < nbLocations; j++) {
     IloExpr v(env);
     for(i = 0; i < nbClients; i++)
        v += supply[i][j];
     model.add(v <= capacity[j] * open[j]);
     v.end();
  }

  IloExpr obj = IloScalProd(fixedCost, open);
  for(i = 0; i < nbClients; i++) {
     obj += IloScalProd(cost[i], supply[i]);
  }
  model.add(IloMinimize(env, obj));
  obj.end();

  IloCplex cplex(env);
  cplex.extract(model);

  if ( doBenders == 1 ) {
     /* We specify the structure for doing a Benders decomposition by telling
      * CPLEX which variables are in the master problem using annotations.
      */
     IloCplex::LongAnnotation bendersdec = cplex.newLongAnnotation (IloCplex::BendersAnnotation, 1);
     for(j = 0; j < nbLocations; j++) {
        cplex.setAnnotation (bendersdec, open[j], 0);
     }
  }
  else if ( doBenders == 2 ) {
     /* We let CPLEX find out the decomposition. In the case of an 
      * uncapacitated facility location the variable of the master problem
      * are the integer variables and CPLEX will find the right decomposition.
      */
     cplex.setParam(IloCplex::Param::Benders::Strategy, 
                    IloCplex::BendersFull);
  }

  cplex.solve();

  cplex.out() << "Solution status: " << cplex.getStatus() << endl;

  IloNum tolerance = cplex.getParam(
     IloCplex::Param::MIP::Tolerances::Integrality);
  cplex.out() << "Optimal value: " << cplex.getObjValue() << endl;
  for(j = 0; j < nbLocations; j++) {
     if (cplex.getValue(open[j]) >= 1 - tolerance) {
        cplex.out() << "Facility " << j << " is open, it serves clients ";
        for(i = 0; i < nbClients; i++) {
           if (cplex.getValue(supply[i][j]) >= 1 - tolerance)
              cplex.out() << i << " ";
        }
        cplex.out() << endl; 
     }
  }

}
catch(IloException& e) {
cerr << " ERROR: " << e << endl;
}
catch(…) {
cerr << " ERROR" << endl;
}
env.end();
return 0;
}

static void usage(const char *progname)
{
cerr << “Usage: " << progname << “[options] [inputfile]” << endl;
cerr << " where” << endl;
cerr << " inputfile describe a facility location instance as in" << endl;
cerr << " …/…/…/examples/data/facility.dat. If no input file" << endl;
cerr << " is specified read the file in example/data directory." < cerr << " Options are:" << endl;
cerr << " -d solve problem without using decomposition (default)" << endl;
cerr << " -b solve problem with Benders specifying a decomposition" << endl;
cerr << " -a solve problem with Benders letting CPLEX do the decomposition" << endl;
cerr << " Exiting…" << endl;
throw (-1);
}
facility.dat 5个待选地址,8个客户

[ 3, 1, 2, 4, 1]
[ 480, 200, 320, 340, 300]
[[ 24, 74, 31, 51, 84],
[ 57, 54, 86, 61, 68],
[ 57, 67, 29, 91, 71],
[ 54, 54, 65, 82, 94],
[ 98, 81, 16, 61, 27],
[ 13, 92, 34, 94, 87],
[ 54, 72, 41, 12, 78],
[ 54, 64, 65, 89, 89]]

你可能感兴趣的:(cplex)