00001 #pragma once
00002 #ifndef OPENGM_MULTICUT_HXX
00003 #define OPENGM_MULTICUT_HXX
00004
00005 #include <algorithm>
00006 #include <vector>
00007 #include <queue>
00008 #include <utility>
00009 #include <string>
00010 #include <iostream>
00011 #include <fstream>
00012 #include <typeinfo>
00013 #include <limits>
00014 #ifndef WIDTH_BOOST
00015 #include <boost/unordered_map.hpp>
00016 #include <boost/unordered_set.hpp>
00017 #else
00018 #include <ext/hash_map>
00019 #include <ext/hash_set>
00020 #endif
00021
00022 #include "opengm/datastructures/marray/marray.hxx"
00023 #include "opengm/opengm.hxx"
00024 #include "opengm/inference/inference.hxx"
00025 #include "opengm/inference/visitors/visitor.hxx"
00026 #include "opengm/utilities/timer.hxx"
00027
00028 #include <ilcplex/ilocplex.h>
00029 ILOSTLBEGIN
00030
00031 namespace opengm {
00032
00034 class HigherOrderTerm
00035 {
00036 public:
00037 size_t factorID_;
00038 bool potts_;
00039 size_t valueIndex_;
00040 std::vector<size_t> lpIndices_;
00041 HigherOrderTerm(size_t factorID, bool potts, size_t valueIndex)
00042 : factorID_(factorID), potts_(potts),valueIndex_(valueIndex) {}
00043 HigherOrderTerm()
00044 : factorID_(0), potts_(false),valueIndex_(0) {}
00045 };
00047
00066 template<class GM, class ACC>
00067 class Multicut : public Inference<GM, ACC>
00068 {
00069 public:
00070 typedef ACC AccumulationType;
00071 typedef GM GraphicalModelType;
00072 OPENGM_GM_TYPE_TYPEDEFS;
00073 typedef size_t LPIndexType;
00074 typedef VerboseVisitor<Multicut<GM,ACC> > VerboseVisitorType;
00075 typedef EmptyVisitor<Multicut<GM,ACC> > EmptyVisitorType;
00076 typedef TimingVisitor<Multicut<GM,ACC> > TimingVisitorType;
00077
00078
00079 #ifndef WIDTH_BOOST
00080 typedef boost::unordered_map<IndexType, LPIndexType> EdgeMapType;
00081 typedef boost::unordered_set<IndexType> MYSET;
00082 #else
00083 typedef __gnu_cxx::hash_map<IndexType, LPIndexType> EdgeMapType;
00084 typedef __gnu_cxx::hash_set<IndexType> MYSET;
00085 #endif
00086
00087
00088 struct Parameter{
00089 public:
00090 enum MWCRounding {NEAREST,DERANDOMIZED,PSEUDODERANDOMIZED};
00091
00092 int numThreads_;
00093 bool verbose_;
00094 bool verboseCPLEX_;
00095 double cutUp_;
00096 double timeOut_;
00097 std::string workFlow_;
00098 size_t maximalNumberOfConstraintsPerRound_;
00099 double edgeRoundingValue_;
00100 MWCRounding MWCRounding_;
00101 size_t reductionMode_;
00102
00105 Parameter
00106 (
00107 int numThreads=0,
00108 double cutUp=1.0e+75
00109 )
00110 : numThreads_(numThreads), verbose_(false),verboseCPLEX_(false), cutUp_(cutUp),
00111 timeOut_(std::numeric_limits<double>::infinity()), maximalNumberOfConstraintsPerRound_(1000000),
00112 edgeRoundingValue_(0.00000001),MWCRounding_(NEAREST), reductionMode_(3)
00113 {};
00114 };
00115
00116 virtual ~Multicut();
00117 Multicut(const GraphicalModelType&, Parameter para=Parameter());
00118 virtual std::string name() const {return "Multicut";}
00119 const GraphicalModelType& graphicalModel() const;
00120 virtual InferenceTermination infer();
00121 template<class VisitorType> InferenceTermination infer(VisitorType&);
00122 virtual InferenceTermination arg(std::vector<LabelType>&, const size_t = 1) const;
00123 ValueType bound() const;
00124 ValueType value() const;
00125 ValueType calcBound(){ return 0; }
00126 ValueType evaluate(std::vector<LabelType>&) const;
00127
00128 template<class LPVariableIndexIterator, class CoefficientIterator>
00129 void addConstraint(LPVariableIndexIterator, LPVariableIndexIterator,
00130 CoefficientIterator, const ValueType&, const ValueType&);
00131 std::vector<double> getEdgeLabeling() const;
00132
00133 size_t inferenceState_;
00134 size_t constraintCounter_;
00135 private:
00136 enum ProblemType {INVALID, MC, MWC};
00137
00138 const GraphicalModelType& gm_;
00139 ProblemType problemType_;
00140 Parameter parameter_;
00141 double constant_;
00142 double bound_;
00143 const double infinity_;
00144
00145 LabelType numberOfTerminals_;
00146 IndexType numberOfNodes_;
00147 LPIndexType numberOfTerminalEdges_;
00148 LPIndexType numberOfInternalEdges_;
00149 LPIndexType terminalOffset_;
00150 LPIndexType numberOfHigherOrderValues_;
00151 LPIndexType numberOfInterTerminalEdges_;
00152
00153 std::vector<std::vector<size_t> > workFlow_;
00154 std::vector<std::pair<IndexType,IndexType> > edgeNodes_;
00155
00158 std::vector<EdgeMapType > neighbours;
00159
00160 IloEnv env_;
00161 IloModel model_;
00162 IloNumVarArray x_;
00163 IloRangeArray c_;
00164 IloObjective obj_;
00165 IloNumArray sol_;
00166 IloCplex cplex_;
00167
00168 bool integerMode_;
00169 const double EPS_;
00170
00171
00172 void initCplex();
00173
00174 size_t findCycleConstraints(IloRangeArray&, bool, bool);
00175 size_t findIntegerCycleConstraints(IloRangeArray&, bool);
00176 size_t findTerminalTriangleConstraints(IloRangeArray&);
00177 size_t findIntegerTerminalTriangleConstraints(IloRangeArray&, std::vector<LabelType>& conf);
00178 size_t findMultiTerminalConstraints(IloRangeArray&);
00179 size_t findOddWheelConstraints(IloRangeArray&);
00180 size_t removeUnusedConstraints();
00181 size_t enforceIntegerConstraints();
00182
00183 bool readWorkFlow(std::string);
00184
00185 InferenceTermination partition(std::vector<LabelType>&, std::vector<std::list<size_t> >&, double) const;
00186 ProblemType setProblemType();
00187 LPIndexType getNeighborhood(const LPIndexType, std::vector<EdgeMapType >&,std::vector<std::pair<IndexType,IndexType> >&, std::vector<HigherOrderTerm>&);
00188
00189 template <class DOUBLEVECTOR>
00190 double shortestPath(const IndexType, const IndexType, const std::vector<EdgeMapType >&, const DOUBLEVECTOR&, std::vector<IndexType>&, const double,bool) const;
00191
00192 InferenceTermination derandomizedRounding(std::vector<LabelType>&) const;
00193 InferenceTermination pseudoDerandomizedRounding(std::vector<LabelType>&, size_t) const;
00194 double derandomizedRoundingSubProcedure(std::vector<LabelType>&,const std::vector<LabelType>&, const double) const;
00195
00196
00197
00198 enum{
00199 Protocol_ID_Solve = 0,
00200 Protocol_ID_AddConstraints = 1,
00201 Protocol_ID_RemoveConstraints = 2,
00202 Protocol_ID_IntegerConstraints = 3,
00203 Protocol_ID_CC = 4,
00204 Protocol_ID_TTC = 5,
00205 Protocol_ID_MTC = 6,
00206 Protocol_ID_OWC = 7,
00207 Protocol_ID_Unknown = 8
00208 };
00209
00210 enum{
00211 Action_ID_RemoveConstraints = 0,
00212 Action_ID_IntegerConstraints = 1,
00213 Action_ID_CC = 10,
00214 Action_ID_CC_I = 11,
00215 Action_ID_CC_IFD = 12,
00216 Action_ID_CC_FD = 13,
00217 Action_ID_CC_B = 14,
00218 Action_ID_CC_FDB = 15,
00219 Action_ID_TTC = 20,
00220 Action_ID_TTC_I = 21,
00221 Action_ID_MTC = 30,
00222 Action_ID_OWC = 40
00223 };
00224
00225 std::vector<std::vector<double> > protocolateTiming_;
00226 std::vector<std::vector<size_t> > protocolateConstraints_;
00227
00228 };
00229
00230 template<class GM, class ACC>
00231 typename Multicut<GM, ACC>::LPIndexType Multicut<GM, ACC>::getNeighborhood
00232 (
00233 const LPIndexType numberOfTerminalEdges,
00234 std::vector<EdgeMapType >& neighbours,
00235 std::vector<std::pair<IndexType,IndexType> >& edgeNodes,
00236 std::vector<HigherOrderTerm>& higherOrderTerms
00237 )
00238 {
00239
00240 neighbours.resize(gm_.numberOfVariables());
00241 LPIndexType numberOfInternalEdges=0;
00242 LPIndexType numberOfAdditionalInternalEdges=0;
00243
00244 for(size_t f=0; f<gm_.numberOfFactors(); ++f) {
00245 if(gm_[f].numberOfVariables()==2) {
00246 IndexType u = gm_[f].variableIndex(1);
00247 IndexType v = gm_[f].variableIndex(0);
00248 if(neighbours[u].find(v)==neighbours[u].end()) {
00249 neighbours[u][v] = numberOfTerminalEdges+numberOfInternalEdges;
00250 neighbours[v][u] = numberOfTerminalEdges+numberOfInternalEdges;
00251 edgeNodes.push_back(std::pair<IndexType,IndexType>(v,u));
00252 ++numberOfInternalEdges;
00253 }
00254 }
00255 }
00256 for(size_t f=0; f<gm_.numberOfFactors(); ++f) {
00257 if(gm_[f].numberOfVariables()>2 && !gm_[f].isPotts()){
00258 higherOrderTerms.push_back(HigherOrderTerm(f, false, 0));
00259 for(size_t i=0; i<gm_[f].numberOfVariables();++i) {
00260 for(size_t j=0; j<i;++j) {
00261 IndexType u = gm_[f].variableIndex(i);
00262 IndexType v = gm_[f].variableIndex(j);
00263 if(neighbours[u].find(v)==neighbours[u].end()) {
00264 neighbours[u][v] = numberOfTerminalEdges+numberOfInternalEdges;
00265 neighbours[v][u] = numberOfTerminalEdges+numberOfInternalEdges;
00266 edgeNodes.push_back(std::pair<IndexType,IndexType>(v,u));
00267 ++numberOfInternalEdges;
00268 ++numberOfAdditionalInternalEdges;
00269 }
00270 }
00271 }
00272 }
00273 }
00274
00275 for(size_t f=0; f<gm_.numberOfFactors(); ++f) {
00276 if(gm_[f].numberOfVariables()>2 && gm_[f].isPotts()) {
00277 higherOrderTerms.push_back(HigherOrderTerm(f, true, 0));
00278 std::vector<LPIndexType> lpIndexVector;
00279
00280 std::vector<bool> variableInSpanningTree(gm_.numberOfVariables(),true);
00281 for(size_t i=0; i<gm_[f].numberOfVariables();++i) {
00282 variableInSpanningTree[gm_[f].variableIndex(i)]=false;
00283 }
00284 size_t connection = 2;
00285
00286
00287 if(connection==2){
00288
00289 for(size_t i=0; i<gm_[f].numberOfVariables();++i) {
00290 const IndexType u = gm_[f].variableIndex(i);
00291 for(typename EdgeMapType::const_iterator it=neighbours[u].begin() ; it != neighbours[u].end(); ++it){
00292 const IndexType v = (*it).first;
00293 if(variableInSpanningTree[v] == false && u<v){
00294 lpIndexVector.push_back((*it).second);
00295 }
00296 }
00297 }
00298 }
00299 else if(connection==1){
00300
00301 for(size_t i=0; i<gm_[f].numberOfVariables();++i) {
00302 const IndexType u = gm_[f].variableIndex(i);
00303 for(typename EdgeMapType::const_iterator it=neighbours[u].begin() ; it != neighbours[u].end(); ++it){
00304 const IndexType v = (*it).first;
00305 if(variableInSpanningTree[v] == false){
00306 variableInSpanningTree[v] = true;
00307 lpIndexVector.push_back((*it).second);
00308 }
00309 }
00310 }
00311 }
00312 else{
00313 OPENGM_ASSERT(false);
00314 }
00315 higherOrderTerms.back().lpIndices_=lpIndexVector;
00316
00317
00318
00319 }
00320 }
00321
00322 return numberOfInternalEdges;
00323 }
00324
00325 template<class GM, class ACC>
00326 Multicut<GM, ACC>::~Multicut() {
00327 env_.end();
00328 }
00329
00330 template<class GM, class ACC>
00331 Multicut<GM, ACC>::Multicut
00332 (
00333 const GraphicalModelType& gm,
00334 Parameter para
00335 ) : gm_(gm), parameter_(para) , bound_(-std::numeric_limits<double>::infinity()), infinity_(1e8), integerMode_(false),
00336 EPS_(1e-7)
00337 {
00338 if(typeid(ACC) != typeid(opengm::Minimizer) || typeid(OperatorType) != typeid(opengm::Adder)) {
00339 throw RuntimeError("This implementation does only supports Min-Plus-Semiring.");
00340 }
00341 if(parameter_.reductionMode_<0 ||parameter_.reductionMode_>3) {
00342 throw RuntimeError("Reduction Mode has to be 1, 2 or 3!");
00343 }
00344
00345
00346 setProblemType();
00347 if(problemType_ == INVALID)
00348 throw RuntimeError("Invalid Model for Multicut-Solver! Solver requires a generalized potts model!");
00349
00350
00351 std::vector<double> valuesHigherOrder;
00352 std::vector<HigherOrderTerm> higherOrderTerms;
00353 numberOfInternalEdges_ = getNeighborhood(numberOfTerminalEdges_, neighbours, edgeNodes_ ,higherOrderTerms);
00354 numberOfNodes_ = gm_.numberOfVariables();
00355
00356
00357 constant_=0;
00358 size_t valueSize;
00359 if(numberOfTerminals_==0) valueSize = numberOfInternalEdges_;
00360 else valueSize = numberOfTerminalEdges_+numberOfInternalEdges_+numberOfInterTerminalEdges_;
00361 std::vector<double> values (valueSize,0);
00362
00363
00364 for(size_t f=0; f<gm_.numberOfFactors(); ++f) {
00365 if(gm_[f].numberOfVariables() == 1) {
00366 IndexType node = gm_[f].variableIndex(0);
00367 for(LabelType i=0; i<gm_.numberOfLabels(node); ++i) {
00368 for(LabelType j=0; j<gm_.numberOfLabels(node); ++j) {
00369 if(i==j) values[node*numberOfTerminals_+i] += (1.0/(numberOfTerminals_-1)-1) * gm_[f](&j);
00370 else values[node*numberOfTerminals_+i] += (1.0/(numberOfTerminals_-1)) * gm_[f](&j);
00371 }
00372 }
00373 }
00374 else if(gm_[f].numberOfVariables() == 2) {
00375 if(gm_[f].numberOfLabels(0)==2 && gm_[f].numberOfLabels(1)==2){
00376 IndexType node0 = gm_[f].variableIndex(0);
00377 IndexType node1 = gm_[f].variableIndex(1);
00378 LabelType cc[] = {0,0}; ValueType a = gm_[f](cc);
00379 cc[0]=1;cc[1]=1; ValueType b = gm_[f](cc);
00380 cc[0]=0;cc[1]=1; ValueType c = gm_[f](cc);
00381 cc[0]=1;cc[1]=0; ValueType d = gm_[f](cc);
00382
00383 values[neighbours[gm_[f].variableIndex(0)][gm_[f].variableIndex(1)]] += ((c+d-a-a) - (b-a))/2.0;
00384 values[node0*numberOfTerminals_+0] += ((b-a)-(-d+c))/2.0;
00385 values[node1*numberOfTerminals_+0] += ((b-a)-( d-c))/2.0;
00386 constant_ += a;
00387 }else{
00388 LabelType cc0[] = {0,0};
00389 LabelType cc1[] = {0,1};
00390 values[neighbours[gm_[f].variableIndex(0)][gm_[f].variableIndex(1)]] += gm_[f](cc1) - gm_[f](cc0);
00391 constant_ += gm_[f](cc0);
00392 }
00393 }
00394 }
00395 for(size_t h=0; h<higherOrderTerms.size();++h){
00396 if(higherOrderTerms[h].potts_) {
00397 const IndexType f = higherOrderTerms[h].factorID_;
00398 higherOrderTerms[h].valueIndex_= valuesHigherOrder.size();
00399 OPENGM_ASSERT(gm_[f].numberOfVariables() > 2);
00400 std::vector<LabelType> cc0(gm_[f].numberOfVariables(),0);
00401 std::vector<LabelType> cc1(gm_[f].numberOfVariables(),0);
00402 cc1[0] = 1;
00403 valuesHigherOrder.push_back(gm_[f](cc1.begin()) - gm_[f](cc0.begin()) );
00404 constant_ += gm_[f](cc0.begin());
00405 }
00406 else{
00407 const IndexType f = higherOrderTerms[h].factorID_;
00408 higherOrderTerms[h].valueIndex_= valuesHigherOrder.size();
00409 if(gm_[f].numberOfVariables() == 3) {
00410 size_t i[] = {0, 1, 2 };
00411 valuesHigherOrder.push_back(gm_[f](i));
00412 i[0]=0; i[1]=0; i[2]=1;
00413 valuesHigherOrder.push_back(gm_[f](i));
00414 i[0]=0; i[1]=1; i[2]=0;
00415 valuesHigherOrder.push_back(gm_[f](i));
00416 i[0]=1; i[1]=0; i[2]=0;
00417 valuesHigherOrder.push_back(gm_[f](i));
00418 i[0]=0; i[1]=0; i[2]=0;
00419 valuesHigherOrder.push_back(gm_[f](i));
00420 }
00421 else if(gm_[f].numberOfVariables() == 4) {
00422 size_t i[] = {0, 1, 2, 3 };
00423 if(numberOfTerminals_>=4){
00424 valuesHigherOrder.push_back(gm_[f](i));
00425 }else{
00426 valuesHigherOrder.push_back(0.0);
00427 }
00428 if(numberOfTerminals_>=3){
00429 i[0]=0; i[1]=0; i[2]=1; i[3] = 2;
00430 valuesHigherOrder.push_back(gm_[f](i));
00431 i[0]=0; i[1]=1; i[2]=0; i[3] = 2;
00432 valuesHigherOrder.push_back(gm_[f](i));
00433 i[0]=0; i[1]=1; i[2]=1; i[3] = 2;
00434 valuesHigherOrder.push_back(gm_[f](i));
00435 }else{
00436 valuesHigherOrder.push_back(0.0);
00437 valuesHigherOrder.push_back(0.0);
00438 valuesHigherOrder.push_back(0.0);
00439 }
00440 i[0]=0; i[1]=0; i[2]=0; i[3] = 1;
00441 valuesHigherOrder.push_back(gm_[f](i));
00442 i[0]=0; i[1]=1; i[2]=2; i[3] = 0;
00443 valuesHigherOrder.push_back(gm_[f](i));
00444 i[0]=0; i[1]=1; i[2]=1; i[3] = 0;
00445 valuesHigherOrder.push_back(gm_[f](i));
00446 i[0]=1; i[1]=0; i[2]=2; i[3] = 0;
00447 valuesHigherOrder.push_back(gm_[f](i));
00448 i[0]=1; i[1]=0; i[2]=1; i[3] = 0;
00449 valuesHigherOrder.push_back(gm_[f](i));
00450 i[0]=0; i[1]=0; i[2]=1; i[3] = 0;
00451 valuesHigherOrder.push_back(gm_[f](i));
00452 i[0]=1; i[1]=2; i[2]=0; i[3] = 0;
00453 valuesHigherOrder.push_back(gm_[f](i));
00454 i[0]=1; i[1]=1; i[2]=0; i[3] = 0;
00455 valuesHigherOrder.push_back(gm_[f](i));
00456 i[0]=0; i[1]=1; i[2]=0; i[3] = 0;
00457 valuesHigherOrder.push_back(gm_[f](i));
00458 i[0]=1; i[1]=0; i[2]=0; i[3] = 0;
00459 valuesHigherOrder.push_back(gm_[f](i));
00460 i[0]=0; i[1]=0; i[2]=0; i[3] = 0;
00461 valuesHigherOrder.push_back(gm_[f](i));
00462 }
00463 else{
00464 throw RuntimeError("Generalized Potts Terms of an order larger than 4 a currently not supported. If U really need them let us know!");
00465 }
00466 }
00467 }
00468
00469
00470 numberOfHigherOrderValues_ = valuesHigherOrder.size();
00471
00472
00473
00474
00475 OPENGM_ASSERT( numberOfTerminalEdges_ == gm_.numberOfVariables()*numberOfTerminals_ );
00476
00477
00478 OPENGM_ASSERT(values.size() == numberOfTerminalEdges_+numberOfInternalEdges_+numberOfInterTerminalEdges_);
00479 IloInt N = values.size() + numberOfHigherOrderValues_;
00480 model_ = IloModel(env_);
00481 x_ = IloNumVarArray(env_);
00482 c_ = IloRangeArray(env_);
00483 obj_ = IloMinimize(env_);
00484 sol_ = IloNumArray(env_,N);
00485
00486
00487 x_.add(IloNumVarArray(env_, N, 0, 1, ILOFLOAT));
00488
00489 IloNumArray obj(env_,N);
00490 for (size_t i=0; i< values.size();++i) {
00491 if(values[i]==0)
00492 obj[i] = 0;
00493 else
00494 obj[i] = values[i];
00495 }
00496 {
00497 size_t count =0;
00498 for (size_t i=0; i<valuesHigherOrder.size();++i) {
00499 obj[values.size()+count++] = valuesHigherOrder[i];
00500 }
00501 OPENGM_ASSERT(count == numberOfHigherOrderValues_);
00502 }
00503 obj_.setLinearCoefs(x_,obj);
00504
00505
00506 size_t constraintCounter = 0;
00507
00508 if(problemType_ == MWC) {
00509
00510 for(IndexType var=0; var<gm_.numberOfVariables(); ++var) {
00511 c_.add(IloRange(env_, numberOfTerminals_-1, numberOfTerminals_-1));
00512 for(LabelType i=0; i<gm_.numberOfLabels(var); ++i) {
00513 c_[constraintCounter].setLinearCoef(x_[var*numberOfTerminals_+i],1);
00514 }
00515 ++constraintCounter;
00516 }
00517
00518 for(size_t i=0; i<(size_t)(numberOfTerminals_*(numberOfTerminals_-1)/2); ++i) {
00519 c_.add(IloRange(env_, 1, 1));
00520 c_[constraintCounter].setLinearCoef(x_[numberOfTerminalEdges_+numberOfInternalEdges_+i],1);
00521 ++constraintCounter;
00522 }
00523 }
00524
00525
00526
00527 size_t count = 0;
00528 for(size_t i=0; i<higherOrderTerms.size(); ++i) {
00529 size_t factorID = higherOrderTerms[i].factorID_;
00530 size_t numVar = gm_[factorID].numberOfVariables();
00531 OPENGM_ASSERT(numVar>2);
00532
00533 if(higherOrderTerms[i].potts_) {
00534 double b = higherOrderTerms[i].lpIndices_.size();
00535
00536
00537
00538
00539
00540 if(parameter_.reductionMode_ % 2 == 1){
00541 c_.add(IloRange(env_, -b+1 , 0));
00542 for(size_t i1=0; i1<higherOrderTerms[i].lpIndices_.size();++i1) {
00543 const LPIndexType edgeID = higherOrderTerms[i].lpIndices_[i1];
00544 c_[constraintCounter].setLinearCoef(x_[edgeID],1);
00545 }
00546 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-b);
00547 constraintCounter += 1;
00548 }
00549
00550
00551 if(parameter_.reductionMode_ % 4 >=2){
00552
00553 c_.add(IloRange(env_, -2.0*b, 0));
00554 for(size_t i1=0; i1<higherOrderTerms[i].lpIndices_.size();++i1) {
00555 const LPIndexType edgeID = higherOrderTerms[i].lpIndices_[i1];
00556 c_[constraintCounter].setLinearCoef(x_[edgeID],-1);
00557 }
00558 c_[constraintCounter].setLinearCoef(x_[values.size()+count],1);
00559 constraintCounter += 1;
00560
00561
00562 for(size_t i1=0; i1<higherOrderTerms[i].lpIndices_.size();++i1) {
00563 const LPIndexType edgeID = higherOrderTerms[i].lpIndices_[i1];
00564 c_.add(IloRange(env_, 0 , 1));
00565 c_[constraintCounter].setLinearCoef(x_[edgeID],-1);
00566 c_[constraintCounter].setLinearCoef(x_[values.size()+count],1);
00567 constraintCounter += 1;
00568 }
00569 }
00570 count++;
00571 }else{
00572 if(numVar==3) {
00573 OPENGM_ASSERT(higherOrderTerms[i].valueIndex_<=valuesHigherOrder.size());
00574 LPIndexType edgeIDs[3];
00575 edgeIDs[0] = neighbours[gm_[factorID].variableIndex(0)][gm_[factorID].variableIndex(1)];
00576 edgeIDs[1] = neighbours[gm_[factorID].variableIndex(0)][gm_[factorID].variableIndex(2)];
00577 edgeIDs[2] = neighbours[gm_[factorID].variableIndex(1)][gm_[factorID].variableIndex(2)];
00578
00579 const unsigned int P[] = {0,1,2,4,7,8,12,16,18,25,32,33,42,52,63};
00580 double c[3];
00581
00582 c_.add(IloRange(env_, 1, 1));
00583 size_t lvc=0;
00584 for(size_t p=0; p<5; p++){
00585 if(true || valuesHigherOrder[higherOrderTerms[i].valueIndex_+p]!=0){
00586 c_[constraintCounter].setLinearCoef(x_[values.size()+count+lvc],1);
00587 ++lvc;
00588 }
00589 }
00590 ++constraintCounter;
00591
00592 for(size_t p=0; p<5; p++){
00593 if(true || valuesHigherOrder[higherOrderTerms[i].valueIndex_+p]!=0){
00594 double ub = 2.0;
00595 double lb = 0.0;
00596 unsigned int mask = 1;
00597 for(size_t n=0; n<3; n++){
00598 if(P[p] & mask){
00599 c[n] = -1.0;
00600 ub--;
00601 lb--;
00602 }
00603 else{
00604 c[n] = 1.0;
00605 }
00606 mask = mask << 1;
00607 }
00608 c_.add(IloRange(env_, lb, ub));
00609 for(size_t n=0; n<3; n++){
00610 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],c[n]);
00611 }
00612 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
00613 ++constraintCounter;
00614
00615 for(size_t n=0; n<3; n++){
00616 if(c[n]>0){
00617 c_.add(IloRange(env_, 0, 1));
00618 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],1);
00619 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
00620 ++constraintCounter;
00621 }else{
00622 c_.add(IloRange(env_, -1, 0));
00623 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],-1);
00624 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
00625 ++constraintCounter;
00626 }
00627 }
00628 ++count;
00629 }
00630 }
00631 }
00632 else if(numVar==4) {
00633 OPENGM_ASSERT(higherOrderTerms[i].valueIndex_<=valuesHigherOrder.size());
00634 LPIndexType edgeIDs[6];
00635 edgeIDs[0] = neighbours[gm_[factorID].variableIndex(0)][gm_[factorID].variableIndex(1)];
00636 edgeIDs[1] = neighbours[gm_[factorID].variableIndex(0)][gm_[factorID].variableIndex(2)];
00637 edgeIDs[2] = neighbours[gm_[factorID].variableIndex(1)][gm_[factorID].variableIndex(2)];
00638 edgeIDs[3] = neighbours[gm_[factorID].variableIndex(0)][gm_[factorID].variableIndex(3)];
00639 edgeIDs[4] = neighbours[gm_[factorID].variableIndex(1)][gm_[factorID].variableIndex(3)];
00640 edgeIDs[5] = neighbours[gm_[factorID].variableIndex(2)][gm_[factorID].variableIndex(3)];
00641
00642
00643 const unsigned int P[] = {0,1,2,4,7,8,12,16,18,25,32,33,42,52,63};
00644 double c[6];
00645
00646 c_.add(IloRange(env_, 1, 1));
00647 size_t lvc=0;
00648 for(size_t p=0; p<15; p++){
00649 if(true ||valuesHigherOrder[higherOrderTerms[i].valueIndex_+p]!=0){
00650 c_[constraintCounter].setLinearCoef(x_[values.size()+count+lvc],1);
00651 ++lvc;
00652 }
00653 }
00654 ++constraintCounter;
00655
00656
00657 for(size_t p=0; p<15; p++){
00658 double ub = 5.0;
00659 double lb = 0.0;
00660 unsigned int mask = 1;
00661 for(size_t n=0; n<6; n++){
00662 if(P[p] & mask){
00663 c[n] = -1.0;
00664 ub--;
00665 lb--;
00666 }
00667 else{
00668 c[n] = 1.0;
00669 }
00670 mask = mask << 1;
00671 }
00672 c_.add(IloRange(env_, lb, ub));
00673 for(size_t n=0; n<6; n++){
00674 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],c[n]);
00675 }
00676 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
00677 ++constraintCounter;
00678
00679 for(size_t n=0; n<6; n++){
00680 if(c[n]>0){
00681 c_.add(IloRange(env_, 0, 1));
00682 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],1);
00683 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
00684 ++constraintCounter;
00685 }else{
00686 c_.add(IloRange(env_, -1, 0));
00687 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],-1);
00688 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
00689 ++constraintCounter;
00690 }
00691 }
00692 ++count;
00693 }
00694 }
00695 else{
00696 OPENGM_ASSERT(false);
00697 }
00698 }
00699 }
00700
00701
00702 model_.add(obj_);
00703 if(constraintCounter>0) {
00704 model_.add(c_);
00705 }
00706
00707
00708 cplex_ = IloCplex(model_);
00709
00710 }
00711
00712 template<class GM, class ACC>
00713 typename Multicut<GM, ACC>::ProblemType Multicut<GM, ACC>::setProblemType() {
00714 problemType_ = MC;
00715 for(size_t f=0; f<gm_.numberOfFactors();++f) {
00716 if(gm_[f].numberOfVariables()==1) {
00717 problemType_ = MWC;
00718 }
00719 if(gm_[f].numberOfVariables()>1) {
00720 for(size_t i=0; i<gm_[f].numberOfVariables();++i) {
00721 if(gm_[f].numberOfLabels(i)<gm_.numberOfVariables()) {
00722 problemType_ = MWC;
00723 }
00724 }
00725 }
00726 if(gm_[f].numberOfVariables()==2 && gm_[f].numberOfLabels(0)==2 && gm_[f].numberOfLabels(1)==2){
00727 problemType_ = MWC;
00728 }
00729 else if(gm_[f].numberOfVariables()>1 && !gm_[f].isGeneralizedPotts()) {
00730 problemType_ = INVALID;
00731 break;
00732 }
00733 }
00734
00735
00736 if(problemType_ == MWC) {
00737 numberOfTerminals_ = gm_.numberOfLabels(0);
00738 numberOfInterTerminalEdges_ = (numberOfTerminals_*(numberOfTerminals_-1))/2;
00739 numberOfTerminalEdges_ = 0;
00740 for(IndexType i=0; i<gm_.numberOfVariables(); ++i) {
00741 for(LabelType j=0; j<gm_.numberOfLabels(i); ++j) {
00742 ++numberOfTerminalEdges_;
00743 }
00744 }
00745 }
00746 else{
00747 numberOfTerminalEdges_ = 0;
00748 numberOfTerminals_ = 0;
00749 numberOfInterTerminalEdges_ = 0;
00750 }
00751 return problemType_;
00752 }
00753
00754
00755
00756
00757
00758
00759
00760 template<class GM, class ACC>
00761 size_t Multicut<GM, ACC>::removeUnusedConstraints()
00762 {
00763 std::cout << "Not Implemented " <<std::endl ;
00764 return 0;
00765 }
00766
00767
00768
00769 template<class GM, class ACC>
00770 size_t Multicut<GM, ACC>::enforceIntegerConstraints()
00771 {
00772 size_t N=numberOfTerminalEdges_;
00773 if (N==0) N = numberOfInternalEdges_;
00774
00775 for(size_t i=0; i<N; ++i)
00776 model_.add(IloConversion(env_, x_[i], ILOBOOL));
00777 for(size_t i=0; i<numberOfHigherOrderValues_; ++i)
00778 model_.add(IloConversion(env_, x_[numberOfTerminalEdges_+numberOfInternalEdges_+numberOfInterTerminalEdges_+i], ILOBOOL));
00779 integerMode_ = true;
00780
00781 return N+numberOfHigherOrderValues_;
00782 }
00783
00790 template<class GM, class ACC>
00791 size_t Multicut<GM, ACC>::findTerminalTriangleConstraints(IloRangeArray& constraint)
00792 {
00793 OPENGM_ASSERT(problemType_ == MWC);
00794 if(!(problemType_ == MWC)) return 0;
00795 size_t tempConstrainCounter = constraintCounter_;
00796
00797 size_t u,v;
00798 for(size_t i=0; i<numberOfInternalEdges_;++i) {
00799 u = edgeNodes_[i].first;
00800 v = edgeNodes_[i].second;
00801 for(size_t l=0; l<numberOfTerminals_;++l) {
00802 if(-sol_[numberOfTerminalEdges_+i]+sol_[u*numberOfTerminals_+l]+sol_[v*numberOfTerminals_+l]<-EPS_) {
00803 constraint.add(IloRange(env_, 0 , 2));
00804 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],-1);
00805 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+l],1);
00806 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+l],1);
00807 ++constraintCounter_;
00808 }
00809 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+l]+sol_[v*numberOfTerminals_+l]<-EPS_) {
00810 constraint.add(IloRange(env_, 0 , 2));
00811 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
00812 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+l],-1);
00813 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+l],1);
00814 ++constraintCounter_;
00815 }
00816 if(sol_[numberOfTerminalEdges_+i]+sol_[u*numberOfTerminals_+l]-sol_[v*numberOfTerminals_+l]<-EPS_) {
00817 constraint.add(IloRange(env_, 0 , 2));
00818 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
00819 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+l],1);
00820 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+l],-1);
00821 ++constraintCounter_;
00822 }
00823 }
00824 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
00825 break;
00826 }
00827 return constraintCounter_-tempConstrainCounter;
00828 }
00829
00836 template<class GM, class ACC>
00837 size_t Multicut<GM, ACC>::findMultiTerminalConstraints(IloRangeArray& constraint)
00838 {
00839 OPENGM_ASSERT(problemType_ == MWC);
00840 if(!(problemType_ == MWC)) return 0;
00841 size_t tempConstrainCounter = constraintCounter_;
00842
00843 size_t u,v;
00844 for(size_t i=0; i<numberOfInternalEdges_;++i) {
00845 u = edgeNodes_[i].first;
00846 v = edgeNodes_[i].second;
00847 std::vector<size_t> terminals1;
00848 std::vector<size_t> terminals2;
00849 double sum1 = 0;
00850 double sum2 = 0;
00851 for(size_t l=0; l<numberOfTerminals_;++l) {
00852 if(sol_[u*numberOfTerminals_+l]-sol_[v*numberOfTerminals_+l] > EPS_) {
00853 terminals1.push_back(l);
00854 sum1 += sol_[u*numberOfTerminals_+l]-sol_[v*numberOfTerminals_+l];
00855 }
00856 if(sol_[v*numberOfTerminals_+l]-sol_[u*numberOfTerminals_+l] > EPS_) {
00857 terminals2.push_back(l);
00858 sum2 +=sol_[v*numberOfTerminals_+l]-sol_[u*numberOfTerminals_+l];
00859 }
00860 }
00861 if(sol_[numberOfTerminalEdges_+i]-sum1<-EPS_) {
00862 constraint.add(IloRange(env_, 0 , 200000));
00863 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
00864 for(size_t k=0; k<terminals1.size(); ++k) {
00865 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+terminals1[k]],-1);
00866 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+terminals1[k]],1);
00867 }
00868 ++constraintCounter_;
00869 }
00870 if(sol_[numberOfTerminalEdges_+i]-sum2<-EPS_) {
00871 constraint.add(IloRange(env_, 0 , 200000));
00872 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
00873 for(size_t k=0; k<terminals2.size(); ++k) {
00874 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+terminals2[k]],1);
00875 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+terminals2[k]],-1);
00876 }
00877 ++constraintCounter_;
00878 }
00879 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
00880 break;
00881 }
00882 return constraintCounter_-tempConstrainCounter;
00883 }
00884
00891 template<class GM, class ACC>
00892 size_t Multicut<GM, ACC>::findIntegerTerminalTriangleConstraints(IloRangeArray& constraint, std::vector<LabelType>& conf)
00893 {
00894 OPENGM_ASSERT(integerMode_);
00895 OPENGM_ASSERT(problemType_ == MWC);
00896 if(!(problemType_ == MWC)) return 0;
00897 size_t tempConstrainCounter = constraintCounter_;
00898
00899 size_t u,v;
00900 for(size_t i=0; i<numberOfInternalEdges_;++i) {
00901 u = edgeNodes_[i].first;
00902 v = edgeNodes_[i].second;
00903 if(sol_[numberOfTerminalEdges_+i]<EPS_ && (conf[u]!=conf[v]) ) {
00904 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+conf[u]]+sol_[v*numberOfTerminals_+conf[u]]<=0) {
00905 constraint.add(IloRange(env_, 0 , 10));
00906 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
00907 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[u]],-1);
00908 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[u]],1);
00909 ++constraintCounter_;
00910 }
00911 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+conf[u]]+sol_[v*numberOfTerminals_+conf[u]]<=0) {
00912 constraint.add(IloRange(env_, 0 , 10));
00913 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
00914 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[u]],1);
00915 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[u]],-1);
00916 ++constraintCounter_;
00917 }
00918 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+conf[v]]+sol_[v*numberOfTerminals_+conf[v]]<=0) {
00919 constraint.add(IloRange(env_, 0 , 10));
00920 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
00921 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[v]],-1);
00922 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[v]],1);
00923 ++constraintCounter_;
00924 }
00925 if(sol_[numberOfTerminalEdges_+i]+sol_[u*numberOfTerminals_+conf[v]]-sol_[v*numberOfTerminals_+conf[v]]<=0) {
00926 constraint.add(IloRange(env_, 0 , 10));
00927 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
00928 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[v]],1);
00929 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[v]],-1);
00930 ++constraintCounter_;
00931 }
00932 }
00933 if(sol_[numberOfTerminalEdges_+i]>1-EPS_ && (conf[u]==conf[v]) ) {
00934 constraint.add(IloRange(env_, 0 , 10));
00935 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],-1);
00936 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[u]],1);
00937 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[v]],1);
00938 ++constraintCounter_;
00939 }
00940 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
00941 break;
00942 }
00943 return constraintCounter_-tempConstrainCounter;
00944 }
00945
00950 template<class GM, class ACC>
00951 size_t Multicut<GM, ACC>::findCycleConstraints(
00952 IloRangeArray& constraint,
00953 bool addOnlyFacetDefiningConstraints = true,
00954 bool usePreBounding = true
00955 )
00956 {
00957 std::vector<LabelType> partit;
00958 std::vector<std::list<size_t> > neighbours0;
00959
00960 size_t tempConstrainCounter = constraintCounter_;
00961
00962 if(usePreBounding){
00963 partition(partit,neighbours0,1-EPS_);
00964 }
00965
00966 std::map<std::pair<IndexType,IndexType>,size_t> counter;
00967 for(size_t i=0; i<numberOfInternalEdges_;++i) {
00968
00969 IndexType u = edgeNodes_[i].first;
00970 IndexType v = edgeNodes_[i].second;
00971
00972 if(usePreBounding && partit[u] != partit[v])
00973 continue;
00974
00975 OPENGM_ASSERT(i+numberOfTerminalEdges_ == neighbours[u][v]);
00976 OPENGM_ASSERT(i+numberOfTerminalEdges_ == neighbours[v][u]);
00977
00978 if(sol_[numberOfTerminalEdges_+i]>EPS_){
00979
00980 std::vector<IndexType> path;
00981 const double pathLength = shortestPath(u,v,neighbours,sol_,path,sol_[numberOfTerminalEdges_+i],addOnlyFacetDefiningConstraints);
00982 if(sol_[numberOfTerminalEdges_+i]-EPS_>pathLength){
00983 OPENGM_ASSERT(path.size()>2);
00984 constraint.add(IloRange(env_, 0 , 1000000000));
00985 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],-1);
00986 for(size_t n=0;n<path.size()-1;++n){
00987 constraint[constraintCounter_].setLinearCoef(x_[neighbours[path[n]][path[n+1]]],1);
00988 }
00989 ++constraintCounter_;
00990 }
00991 }
00992 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
00993 break;
00994 }
00995 return constraintCounter_-tempConstrainCounter;
00996 }
00997
00998 template<class GM, class ACC>
00999 size_t Multicut<GM, ACC>::findOddWheelConstraints(IloRangeArray& constraints){
01000 size_t tempConstrainCounter = constraintCounter_;
01001 std::vector<IndexType> var2node(gm_.numberOfVariables(),std::numeric_limits<IndexType>::max());
01002 for(size_t center=0; center<gm_.numberOfVariables();++center){
01003 var2node.assign(gm_.numberOfVariables(),std::numeric_limits<IndexType>::max());
01004 size_t N = neighbours[center].size();
01005 std::vector<IndexType> node2var(N);
01006 std::vector<EdgeMapType> E(2*N);
01007 std::vector<double> w;
01008 typename EdgeMapType::const_iterator it;
01009 size_t id=0;
01010 for(it=neighbours[center].begin() ; it != neighbours[center].end(); ++it) {
01011 IndexType var = (*it).first;
01012 node2var[id] = var;
01013 var2node[var] = id++;
01014 }
01015
01016 for(it=neighbours[center].begin() ; it != neighbours[center].end(); ++it) {
01017 const IndexType var1 = (*it).first;
01018 const LPIndexType u = var2node[var1];
01019 typename EdgeMapType::const_iterator it2;
01020 for(it2=neighbours[var1].begin() ; it2 != neighbours[var1].end(); ++it2) {
01021 const IndexType var2 = (*it2).first;
01022 const LPIndexType v = var2node[var2];
01023 if( v != std::numeric_limits<IndexType>::max()){
01024 if(u<v){
01025 E[2*u][2*v+1]=w.size();
01026 E[2*v+1][2*u]=w.size();
01027 E[2*u+1][2*v]=w.size();
01028 E[2*v][2*u+1]=w.size();
01029 double weight = 0.5-sol_[neighbours[var1][var2]]+0.5*(sol_[neighbours[center][var1]]+sol_[neighbours[center][var2]]);
01030
01031 if(weight<0) weight=0;
01032 w.push_back(weight);
01033
01034 }
01035 }
01036 }
01037 }
01038
01039
01040 for(size_t n=0; n<N;++n) {
01041 std::vector<IndexType> path;
01042 const double pathLength = shortestPath(2*n,2*n+1,E,w,path,1e22,false);
01043 if(pathLength<0.5-EPS_){
01044 OPENGM_ASSERT((path.size())>3);
01045 OPENGM_ASSERT(((path.size())/2)*2 == path.size() );
01046
01047 constraints.add(IloRange(env_, -100000 , (path.size()-2)/2 ));
01048 for(size_t k=0;k<path.size()-1;++k){
01049 constraints[constraintCounter_].setLinearCoef(x_[neighbours[center][node2var[path[k]/2]]],-1);
01050 }
01051 for(size_t k=0;k<path.size()-1;++k){
01052 const IndexType u= node2var[path[k]/2];
01053 const IndexType v= node2var[path[k+1]/2];
01054 constraints[constraintCounter_].setLinearCoef(x_[neighbours[u][v]],1);
01055 }
01056 ++constraintCounter_;
01057 }
01058 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
01059 break;
01060 }
01061
01062
01063 for(it=neighbours[center].begin() ; it != neighbours[center].end(); ++it) {
01064 var2node[(*it).first] = std::numeric_limits<IndexType>::max();
01065 }
01066
01067 }
01068
01069 return constraintCounter_-tempConstrainCounter;
01070 }
01071
01077 template<class GM, class ACC>
01078 size_t Multicut<GM, ACC>::findIntegerCycleConstraints(
01079 IloRangeArray& constraint,
01080 bool addFacetDefiningConstraintsOnly=true
01081 )
01082 {
01083 OPENGM_ASSERT(integerMode_);
01084 std::vector<LabelType> partit(numberOfNodes_,EPS_);
01085 std::vector<std::list<size_t> > neighbours0;
01086 partition(partit,neighbours0);
01087 size_t tempConstrainCounter = constraintCounter_;
01088
01089
01090 size_t u,v;
01091 for(size_t i=0; i<numberOfInternalEdges_;++i) {
01092 u = edgeNodes_[i].first;
01093 v = edgeNodes_[i].second;
01094 OPENGM_ASSERT(partit[u] >= 0);
01095 if(sol_[numberOfTerminalEdges_+i]>=1-EPS_ && partit[u] == partit[v]) {
01096
01097 std::queue<size_t> nodeList;
01098 std::vector<size_t> path(numberOfNodes_,std::numeric_limits<size_t>::max());
01099 size_t n = u;
01100 while(n!=v) {
01101 std::list<size_t>::iterator it;
01102 for(it=neighbours0[n].begin() ; it != neighbours0[n].end(); ++it) {
01103 if(path[*it]==std::numeric_limits<size_t>::max()) {
01104
01105 if(addFacetDefiningConstraintsOnly) {
01106 bool isCordless = true;
01107 size_t s = n;
01108 const size_t c = *it;
01109 while(s!=u){
01110 s = path[s];
01111 if(s==u && c==v) continue;
01112 if(neighbours[c].find(s)!=neighbours[c].end()) {
01113 isCordless = false;
01114 break;
01115 }
01116 }
01117 if(isCordless){
01118 path[*it]=n;
01119 nodeList.push(*it);
01120 }
01121 }
01122 else{
01123 path[*it]=n;
01124 nodeList.push(*it);
01125 }
01126 }
01127 }
01128 if(nodeList.size()==0)
01129 break;
01130 n = nodeList.front(); nodeList.pop();
01131 }
01132 if(path[v] != std::numeric_limits<size_t>::max()){
01133 if(!integerMode_){
01134 double w=0;
01135 while(n!=u) {
01136 w += sol_[neighbours[n][path[n]]];
01137 n=path[n];
01138 }
01139 if(sol_[neighbours[u][v]]-EPS_<w)
01140 continue;
01141 }
01142
01143 constraint.add(IloRange(env_, 0 , 1000000000));
01144 constraint[constraintCounter_].setLinearCoef(x_[neighbours[u][v]],-1);
01145 while(n!=u) {
01146 constraint[constraintCounter_].setLinearCoef(x_[neighbours[n][path[n]]],1);
01147 n=path[n];
01148 }
01149 ++constraintCounter_;
01150 }
01151 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
01152 break;
01153 }
01154 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
01155 break;
01156 }
01157 return constraintCounter_-tempConstrainCounter;
01158 }
01159
01160
01161 template <class GM, class ACC>
01162 InferenceTermination
01163 Multicut<GM,ACC>::infer()
01164 {
01165 EmptyVisitorType mcv;
01166 return infer(mcv);
01167 }
01168
01169 template <class GM, class ACC>
01170 void
01171 Multicut<GM,ACC>::initCplex()
01172 {
01173
01174 cplex_.setParam(IloCplex::Threads, parameter_.numThreads_);
01175 cplex_.setParam(IloCplex::CutUp, parameter_.cutUp_);
01176 cplex_.setParam(IloCplex::MIPDisplay,0);
01177 cplex_.setParam(IloCplex::BarDisplay,0);
01178 cplex_.setParam(IloCplex::NetDisplay,0);
01179 cplex_.setParam(IloCplex::SiftDisplay,0);
01180 cplex_.setParam(IloCplex::SimDisplay,0);
01181
01182 cplex_.setParam(IloCplex::EpOpt,1e-9);
01183 cplex_.setParam(IloCplex::EpRHS,1e-9);
01184 cplex_.setParam(IloCplex::EpInt,0);
01185 cplex_.setParam(IloCplex::EpAGap,0);
01186 cplex_.setParam(IloCplex::EpGap,0);
01187
01188 if(parameter_.verbose_ == true && parameter_.verboseCPLEX_) {
01189 cplex_.setParam(IloCplex::MIPDisplay,2);
01190 cplex_.setParam(IloCplex::BarDisplay,1);
01191 cplex_.setParam(IloCplex::NetDisplay,1);
01192 cplex_.setParam(IloCplex::SiftDisplay,1);
01193 cplex_.setParam(IloCplex::SimDisplay,1);
01194 }
01195 }
01196
01197
01198 template <class GM, class ACC>
01199 template<class VisitorType>
01200 InferenceTermination
01201 Multicut<GM,ACC>::infer(VisitorType& mcv)
01202 {
01203
01204
01205
01206 std::vector<LabelType> conf(gm_.numberOfVariables());
01207 initCplex();
01208
01209
01210 if(problemType_ == INVALID){
01211 throw RuntimeError("Error: Model can not be solved!");
01212 }
01213 else if(!readWorkFlow(parameter_.workFlow_)){
01214 std::cout << "Error: can not parse workflow : " << parameter_.workFlow_ <<std::endl;
01215 std::cout << "Using default workflow ";
01216 if(problemType_ == MWC){
01217 std::cout << "(TTC)(MTC)(IC)(CC-IFD,TTC-I)" <<std::endl;
01218 readWorkFlow("(TTC)(MTC)(IC)(CC-IFD,TTC-I)");
01219 }
01220 else if(problemType_ == MC){
01221 std::cout << "(CC-FDB)(IC)(CC-I)" <<std::endl;
01222 readWorkFlow("(CC-FDB)(IC)(CC-I)");
01223 }
01224 else{
01225 throw RuntimeError("Error: Model can not be solved!");
01226 }
01227 }
01228
01229
01230 Timer timer,timer2;
01231 timer.tic();
01232 mcv.begin(*this);
01233 size_t workingState = 0;
01234 while(workingState<workFlow_.size()){
01235 protocolateTiming_.push_back(std::vector<double>(20,0));
01236 protocolateConstraints_.push_back(std::vector<size_t>(20,0));
01237 std::vector<double>& T = protocolateTiming_.back();
01238 std::vector<size_t>& C = protocolateConstraints_.back();
01239
01240
01241 timer.toc();
01242 if(timer.elapsedTime()>parameter_.timeOut_) {
01243 break;
01244 }
01245
01246 for (size_t it=1; it<10000000000; ++it) {
01247 cplex_.setParam(IloCplex::Threads, parameter_.numThreads_);
01248 timer2.tic();
01249 if(!cplex_.solve()) {
01250 std::cout << "failed to optimize. " <<cplex_.getStatus()<< std::endl;
01251 mcv(*this);
01252 return UNKNOWN;
01253 }
01254 if(!integerMode_)
01255
01256 bound_ = cplex_.getObjValue()+constant_;
01257 else{
01258 bound_ = cplex_.getBestObjValue()+constant_;
01259 if(!cplex_.solveFixed()) {
01260 std::cout << "failed to fixed optimize." << std::endl;
01261 mcv(*this);
01262 return UNKNOWN;
01263 }
01264 }
01265 cplex_.getValues(sol_, x_);
01266 timer2.toc();
01267 T[Protocol_ID_Solve] += timer2.elapsedTime();
01268 mcv(*this);
01269
01270
01271
01272
01273 IloRangeArray constraint = IloRangeArray(env_);
01274 constraintCounter_ = 0;
01275
01276
01277
01278
01279 size_t cycleConstraints = std::numeric_limits<size_t>::max();
01280 bool constraintAdded = false;
01281 for(std::vector<size_t>::iterator it=workFlow_[workingState].begin() ; it != workFlow_[workingState].end(); it++ ){
01282 size_t n = 0;
01283 size_t protocol_ID = Protocol_ID_Unknown;
01284 timer2.tic();
01285 if(*it == Action_ID_TTC){
01286 if(parameter_.verbose_) std::cout << "* Add terminal triangle constraints: " << std::flush;
01287 n = findTerminalTriangleConstraints(constraint);
01288 if(parameter_.verbose_) std::cout << n << std::endl;
01289 protocol_ID = Protocol_ID_TTC;
01290 }
01291 else if(*it == Action_ID_TTC_I){
01292 if(!integerMode_){
01293 throw RuntimeError("Error: Calling integer terminal triangle constraint (TTC-I) seperation provedure before switching in integer mode (IC)");
01294 }
01295 if(parameter_.verbose_) std::cout << "* Add integer terminal triangle constraints: " << std::flush;
01296 arg(conf);
01297 n = findIntegerTerminalTriangleConstraints(constraint, conf);
01298 if(parameter_.verbose_) std::cout << n << std::endl;
01299 protocol_ID = Protocol_ID_TTC;
01300
01301 }
01302 else if(*it == Action_ID_MTC){
01303 if(parameter_.verbose_) std::cout << "* Add multi terminal constraints: " << std::flush;
01304 n = findMultiTerminalConstraints(constraint);
01305 if(parameter_.verbose_) std::cout << n << std::endl;
01306 protocol_ID = Protocol_ID_MTC;
01307
01308 }
01309 else if(*it == Action_ID_CC_I){
01310 if(!integerMode_){
01311 throw RuntimeError("Error: Calling integer cycle constraints (CC-I) seperation provedure before switching in integer mode (IC)");
01312 }
01313 if(parameter_.verbose_) std::cout << "Add integer cycle constraints: " << std::flush;
01314 n = findIntegerCycleConstraints(constraint, false);
01315 if(parameter_.verbose_) std::cout << n << std::endl;
01316 protocol_ID = Protocol_ID_CC;
01317 }
01318 else if(*it == Action_ID_CC_IFD){
01319 if(!integerMode_){
01320 throw RuntimeError("Error: Calling facet defining integer cycle constraints (CC-IFD) seperation provedure before switching in integer mode (IC)");
01321 }
01322 if(parameter_.verbose_) std::cout << "Add facet defining integer cycle constraints: " << std::flush;
01323 n = findIntegerCycleConstraints(constraint, true);
01324 if(parameter_.verbose_) std::cout << n << std::endl;
01325 protocol_ID = Protocol_ID_CC;
01326 }
01327 else if(*it == Action_ID_CC){
01328 if(parameter_.verbose_) std::cout << "Add cycle constraints: " << std::flush;
01329 n = findCycleConstraints(constraint, false, false);
01330 cycleConstraints=n;
01331 if(parameter_.verbose_) std::cout << n << std::endl;
01332 protocol_ID = Protocol_ID_CC;
01333 }
01334 else if(*it == Action_ID_CC_FD){
01335 if(parameter_.verbose_) std::cout << "Add facet defining cycle constraints: " << std::flush;
01336 n = findCycleConstraints(constraint, true, false);
01337 cycleConstraints=n;
01338 if(parameter_.verbose_) std::cout << n << std::endl;
01339 protocol_ID = Protocol_ID_CC;
01340 }
01341 else if(*it == Action_ID_CC_FDB){
01342 if(parameter_.verbose_) std::cout << "Add facet defining cycle constraints (with bounding): " << std::flush;
01343 n = findCycleConstraints(constraint, true, true);
01344 cycleConstraints=n;
01345 if(parameter_.verbose_) std::cout << n << std::endl;
01346 protocol_ID = Protocol_ID_CC;
01347 }
01348 else if(*it == Action_ID_CC_B){
01349 if(parameter_.verbose_) std::cout << "Add cycle constraints (with bounding): " << std::flush;
01350 n = findCycleConstraints(constraint, false, true);
01351 cycleConstraints=n;
01352 if(parameter_.verbose_) std::cout << n << std::endl;
01353 protocol_ID = Protocol_ID_CC;
01354 }
01355 else if(*it == Action_ID_RemoveConstraints){
01356 if(parameter_.verbose_) std::cout << "Remove unused constraints: " << std::flush;
01357 n = removeUnusedConstraints();
01358 if(parameter_.verbose_) std::cout << n << std::endl;
01359 protocol_ID = Protocol_ID_RemoveConstraints;
01360 }
01361 else if(*it == Action_ID_IntegerConstraints && !integerMode_){
01362 if(parameter_.verbose_) std::cout << "Add integer constraints: " << std::flush;
01363 n = enforceIntegerConstraints();
01364 if(parameter_.verbose_) std::cout << n << std::endl;
01365 protocol_ID = Protocol_ID_IntegerConstraints;
01366 }
01367 else if(*it == Action_ID_OWC){
01368 if(cycleConstraints== std::numeric_limits<size_t>::max()){
01369 std::cout << "WARNING: using Odd Wheel Contraints without Cycle Constrains! -> Use CC,OWC!"<<std::endl;
01370 n=0;
01371 }
01372 else if(cycleConstraints==0){
01373 if(parameter_.verbose_) std::cout << "Add odd wheel constraints: " << std::flush;
01374 n = findOddWheelConstraints(constraint);
01375 if(parameter_.verbose_) std::cout << n << std::endl;
01376 }
01377 else{
01378
01379 }
01380 protocol_ID = Protocol_ID_OWC;
01381 }
01382 else{
01383 std::cout <<"Unknown Inference State "<<*it<<std::endl;
01384 }
01385 timer2.toc();
01386 T[protocol_ID] += timer2.elapsedTime();
01387 C[protocol_ID] += n;
01388 if(n>0) constraintAdded = true;
01389 }
01390
01391
01392
01393
01394 if(!constraintAdded){
01395
01396 ++workingState;
01397 if(workingState<workFlow_.size())
01398 if(parameter_.verbose_) std::cout <<std::endl<< "** Switching into next state ( "<< workingState << " )**" << std::endl;
01399 break;
01400 }
01401 else{
01402 timer2.tic();
01403
01404 model_.add(constraint);
01405
01406 timer2.toc();
01407 T[Protocol_ID_AddConstraints] += timer2.elapsedTime();
01408 }
01409
01410
01411 timer.toc();
01412 if(timer.elapsedTime()>parameter_.timeOut_) {
01413 break;
01414 }
01415
01416 }
01417 }
01418
01419 mcv.end(*this);
01420 if(parameter_.verbose_){
01421 std::cout << "end normal"<<std::endl;
01422 std::cout <<"Protokoll:"<<std::endl;
01423 std::cout <<"=========="<<std::endl;
01424 std::cout << " i | SOLVE | ADD | CC | OWC | TTC | MTV | IC " <<std::endl;
01425 std::cout << "-----+----------+----------+----------+----------+----------+----------+-----------" <<std::endl;
01426 }
01427 std::vector<size_t> IDS;
01428 IDS.push_back(Protocol_ID_Solve);
01429 IDS.push_back(Protocol_ID_AddConstraints);
01430 IDS.push_back(Protocol_ID_CC);
01431 IDS.push_back(Protocol_ID_OWC);
01432 IDS.push_back(Protocol_ID_TTC);
01433 IDS.push_back(Protocol_ID_MTC);
01434 IDS.push_back(Protocol_ID_IntegerConstraints);
01435
01436 if(parameter_.verbose_){
01437 for(size_t i=0; i<protocolateTiming_.size(); ++i){
01438 std::cout << setw(5)<< i ;
01439 for(size_t n=0; n<IDS.size(); ++n){
01440 std::cout << "|"<< setw(10) << setiosflags(ios::fixed)<< setprecision(4) << protocolateConstraints_[i][IDS[n]];
01441 }
01442 std::cout << std::endl;
01443 std::cout << " " ;
01444 for(size_t n=0; n<IDS.size(); ++n){
01445 std::cout << "|"<< setw(10) << setiosflags(ios::fixed)<< setprecision(4) << protocolateTiming_[i][IDS[n]];
01446 }
01447 std::cout << std::endl;
01448 std::cout << "-----+----------+----------+----------+----------+----------+----------+-----------" <<std::endl;
01449 }
01450 std::cout << "sum ";
01451 double t_all=0;
01452 for(size_t n=0; n<IDS.size(); ++n){
01453 double t_one=0;
01454 for(size_t i=0; i<protocolateTiming_.size(); ++i){
01455 t_one += protocolateTiming_[i][IDS[n]];
01456 }
01457 std::cout << "|"<< setw(10) << setiosflags(ios::fixed)<< setprecision(4) << t_one;
01458 t_all += t_one;
01459 }
01460 std::cout << " | " <<t_all <<std::endl;
01461 std::cout << "-----+----------+----------+----------+----------+----------+----------+-----------" <<std::endl;
01462 }
01463 return NORMAL;
01464 }
01465
01466 template <class GM, class ACC>
01467 InferenceTermination
01468 Multicut<GM,ACC>::arg
01469 (
01470 std::vector<typename Multicut<GM,ACC>::LabelType>& x,
01471 const size_t N
01472 ) const
01473 {
01474 if(N!=1) {
01475 return UNKNOWN;
01476 }
01477 else{
01478 if(problemType_ == MWC) {
01479 if(parameter_.MWCRounding_== parameter_.NEAREST){
01480 x.resize(gm_.numberOfVariables());
01481 for(IndexType node = 0; node<gm_.numberOfVariables(); ++node) {
01482 double v = sol_[numberOfTerminals_*node+0];
01483 x[node] = 0;
01484 for(LabelType i=0; i<gm_.numberOfLabels(node); ++i) {
01485 if(sol_[numberOfTerminals_*node+i]<v) {
01486 x[node]=i;
01487 }
01488 }
01489 }
01490 return NORMAL;
01491 }
01492 else if(parameter_.MWCRounding_==parameter_.DERANDOMIZED){
01493 return derandomizedRounding(x);
01494 }
01495 else if(parameter_.MWCRounding_==parameter_.PSEUDODERANDOMIZED){
01496 return pseudoDerandomizedRounding(x,1000);
01497 }
01498 else{
01499 return UNKNOWN;
01500 }
01501 }
01502 else{
01503 std::vector<std::list<size_t> > neighbours0;
01504 InferenceTermination r = partition(x, neighbours0,parameter_.edgeRoundingValue_);
01505 return r;
01506 }
01507 }
01508 }
01509
01510
01511 template <class GM, class ACC>
01512 InferenceTermination
01513 Multicut<GM,ACC>::pseudoDerandomizedRounding
01514 (
01515 std::vector<typename Multicut<GM,ACC>::LabelType>& x,
01516 size_t bins = 1000
01517 ) const
01518 {
01519 std::vector<bool> processedBins(bins+1,false);
01520 std::vector<LabelType> temp;
01521 double value = 1000000000000.0;
01522 std::vector<LabelType> labelorder1(numberOfTerminals_,numberOfTerminals_-1);
01523 std::vector<LabelType> labelorder2(numberOfTerminals_,numberOfTerminals_-1);
01524 for(LabelType i=0; i<numberOfTerminals_-1;++i){
01525 labelorder1[i]=i;
01526 labelorder2[i]=numberOfTerminals_-2-i;
01527 }
01528 for(size_t i=0; i<numberOfTerminals_*gm_.numberOfVariables();++i){
01529 size_t bin;
01530 double t,d;
01531 if(sol_[i]<=0){
01532 bin=0;
01533 t=0;
01534 }
01535 else if(sol_[i]>=1){
01536 bin=bins;
01537 t=1;
01538 }
01539 else{
01540 bin = (size_t)(sol_[i]*bins)%bins;
01541 t = sol_[i];
01542 }
01543 if(!processedBins[bin]){
01544 processedBins[bin]=true;
01545 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder1,sol_[i]))){
01546 value=d;
01547 x=temp;
01548 }
01549 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder2,sol_[i]))){
01550 value=d;
01551 x=temp;
01552 }
01553 }
01554 }
01555 return NORMAL;
01556 }
01557
01558 template <class GM, class ACC>
01559 InferenceTermination
01560 Multicut<GM,ACC>::derandomizedRounding
01561 (
01562 std::vector<typename Multicut<GM,ACC>::LabelType>& x
01563 ) const
01564 {
01565 std::vector<LabelType> temp;
01566 double value = 1000000000000.0;
01567 std::vector<LabelType> labelorder1(numberOfTerminals_,numberOfTerminals_-1);
01568 std::vector<LabelType> labelorder2(numberOfTerminals_,numberOfTerminals_-1);
01569 for(LabelType i=0; i<numberOfTerminals_-1;++i){
01570 labelorder1[i]=i;
01571 labelorder2[i]=numberOfTerminals_-2-i;
01572 }
01573
01574 double d;
01575 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder1,1e-8))){
01576 value=d;
01577 x=temp;
01578 }
01579 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder2,1e-8))){
01580 value=d;
01581 x=temp;
01582 }
01583 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder1,1-1e-8))){
01584 value=d;
01585 x=temp;
01586 }
01587 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder2,1-1e-8))){
01588 value=d;
01589 x=temp;
01590 }
01591 for(size_t i=0; i<numberOfTerminals_*gm_.numberOfVariables();++i){
01592 if( sol_[i]>1e-8 && sol_[i]<1-1e-8){
01593 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder1,sol_[i]))){
01594 value=d;
01595 x=temp;
01596 }
01597 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder2,sol_[i]))){
01598 value=d;
01599 x=temp;
01600 }
01601 }
01602 }
01603 return NORMAL;
01604 }
01605
01606 template <class GM, class ACC>
01607 double
01608 Multicut<GM,ACC>::derandomizedRoundingSubProcedure
01609 (
01610 std::vector<typename Multicut<GM,ACC>::LabelType>& x,
01611 const std::vector<typename Multicut<GM,ACC>::LabelType>& labelorder,
01612 const double threshold
01613 ) const
01614 {
01615 const LabelType lastLabel = labelorder.back();
01616 const IndexType numVar = gm_.numberOfVariables();
01617
01618 x.assign(numVar,lastLabel);
01619
01620 for(size_t i=0; i<labelorder.size()-1; ++i){
01621 for(IndexType v=0; v<numVar; ++v){
01622 if(x[v]==lastLabel && sol_[numberOfTerminals_*v+i]<=threshold){
01623 x[v]=labelorder[i];
01624 }
01625 }
01626 }
01627 return gm_.evaluate(x);
01628 }
01629
01630
01631
01632
01633 template <class GM, class ACC>
01634 InferenceTermination
01635 Multicut<GM,ACC>::partition
01636 (
01637 std::vector<LabelType>& partit,
01638 std::vector<std::list<size_t> >& neighbours0,
01639 double threshold = 0.5
01640 ) const
01641 {
01642
01643 partit.resize(numberOfNodes_,0);
01644 neighbours0.resize(numberOfNodes_, std::list<size_t>());
01645
01646 size_t counter=0;
01647 for(size_t i=0; i<numberOfInternalEdges_; ++i) {
01648 IndexType u = edgeNodes_[i].first;
01649 IndexType v = edgeNodes_[i].second;
01650 if(sol_[numberOfTerminalEdges_+counter] <= threshold) {
01651 neighbours0[u].push_back(v);
01652 neighbours0[v].push_back(u);
01653 }
01654 ++counter;
01655 }
01656
01657 LabelType p=0;
01658 std::vector<bool> assigned(numberOfNodes_,false);
01659 for(size_t node=0; node<numberOfNodes_; ++node) {
01660 if(assigned[node])
01661 continue;
01662 else{
01663 std::list<size_t> nodeList;
01664 partit[node] = p;
01665 assigned[node] = true;
01666 nodeList.push_back(node);
01667 while(!nodeList.empty()) {
01668 size_t n=nodeList.front(); nodeList.pop_front();
01669 std::list<size_t>::const_iterator it;
01670 for(it=neighbours0[n].begin() ; it != neighbours0[n].end(); ++it) {
01671 if(!assigned[*it]) {
01672 partit[*it] = p;
01673 assigned[*it] = true;
01674 nodeList.push_back(*it);
01675 }
01676 }
01677 }
01678 ++p;
01679 }
01680 }
01681 return NORMAL;
01682 }
01683
01684
01685 template <class GM, class ACC>
01686 typename Multicut<GM,ACC>::ValueType
01687 Multicut<GM,ACC>::evaluate
01688 (
01689 std::vector<LabelType>& conf
01690 ) const
01691 {
01692
01693 return gm_.evaluate(conf);
01694 }
01695
01696 template<class GM, class ACC>
01697 inline const typename Multicut<GM, ACC>::GraphicalModelType&
01698 Multicut<GM, ACC>::graphicalModel() const
01699 {
01700 return gm_;
01701 }
01702
01703 template<class GM, class ACC>
01704 typename GM::ValueType Multicut<GM, ACC>::bound() const
01705 {
01706 return bound_;
01707 }
01708
01709 template<class GM, class ACC>
01710 typename GM::ValueType Multicut<GM, ACC>::value() const
01711 {
01712 std::vector<LabelType> c;
01713 arg(c);
01714 ValueType value = gm_.evaluate(c);
01715 return value;
01716 }
01717
01718 template<class GM, class ACC>
01719 bool Multicut<GM, ACC>::readWorkFlow(std::string s)
01720 {
01721 if(s[0]!='(' || s[s.size()-1] !=')')
01722 return false;
01723 workFlow_.clear();
01724 size_t n=0;
01725 std::string sepString;
01726 if(s.size()<2)
01727 return false;
01728 while(n<s.size()){
01729 if(s[n]==',' || s[n]==')'){
01730 if(sepString.compare("CC")==0)
01731 workFlow_.back().push_back(Action_ID_CC);
01732 else if(sepString.compare("CC-I")==0)
01733 workFlow_.back().push_back(Action_ID_CC_I);
01734 else if(sepString.compare("CC-IFD")==0)
01735 workFlow_.back().push_back(Action_ID_CC_IFD);
01736 else if(sepString.compare("CC-B")==0)
01737 workFlow_.back().push_back(Action_ID_CC_B);
01738 else if(sepString.compare("CC-FDB")==0)
01739 workFlow_.back().push_back(Action_ID_CC_FDB);
01740 else if(sepString.compare("CC-FD")==0)
01741 workFlow_.back().push_back(Action_ID_CC_FD);
01742 else if(sepString.compare("TTC")==0)
01743 workFlow_.back().push_back(Action_ID_TTC);
01744 else if(sepString.compare("TTC-I")==0)
01745 workFlow_.back().push_back(Action_ID_TTC_I);
01746 else if(sepString.compare("MTC")==0)
01747 workFlow_.back().push_back(Action_ID_MTC);
01748 else if(sepString.compare("OWC")==0)
01749 workFlow_.back().push_back(Action_ID_OWC);
01750 else if(sepString.compare("IC")==0)
01751 workFlow_.back().push_back(Action_ID_IntegerConstraints);
01752 else
01753 std::cout << "WARNING: Unknown Seperation Procedure ' "<<sepString<<"' is skipped!"<<std::endl;
01754 sepString.clear();
01755 }
01756 else if(s[n]=='('){
01757 workFlow_.push_back(std::vector<size_t>());
01758 }
01759 else{
01760 sepString += s[n];
01761 }
01762 ++n;
01763 }
01764 return true;
01765 }
01766
01767
01773 template<class GM, class ACC>
01774 template<class DOUBLEVECTOR>
01775 inline double Multicut<GM, ACC>::shortestPath(
01776 const IndexType startNode,
01777 const IndexType endNode,
01778 const std::vector<EdgeMapType >& E,
01779 const DOUBLEVECTOR& w,
01780 std::vector<IndexType>& shortestPath,
01781 const double maxLength = std::numeric_limits<double>::infinity(),
01782 bool cordless = true
01783 ) const
01784 {
01785
01786 const IndexType numberOfNodes = E.size();
01787 const double inf = std::numeric_limits<double>::infinity();
01788 const IndexType nonePrev = endNode;
01789
01790 std::vector<IndexType> prev(numberOfNodes,nonePrev);
01791 std::vector<double> dist(numberOfNodes,inf);
01792 MYSET openNodes;
01793
01794 openNodes.insert(startNode);
01795 dist[startNode]=0.0;
01796
01797 while(!openNodes.empty()){
01798 IndexType node;
01799
01800 {
01801 typename MYSET::iterator it, itMin;
01802 double v = std::numeric_limits<double>::infinity();
01803 for(it = openNodes.begin(); it!= openNodes.end(); ++it){
01804 if( dist[*it]<v ){
01805 v = dist[*it];
01806 itMin = it;
01807 }
01808 }
01809 node = *itMin;
01810 openNodes.erase(itMin);
01811 }
01812
01813 if(node == endNode)
01814 break;
01815
01816 {
01817 typename EdgeMapType::const_iterator it;
01818 for(it=E[node].begin() ; it != E[node].end(); ++it) {
01819 const IndexType node2 = (*it).first;
01820 const LPIndexType weighId = (*it).second;
01821 double cuttedWeight = max(0.0,w[weighId]);
01822 const double weight2 = dist[node]+cuttedWeight;
01823
01824
01825 if(dist[node2] > weight2 && weight2 < maxLength){
01826
01827 bool updateNode = true;
01828 if(cordless) {
01829 IndexType s = node;
01830 while(s!=startNode){
01831 s= prev[s];
01832 if(s==startNode && node2==endNode) continue;
01833 if(neighbours[node2].find(s)!=neighbours[node2].end()) {
01834 updateNode = false;
01835 break;
01836 }
01837 }
01838 }
01839 if(updateNode){
01840 prev[node2] = node;
01841 dist[node2] = weight2;
01842 openNodes.insert(node2);
01843 }
01844 }
01845 }
01846 }
01847 }
01848
01849 if(prev[endNode] != nonePrev){
01850 shortestPath.clear();
01851 shortestPath.push_back(endNode);
01852 IndexType n = endNode;
01853 do{
01854 n=prev[n];
01855 shortestPath.push_back(n);
01856 }while(n!=startNode);
01857 OPENGM_ASSERT(shortestPath.back() == startNode);
01858 }
01859
01860 return dist[endNode];
01861 }
01862
01863
01864 template<class GM, class ACC>
01865 std::vector<double>
01866 Multicut<GM, ACC>::getEdgeLabeling
01867 () const
01868 {
01869 std::vector<double> l(numberOfInternalEdges_,0);
01870 for(size_t i=0; i<numberOfInternalEdges_; ++i) {
01871 l[i] = sol_[numberOfTerminalEdges_+i];
01872 }
01873 return l;
01874 }
01875
01876
01877
01878
01879
01880 template<class GM, class ACC>
01881 template<class LPVariableIndexIterator, class CoefficientIterator>
01882 void Multicut<GM, ACC>::addConstraint
01883 (
01884 LPVariableIndexIterator viBegin,
01885 LPVariableIndexIterator viEnd,
01886 CoefficientIterator coefficient,
01887 const ValueType& lowerBound,
01888 const ValueType& upperBound)
01889 {
01890 IloRange constraint(env_, lowerBound, upperBound);
01891 while(viBegin != viEnd) {
01892 constraint.setLinearCoef(x_[*viBegin], *coefficient);
01893 ++viBegin;
01894 ++coefficient;
01895 }
01896 model_.add(constraint);
01897
01898
01899
01900 }
01901
01902 }
01903
01904 #endif