Commit 50be9cf4 authored by David Bommes's avatar David Bommes

iproved GUROBI and CPLEX interfaces

git-svn-id: http://www.openflipper.org/svnrepo/CoMISo/trunk@256 1355f012-dd97-4b2f-ae87-10fa9f823a57
parent 79211a6c
......@@ -4,7 +4,7 @@
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
* www.rwth-graphics.de *
* *
*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*
* This file is part of CoMISo. *
* *
* CoMISo is free software: you can redistribute it and/or modify *
......@@ -27,13 +27,13 @@
#ifdef COMISODLL
#ifdef USECOMISO
#define COMISODLLEXPORT __declspec(dllimport)
#define COMISODLLEXPORTONLY
#define COMISODLLEXPORTONLY
#else
#define COMISODLLEXPORT __declspec(dllexport)
#define COMISODLLEXPORTONLY __declspec(dllexport)
#endif
#else
#define COMISODLLEXPORT
#define COMISODLLEXPORT
#define COMISODLLEXPORTONLY
#endif
#else
......
......@@ -66,6 +66,45 @@ public:
const bool _silent = false) // time limit in seconds
{ std::vector<PairIndexVtype> dc; return solve(_problem, _constraints, dc, _time_limit, _silent);}
// same as previous but more control over stopping criteria
// the optimizer runs in two phases
// phase 1) stops if solution with a MIP gap lower than _gap0 is found or _time_limit0 is reached
// phase 2) starts only if in phase 1 no solution with a MIP gap lower than _gap1 was found and
// uses _gap1 and _time_limit2 as parameters
inline bool solve_two_phase(NProblemInterface* _problem, // problem instance
std::vector<NConstraintInterface*>& _constraints, // linear constraints
std::vector<PairIndexVtype>& _discrete_constraints, // discrete constraints
const double _time_limit0 = 60, // time limit phase 1 in seconds
const double _gap0 = 0.001, // MIP gap phase 1
const double _time_limit1 = 120, // time limit phase 2 in seconds
const double _gap1 = 0.2, // MIP gap phase 2
const bool _silent = false);
// optimization with additional lazy constraints that are only added iteratively to the problem if not satisfied
inline bool solve(NProblemInterface* _problem,
const std::vector<NConstraintInterface*>& _constraints,
const std::vector<NConstraintInterface*>& _lazy_constraints,
std::vector<PairIndexVtype>& _discrete_constraints, // discrete constraints
const double _almost_infeasible = 0.5,
const int _max_passes = 5,
const double _time_limit = 60,
const bool _silent = false);
// same as above with additional lazy constraints that are only added iteratively to the problem if not satisfied
inline bool solve(NProblemInterface* _problem,
const std::vector<NConstraintInterface*>& _constraints,
const std::vector<NConstraintInterface*>& _lazy_constraints,
const double _almost_infeasible = 0.5,
const int _max_passes = 5,
const double _time_limit = 60,
const bool _silent = false)
{
std::vector<PairIndexVtype> dc; return solve(_problem, _constraints, _lazy_constraints, dc, _almost_infeasible, _max_passes, _time_limit, _silent);
}
// with handling of cone constrints
inline bool solve2(NProblemInterface* _problem, // problem instance
std::vector<NConstraintInterface*>& _constraints, // linear constraints
......@@ -78,6 +117,8 @@ public:
// void set_problem_env_output_path( const std::string &_problem_env_output_path);
// void set_solution_input_path ( const std::string &_solution_input_path);
inline void test();
protected:
double* P(std::vector<double>& _v)
{
......@@ -89,6 +130,9 @@ protected:
private:
inline void add_constraint_to_model( NConstraintInterface* _constraint, std::vector<IloNumVar>& _vars, IloModel& _model, IloEnv& _env, double* _x);
// CPLEX environment
// IloEnv env_;
......
This diff is collapsed.
This diff is collapsed.
......@@ -57,6 +57,51 @@ public:
std::vector<PairIndexVtype>& _discrete_constraints, // discrete constraints
const double _time_limit = 60 ); // time limit in seconds
bool solve(NProblemInterface* _problem, // problem instance
std::vector<NConstraintInterface*>& _constraints, // linear constraints
const double _time_limit = 60 ) // time limit in seconds
{
std::vector<PairIndexVtype> dc; return solve(_problem, _constraints, dc, _time_limit);
}
// same as previous but more control over stopping criteria
// the optimizer runs in two phases
// phase 1) stops if solution with a MIP gap lower than _gap0 is found or _time_limit0 is reached
// phase 2) starts only if in phase 1 no solution with a MIP gap lower than _gap1 was found and
// uses _gap1 and _time_limit2 as parameters
bool solve_two_phase(NProblemInterface* _problem, // problem instance
std::vector<NConstraintInterface*>& _constraints, // linear constraints
std::vector<PairIndexVtype>& _discrete_constraints, // discrete constraints
const double _time_limit0 = 60, // time limit phase 1 in seconds
const double _gap0 = 0.001, // MIP gap phase 1
const double _time_limit1 = 120, // time limit phase 2 in seconds
const double _gap1 = 0.2 ); // MIP gap phase 2
// optimization with additional lazy constraints that are only added iteratively to the problem if not satisfied
bool solve(NProblemInterface* _problem,
const std::vector<NConstraintInterface*>& _constraints,
const std::vector<NConstraintInterface*>& _lazy_constraints,
std::vector<PairIndexVtype>& _discrete_constraints, // discrete constraints
const double _almost_infeasible = 0.5,
const int _max_passes = 5,
const double _time_limit = 60,
const bool _silent = false);
// same as above with additional lazy constraints that are only added iteratively to the problem if not satisfied
bool solve(NProblemInterface* _problem,
const std::vector<NConstraintInterface*>& _constraints,
const std::vector<NConstraintInterface*>& _lazy_constraints,
const double _almost_infeasible = 0.5,
const int _max_passes = 5,
const double _time_limit = 60,
const bool _silent = false)
{
std::vector<PairIndexVtype> dc; return solve(_problem, _constraints, _lazy_constraints, dc, _almost_infeasible, _max_passes, _time_limit, _silent);
}
void set_problem_output_path ( const std::string &_problem_output_path);
void set_problem_env_output_path( const std::string &_problem_env_output_path);
void set_solution_input_path ( const std::string &_solution_input_path);
......@@ -70,6 +115,9 @@ protected:
return 0;
}
private:
void add_constraint_to_model(COMISO::NConstraintInterface* _constraint, GRBModel& _model, std::vector<GRBVar>& _vars, double * _x);
private:
// filenames for exporting/importing gurobi solutions
......
......@@ -9,8 +9,11 @@
#if (COMISO_GUROBI_AVAILABLE && COMISO_BOOST_AVAILABLE)
#include <QTemporaryFile>
#include <QFileInfo>
#if (COMISO_QT4_AVAILABLE)
#include <QTemporaryFile>
#include <QFileInfo>
#endif
#include <boost/filesystem.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/regex.hpp>
......@@ -82,6 +85,7 @@ void GurobiHelper::outputModelToMpsGz(GRBModel &model, const std::string &proble
#if OUTPUT_UNCOMPRESSED_WITH_CONSTANT_COMMENT
boost::scoped_ptr<TempFileGuard> tempFileGuard;
{
#if (COMISO_QT4_AVAILABLE)
QTemporaryFile tempFile("XXXXXX.mps");
tempFile.setAutoRemove(false);
tempFile.open();
......@@ -90,6 +94,7 @@ void GurobiHelper::outputModelToMpsGz(GRBModel &model, const std::string &proble
// we initialize tempFileGuard right here.
tempFileGuard.reset(new TempFileGuard(QFileInfo(tempFile).absoluteFilePath().toStdString()));
tempFile.close();
#endif
}
const std::string fileName = tempFileGuard->filePath().string();
......@@ -128,6 +133,7 @@ void GurobiHelper::outputModelToMpsGz(GRBModel &model, const std::string &proble
void GurobiHelper::importInitialSolutionIntoModel(GRBModel &model, const std::string &solution_path_) {
boost::scoped_ptr<TempFileGuard> tempFileGuard;
{
#if (COMISO_QT4_AVAILABLE)
QTemporaryFile tempFile("XXXXXX.mst");
tempFile.setAutoRemove(false);
tempFile.open();
......@@ -136,6 +142,7 @@ void GurobiHelper::importInitialSolutionIntoModel(GRBModel &model, const std::st
// we initialize tempFileGuard right here.
tempFileGuard.reset(new TempFileGuard(QFileInfo(tempFile).absoluteFilePath().toStdString()));
tempFile.close();
#endif
}
const std::string fileName = tempFileGuard->filePath().string();
......
#ifndef QUADRATICPROBLEM_H
#define QUADRATICPROBLEM_H
#include <CoMISo/Config/config.hh>
#include <CoMISo/Utils/StopWatch.hh>
#include <vector>
#include <CoMISo/NSolver/NProblemInterface.hh>
#include <Eigen/Eigen>
#include <Eigen/Core>
#include <Eigen/Sparse>
// this problem optimizes the quadratic functional 0.5*x^T A x -x^t b + c
class QuadraticProblem : public COMISO::NProblemInterface
{
public:
// Sparse Matrix Type
// typedef Eigen::DynamicSparseMatrix<double,Eigen::ColMajor> SMatrixNP;
QuadraticProblem(SMatrixNP& _A, VectorXd _b, const double _c)
: A_(_A), c_(_c)
{
if(A_.rows() != A_.cols())
std::cerr << "Warning: matrix not square in QuadraticProblem" << std::endl;
b_ = _b;
x_ = Eigen::VectorXd(A_.cols(),0.0);
}
// number of unknowns
virtual int n_unknowns()
{
return A_.rows();
}
// initial value where the optimization should start from
virtual void initial_x(double* _x)
{
for(unsigned int i=0; i<this->n_unknowns(); ++i)
_x[i] = x_[i];
}
// function evaluation at location _x
virtual double eval_f( const double* _x )
{
Eigen::Map<const VectorXd> x(_x, this->n_unknowns());
return (double)(x.transpose()*A_*x)*0.5 - (double)(x.transpose()*b_) + c_;
}
// gradient evaluation at location _x
virtual void eval_gradient( const double* _x, double* _g)
{
Eigen::Map<const VectorXd> x(_x, this->n_unknowns());
Eigen::Map<VectorXd> g(_g, this->n_unknowns());
g = A_*x - b_;
}
// hessian matrix evaluation at location _x
virtual void eval_hessian ( const double* _x, SMatrixNP& _H)
{
_H = A_;
}
// print result
virtual void store_result ( const double* _x )
{
Eigen::Map<const VectorXd> x(_x, this->n_unknowns());
x_ = x;
}
// get current solution
Eigen::VectorXd& x() { return x_;}
// advanced properties
virtual bool constant_hessian() { return true; }
private:
// quadratic problem 0.5*x^T A x -x^t b + c
SMatrixNP A_;
Eigen::VectorXd b_;
double c_;
// current solution, which is also used as initial value
Eigen::VectorXd x_;
};
#endif // QUADRATICPROBLEM_H
......@@ -59,6 +59,11 @@
return !_finite(x);
}
inline int isfinite(double x)
{
return _finite(x);
}
}
inline double nearbyint(double x) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment