2 #ifndef OPENGM_MULTICUT_HXX 3 #define OPENGM_MULTICUT_HXX 15 #include <boost/unordered_map.hpp> 16 #include <boost/unordered_set.hpp> 18 #include <ext/hash_map> 19 #include <ext/hash_set> 30 #include <ilcplex/ilocplex.h> 42 std::vector<size_t> lpIndices_;
43 HigherOrderTerm(
size_t factorID,
bool potts,
size_t valueIndex)
44 : factorID_(factorID), potts_(potts),valueIndex_(valueIndex) {}
46 : factorID_(0), potts_(
false),valueIndex_(0) {}
76 template<
class GM,
class ACC>
92 template<
class _GM,
class _ACC>
98 typedef boost::unordered_map<IndexType, LPIndexType>
EdgeMapType;
99 typedef boost::unordered_set<IndexType>
MYSET;
102 typedef __gnu_cxx::hash_set<IndexType>
MYSET;
106 template<
class GM_,
class ACC_>
139 : numThreads_(numThreads),
141 verboseCPLEX_(
false),
144 maximalNumberOfConstraintsPerRound_(1000000),
145 edgeRoundingValue_(0.00000001),
146 MWCRounding_(NEAREST),
148 useOldPriorityQueue_(
false),
149 useChordalSearch_(
false),
150 useBufferedStates_(
false),
151 initializeWith3Cycles_(
false)
154 template<
class OTHER_PARAM>
157 const OTHER_PARAM & p
159 : numThreads_(p.numThreads_),
160 verbose_(p.verbose_),
161 verboseCPLEX_(p.verboseCPLEX_),
163 timeOut_(p.timeOut_),
164 maximalNumberOfConstraintsPerRound_(p.maximalNumberOfConstraintsPerRound_),
165 edgeRoundingValue_(p.edgeRoundingValue_),
166 MWCRounding_(p.MWCRounding_),
167 reductionMode_(p.reductionMode_),
168 useOldPriorityQueue_(p.useOldPriorityQueue_),
169 useChordalSearch_(p.useChordalSearch_),
170 initializeWith3Cycles_(
false)
179 virtual std::string
name()
const {
return "Multicut";}
180 const GraphicalModelType& graphicalModel()
const;
187 ValueType evaluate(std::vector<LabelType>&)
const;
189 template<
class LPVariableIndexIterator,
class CoefficientIterator>
190 void addConstraint(LPVariableIndexIterator, LPVariableIndexIterator,
192 std::vector<double> getEdgeLabeling()
const;
193 std::vector<size_t> getSegmentation()
const;
196 size_t getLPIndex(IT a, IT b) {
return neighbours[a][b]; };
201 enum ProblemType {INVALID, MC, MWC};
203 const GraphicalModelType& gm_;
204 ProblemType problemType_;
208 double bufferedValue_;
209 std::vector<LabelType> bufferedStates_;
210 const double infinity_;
212 IndexType numberOfNodes_;
213 LPIndexType numberOfTerminalEdges_;
214 LPIndexType numberOfInternalEdges_;
215 LPIndexType terminalOffset_;
216 LPIndexType numberOfHigherOrderValues_;
217 LPIndexType numberOfInterTerminalEdges_;
219 std::vector<std::vector<size_t> > workFlow_;
220 std::vector<std::pair<IndexType,IndexType> > edgeNodes_;
224 std::vector<EdgeMapType > neighbours;
240 size_t findCycleConstraints(IloRangeArray&,
bool =
true,
bool =
true);
241 size_t findIntegerCycleConstraints(IloRangeArray&,
bool =
true);
242 size_t findTerminalTriangleConstraints(IloRangeArray&);
243 size_t findIntegerTerminalTriangleConstraints(IloRangeArray&, std::vector<LabelType>& conf);
244 size_t findMultiTerminalConstraints(IloRangeArray&);
245 size_t findOddWheelConstraints(IloRangeArray&);
246 size_t removeUnusedConstraints();
247 size_t enforceIntegerConstraints();
248 size_t add3CycleConstraints();
250 bool readWorkFlow(std::string);
252 InferenceTermination partition(std::vector<LabelType>&, std::vector<std::list<size_t> >&,
double = 0.5)
const;
253 ProblemType setProblemType();
254 LPIndexType getNeighborhood(
const LPIndexType, std::vector<EdgeMapType >&,std::vector<std::pair<IndexType,IndexType> >&, std::vector<HigherOrderTerm>&);
256 template <
class DOUBLEVECTOR>
257 double shortestPath(
const IndexType,
const IndexType,
const std::vector<EdgeMapType >&,
const DOUBLEVECTOR&, std::vector<IndexType>&,
const double = std::numeric_limits<double>::infinity(),
bool =
true)
const;
258 template <
class DOUBLEVECTOR>
259 double shortestPath2(
const IndexType,
const IndexType,
const std::vector<EdgeMapType >&,
const DOUBLEVECTOR&, std::vector<IndexType>&,
261 const double = std::numeric_limits<double>::infinity(),
bool =
true)
const;
265 double derandomizedRoundingSubProcedure(std::vector<LabelType>&,
const std::vector<LabelType>&,
const double)
const;
270 Protocol_ID_Solve = 0,
271 Protocol_ID_AddConstraints = 1,
272 Protocol_ID_RemoveConstraints = 2,
273 Protocol_ID_IntegerConstraints = 3,
278 Protocol_ID_Unknown = 8
282 Action_ID_RemoveConstraints = 0,
283 Action_ID_IntegerConstraints = 1,
286 Action_ID_CC_IFD = 12,
287 Action_ID_CC_FD = 13,
289 Action_ID_CC_FDB = 15,
291 Action_ID_TTC_I = 21,
296 std::vector<std::vector<double> > protocolateTiming_;
297 std::vector<std::vector<size_t> > protocolateConstraints_;
303 template<
class GM,
class ACC>
306 const size_t numNodes,
307 const std::map<UInt64Type, ValueType> & accWeights,
309 ) : gm_(GM()), parameter_(para) , bound_(-std::numeric_limits<double>::infinity()), infinity_(1e8), integerMode_(
false),
313 throw RuntimeError(
"This implementation does only supports Min-Plus-Semiring.");
315 if(parameter_.reductionMode_<0 ||parameter_.reductionMode_>3) {
316 throw RuntimeError(
"Reduction Mode has to be 1, 2 or 3!");
321 numberOfTerminalEdges_ = 0;
322 numberOfTerminals_ = 0;
323 numberOfInterTerminalEdges_ = 0;
324 numberOfHigherOrderValues_ = 0;
325 numberOfNodes_ = numNodes;
326 size_t numEdges = accWeights.size();
328 neighbours.resize(numberOfNodes_);
329 numberOfInternalEdges_=0;
330 LPIndexType numberOfAdditionalInternalEdges=0;
333 bufferedValue_ = std::numeric_limits<double>::infinity();
334 bufferedStates_.resize(numNodes,0);
338 typedef std::map<IndexType, ValueType> MapType;
339 typedef typename MapType::const_iterator MapIter;
343 model_ = IloModel(env_);
344 x_ = IloNumVarArray(env_);
345 c_ = IloRangeArray(env_);
346 obj_ = IloMinimize(env_);
347 sol_ = IloNumArray(env_,N);
349 x_.add(IloNumVarArray(env_, N, 0, 1, ILOFLOAT));
351 IloNumArray obj(env_,N);
355 for(MapIter i = accWeights.begin(); i!=accWeights.end(); ++i){
360 if(neighbours[u].find(v)==neighbours[u].end()) {
361 neighbours[u][v] = numberOfInternalEdges_;
362 neighbours[v][u] = numberOfInternalEdges_;
363 edgeNodes_.push_back(std::pair<IndexType,IndexType>(v,u));
364 obj[numberOfInternalEdges_] = weight;
365 ++numberOfInternalEdges_;
373 obj_.setLinearCoefs(x_,obj);
376 add3CycleConstraints();
379 cplex_ = IloCplex(model_);
384 template<
class GM,
class ACC>
387 const LPIndexType numberOfTerminalEdges,
388 std::vector<EdgeMapType >& neighbours,
389 std::vector<std::pair<IndexType,IndexType> >& edgeNodes,
390 std::vector<HigherOrderTerm>& higherOrderTerms
394 neighbours.resize(gm_.numberOfVariables());
395 LPIndexType numberOfInternalEdges=0;
396 LPIndexType numberOfAdditionalInternalEdges=0;
398 for(
size_t f=0; f<gm_.numberOfFactors(); ++f) {
399 if(gm_[f].numberOfVariables()==2) {
400 IndexType u = gm_[f].variableIndex(1);
401 IndexType v = gm_[f].variableIndex(0);
402 if(neighbours[u].find(v)==neighbours[u].end()) {
403 neighbours[u][v] = numberOfTerminalEdges+numberOfInternalEdges;
404 neighbours[v][u] = numberOfTerminalEdges+numberOfInternalEdges;
405 edgeNodes.push_back(std::pair<IndexType,IndexType>(v,u));
406 ++numberOfInternalEdges;
410 for(
size_t f=0; f<gm_.numberOfFactors(); ++f) {
411 if(gm_[f].numberOfVariables()>2 && !gm_[f].isPotts()){
412 higherOrderTerms.push_back(HigherOrderTerm(f,
false, 0));
413 for(
size_t i=0; i<gm_[f].numberOfVariables();++i) {
414 for(
size_t j=0; j<i;++j) {
415 IndexType u = gm_[f].variableIndex(i);
416 IndexType v = gm_[f].variableIndex(j);
417 if(neighbours[u].find(v)==neighbours[u].end()) {
418 neighbours[u][v] = numberOfTerminalEdges+numberOfInternalEdges;
419 neighbours[v][u] = numberOfTerminalEdges+numberOfInternalEdges;
420 edgeNodes.push_back(std::pair<IndexType,IndexType>(v,u));
421 ++numberOfInternalEdges;
422 ++numberOfAdditionalInternalEdges;
429 for(
size_t f=0; f<gm_.numberOfFactors(); ++f) {
430 if(gm_[f].numberOfVariables()>2 && gm_[f].isPotts()) {
431 higherOrderTerms.push_back(HigherOrderTerm(f,
true, 0));
432 std::vector<LPIndexType> lpIndexVector;
434 std::vector<bool> variableInSpanningTree(gm_.numberOfVariables(),
true);
435 for(
size_t i=0; i<gm_[f].numberOfVariables();++i) {
436 variableInSpanningTree[gm_[f].variableIndex(i)]=
false;
438 size_t connection = 2;
443 for(
size_t i=0; i<gm_[f].numberOfVariables();++i) {
444 const IndexType u = gm_[f].variableIndex(i);
445 for(
typename EdgeMapType::const_iterator it=neighbours[u].begin() ; it != neighbours[u].end(); ++it){
446 const IndexType v = (*it).first;
447 if(variableInSpanningTree[v] ==
false && u<v){
448 lpIndexVector.push_back((*it).second);
453 else if(connection==1){
455 for(
size_t i=0; i<gm_[f].numberOfVariables();++i) {
456 const IndexType u = gm_[f].variableIndex(i);
457 for(
typename EdgeMapType::const_iterator it=neighbours[u].begin() ; it != neighbours[u].end(); ++it){
458 const IndexType v = (*it).first;
459 if(variableInSpanningTree[v] ==
false){
460 variableInSpanningTree[v] =
true;
461 lpIndexVector.push_back((*it).second);
469 higherOrderTerms.back().lpIndices_=lpIndexVector;
476 return numberOfInternalEdges;
479 template<
class GM,
class ACC>
484 template<
class GM,
class ACC>
487 const GraphicalModelType& gm,
489 ) : gm_(gm), parameter_(para) , bound_(-std::numeric_limits<double>::infinity()), infinity_(1e8), integerMode_(
false),
493 throw RuntimeError(
"This implementation does only supports Min-Plus-Semiring.");
495 if(parameter_.reductionMode_<0 ||parameter_.reductionMode_>3) {
496 throw RuntimeError(
"Reduction Mode has to be 1, 2 or 3!");
501 if(problemType_ == INVALID)
502 throw RuntimeError(
"Invalid Model for Multicut-Solver! Solver requires a generalized potts model!");
505 std::vector<double> valuesHigherOrder;
506 std::vector<HigherOrderTerm> higherOrderTerms;
507 numberOfInternalEdges_ = getNeighborhood(numberOfTerminalEdges_, neighbours, edgeNodes_ ,higherOrderTerms);
508 numberOfNodes_ = gm_.numberOfVariables();
510 if(parameter_.useBufferedStates_){
511 bufferedValue_ = std::numeric_limits<double>::infinity();
512 bufferedStates_.resize(numberOfNodes_,0);
516 if(parameter_.verbose_ ==
true) {
517 std::cout <<
"** Multicut Info" << std::endl;
519 std::cout <<
" problemType_: Multicut" << std::endl;
520 if(problemType_==MWC)
521 std::cout <<
" problemType_: Multiway Cut" << std::endl;
522 std::cout <<
" numberOfInternalEdges_: " << numberOfInternalEdges_ << std::endl;
523 std::cout <<
" numberOfNodes_: " << numberOfNodes_ << std::endl;
524 std::cout <<
" allowCutsWithin_: ";
525 if(problemType_==MWC && parameter_.allowCutsWithin_.size() == numberOfTerminals_){
526 for(
size_t i=0; i<parameter_.allowCutsWithin_.size(); ++i)
527 if(parameter_.allowCutsWithin_[i]) std::cout<<i<<
" ";
532 std::cout << std::endl;
533 std::cout <<
" higherOrderTerms.size(): " << higherOrderTerms.size() << std::endl;
534 std::cout <<
" numberOfTerminals_: " << numberOfTerminals_ << std::endl;
540 if(numberOfTerminals_==0) valueSize = numberOfInternalEdges_;
541 else valueSize = numberOfTerminalEdges_+numberOfInternalEdges_+numberOfInterTerminalEdges_;
542 std::vector<double> values (valueSize,0);
544 for(
size_t f=0; f<gm_.numberOfFactors(); ++f) {
545 if(gm_[f].numberOfVariables() == 0) {
547 constant_ += gm_[f](&l);
549 else if(gm_[f].numberOfVariables() == 1) {
550 IndexType node = gm_[f].variableIndex(0);
551 for(
LabelType i=0; i<gm_.numberOfLabels(node); ++i) {
552 for(
LabelType j=0; j<gm_.numberOfLabels(node); ++j) {
553 if(i==j) values[node*numberOfTerminals_+i] += (1.0/(numberOfTerminals_-1)-1) * gm_[f](&j);
554 else values[node*numberOfTerminals_+i] += (1.0/(numberOfTerminals_-1)) * gm_[f](&j);
558 else if(gm_[f].numberOfVariables() == 2) {
559 if(gm_[f].numberOfLabels(0)==2 && gm_[f].numberOfLabels(1)==2){
560 IndexType node0 = gm_[f].variableIndex(0);
561 IndexType node1 = gm_[f].variableIndex(1);
563 cc[0]=1;cc[1]=1;
ValueType b = gm_[f](cc);
564 cc[0]=0;cc[1]=1;
ValueType c = gm_[f](cc);
565 cc[0]=1;cc[1]=0;
ValueType d = gm_[f](cc);
567 values[neighbours[gm_[f].variableIndex(0)][gm_[f].variableIndex(1)]] += ((c+d-a-a) - (b-a))/2.0;
568 values[node0*numberOfTerminals_+0] += ((b-a)-(-d+c))/2.0;
569 values[node1*numberOfTerminals_+0] += ((b-a)-( d-c))/2.0;
574 values[neighbours[gm_[f].variableIndex(0)][gm_[f].variableIndex(1)]] += gm_[f](cc1) - gm_[f](cc0);
575 constant_ += gm_[f](cc0);
579 for(
size_t h=0; h<higherOrderTerms.size();++h){
580 if(higherOrderTerms[h].potts_) {
581 const IndexType f = higherOrderTerms[h].factorID_;
582 higherOrderTerms[h].valueIndex_= valuesHigherOrder.size();
584 std::vector<LabelType> cc0(gm_[f].numberOfVariables(),0);
585 std::vector<LabelType> cc1(gm_[f].numberOfVariables(),0);
587 valuesHigherOrder.push_back(gm_[f](cc1.begin()) - gm_[f](cc0.begin()) );
588 constant_ += gm_[f](cc0.begin());
591 const IndexType f = higherOrderTerms[h].factorID_;
592 higherOrderTerms[h].valueIndex_= valuesHigherOrder.size();
593 if(gm_[f].numberOfVariables() == 3) {
594 size_t i[] = {0, 1, 2 };
595 valuesHigherOrder.push_back(gm_[f](i));
596 i[0]=0; i[1]=0; i[2]=1;
597 valuesHigherOrder.push_back(gm_[f](i));
598 i[0]=0; i[1]=1; i[2]=0;
599 valuesHigherOrder.push_back(gm_[f](i));
600 i[0]=1; i[1]=0; i[2]=0;
601 valuesHigherOrder.push_back(gm_[f](i));
602 i[0]=0; i[1]=0; i[2]=0;
603 valuesHigherOrder.push_back(gm_[f](i));
605 else if(gm_[f].numberOfVariables() == 4) {
606 size_t i[] = {0, 1, 2, 3 };
607 if(numberOfTerminals_>=4){
608 valuesHigherOrder.push_back(gm_[f](i));
610 valuesHigherOrder.push_back(0.0);
612 if(numberOfTerminals_>=3){
613 i[0]=0; i[1]=0; i[2]=1; i[3] = 2;
614 valuesHigherOrder.push_back(gm_[f](i));
615 i[0]=0; i[1]=1; i[2]=0; i[3] = 2;
616 valuesHigherOrder.push_back(gm_[f](i));
617 i[0]=0; i[1]=1; i[2]=1; i[3] = 2;
618 valuesHigherOrder.push_back(gm_[f](i));
620 valuesHigherOrder.push_back(0.0);
621 valuesHigherOrder.push_back(0.0);
622 valuesHigherOrder.push_back(0.0);
624 i[0]=0; i[1]=0; i[2]=0; i[3] = 1;
625 valuesHigherOrder.push_back(gm_[f](i));
626 i[0]=0; i[1]=1; i[2]=2; i[3] = 0;
627 valuesHigherOrder.push_back(gm_[f](i));
628 i[0]=0; i[1]=1; i[2]=1; i[3] = 0;
629 valuesHigherOrder.push_back(gm_[f](i));
630 i[0]=1; i[1]=0; i[2]=2; i[3] = 0;
631 valuesHigherOrder.push_back(gm_[f](i));
632 i[0]=1; i[1]=0; i[2]=1; i[3] = 0;
633 valuesHigherOrder.push_back(gm_[f](i));
634 i[0]=0; i[1]=0; i[2]=1; i[3] = 0;
635 valuesHigherOrder.push_back(gm_[f](i));
636 i[0]=1; i[1]=2; i[2]=0; i[3] = 0;
637 valuesHigherOrder.push_back(gm_[f](i));
638 i[0]=1; i[1]=1; i[2]=0; i[3] = 0;
639 valuesHigherOrder.push_back(gm_[f](i));
640 i[0]=0; i[1]=1; i[2]=0; i[3] = 0;
641 valuesHigherOrder.push_back(gm_[f](i));
642 i[0]=1; i[1]=0; i[2]=0; i[3] = 0;
643 valuesHigherOrder.push_back(gm_[f](i));
644 i[0]=0; i[1]=0; i[2]=0; i[3] = 0;
645 valuesHigherOrder.push_back(gm_[f](i));
648 const IndexType f = higherOrderTerms[h].factorID_;
649 higherOrderTerms[h].valueIndex_= valuesHigherOrder.size();
650 P_.resize(gm_[f].numberOfVariables());
651 std::vector<LabelType> l(gm_[f].numberOfVariables());
652 for(
size_t i=0; i<P_.BellNumber(gm_[f].numberOfVariables()); ++i){
653 P_.getPartition(i,l);
654 valuesHigherOrder.push_back(gm_[f](l.begin()));
662 numberOfHigherOrderValues_ = valuesHigherOrder.size();
667 OPENGM_ASSERT( numberOfTerminalEdges_ == gm_.numberOfVariables()*numberOfTerminals_ );
670 OPENGM_ASSERT(values.size() == numberOfTerminalEdges_+numberOfInternalEdges_+numberOfInterTerminalEdges_);
671 IloInt N = values.size() + numberOfHigherOrderValues_;
672 model_ = IloModel(env_);
673 x_ = IloNumVarArray(env_);
674 c_ = IloRangeArray(env_);
675 obj_ = IloMinimize(env_);
676 sol_ = IloNumArray(env_,N);
679 x_.add(IloNumVarArray(env_, N, 0, 1, ILOFLOAT));
681 IloNumArray obj(env_,N);
682 for (
size_t i=0; i< values.size();++i) {
690 for (
size_t i=0; i<valuesHigherOrder.size();++i) {
691 obj[values.size()+count++] = valuesHigherOrder[i];
695 obj_.setLinearCoefs(x_,obj);
698 size_t constraintCounter = 0;
700 if(problemType_ == MWC) {
702 for(IndexType var=0; var<gm_.numberOfVariables(); ++var) {
703 c_.add(IloRange(env_, numberOfTerminals_-1, numberOfTerminals_-1));
704 for(
LabelType i=0; i<gm_.numberOfLabels(var); ++i) {
705 c_[constraintCounter].setLinearCoef(x_[var*numberOfTerminals_+i],1);
710 for(
size_t i=0; i<(
size_t)(numberOfTerminals_*(numberOfTerminals_-1)/2); ++i) {
711 c_.add(IloRange(env_, 1, 1));
712 c_[constraintCounter].setLinearCoef(x_[numberOfTerminalEdges_+numberOfInternalEdges_+i],1);
720 for(
size_t i=0; i<higherOrderTerms.size(); ++i) {
721 size_t factorID = higherOrderTerms[i].factorID_;
722 size_t numVar = gm_[factorID].numberOfVariables();
725 if(higherOrderTerms[i].potts_) {
726 double b = higherOrderTerms[i].lpIndices_.size();
732 if(parameter_.reductionMode_ % 2 == 1){
733 c_.add(IloRange(env_, -b+1 , 0));
734 for(
size_t i1=0; i1<higherOrderTerms[i].lpIndices_.size();++i1) {
735 const LPIndexType edgeID = higherOrderTerms[i].lpIndices_[i1];
736 c_[constraintCounter].setLinearCoef(x_[edgeID],1);
738 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-b);
739 constraintCounter += 1;
743 if(parameter_.reductionMode_ % 4 >=2){
745 c_.add(IloRange(env_, -2.0*b, 0));
746 for(
size_t i1=0; i1<higherOrderTerms[i].lpIndices_.size();++i1) {
747 const LPIndexType edgeID = higherOrderTerms[i].lpIndices_[i1];
748 c_[constraintCounter].setLinearCoef(x_[edgeID],-1);
750 c_[constraintCounter].setLinearCoef(x_[values.size()+count],1);
751 constraintCounter += 1;
754 for(
size_t i1=0; i1<higherOrderTerms[i].lpIndices_.size();++i1) {
755 const LPIndexType edgeID = higherOrderTerms[i].lpIndices_[i1];
756 c_.add(IloRange(env_, 0 , 1));
757 c_[constraintCounter].setLinearCoef(x_[edgeID],-1);
758 c_[constraintCounter].setLinearCoef(x_[values.size()+count],1);
759 constraintCounter += 1;
765 OPENGM_ASSERT(higherOrderTerms[i].valueIndex_<=valuesHigherOrder.size());
766 LPIndexType edgeIDs[3];
767 edgeIDs[0] = neighbours[gm_[factorID].variableIndex(0)][gm_[factorID].variableIndex(1)];
768 edgeIDs[1] = neighbours[gm_[factorID].variableIndex(0)][gm_[factorID].variableIndex(2)];
769 edgeIDs[2] = neighbours[gm_[factorID].variableIndex(1)][gm_[factorID].variableIndex(2)];
771 const unsigned int P[] = {0,1,2,4,7,8,12,16,18,25,32,33,42,52,63};
774 c_.add(IloRange(env_, 1, 1));
776 for(
size_t p=0; p<5; p++){
777 if(
true || valuesHigherOrder[higherOrderTerms[i].valueIndex_+p]!=0){
778 c_[constraintCounter].setLinearCoef(x_[values.size()+count+lvc],1);
784 for(
size_t p=0; p<5; p++){
785 if(
true || valuesHigherOrder[higherOrderTerms[i].valueIndex_+p]!=0){
788 unsigned int mask = 1;
789 for(
size_t n=0; n<3; n++){
800 c_.add(IloRange(env_, lb, ub));
801 for(
size_t n=0; n<3; n++){
802 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],c[n]);
804 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
807 for(
size_t n=0; n<3; n++){
809 c_.add(IloRange(env_, 0, 1));
810 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],1);
811 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
814 c_.add(IloRange(env_, -1, 0));
815 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],-1);
816 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
825 OPENGM_ASSERT(higherOrderTerms[i].valueIndex_<=valuesHigherOrder.size());
826 LPIndexType edgeIDs[6];
827 edgeIDs[0] = neighbours[gm_[factorID].variableIndex(0)][gm_[factorID].variableIndex(1)];
828 edgeIDs[1] = neighbours[gm_[factorID].variableIndex(0)][gm_[factorID].variableIndex(2)];
829 edgeIDs[2] = neighbours[gm_[factorID].variableIndex(1)][gm_[factorID].variableIndex(2)];
830 edgeIDs[3] = neighbours[gm_[factorID].variableIndex(0)][gm_[factorID].variableIndex(3)];
831 edgeIDs[4] = neighbours[gm_[factorID].variableIndex(1)][gm_[factorID].variableIndex(3)];
832 edgeIDs[5] = neighbours[gm_[factorID].variableIndex(2)][gm_[factorID].variableIndex(3)];
835 const unsigned int P[] = {0,1,2,4,7,8,12,16,18,25,32,33,42,52,63};
838 c_.add(IloRange(env_, 1, 1));
840 for(
size_t p=0; p<15; p++){
841 if(
true ||valuesHigherOrder[higherOrderTerms[i].valueIndex_+p]!=0){
842 c_[constraintCounter].setLinearCoef(x_[values.size()+count+lvc],1);
849 for(
size_t p=0; p<15; p++){
852 unsigned int mask = 1;
853 for(
size_t n=0; n<6; n++){
864 c_.add(IloRange(env_, lb, ub));
865 for(
size_t n=0; n<6; n++){
866 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],c[n]);
868 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
871 for(
size_t n=0; n<6; n++){
873 c_.add(IloRange(env_, 0, 1));
874 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],1);
875 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
878 c_.add(IloRange(env_, -1, 0));
879 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],-1);
880 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
888 std::vector<LPIndexType> edgeIDs(P_.BellNumber(numVar));
891 for(
size_t v1=1; v1<numVar; ++v1){
892 for(
size_t v2=0; v2<v1; ++v2){
893 edgeIDs[cc] = neighbours[gm_[factorID].variableIndex(v2)][gm_[factorID].variableIndex(v1)];
898 c_.add(IloRange(env_, 1, 1));
900 for(
size_t p=0; p<P_.BellNumber(numVar); p++){
901 if(
true || valuesHigherOrder[higherOrderTerms[i].valueIndex_+p]!=0){
902 c_[constraintCounter].setLinearCoef(x_[values.size()+count+lvc],1);
908 std::vector<double> c(numVar*(numVar-1)/2,0);
909 for(
size_t p=0; p<P_.BellNumber(numVar); p++){
910 double ub = numVar*(numVar-1)/2 -1;
912 unsigned int mask = 1;
913 size_t el = P_.getPartition(p);
914 for(
size_t n=0; n<numVar*(numVar-1)/2; n++){
925 c_.add(IloRange(env_, lb, ub));
926 for(
size_t n=0; n<numVar*(numVar-1)/2; n++){
927 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],c[n]);
929 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
932 for(
size_t n=0; n<numVar*(numVar-1)/2; n++){
934 c_.add(IloRange(env_, 0, 1));
935 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],1);
936 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
939 c_.add(IloRange(env_, -1, 0));
940 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],-1);
941 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
953 if(constraintCounter>0) {
957 add3CycleConstraints();
961 cplex_ = IloCplex(model_);
965 template<
class GM,
class ACC>
968 for(
size_t f=0; f<gm_.numberOfFactors();++f) {
969 if(gm_[f].numberOfVariables()==1) {
972 if(gm_[f].numberOfVariables()>1) {
973 for(
size_t i=0; i<gm_[f].numberOfVariables();++i) {
974 if(gm_[f].numberOfLabels(i)<gm_.numberOfVariables()) {
979 if(gm_[f].numberOfVariables()==2 && gm_[f].numberOfLabels(0)==2 && gm_[f].numberOfLabels(1)==2){
984 if(gm_[f](l00)!=gm_[f](l11) || gm_[f](l01)!=gm_[f](l10))
987 else if(gm_[f].numberOfVariables()>1 && !gm_[f].isGeneralizedPotts()) {
988 problemType_ = INVALID;
994 if(problemType_ == MWC) {
995 numberOfTerminals_ = gm_.numberOfLabels(0);
996 numberOfInterTerminalEdges_ = (numberOfTerminals_*(numberOfTerminals_-1))/2;
997 numberOfTerminalEdges_ = 0;
998 for(IndexType i=0; i<gm_.numberOfVariables(); ++i) {
999 for(
LabelType j=0; j<gm_.numberOfLabels(i); ++j) {
1000 ++numberOfTerminalEdges_;
1005 numberOfTerminalEdges_ = 0;
1006 numberOfTerminals_ = 0;
1007 numberOfInterTerminalEdges_ = 0;
1010 return problemType_;
1019 template<
class GM,
class ACC>
1022 std::cout <<
"Not Implemented " <<std::endl ;
1028 template<
class GM,
class ACC>
1031 bool enforceIntegerConstraintsOnTerminalEdges =
true;
1032 bool enforceIntegerConstraintsOnInternalEdges =
false;
1034 if(numberOfTerminalEdges_ == 0 || parameter_.allowCutsWithin_.size() == numberOfTerminals_) {
1035 enforceIntegerConstraintsOnInternalEdges =
true;
1039 if (enforceIntegerConstraintsOnTerminalEdges)
1040 N += numberOfTerminalEdges_;
1041 if (enforceIntegerConstraintsOnInternalEdges)
1042 N += numberOfInternalEdges_;
1044 for(
size_t i=0; i<N; ++i)
1045 model_.add(IloConversion(env_, x_[i], ILOBOOL));
1047 for(
size_t i=0; i<numberOfHigherOrderValues_; ++i)
1048 model_.add(IloConversion(env_, x_[numberOfTerminalEdges_+numberOfInternalEdges_+numberOfInterTerminalEdges_+i], ILOBOOL));
1050 integerMode_ =
true;
1052 return N+numberOfHigherOrderValues_;
1061 template<
class GM,
class ACC>
1065 if(!(problemType_ == MWC))
return 0;
1066 size_t tempConstrainCounter = constraintCounter_;
1069 if(parameter_.allowCutsWithin_.size()!=numberOfTerminals_){
1070 for(
size_t i=0; i<numberOfInternalEdges_;++i) {
1071 u = edgeNodes_[i].first;
1072 v = edgeNodes_[i].second;
1073 for(
size_t l=0; l<numberOfTerminals_;++l) {
1074 if(-sol_[numberOfTerminalEdges_+i]+sol_[u*numberOfTerminals_+l]+sol_[v*numberOfTerminals_+l]<-EPS_) {
1075 constraint.add(IloRange(env_, 0 , 2));
1076 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],-1);
1077 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+l],1);
1078 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+l],1);
1079 ++constraintCounter_;
1081 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+l]+sol_[v*numberOfTerminals_+l]<-EPS_) {
1082 constraint.add(IloRange(env_, 0 , 2));
1083 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1084 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+l],-1);
1085 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+l],1);
1086 ++constraintCounter_;
1088 if(sol_[numberOfTerminalEdges_+i]+sol_[u*numberOfTerminals_+l]-sol_[v*numberOfTerminals_+l]<-EPS_) {
1089 constraint.add(IloRange(env_, 0 , 2));
1090 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1091 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+l],1);
1092 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+l],-1);
1093 ++constraintCounter_;
1096 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1101 for(
size_t i=0; i<numberOfInternalEdges_;++i) {
1102 u = edgeNodes_[i].first;
1103 v = edgeNodes_[i].second;
1104 for(
size_t l=0; l<numberOfTerminals_;++l) {
1105 if(parameter_.allowCutsWithin_[l])
1107 if(-sol_[numberOfTerminalEdges_+i]+sol_[u*numberOfTerminals_+l]+sol_[v*numberOfTerminals_+l]<-EPS_) {
1108 constraint.add(IloRange(env_, 0 , 2));
1109 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],-1);
1110 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+l],1);
1111 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+l],1);
1112 ++constraintCounter_;
1114 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+l]+sol_[v*numberOfTerminals_+l]<-EPS_) {
1115 constraint.add(IloRange(env_, 0 , 2));
1116 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1117 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+l],-1);
1118 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+l],1);
1119 ++constraintCounter_;
1121 if(sol_[numberOfTerminalEdges_+i]+sol_[u*numberOfTerminals_+l]-sol_[v*numberOfTerminals_+l]<-EPS_) {
1122 constraint.add(IloRange(env_, 0 , 2));
1123 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1124 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+l],1);
1125 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+l],-1);
1126 ++constraintCounter_;
1129 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1133 return constraintCounter_-tempConstrainCounter;
1142 template<
class GM,
class ACC>
1146 if(!(problemType_ == MWC))
return 0;
1147 size_t tempConstrainCounter = constraintCounter_;
1148 if(parameter_.allowCutsWithin_.size()==numberOfTerminals_){
1149 for(
size_t i=0; i<parameter_.allowCutsWithin_.size();++i)
1150 if(parameter_.allowCutsWithin_[i])
1155 for(
size_t i=0; i<numberOfInternalEdges_;++i) {
1156 u = edgeNodes_[i].first;
1157 v = edgeNodes_[i].second;
1158 std::vector<size_t> terminals1;
1159 std::vector<size_t> terminals2;
1162 for(
size_t l=0; l<numberOfTerminals_;++l) {
1163 if(sol_[u*numberOfTerminals_+l]-sol_[v*numberOfTerminals_+l] > EPS_) {
1164 terminals1.push_back(l);
1165 sum1 += sol_[u*numberOfTerminals_+l]-sol_[v*numberOfTerminals_+l];
1167 if(sol_[v*numberOfTerminals_+l]-sol_[u*numberOfTerminals_+l] > EPS_) {
1168 terminals2.push_back(l);
1169 sum2 +=sol_[v*numberOfTerminals_+l]-sol_[u*numberOfTerminals_+l];
1172 if(sol_[numberOfTerminalEdges_+i]-sum1<-EPS_) {
1173 constraint.add(IloRange(env_, 0 , 200000));
1174 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1175 for(
size_t k=0; k<terminals1.size(); ++k) {
1176 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+terminals1[k]],-1);
1177 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+terminals1[k]],1);
1179 ++constraintCounter_;
1181 if(sol_[numberOfTerminalEdges_+i]-sum2<-EPS_) {
1182 constraint.add(IloRange(env_, 0 , 200000));
1183 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1184 for(
size_t k=0; k<terminals2.size(); ++k) {
1185 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+terminals2[k]],1);
1186 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+terminals2[k]],-1);
1188 ++constraintCounter_;
1190 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1193 return constraintCounter_-tempConstrainCounter;
1202 template<
class GM,
class ACC>
1207 if(!(problemType_ == MWC))
return 0;
1208 size_t tempConstrainCounter = constraintCounter_;
1211 if(parameter_.allowCutsWithin_.size()!=numberOfTerminals_){
1212 for(
size_t i=0; i<numberOfInternalEdges_;++i) {
1213 u = edgeNodes_[i].first;
1214 v = edgeNodes_[i].second;
1215 if(sol_[numberOfTerminalEdges_+i]<EPS_ && (conf[u]!=conf[v]) ) {
1216 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+conf[u]]+sol_[v*numberOfTerminals_+conf[u]]<=0) {
1217 constraint.add(IloRange(env_, 0 , 10));
1218 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1219 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[u]],-1);
1220 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[u]],1);
1221 ++constraintCounter_;
1223 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+conf[u]]+sol_[v*numberOfTerminals_+conf[u]]<=0) {
1224 constraint.add(IloRange(env_, 0 , 10));
1225 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1226 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[u]],1);
1227 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[u]],-1);
1228 ++constraintCounter_;
1230 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+conf[v]]+sol_[v*numberOfTerminals_+conf[v]]<=0) {
1231 constraint.add(IloRange(env_, 0 , 10));
1232 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1233 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[v]],-1);
1234 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[v]],1);
1235 ++constraintCounter_;
1237 if(sol_[numberOfTerminalEdges_+i]+sol_[u*numberOfTerminals_+conf[v]]-sol_[v*numberOfTerminals_+conf[v]]<=0) {
1238 constraint.add(IloRange(env_, 0 , 10));
1239 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1240 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[v]],1);
1241 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[v]],-1);
1242 ++constraintCounter_;
1245 if(sol_[numberOfTerminalEdges_+i]>1-EPS_ && (conf[u]==conf[v]) ) {
1246 constraint.add(IloRange(env_, 0 , 10));
1247 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],-1);
1248 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[u]],1);
1249 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[v]],1);
1250 ++constraintCounter_;
1252 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1257 for(
size_t i=0; i<numberOfInternalEdges_;++i) {
1258 u = edgeNodes_[i].first;
1259 v = edgeNodes_[i].second;
1260 if(sol_[numberOfTerminalEdges_+i]<EPS_ && (conf[u]!=conf[v]) ) {
1261 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+conf[u]]+sol_[v*numberOfTerminals_+conf[u]]<=0) {
1262 constraint.add(IloRange(env_, 0 , 10));
1263 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1264 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[u]],-1);
1265 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[u]],1);
1266 ++constraintCounter_;
1268 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+conf[u]]+sol_[v*numberOfTerminals_+conf[u]]<=0) {
1269 constraint.add(IloRange(env_, 0 , 10));
1270 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1271 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[u]],1);
1272 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[u]],-1);
1273 ++constraintCounter_;
1275 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+conf[v]]+sol_[v*numberOfTerminals_+conf[v]]<=0) {
1276 constraint.add(IloRange(env_, 0 , 10));
1277 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1278 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[v]],-1);
1279 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[v]],1);
1280 ++constraintCounter_;
1282 if(sol_[numberOfTerminalEdges_+i]+sol_[u*numberOfTerminals_+conf[v]]-sol_[v*numberOfTerminals_+conf[v]]<=0) {
1283 constraint.add(IloRange(env_, 0 , 10));
1284 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1285 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[v]],1);
1286 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[v]],-1);
1287 ++constraintCounter_;
1290 if(sol_[numberOfTerminalEdges_+i]>1-EPS_ && (conf[u]==conf[v]) && !parameter_.allowCutsWithin_[conf[u]] ) {
1291 constraint.add(IloRange(env_, 0 , 10));
1292 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],-1);
1293 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[u]],1);
1294 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[v]],1);
1295 ++constraintCounter_;
1297 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1302 return constraintCounter_-tempConstrainCounter;
1308 template<
class GM,
class ACC>
1312 IloRangeArray constraint = IloRangeArray(env_);
1313 size_t constraintCounter =0;
1314 LPIndexType edge1,edge2,edge3;
1315 typename EdgeMapType::const_iterator it2;
1316 typename EdgeMapType::const_iterator it3;
1317 typename EdgeMapType::const_iterator it4;
1318 for(IndexType node1=0; node1<numberOfNodes_; ++node1){
1319 for(it2=neighbours[node1].begin() ; it2 != neighbours[node1].end(); ++it2) {
1320 const IndexType node2=(*it2).first;
1321 edge1 = (*it2).second;
1322 if(node2<=node1)
continue;
1323 for(it3=neighbours[node1].begin() ; it3 != neighbours[node1].end(); ++it3) {
1324 const IndexType node3=(*it3).first;
1325 edge2 = (*it3).second;
1326 if(node3<=node1)
continue;
1327 if(node3<=node2)
continue;
1328 it4 = neighbours[node2].find(node3);
1329 if(it4 != neighbours[node2].end()) {
1330 edge3 = (*it4).second;
1332 constraint.add(IloRange(env_, 0 , 1000000000));
1333 constraint[constraintCounter].setLinearCoef(x_[edge1],-1);
1334 constraint[constraintCounter].setLinearCoef(x_[edge2],1);
1335 constraint[constraintCounter].setLinearCoef(x_[edge3],1);
1336 ++constraintCounter;
1338 constraint.add(IloRange(env_, 0 , 1000000000));
1339 constraint[constraintCounter].setLinearCoef(x_[edge1],1);
1340 constraint[constraintCounter].setLinearCoef(x_[edge2],-1);
1341 constraint[constraintCounter].setLinearCoef(x_[edge3],1);
1342 ++constraintCounter;
1344 constraint.add(IloRange(env_, 0 , 1000000000));
1345 constraint[constraintCounter].setLinearCoef(x_[edge1],1);
1346 constraint[constraintCounter].setLinearCoef(x_[edge2],1);
1347 constraint[constraintCounter].setLinearCoef(x_[edge3],-1);
1348 ++constraintCounter;
1353 if(constraintCounter>0){
1354 std::cout <<
"Add "<<constraintCounter<<
" constraints for the initial relaxation"<<std::endl;
1355 model_.add(constraint);
1357 return constraintCounter;
1364 template<
class GM,
class ACC>
1366 IloRangeArray& constraint,
1367 bool addOnlyFacetDefiningConstraints,
1371 std::vector<LabelType> partit;
1372 std::vector<std::list<size_t> > neighbours0;
1374 size_t tempConstrainCounter = constraintCounter_;
1377 partition(partit,neighbours0,1-EPS_);
1380 std::map<std::pair<IndexType,IndexType>,
size_t> counter;
1382 if(!parameter_.useOldPriorityQueue_){
1383 std::vector<IndexType> prev(neighbours.size());
1385 std::vector<IndexType> path;
1386 path.reserve(neighbours.size());
1387 for(
size_t i=0; i<numberOfInternalEdges_;++i) {
1389 IndexType u = edgeNodes_[i].first;
1390 IndexType v = edgeNodes_[i].second;
1392 if(usePreBounding && partit[u] != partit[v])
1395 OPENGM_ASSERT(i+numberOfTerminalEdges_ == neighbours[u][v]);
1396 OPENGM_ASSERT(i+numberOfTerminalEdges_ == neighbours[v][u]);
1398 if(sol_[numberOfTerminalEdges_+i]>EPS_){
1401 pathLength = shortestPath2(u,v,neighbours,sol_,path,prev,openNodes,sol_[numberOfTerminalEdges_+i],addOnlyFacetDefiningConstraints && parameter_.useChordalSearch_);
1404 if(sol_[numberOfTerminalEdges_+i]-EPS_>pathLength){
1405 bool postChordlessCheck = addOnlyFacetDefiningConstraints && !parameter_.useChordalSearch_;
1406 bool chordless =
true;
1407 if(postChordlessCheck){
1408 for(
size_t n1=0;n1<path.size();++n1){
1409 for(
size_t n2=n1+2;n2<path.size();++n2){
1410 if(path[n1]==v && path[n2]==u)
continue;
1411 if(neighbours[path[n2]].find(path[n1])!=neighbours[path[n2]].end()) {
1422 constraint.add(IloRange(env_, 0 , 1000000000));
1424 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],-1);
1425 for(
size_t n=0;n<path.size()-1;++n){
1426 constraint[constraintCounter_].setLinearCoef(x_[neighbours[path[n]][path[n+1]]],1);
1428 ++constraintCounter_;
1432 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1437 for(
size_t i=0; i<numberOfInternalEdges_;++i) {
1439 IndexType u = edgeNodes_[i].first;
1440 IndexType v = edgeNodes_[i].second;
1442 if(usePreBounding && partit[u] != partit[v])
1445 OPENGM_ASSERT(i+numberOfTerminalEdges_ == neighbours[u][v]);
1446 OPENGM_ASSERT(i+numberOfTerminalEdges_ == neighbours[v][u]);
1448 if(sol_[numberOfTerminalEdges_+i]>EPS_){
1450 std::vector<IndexType> path;
1452 pathLength = shortestPath(u,v,neighbours,sol_,path,sol_[numberOfTerminalEdges_+i],addOnlyFacetDefiningConstraints);
1453 if(sol_[numberOfTerminalEdges_+i]-EPS_>pathLength){
1455 constraint.add(IloRange(env_, 0 , 1000000000));
1457 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],-1);
1458 for(
size_t n=0;n<path.size()-1;++n){
1459 constraint[constraintCounter_].setLinearCoef(x_[neighbours[path[n]][path[n+1]]],1);
1461 ++constraintCounter_;
1464 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1468 return constraintCounter_-tempConstrainCounter;
1471 template<
class GM,
class ACC>
1473 size_t tempConstrainCounter = constraintCounter_;
1474 std::vector<IndexType> var2node(gm_.numberOfVariables(),std::numeric_limits<IndexType>::max());
1475 for(
size_t center=0; center<gm_.numberOfVariables();++center){
1476 var2node.assign(gm_.numberOfVariables(),std::numeric_limits<IndexType>::max());
1477 size_t N = neighbours[center].size();
1478 std::vector<IndexType> node2var(N);
1479 std::vector<EdgeMapType> E(2*N);
1480 std::vector<double> w;
1481 typename EdgeMapType::const_iterator it;
1483 for(it=neighbours[center].begin() ; it != neighbours[center].end(); ++it) {
1484 IndexType var = (*it).first;
1486 var2node[var] =
id++;
1489 for(it=neighbours[center].begin() ; it != neighbours[center].end(); ++it) {
1490 const IndexType var1 = (*it).first;
1491 const LPIndexType u = var2node[var1];
1492 typename EdgeMapType::const_iterator it2;
1493 for(it2=neighbours[var1].begin() ; it2 != neighbours[var1].end(); ++it2) {
1494 const IndexType var2 = (*it2).first;
1495 const LPIndexType v = var2node[var2];
1496 if( v != std::numeric_limits<IndexType>::max()){
1498 E[2*u][2*v+1]=w.size();
1499 E[2*v+1][2*u]=w.size();
1500 E[2*u+1][2*v]=w.size();
1501 E[2*v][2*u+1]=w.size();
1502 double weight = 0.5-sol_[neighbours[var1][var2]]+0.5*(sol_[neighbours[center][var1]]+sol_[neighbours[center][var2]]);
1504 if(weight<0) weight=0;
1505 w.push_back(weight);
1513 for(
size_t n=0; n<N;++n) {
1514 std::vector<IndexType> path;
1516 if(!parameter_.useOldPriorityQueue_){
1517 std::vector<IndexType> prev(2*N);
1519 pathLength = shortestPath2(2*n,2*n+1,E,w,path,prev,openNodes,1e22,
false);
1521 pathLength = shortestPath(2*n,2*n+1,E,w,path,1e22,
false);
1523 if(pathLength<0.5-EPS_*path.size()){
1527 constraints.add(IloRange(env_, -100000 , (path.size()-2)/2 ));
1528 for(
size_t k=0;k<path.size()-1;++k){
1529 constraints[constraintCounter_].setLinearCoef(x_[neighbours[center][node2var[path[k]/2]]],-1);
1531 for(
size_t k=0;k<path.size()-1;++k){
1532 const IndexType u= node2var[path[k]/2];
1533 const IndexType v= node2var[path[k+1]/2];
1534 constraints[constraintCounter_].setLinearCoef(x_[neighbours[u][v]],1);
1536 ++constraintCounter_;
1538 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1543 for(it=neighbours[center].begin() ; it != neighbours[center].end(); ++it) {
1544 var2node[(*it).first] = std::numeric_limits<IndexType>::max();
1549 return constraintCounter_-tempConstrainCounter;
1557 template<
class GM,
class ACC>
1559 IloRangeArray& constraint,
1560 bool addFacetDefiningConstraintsOnly
1564 std::vector<LabelType> partit(numberOfNodes_,0);
1565 std::vector<std::list<size_t> > neighbours0;
1566 partition(partit,neighbours0);
1567 size_t tempConstrainCounter = constraintCounter_;
1572 std::vector<size_t> path(numberOfNodes_,std::numeric_limits<size_t>::max());
1573 for(
size_t i=0; i<numberOfInternalEdges_;++i) {
1574 u = edgeNodes_[i].first;
1575 v = edgeNodes_[i].second;
1577 if(sol_[numberOfTerminalEdges_+i]>=EPS_ && partit[u] == partit[v]) {
1583 std::fill(path.begin(),path.end(),std::numeric_limits<size_t>::max());
1585 const bool preChordalcheck =addFacetDefiningConstraintsOnly && parameter_.useChordalSearch_;
1587 std::list<size_t>::iterator it;
1588 for(it=neighbours0[n].begin() ; it != neighbours0[n].end(); ++it) {
1589 if(path[*it]==std::numeric_limits<size_t>::max()) {
1591 if(preChordalcheck) {
1592 bool isChordless =
true;
1594 const size_t c = *it;
1597 if(s==u && c==v)
continue;
1598 if(neighbours[c].find(s)!=neighbours[c].end()) {
1599 isChordless =
false;
1615 if(nodeList.
empty())
1617 n = nodeList.
front(); nodeList.
pop();
1619 if(path[v] != std::numeric_limits<size_t>::max()){
1623 w += sol_[neighbours[n][path[n]]];
1626 if(sol_[neighbours[u][v]]-EPS_<w)
1629 const bool postChordlessCheck = addFacetDefiningConstraintsOnly && !parameter_.useChordalSearch_;
1630 bool chordless =
true;
1631 if(postChordlessCheck){
1636 size_t t = path[path[s]];
1638 if(s==v && t==u)
break;
1639 if(neighbours[t].find(s)!=neighbours[t].end()) {
1652 constraint.add(IloRange(env_, 0 , 1000000000));
1653 constraint[constraintCounter_].setLinearCoef(x_[neighbours[u][v]],-1);
1655 constraint[constraintCounter_].setLinearCoef(x_[neighbours[n][path[n]]],1);
1658 ++constraintCounter_;
1661 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1664 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1667 return constraintCounter_-tempConstrainCounter;
1671 template <
class GM,
class ACC>
1675 EmptyVisitorType mcv;
1679 template <
class GM,
class ACC>
1684 cplex_.setParam(IloCplex::Threads, parameter_.numThreads_);
1685 cplex_.setParam(IloCplex::CutUp, parameter_.cutUp_);
1686 cplex_.setParam(IloCplex::MIPDisplay,0);
1687 cplex_.setParam(IloCplex::BarDisplay,0);
1688 cplex_.setParam(IloCplex::NetDisplay,0);
1689 cplex_.setParam(IloCplex::SiftDisplay,0);
1690 cplex_.setParam(IloCplex::SimDisplay,0);
1692 cplex_.setParam(IloCplex::EpOpt,1e-9);
1693 cplex_.setParam(IloCplex::EpRHS,1e-8);
1694 cplex_.setParam(IloCplex::EpInt,0);
1695 cplex_.setParam(IloCplex::EpAGap,0);
1696 cplex_.setParam(IloCplex::EpGap,0);
1698 if(parameter_.verbose_ ==
true && parameter_.verboseCPLEX_) {
1699 cplex_.setParam(IloCplex::MIPDisplay,2);
1700 cplex_.setParam(IloCplex::BarDisplay,1);
1701 cplex_.setParam(IloCplex::NetDisplay,1);
1702 cplex_.setParam(IloCplex::SiftDisplay,1);
1703 cplex_.setParam(IloCplex::SimDisplay,1);
1708 template <
class GM,
class ACC>
1709 template<
class VisitorType>
1713 std::vector<LabelType> conf(gm_.numberOfVariables());
1717 if(problemType_ == INVALID){
1720 else if(!readWorkFlow(parameter_.workFlow_)){
1721 if(parameter_.workFlow_.size()>0){
1722 std::cout <<
"Warning: can not parse workflow : " << parameter_.workFlow_ <<std::endl;
1723 std::cout <<
"Using default workflow ";
1725 if(problemType_ == MWC){
1727 readWorkFlow(
"(TTC)(MTC)(IC)(CC-IFD,TTC-I)");
1729 else if(problemType_ == MC){
1731 readWorkFlow(
"(CC-FDB)(IC)(CC-I)");
1741 size_t workingState = 0;
1742 while(workingState<workFlow_.size()){
1743 protocolateTiming_.push_back(std::vector<double>(20,0));
1744 protocolateConstraints_.push_back(std::vector<size_t>(20,0));
1745 std::vector<double>& T = protocolateTiming_.back();
1746 std::vector<size_t>& C = protocolateConstraints_.back();
1754 for (
size_t it=1; it<10000000000; ++it) {
1755 cplex_.setParam(IloCplex::Threads, parameter_.numThreads_);
1756 cplex_.setParam(IloCplex::TiLim, parameter_.timeOut_-timer.
elapsedTime());
1758 if(!cplex_.solve()) {
1759 if(cplex_.getStatus() != IloAlgorithm::Unbounded){
1760 std::cout <<
"failed to optimize. " <<cplex_.getStatus()<< std::endl;
1769 if(cplex_.getStatus()!= IloAlgorithm::Unbounded){
1771 bound_ = cplex_.getObjValue()+constant_;
1773 bound_ = cplex_.getBestObjValue()+constant_;
1774 if(!cplex_.solveFixed()) {
1775 std::cout <<
"failed to fixed optimize." << std::endl;
1784 try{ cplex_.getValues(sol_, x_);}
1785 catch(IloAlgorithm::NotExtractedException e) {
1789 for(IndexType v=0; v<numberOfTerminalEdges_+numberOfInternalEdges_+numberOfInterTerminalEdges_ + numberOfHigherOrderValues_; ++v){
1791 sol_.add(cplex_.getValue(x_[v]));
1792 }
catch(IloAlgorithm::NotExtractedException e) {
1797 if(parameter_.useBufferedStates_){
1798 std::vector<LabelType> s(gm_.numberOfVariables());
1799 parameter_.useBufferedStates_ =
false;
1801 parameter_.useBufferedStates_ =
true;
1803 if(bufferedValue_ > v){
1805 bufferedStates_.assign(s.begin(), s.end());
1812 workingState = workFlow_.size();
1819 IloRangeArray constraint = IloRangeArray(env_);
1820 constraintCounter_ = 0;
1825 size_t cycleConstraints = std::numeric_limits<size_t>::max();
1826 bool constraintAdded =
false;
1827 for(std::vector<size_t>::iterator it=workFlow_[workingState].begin() ; it != workFlow_[workingState].end(); it++ ){
1829 size_t protocol_ID = Protocol_ID_Unknown;
1831 if(*it == Action_ID_TTC){
1832 if(parameter_.verbose_) std::cout <<
"* Add terminal triangle constraints: " << std::flush;
1833 n = findTerminalTriangleConstraints(constraint);
1834 if(parameter_.verbose_) std::cout << n << std::endl;
1835 protocol_ID = Protocol_ID_TTC;
1837 else if(*it == Action_ID_TTC_I){
1839 throw RuntimeError(
"Error: Calling integer terminal triangle constraint (TTC-I) seperation provedure before switching in integer mode (IC)");
1841 if(parameter_.verbose_) std::cout <<
"* Add integer terminal triangle constraints: " << std::flush;
1843 n = findIntegerTerminalTriangleConstraints(constraint, conf);
1844 if(parameter_.verbose_) std::cout << n << std::endl;
1845 protocol_ID = Protocol_ID_TTC;
1848 else if(*it == Action_ID_MTC){
1849 if(parameter_.verbose_) std::cout <<
"* Add multi terminal constraints: " << std::flush;
1850 n = findMultiTerminalConstraints(constraint);
1851 if(parameter_.verbose_) std::cout << n << std::endl;
1852 protocol_ID = Protocol_ID_MTC;
1855 else if(*it == Action_ID_CC_I){
1857 throw RuntimeError(
"Error: Calling integer cycle constraints (CC-I) seperation provedure before switching in integer mode (IC)");
1859 if(parameter_.verbose_) std::cout <<
"Add integer cycle constraints: " << std::flush;
1860 n = findIntegerCycleConstraints(constraint,
false);
1861 if(parameter_.verbose_) std::cout << n << std::endl;
1862 protocol_ID = Protocol_ID_CC;
1864 else if(*it == Action_ID_CC_IFD){
1866 throw RuntimeError(
"Error: Calling facet defining integer cycle constraints (CC-IFD) seperation provedure before switching in integer mode (IC)");
1868 if(parameter_.verbose_) std::cout <<
"Add facet defining integer cycle constraints: " << std::flush;
1869 n = findIntegerCycleConstraints(constraint,
true);
1870 if(parameter_.verbose_) std::cout << n << std::endl;
1871 protocol_ID = Protocol_ID_CC;
1873 else if(*it == Action_ID_CC){
1874 if(parameter_.verbose_) std::cout <<
"Add cycle constraints: " << std::flush;
1875 n = findCycleConstraints(constraint,
false,
false);
1877 if(parameter_.verbose_) std::cout << n << std::endl;
1878 protocol_ID = Protocol_ID_CC;
1880 else if(*it == Action_ID_CC_FD){
1881 if(parameter_.verbose_) std::cout <<
"Add facet defining cycle constraints: " << std::flush;
1882 n = findCycleConstraints(constraint,
true,
false);
1884 if(parameter_.verbose_) std::cout << n << std::endl;
1885 protocol_ID = Protocol_ID_CC;
1887 else if(*it == Action_ID_CC_FDB){
1888 if(parameter_.verbose_) std::cout <<
"Add facet defining cycle constraints (with bounding): " << std::flush;
1889 n = findCycleConstraints(constraint,
true,
true);
1891 if(parameter_.verbose_) std::cout << n << std::endl;
1892 protocol_ID = Protocol_ID_CC;
1894 else if(*it == Action_ID_CC_B){
1895 if(parameter_.verbose_) std::cout <<
"Add cycle constraints (with bounding): " << std::flush;
1896 n = findCycleConstraints(constraint,
false,
true);
1898 if(parameter_.verbose_) std::cout << n << std::endl;
1899 protocol_ID = Protocol_ID_CC;
1901 else if(*it == Action_ID_RemoveConstraints){
1902 if(parameter_.verbose_) std::cout <<
"Remove unused constraints: " << std::flush;
1903 n = removeUnusedConstraints();
1904 if(parameter_.verbose_) std::cout << n << std::endl;
1905 protocol_ID = Protocol_ID_RemoveConstraints;
1907 else if(*it == Action_ID_IntegerConstraints){
1908 if(integerMode_)
continue;
1909 if(parameter_.verbose_) std::cout <<
"Add integer constraints: " << std::flush;
1910 n = enforceIntegerConstraints();
1911 if(parameter_.verbose_) std::cout << n << std::endl;
1912 protocol_ID = Protocol_ID_IntegerConstraints;
1914 else if(*it == Action_ID_OWC){
1915 if(cycleConstraints== std::numeric_limits<size_t>::max()){
1916 std::cout <<
"WARNING: using Odd Wheel Contraints without Cycle Constrains! -> Use CC,OWC!"<<std::endl;
1919 else if(cycleConstraints==0){
1920 if(parameter_.verbose_) std::cout <<
"Add odd wheel constraints: " << std::flush;
1921 n = findOddWheelConstraints(constraint);
1922 if(parameter_.verbose_) std::cout << n << std::endl;
1927 protocol_ID = Protocol_ID_OWC;
1930 std::cout <<
"Unknown Inference State "<<*it<<std::endl;
1934 C[protocol_ID] += n;
1935 if(n>0) constraintAdded =
true;
1941 if(!constraintAdded){
1944 if(workingState<workFlow_.size())
1945 if(parameter_.verbose_) std::cout <<std::endl<<
"** Switching into next state ( "<< workingState <<
" )**" << std::endl;
1951 model_.add(constraint);
1954 T[Protocol_ID_AddConstraints] += timer2.
elapsedTime();
1967 if(parameter_.verbose_){
1968 std::cout <<
"end normal"<<std::endl;
1969 std::cout <<
"Protokoll:"<<std::endl;
1970 std::cout <<
"=========="<<std::endl;
1971 std::cout <<
" i | SOLVE | ADD | CC | OWC | TTC | MTV | IC " <<std::endl;
1972 std::cout <<
"-----+----------+----------+----------+----------+----------+----------+-----------" <<std::endl;
1974 std::vector<size_t> IDS;
1975 IDS.push_back(Protocol_ID_Solve);
1976 IDS.push_back(Protocol_ID_AddConstraints);
1977 IDS.push_back(Protocol_ID_CC);
1978 IDS.push_back(Protocol_ID_OWC);
1979 IDS.push_back(Protocol_ID_TTC);
1980 IDS.push_back(Protocol_ID_MTC);
1981 IDS.push_back(Protocol_ID_IntegerConstraints);
1983 if(parameter_.verbose_){
1984 for(
size_t i=0; i<protocolateTiming_.size(); ++i){
1985 std::cout << std::setw(5)<< i ;
1986 for(
size_t n=0; n<IDS.size(); ++n){
1987 std::cout <<
"|"<< std::setw(10) << setiosflags(std::ios::fixed)<< std::setprecision(4) << protocolateConstraints_[i][IDS[n]];
1989 std::cout << std::endl;
1991 for(
size_t n=0; n<IDS.size(); ++n){
1992 std::cout <<
"|"<< std::setw(10) << setiosflags(std::ios::fixed)<< std::setprecision(4) << protocolateTiming_[i][IDS[n]];
1994 std::cout << std::endl;
1995 std::cout <<
"-----+----------+----------+----------+----------+----------+----------+-----------" <<std::endl;
1997 std::cout <<
"sum ";
1999 for(
size_t n=0; n<IDS.size(); ++n){
2001 for(
size_t i=0; i<protocolateTiming_.size(); ++i){
2002 t_one += protocolateTiming_[i][IDS[n]];
2004 std::cout <<
"|"<< std::setw(10) << setiosflags(std::ios::fixed)<< std::setprecision(4) << t_one;
2007 std::cout <<
" | " <<t_all <<std::endl;
2008 std::cout <<
"-----+----------+----------+----------+----------+----------+----------+-----------" <<std::endl;
2013 template <
class GM,
class ACC>
2025 if(parameter_.useBufferedStates_){
2026 x.assign(bufferedStates_.begin(),bufferedStates_.end());
2030 if(problemType_ == MWC) {
2031 if(parameter_.MWCRounding_== parameter_.NEAREST){
2032 x.resize(gm_.numberOfVariables());
2033 for(IndexType node = 0; node<gm_.numberOfVariables(); ++node) {
2034 double v = sol_[numberOfTerminals_*node+0];
2036 for(
LabelType i=0; i<gm_.numberOfLabels(node); ++i) {
2037 if(sol_[numberOfTerminals_*node+i]<v) {
2044 else if(parameter_.MWCRounding_==Parameter::DERANDOMIZED){
2045 return derandomizedRounding(x);
2047 else if(parameter_.MWCRounding_==Parameter::PSEUDODERANDOMIZED){
2048 return pseudoDerandomizedRounding(x,1000);
2055 std::vector<std::list<size_t> > neighbours0;
2061 template <
class GM,
class ACC>
2064 std::vector<size_t> seg;
2065 std::vector<std::list<size_t> > neighbours0;
2066 partition(seg, neighbours0, 0.3);
2071 template <
class GM,
class ACC>
2079 std::vector<bool> processedBins(bins+1,
false);
2080 std::vector<LabelType> temp;
2081 double value = 1000000000000.0;
2082 std::vector<LabelType> labelorder1(numberOfTerminals_,numberOfTerminals_-1);
2083 std::vector<LabelType> labelorder2(numberOfTerminals_,numberOfTerminals_-1);
2084 for(
LabelType i=0; i<numberOfTerminals_-1;++i){
2086 labelorder2[i]=numberOfTerminals_-2-i;
2088 for(
size_t i=0; i<numberOfTerminals_*gm_.numberOfVariables();++i){
2095 else if(sol_[i]>=1){
2100 bin = (
size_t)(sol_[i]*bins)%bins;
2103 if(!processedBins[bin]){
2104 processedBins[bin]=
true;
2105 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder1,sol_[i]))){
2109 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder2,sol_[i]))){
2118 template <
class GM,
class ACC>
2125 std::vector<LabelType> temp;
2126 double value = 1000000000000.0;
2127 std::vector<LabelType> labelorder1(numberOfTerminals_,numberOfTerminals_-1);
2128 std::vector<LabelType> labelorder2(numberOfTerminals_,numberOfTerminals_-1);
2129 for(
LabelType i=0; i<numberOfTerminals_-1;++i){
2131 labelorder2[i]=numberOfTerminals_-2-i;
2135 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder1,1e-8))){
2139 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder2,1e-8))){
2143 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder1,1-1e-8))){
2147 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder2,1-1e-8))){
2151 for(
size_t i=0; i<numberOfTerminals_*gm_.numberOfVariables();++i){
2152 if( sol_[i]>1e-8 && sol_[i]<1-1e-8){
2153 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder1,sol_[i]))){
2157 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder2,sol_[i]))){
2166 template <
class GM,
class ACC>
2172 const double threshold
2175 const LabelType lastLabel = labelorder.back();
2176 const IndexType numVar = gm_.numberOfVariables();
2178 x.assign(numVar,lastLabel);
2180 for(
size_t i=0; i<labelorder.size()-1; ++i){
2181 for(IndexType v=0; v<numVar; ++v){
2182 if(x[v]==lastLabel && sol_[numberOfTerminals_*v+i]<=threshold){
2187 return gm_.evaluate(x);
2193 template <
class GM,
class ACC>
2197 std::vector<LabelType>& partit,
2198 std::vector<std::list<size_t> >& neighbours0,
2203 partit.resize(numberOfNodes_,0);
2204 neighbours0.resize(numberOfNodes_, std::list<size_t>());
2207 for(
size_t i=0; i<numberOfInternalEdges_; ++i) {
2208 IndexType u = edgeNodes_[i].first;
2209 IndexType v = edgeNodes_[i].second;
2210 if(sol_[numberOfTerminalEdges_+counter] <= threshold) {
2211 neighbours0[u].push_back(v);
2212 neighbours0[v].push_back(u);
2218 std::vector<bool> assigned(numberOfNodes_,
false);
2219 for(
size_t node=0; node<numberOfNodes_; ++node) {
2223 std::list<size_t> nodeList;
2225 assigned[node] =
true;
2226 nodeList.push_back(node);
2227 while(!nodeList.empty()) {
2228 size_t n=nodeList.front(); nodeList.pop_front();
2229 std::list<size_t>::const_iterator it;
2230 for(it=neighbours0[n].begin() ; it != neighbours0[n].end(); ++it) {
2231 if(!assigned[*it]) {
2233 assigned[*it] =
true;
2234 nodeList.push_back(*it);
2245 template <
class GM,
class ACC>
2249 std::vector<LabelType>& conf
2253 return gm_.evaluate(conf);
2256 template<
class GM,
class ACC>
2263 template<
class GM,
class ACC>
2269 template<
class GM,
class ACC>
2272 std::vector<LabelType> c;
2278 template<
class GM,
class ACC>
2281 if(s[0]!=
'(' || s[s.size()-1] !=
')')
2285 std::string sepString;
2289 if(s[n]==
',' || s[n]==
')'){
2290 if(sepString.compare(
"CC")==0)
2291 workFlow_.back().push_back(Action_ID_CC);
2292 else if(sepString.compare(
"CC-I")==0)
2293 workFlow_.back().push_back(Action_ID_CC_I);
2294 else if(sepString.compare(
"CC-IFD")==0)
2295 workFlow_.back().push_back(Action_ID_CC_IFD);
2296 else if(sepString.compare(
"CC-B")==0)
2297 workFlow_.back().push_back(Action_ID_CC_B);
2298 else if(sepString.compare(
"CC-FDB")==0)
2299 workFlow_.back().push_back(Action_ID_CC_FDB);
2300 else if(sepString.compare(
"CC-FD")==0)
2301 workFlow_.back().push_back(Action_ID_CC_FD);
2302 else if(sepString.compare(
"TTC")==0)
2303 workFlow_.back().push_back(Action_ID_TTC);
2304 else if(sepString.compare(
"TTC-I")==0)
2305 workFlow_.back().push_back(Action_ID_TTC_I);
2306 else if(sepString.compare(
"MTC")==0)
2307 workFlow_.back().push_back(Action_ID_MTC);
2308 else if(sepString.compare(
"OWC")==0)
2309 workFlow_.back().push_back(Action_ID_OWC);
2310 else if(sepString.compare(
"IC")==0)
2311 workFlow_.back().push_back(Action_ID_IntegerConstraints);
2313 std::cout <<
"WARNING: Unknown Seperation Procedure ' "<<sepString<<
"' is skipped!"<<std::endl;
2317 workFlow_.push_back(std::vector<size_t>());
2333 template<
class GM,
class ACC>
2334 template<
class DOUBLEVECTOR>
2336 const IndexType startNode,
2337 const IndexType endNode,
2338 const std::vector<EdgeMapType >& E,
2339 const DOUBLEVECTOR& w,
2340 std::vector<IndexType>& shortestPath,
2341 const double maxLength,
2346 const IndexType numberOfNodes = E.size();
2347 const double inf = std::numeric_limits<double>::infinity();
2348 const IndexType nonePrev = endNode;
2350 std::vector<IndexType> prev(numberOfNodes,nonePrev);
2351 std::vector<double> dist(numberOfNodes,inf);
2354 openNodes.insert(startNode);
2355 dist[startNode]=0.0;
2357 while(!openNodes.empty()){
2361 typename MYSET::iterator it, itMin;
2362 double v = std::numeric_limits<double>::infinity();
2363 for(it = openNodes.begin(); it!= openNodes.end(); ++it){
2370 openNodes.erase(itMin);
2377 typename EdgeMapType::const_iterator it;
2378 for(it=E[node].begin() ; it != E[node].end(); ++it) {
2379 const IndexType node2 = (*it).first;
2380 const LPIndexType weighId = (*it).second;
2381 double cuttedWeight = std::max(0.0,w[weighId]);
2382 const double weight2 = dist[node]+cuttedWeight;
2385 if(dist[node2] > weight2 && weight2 < maxLength){
2387 bool updateNode =
true;
2390 while(s!=startNode){
2392 if(s==startNode && node2==endNode)
continue;
2393 if(neighbours[node2].find(s)!=neighbours[node2].end()) {
2401 dist[node2] = weight2;
2402 openNodes.insert(node2);
2409 if(prev[endNode] != nonePrev){
2410 shortestPath.clear();
2411 shortestPath.push_back(endNode);
2412 IndexType n = endNode;
2415 shortestPath.push_back(n);
2416 }
while(n!=startNode);
2423 return dist[endNode];
2427 template<
class GM,
class ACC>
2428 template<
class DOUBLEVECTOR>
2430 const IndexType startNode,
2431 const IndexType endNode,
2432 const std::vector<EdgeMapType >& E,
2433 const DOUBLEVECTOR& w,
2434 std::vector<IndexType>& shortestPath,
2435 std::vector<IndexType>& prev,
2437 const double maxLength,
2442 const IndexType numberOfNodes = E.size();
2443 const IndexType nonePrev = endNode;
2449 openNodes.
push(startNode,0.0);
2450 prev[endNode] = nonePrev;
2455 while(!openNodes.
empty()){
2457 node = openNodes.
top();
2467 typename EdgeMapType::const_iterator it;
2468 for(it=E[node].begin() ; it != E[node].end(); ++it) {
2469 const IndexType node2 = (*it).first;
2470 const LPIndexType weighId = (*it).second;
2471 double cuttedWeight = std::max(0.0,w[weighId]);
2472 const double weight2 = priority+cuttedWeight;
2476 if(openNodes.
priority(node2) > weight2 && weight2 < maxLength ){
2478 bool updateNode =
true;
2481 while(s!=startNode){
2483 if(s==startNode && node2==endNode)
continue;
2484 if(neighbours[node2].find(s)!=neighbours[node2].end()) {
2491 openNodes.
push(node2,weight2);
2499 if(prev[endNode] != nonePrev){
2500 shortestPath.resize(0);
2501 shortestPath.push_back(endNode);
2502 IndexType n = endNode;
2505 shortestPath.push_back(n);
2506 }
while(n!=startNode);
2512 return openNodes.
priority(endNode);
2516 template<
class GM,
class ACC>
2521 std::vector<double> l(numberOfInternalEdges_,0);
2522 for(
size_t i=0; i<numberOfInternalEdges_; ++i) {
2523 l[i] = sol_[numberOfTerminalEdges_+i];
2532 template<
class GM,
class ACC>
2533 template<
class LPVariableIndexIterator,
class CoefficientIterator>
2536 LPVariableIndexIterator viBegin,
2537 LPVariableIndexIterator viEnd,
2538 CoefficientIterator coefficient,
2542 IloRange constraint(env_, lowerBound, upperBound);
2543 while(viBegin != viEnd) {
2544 constraint.setLinearCoef(x_[*viBegin], *coefficient);
2548 model_.add(constraint);
void reset()
reset heap - priorities are not changed
virtual InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a solution
virtual InferenceTermination infer()
Addition as a binary operation.
void pop()
Remove the current top element.
size_t constraintCounter_
ValueType bound() const
return a bound on the solution
Multicut Algorithm [1] J. Kappes, M. Speth, B. Andres, G. Reinelt and C. Schnoerr, "Globally Optimal Image Partitioning by Multicuts", EMMCVPR 2011 [2] J. Kappes, M. Speth, G. Reinelt and C. Schnoerr, "Higher-order Segmentation via Multicuts", Technical Report (http://ipa.iwr.uni-heidelberg.de/ipabib/Papers/kappes-2013-multicut.pdf) .
virtual std::string name() const
__gnu_cxx::hash_set< IndexType > MYSET
void infer(const typename INF::GraphicalModelType &gm, const typename INF::Parameter ¶m, std::vector< typename INF::LabelType > &conf)
ValueType value() const
return the solution (value)
Heap-based changable priority queue with a maximum number of elemements.
Platform-independent runtime measurements.
#define OPENGM_ASSERT(expression)
ParamHeper::MWCRounding MWCRounding_
std::vector< size_t > getSegmentation() const
detail_types::UInt64Type UInt64Type
uint64
GraphicalModelType::OperatorType OperatorType
bool empty() const
check if the PQ is empty
void push(const value_type i, const priority_type p)
Insert a index with a given priority.
const GraphicalModelType & graphicalModel() const
std::vector< bool > allowCutsWithin_
ValueType evaluate(std::vector< LabelType > &) const
__gnu_cxx::hash_map< IndexType, LPIndexType > EdgeMapType
visitors::TimingVisitor< Multicut< GM, ACC > > TimingVisitorType
GraphicalModelType::ValueType ValueType
Inference algorithm interface.
void addConstraint(LPVariableIndexIterator, LPVariableIndexIterator, CoefficientIterator, const ValueType &, const ValueType &)
size_t maximalNumberOfConstraintsPerRound_
Multicut< _GM, ACC > type
double elapsedTime() const
const_reference top() const
get index with top priority
#define OPENGM_CHECK_OP(A, OP, B, TXT)
void setPriorities(T newPriority)
set all priorities to the given value
Multicut< GM_, ACC_ > type
bool useOldPriorityQueue_
visitors::EmptyVisitor< Multicut< GM, ACC > > EmptyVisitorType
GraphicalModelType::LabelType LabelType
Minimization as a unary accumulation.
priority_type priority(const value_type i) const
returns the value associated with index i
std::vector< double > getEdgeLabeling() const
visitors::VerboseVisitor< Multicut< GM, ACC > > VerboseVisitorType
priority_type topPriority() const
get top priority
Multicut< _GM, _ACC > type
Multicut(const GraphicalModelType &, Parameter para=Parameter())
bool initializeWith3Cycles_
double edgeRoundingValue_