1 #ifndef OPENGM_EXTERNAL_MPLP_HXX_
2 #define OPENGM_EXTERNAL_MPLP_HXX_
49 const size_t maxIterLP = 1000,
50 const size_t maxIterTight = 100000,
51 const size_t maxIterLater = 20,
52 const double maxTime = 3600,
53 const double maxTimeLP = 1200,
54 const size_t numClusToAddMin = 5,
55 const size_t numClusToAddMax = 20,
56 const double objDelThr = 0.0002,
57 const double intGapThr = 0.0002,
58 const bool UAIsettings =
false,
59 const bool addEdgeIntersections =
true,
60 const bool doGlobalDecoding =
false,
61 const bool useDecimation=
false,
62 const bool lookForCSPs =
false,
64 const bool logMode =
false,
65 const std::string& logFile = std::string(),
67 const std::string& inputFile = std::string(),
68 const std::string& evidenceFile = std::string()
136 std::string
name()
const;
139 template<
class VISITOR>
143 typename GM::ValueType
bound()
const;
144 typename GM::ValueType
value()
const;
147 const GraphicalModelType&
gm_;
160 : gm_(gm), parameter_(para), mplpLogFile_(NULL), mplp_(NULL) {
181 if(MPLP_DEBUG_MODE) {
193 std::vector<int> var_sizes(
gm_.numberOfVariables());
194 for(
IndexType var = 0; var <
gm_.numberOfVariables(); ++var){
195 var_sizes[var] =
static_cast<int>(
gm_.numberOfLabels(var));
198 std::vector< std::vector<int> > all_factors(
gm_.numberOfFactors());
200 all_factors[f].resize(
gm_[f].numberOfVariables());
201 for(
IndexType i = 0; i <
gm_[f].numberOfVariables(); ++i){
202 all_factors[f][i] =
static_cast<int>(
gm_[f].variableIndex(i));
206 std::vector< std::vector<double> > all_lambdas(
gm_.numberOfFactors());
208 all_lambdas[f].resize(
gm_[f].size());
211 gm_[f].copyValuesSwitchedOrder(all_lambdas[f].begin());
214 for(
size_t i = 0; i < all_lambdas[f].size(); i++) {
215 all_lambdas[f][i] = -all_lambdas[f][i];
243 EmptyVisitorType visitor;
244 return this->infer(visitor);
248 template<
class VISITOR>
250 visitor.begin(*
this);
252 bool decimation_has_started =
false;
253 bool force_decimation =
false;
254 bool prevGlobalDecodingWas1 =
true;
257 std::map<std::vector<int>,
bool> triplet_set;
260 srand(parameter_.seed_);
274 for (
size_t i=0; i<=parameter_.maxIterLP_;++i){
275 value_old = mplp_->last_obj;
276 mplp_->RunMPLP(1, parameter_.objDelThr_, parameter_.intGapThr_);
278 if(!parameter_.logFile_.empty()) fflush(mplpLogFile_);
279 if(!parameter_.logFile_.empty()) fclose(mplpLogFile_);
283 if(((
double)(clock() - mplpStart_) / CLOCKS_PER_SEC) > parameter_.maxTimeLP_){
284 std::cout <<
"stop because of timelimit for LP switching to tightening" <<std::endl;
287 if(((
double)(clock() - mplpStart_) / CLOCKS_PER_SEC) > parameter_.maxTime_){
288 std::cout <<
"stop because of timelimit" <<std::endl;
291 if (std::fabs(value_old- mplp_->last_obj)<parameter_.objDelThr_ && i > 16){
292 std::cout <<
"stop because small progress" <<std::endl;
295 if(std::fabs(value()-bound())<parameter_.intGapThr_){
296 std::cout <<
"stop because small gap" <<std::endl;
301 for(
size_t iter=1; iter<=parameter_.maxIterTight_; iter++){
306 double int_gap = mplp_->last_obj - mplp_->m_best_val;
307 if(int_gap < parameter_.intGapThr_){
308 if (MPLP_DEBUG_MODE) std::cout <<
"Done! Integrality gap less than " << parameter_.intGapThr_ <<
"\n";
311 double time_elapsed = (double)(clock() - mplpStart_)/ CLOCKS_PER_SEC;
312 if (time_elapsed > parameter_.maxTime_) {
320 parameter_.maxIterLater_ = std::max(parameter_.maxIterLater_, static_cast<size_t>(600));
321 parameter_.objDelThr_ = std::min(parameter_.objDelThr_, 1e-5);
322 if (MPLP_DEBUG_MODE) std::cout <<
"Int gap small, so setting niter_later to " << parameter_.maxIterLater_ <<
" and obj_del_thr to " << parameter_.objDelThr_ <<
"\n";
326 if(parameter_.doGlobalDecoding_ && (((
double)clock() - mplp_->last_global_decoding_end_time)/CLOCKS_PER_SEC >= mplp_->last_global_decoding_total_time*4)) {
328 if(prevGlobalDecodingWas1) {
329 mplp_->RunGlobalDecoding(
false);
330 prevGlobalDecodingWas1 =
false;
332 mplp_->RunGlobalDecoding2(
false);
333 prevGlobalDecodingWas1 =
true;
338 if (MPLP_DEBUG_MODE) std::cout <<
"Now attempting to tighten LP relaxation..." << std::endl;
340 clock_t tightening_start_time = clock();
341 double bound=0;
double bound2 = 0;
342 int nClustersAdded = 0;
344 nClustersAdded += TightenTriplet(*mplp_, parameter_.numClusToAddMin_, parameter_.numClusToAddMax_, triplet_set, bound);
345 nClustersAdded += TightenCycle(*mplp_, parameter_.numClusToAddMin_, triplet_set, bound2, 1);
347 if(std::max(bound, bound2) < CLUSTER_THR) {
348 if(MPLP_DEBUG_MODE) std::cout <<
"TightenCycle did not find anything useful! Re-running with FindPartition." << std::endl;
350 nClustersAdded += TightenCycle(*mplp_, parameter_.numClusToAddMin_, triplet_set, bound2, 2);
355 bool noprogress =
false;
356 if(std::max(bound, bound2) < CLUSTER_THR) noprogress =
true;
358 clock_t tightening_end_time = clock();
359 double tightening_total_time = (double)(tightening_end_time - tightening_start_time)/CLOCKS_PER_SEC;
360 if (MPLP_DEBUG_MODE) {
361 std::cout <<
" -- Added " << nClustersAdded <<
" clusters to relaxation. Took " << tightening_total_time <<
" seconds\n";
363 if(!parameter_.logFile_.empty()) {
364 std::stringstream stream;
365 stream <<
"I added " << nClustersAdded <<
" clusters. Took " << tightening_total_time <<
" seconds\n";
366 fprintf(mplpLogFile_,
"%s", stream.str().c_str());
370 if((mplp_->CSP_instance || noprogress) && ((double)(clock() - mplpStart_) / CLOCKS_PER_SEC) > parameter_.maxTimeLP_ + (parameter_.maxTime_-parameter_.maxTimeLP_)/2){
371 force_decimation =
true;
377 if(nClustersAdded == 0 && parameter_.addEdgeIntersections_) {
378 mplp_->AddAllEdgeIntersections();
379 parameter_.addEdgeIntersections_ =
false;
384 else if((!parameter_.addEdgeIntersections_ && nClustersAdded == 0) || force_decimation) {
386 if(parameter_.doGlobalDecoding_ && (!parameter_.useDecimation_ || !decimation_has_started)) mplp_->RunGlobalDecoding3();
389 if (parameter_.useDecimation_) {
390 decimation_has_started =
true;
392 bool fixed_node = mplp_->RunDecimation();
394 if(MPLP_DEBUG_MODE) std::cout <<
"Decimation fixed all of the nodes it could... quiting." << std::endl;
400 if (MPLP_DEBUG_MODE) std::cout <<
"Running MPLP again for " << parameter_.maxIterLater_ <<
" more iterations\n";
401 mplp_->RunMPLP(parameter_.maxIterLater_, parameter_.objDelThr_, parameter_.intGapThr_);
403 if(parameter_.UAIsettings_) {
406 double time_elapsed = (double)(clock() - mplpStart_)/ CLOCKS_PER_SEC;
407 if (time_elapsed > 4000 && time_elapsed > parameter_.maxTime_) {
412 if(!parameter_.logFile_.empty()) fflush(mplpLogFile_);
418 if(!parameter_.logFile_.empty()) fflush(mplpLogFile_);
419 if(!parameter_.logFile_.empty()) fclose(mplpLogFile_);
432 if(parameter_.inputFile_.empty()) {
433 OPENGM_ASSERT(mplp_->m_decoded_res.size() == gm_.numberOfVariables());
436 arg.resize(mplp_->m_decoded_res.size());
437 for(
size_t i = 0; i < arg.size(); i++) {
438 arg[i] =
static_cast<LabelType>(mplp_->m_decoded_res[i]);
446 return -mplp_->last_obj;
452 std::vector<LabelType> state;
454 return gm_.evaluate(state);
463 if(!parameter_.inputFile_.empty()) {
466 static bool visited =
false;
468 std::vector<LabelType> state;
473 std::cout <<
"state: ";
474 for(
size_t i = 0; i < state.size(); i++) {
475 std::cout << state[i] <<
"; ";
477 std::cout << std::endl;
479 std::cout <<
"value: " << -mplp_->m_best_val << std::endl;
480 std::cout <<
"expected: " << gm_.evaluate(state) << std::endl;
GM::ValueType value() const
return the solution (value)
InferenceTermination arg(std::vector< LabelType > &, const size_t &=1) const
std::string evidenceFile_
#define OPENGM_ASSERT(expression)
InferenceTermination infer()
GM::ValueType bound() const
return a bound on the solution
GraphicalModelType::IndexType IndexType
visitors::TimingVisitor< MPLP< GM > > TimingVisitorType
MPLP MPLP inference algorithm class.
const GraphicalModelType & graphicalModel() const
visitors::VerboseVisitor< MPLP< GM > > VerboseVisitorType
Inference algorithm interface.
opengm::Minimizer AccumulationType
visitors::EmptyVisitor< MPLP< GM > > EmptyVisitorType
MPLP(const GraphicalModelType &gm, const Parameter ¶=Parameter())
const GraphicalModelType & gm_
GraphicalModelType::LabelType LabelType
Minimization as a unary accumulation.
static const size_t ContinueInf
Parameter(const size_t maxIterLP=1000, const size_t maxIterTight=100000, const size_t maxIterLater=20, const double maxTime=3600, const double maxTimeLP=1200, const size_t numClusToAddMin=5, const size_t numClusToAddMax=20, const double objDelThr=0.0002, const double intGapThr=0.0002, const bool UAIsettings=false, const bool addEdgeIntersections=true, const bool doGlobalDecoding=false, const bool useDecimation=false, const bool lookForCSPs=false, const bool logMode=false, const std::string &logFile=std::string(), const int seed=0, const std::string &inputFile=std::string(), const std::string &evidenceFile=std::string())
Constructor.
bool addEdgeIntersections_