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>
90 typedef boost::unordered_map<IndexType, LPIndexType>
EdgeMapType;
91 typedef boost::unordered_set<IndexType>
MYSET;
93 typedef __gnu_cxx::hash_map<IndexType, LPIndexType>
EdgeMapType;
94 typedef __gnu_cxx::hash_set<IndexType>
MYSET;
98 template<
class GM_,
class ACC_>
136 template<
class OTHER_PARAM>
139 const OTHER_PARAM & p
150 Multicut(
const GraphicalModelType&, Parameter para=Parameter());
151 Multicut(
const size_t,
const std::map<UInt64Type, ValueType> & accWeights,
const Parameter & para=Parameter());
154 virtual std::string
name()
const {
return "Multicut";}
164 template<
class LPVariableIndexIterator,
class CoefficientIterator>
165 void addConstraint(LPVariableIndexIterator, LPVariableIndexIterator,
176 enum ProblemType {INVALID, MC, MWC};
178 const GraphicalModelType& gm_;
179 ProblemType problemType_;
180 Parameter parameter_;
183 double bufferedValue_;
184 std::vector<LabelType> bufferedStates_;
185 const double infinity_;
188 LPIndexType numberOfTerminalEdges_;
189 LPIndexType numberOfInternalEdges_;
190 LPIndexType terminalOffset_;
191 LPIndexType numberOfHigherOrderValues_;
192 LPIndexType numberOfInterTerminalEdges_;
194 std::vector<std::vector<size_t> > workFlow_;
195 std::vector<std::pair<IndexType,IndexType> > edgeNodes_;
199 std::vector<EdgeMapType > neighbours;
215 size_t findCycleConstraints(IloRangeArray&,
bool =
true,
bool =
true);
216 size_t findIntegerCycleConstraints(IloRangeArray&,
bool =
true);
217 size_t findTerminalTriangleConstraints(IloRangeArray&);
218 size_t findIntegerTerminalTriangleConstraints(IloRangeArray&, std::vector<LabelType>& conf);
219 size_t findMultiTerminalConstraints(IloRangeArray&);
220 size_t findOddWheelConstraints(IloRangeArray&);
221 size_t removeUnusedConstraints();
222 size_t enforceIntegerConstraints();
223 size_t add3CycleConstraints();
225 bool readWorkFlow(std::string);
227 InferenceTermination partition(std::vector<LabelType>&, std::vector<std::list<size_t> >&,
double = 0.5)
const;
228 ProblemType setProblemType();
229 LPIndexType getNeighborhood(
const LPIndexType, std::vector<EdgeMapType >&,std::vector<std::pair<IndexType,IndexType> >&, std::vector<HigherOrderTerm>&);
231 template <
class DOUBLEVECTOR>
232 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;
233 template <
class DOUBLEVECTOR>
234 double shortestPath2(
const IndexType,
const IndexType,
const std::vector<EdgeMapType >&,
const DOUBLEVECTOR&, std::vector<IndexType>&,
236 const double = std::numeric_limits<double>::infinity(),
bool =
true)
const;
240 double derandomizedRoundingSubProcedure(std::vector<LabelType>&,
const std::vector<LabelType>&,
const double)
const;
245 Protocol_ID_Solve = 0,
246 Protocol_ID_AddConstraints = 1,
247 Protocol_ID_RemoveConstraints = 2,
248 Protocol_ID_IntegerConstraints = 3,
253 Protocol_ID_Unknown = 8
257 Action_ID_RemoveConstraints = 0,
258 Action_ID_IntegerConstraints = 1,
261 Action_ID_CC_IFD = 12,
262 Action_ID_CC_FD = 13,
264 Action_ID_CC_FDB = 15,
266 Action_ID_TTC_I = 21,
271 std::vector<std::vector<double> > protocolateTiming_;
272 std::vector<std::vector<size_t> > protocolateConstraints_;
278 template<
class GM,
class ACC>
281 const size_t numNodes,
282 const std::map<UInt64Type, ValueType> & accWeights,
284 ) : gm_(GM()), parameter_(para) , bound_(-std::numeric_limits<double>::infinity()), infinity_(1e8), integerMode_(
false),
288 throw RuntimeError(
"This implementation does only supports Min-Plus-Semiring.");
290 if(parameter_.reductionMode_<0 ||parameter_.reductionMode_>3) {
291 throw RuntimeError(
"Reduction Mode has to be 1, 2 or 3!");
296 numberOfTerminalEdges_ = 0;
297 numberOfTerminals_ = 0;
298 numberOfInterTerminalEdges_ = 0;
299 numberOfHigherOrderValues_ = 0;
300 numberOfNodes_ = numNodes;
301 size_t numEdges = accWeights.size();
303 neighbours.resize(numberOfNodes_);
304 numberOfInternalEdges_=0;
305 LPIndexType numberOfAdditionalInternalEdges=0;
308 bufferedValue_ = std::numeric_limits<double>::infinity();
309 bufferedStates_.resize(numNodes,0);
313 typedef std::map<IndexType, ValueType> MapType;
314 typedef typename MapType::const_iterator MapIter;
318 model_ = IloModel(env_);
319 x_ = IloNumVarArray(env_);
320 c_ = IloRangeArray(env_);
321 obj_ = IloMinimize(env_);
322 sol_ = IloNumArray(env_,N);
324 x_.add(IloNumVarArray(env_, N, 0, 1, ILOFLOAT));
326 IloNumArray obj(env_,N);
330 for(MapIter i = accWeights.begin(); i!=accWeights.end(); ++i){
335 if(neighbours[u].find(v)==neighbours[u].end()) {
336 neighbours[u][v] = numberOfInternalEdges_;
337 neighbours[v][u] = numberOfInternalEdges_;
338 edgeNodes_.push_back(std::pair<IndexType,IndexType>(v,u));
339 obj[numberOfInternalEdges_] = weight;
340 ++numberOfInternalEdges_;
348 obj_.setLinearCoefs(x_,obj);
351 add3CycleConstraints();
354 cplex_ = IloCplex(model_);
359 template<
class GM,
class ACC>
362 const LPIndexType numberOfTerminalEdges,
363 std::vector<EdgeMapType >& neighbours,
364 std::vector<std::pair<IndexType,IndexType> >& edgeNodes,
365 std::vector<HigherOrderTerm>& higherOrderTerms
369 neighbours.resize(gm_.numberOfVariables());
370 LPIndexType numberOfInternalEdges=0;
371 LPIndexType numberOfAdditionalInternalEdges=0;
373 for(
size_t f=0; f<gm_.numberOfFactors(); ++f) {
374 if(gm_[f].numberOfVariables()==2) {
375 IndexType u = gm_[f].variableIndex(1);
376 IndexType v = gm_[f].variableIndex(0);
377 if(neighbours[u].find(v)==neighbours[u].end()) {
378 neighbours[u][v] = numberOfTerminalEdges+numberOfInternalEdges;
379 neighbours[v][u] = numberOfTerminalEdges+numberOfInternalEdges;
380 edgeNodes.push_back(std::pair<IndexType,IndexType>(v,u));
381 ++numberOfInternalEdges;
385 for(
size_t f=0; f<gm_.numberOfFactors(); ++f) {
386 if(gm_[f].numberOfVariables()>2 && !gm_[f].isPotts()){
387 higherOrderTerms.push_back(HigherOrderTerm(f,
false, 0));
388 for(
size_t i=0; i<gm_[f].numberOfVariables();++i) {
389 for(
size_t j=0; j<i;++j) {
390 IndexType u = gm_[f].variableIndex(i);
391 IndexType v = gm_[f].variableIndex(j);
392 if(neighbours[u].find(v)==neighbours[u].end()) {
393 neighbours[u][v] = numberOfTerminalEdges+numberOfInternalEdges;
394 neighbours[v][u] = numberOfTerminalEdges+numberOfInternalEdges;
395 edgeNodes.push_back(std::pair<IndexType,IndexType>(v,u));
396 ++numberOfInternalEdges;
397 ++numberOfAdditionalInternalEdges;
404 for(
size_t f=0; f<gm_.numberOfFactors(); ++f) {
405 if(gm_[f].numberOfVariables()>2 && gm_[f].isPotts()) {
406 higherOrderTerms.push_back(HigherOrderTerm(f,
true, 0));
407 std::vector<LPIndexType> lpIndexVector;
409 std::vector<bool> variableInSpanningTree(gm_.numberOfVariables(),
true);
410 for(
size_t i=0; i<gm_[f].numberOfVariables();++i) {
411 variableInSpanningTree[gm_[f].variableIndex(i)]=
false;
413 size_t connection = 2;
418 for(
size_t i=0; i<gm_[f].numberOfVariables();++i) {
419 const IndexType u = gm_[f].variableIndex(i);
420 for(
typename EdgeMapType::const_iterator it=neighbours[u].begin() ; it != neighbours[u].end(); ++it){
421 const IndexType v = (*it).first;
422 if(variableInSpanningTree[v] ==
false && u<v){
423 lpIndexVector.push_back((*it).second);
428 else if(connection==1){
430 for(
size_t i=0; i<gm_[f].numberOfVariables();++i) {
431 const IndexType u = gm_[f].variableIndex(i);
432 for(
typename EdgeMapType::const_iterator it=neighbours[u].begin() ; it != neighbours[u].end(); ++it){
433 const IndexType v = (*it).first;
434 if(variableInSpanningTree[v] ==
false){
435 variableInSpanningTree[v] =
true;
436 lpIndexVector.push_back((*it).second);
444 higherOrderTerms.back().lpIndices_=lpIndexVector;
451 return numberOfInternalEdges;
454 template<
class GM,
class ACC>
459 template<
class GM,
class ACC>
462 const GraphicalModelType& gm,
464 ) : gm_(gm), parameter_(para) , bound_(-std::numeric_limits<double>::infinity()), infinity_(1e8), integerMode_(
false),
468 throw RuntimeError(
"This implementation does only supports Min-Plus-Semiring.");
470 if(parameter_.reductionMode_<0 ||parameter_.reductionMode_>3) {
471 throw RuntimeError(
"Reduction Mode has to be 1, 2 or 3!");
476 if(problemType_ == INVALID)
477 throw RuntimeError(
"Invalid Model for Multicut-Solver! Solver requires a generalized potts model!");
480 std::vector<double> valuesHigherOrder;
481 std::vector<HigherOrderTerm> higherOrderTerms;
482 numberOfInternalEdges_ = getNeighborhood(numberOfTerminalEdges_, neighbours, edgeNodes_ ,higherOrderTerms);
483 numberOfNodes_ = gm_.numberOfVariables();
485 if(parameter_.useBufferedStates_){
486 bufferedValue_ = std::numeric_limits<double>::infinity();
487 bufferedStates_.resize(numberOfNodes_,0);
491 if(parameter_.verbose_ ==
true) {
492 std::cout <<
"** Multicut Info" << std::endl;
494 std::cout <<
" problemType_: Multicut" << std::endl;
495 if(problemType_==MWC)
496 std::cout <<
" problemType_: Multiway Cut" << std::endl;
497 std::cout <<
" numberOfInternalEdges_: " << numberOfInternalEdges_ << std::endl;
498 std::cout <<
" numberOfNodes_: " << numberOfNodes_ << std::endl;
499 std::cout <<
" allowCutsWithin_: ";
500 if(problemType_==MWC && parameter_.allowCutsWithin_.size() == numberOfTerminals_){
501 for(
size_t i=0; i<parameter_.allowCutsWithin_.size(); ++i)
502 if(parameter_.allowCutsWithin_[i]) std::cout<<i<<
" ";
507 std::cout << std::endl;
508 std::cout <<
" higherOrderTerms.size(): " << higherOrderTerms.size() << std::endl;
509 std::cout <<
" numberOfTerminals_: " << numberOfTerminals_ << std::endl;
515 if(numberOfTerminals_==0) valueSize = numberOfInternalEdges_;
516 else valueSize = numberOfTerminalEdges_+numberOfInternalEdges_+numberOfInterTerminalEdges_;
517 std::vector<double> values (valueSize,0);
519 for(
size_t f=0; f<gm_.numberOfFactors(); ++f) {
520 if(gm_[f].numberOfVariables() == 0) {
522 constant_ += gm_[f](&l);
524 else if(gm_[f].numberOfVariables() == 1) {
525 IndexType node = gm_[f].variableIndex(0);
526 for(
LabelType i=0; i<gm_.numberOfLabels(node); ++i) {
527 for(
LabelType j=0; j<gm_.numberOfLabels(node); ++j) {
528 if(i==j) values[node*numberOfTerminals_+i] += (1.0/(numberOfTerminals_-1)-1) * gm_[f](&j);
529 else values[node*numberOfTerminals_+i] += (1.0/(numberOfTerminals_-1)) * gm_[f](&j);
533 else if(gm_[f].numberOfVariables() == 2) {
534 if(gm_[f].numberOfLabels(0)==2 && gm_[f].numberOfLabels(1)==2){
535 IndexType node0 = gm_[f].variableIndex(0);
536 IndexType node1 = gm_[f].variableIndex(1);
538 cc[0]=1;cc[1]=1;
ValueType b = gm_[f](cc);
539 cc[0]=0;cc[1]=1;
ValueType c = gm_[f](cc);
540 cc[0]=1;cc[1]=0;
ValueType d = gm_[f](cc);
542 values[neighbours[gm_[f].variableIndex(0)][gm_[f].variableIndex(1)]] += ((c+d-a-a) - (b-a))/2.0;
543 values[node0*numberOfTerminals_+0] += ((b-a)-(-d+c))/2.0;
544 values[node1*numberOfTerminals_+0] += ((b-a)-( d-c))/2.0;
549 values[neighbours[gm_[f].variableIndex(0)][gm_[f].variableIndex(1)]] += gm_[f](cc1) - gm_[f](cc0);
550 constant_ += gm_[f](cc0);
554 for(
size_t h=0; h<higherOrderTerms.size();++h){
555 if(higherOrderTerms[h].potts_) {
556 const IndexType f = higherOrderTerms[h].factorID_;
557 higherOrderTerms[h].valueIndex_= valuesHigherOrder.size();
559 std::vector<LabelType> cc0(gm_[f].numberOfVariables(),0);
560 std::vector<LabelType> cc1(gm_[f].numberOfVariables(),0);
562 valuesHigherOrder.push_back(gm_[f](cc1.begin()) - gm_[f](cc0.begin()) );
563 constant_ += gm_[f](cc0.begin());
566 const IndexType f = higherOrderTerms[h].factorID_;
567 higherOrderTerms[h].valueIndex_= valuesHigherOrder.size();
568 if(gm_[f].numberOfVariables() == 3) {
569 size_t i[] = {0, 1, 2 };
570 valuesHigherOrder.push_back(gm_[f](i));
571 i[0]=0; i[1]=0; i[2]=1;
572 valuesHigherOrder.push_back(gm_[f](i));
573 i[0]=0; i[1]=1; i[2]=0;
574 valuesHigherOrder.push_back(gm_[f](i));
575 i[0]=1; i[1]=0; i[2]=0;
576 valuesHigherOrder.push_back(gm_[f](i));
577 i[0]=0; i[1]=0; i[2]=0;
578 valuesHigherOrder.push_back(gm_[f](i));
580 else if(gm_[f].numberOfVariables() == 4) {
581 size_t i[] = {0, 1, 2, 3 };
582 if(numberOfTerminals_>=4){
583 valuesHigherOrder.push_back(gm_[f](i));
585 valuesHigherOrder.push_back(0.0);
587 if(numberOfTerminals_>=3){
588 i[0]=0; i[1]=0; i[2]=1; i[3] = 2;
589 valuesHigherOrder.push_back(gm_[f](i));
590 i[0]=0; i[1]=1; i[2]=0; i[3] = 2;
591 valuesHigherOrder.push_back(gm_[f](i));
592 i[0]=0; i[1]=1; i[2]=1; i[3] = 2;
593 valuesHigherOrder.push_back(gm_[f](i));
595 valuesHigherOrder.push_back(0.0);
596 valuesHigherOrder.push_back(0.0);
597 valuesHigherOrder.push_back(0.0);
599 i[0]=0; i[1]=0; i[2]=0; i[3] = 1;
600 valuesHigherOrder.push_back(gm_[f](i));
601 i[0]=0; i[1]=1; i[2]=2; i[3] = 0;
602 valuesHigherOrder.push_back(gm_[f](i));
603 i[0]=0; i[1]=1; i[2]=1; i[3] = 0;
604 valuesHigherOrder.push_back(gm_[f](i));
605 i[0]=1; i[1]=0; i[2]=2; i[3] = 0;
606 valuesHigherOrder.push_back(gm_[f](i));
607 i[0]=1; i[1]=0; i[2]=1; i[3] = 0;
608 valuesHigherOrder.push_back(gm_[f](i));
609 i[0]=0; i[1]=0; i[2]=1; i[3] = 0;
610 valuesHigherOrder.push_back(gm_[f](i));
611 i[0]=1; i[1]=2; i[2]=0; i[3] = 0;
612 valuesHigherOrder.push_back(gm_[f](i));
613 i[0]=1; i[1]=1; i[2]=0; i[3] = 0;
614 valuesHigherOrder.push_back(gm_[f](i));
615 i[0]=0; i[1]=1; i[2]=0; i[3] = 0;
616 valuesHigherOrder.push_back(gm_[f](i));
617 i[0]=1; i[1]=0; i[2]=0; i[3] = 0;
618 valuesHigherOrder.push_back(gm_[f](i));
619 i[0]=0; i[1]=0; i[2]=0; i[3] = 0;
620 valuesHigherOrder.push_back(gm_[f](i));
623 const IndexType f = higherOrderTerms[h].factorID_;
624 higherOrderTerms[h].valueIndex_= valuesHigherOrder.size();
625 P_.
resize(gm_[f].numberOfVariables());
626 std::vector<LabelType> l(gm_[f].numberOfVariables());
627 for(
size_t i=0; i<P_.
BellNumber(gm_[f].numberOfVariables()); ++i){
629 valuesHigherOrder.push_back(gm_[f](l.begin()));
637 numberOfHigherOrderValues_ = valuesHigherOrder.size();
642 OPENGM_ASSERT( numberOfTerminalEdges_ == gm_.numberOfVariables()*numberOfTerminals_ );
645 OPENGM_ASSERT(values.size() == numberOfTerminalEdges_+numberOfInternalEdges_+numberOfInterTerminalEdges_);
646 IloInt N = values.size() + numberOfHigherOrderValues_;
647 model_ = IloModel(env_);
648 x_ = IloNumVarArray(env_);
649 c_ = IloRangeArray(env_);
650 obj_ = IloMinimize(env_);
651 sol_ = IloNumArray(env_,N);
654 x_.add(IloNumVarArray(env_, N, 0, 1, ILOFLOAT));
656 IloNumArray obj(env_,N);
657 for (
size_t i=0; i< values.size();++i) {
665 for (
size_t i=0; i<valuesHigherOrder.size();++i) {
666 obj[values.size()+count++] = valuesHigherOrder[i];
670 obj_.setLinearCoefs(x_,obj);
673 size_t constraintCounter = 0;
675 if(problemType_ == MWC) {
677 for(IndexType var=0; var<gm_.numberOfVariables(); ++var) {
678 c_.add(IloRange(env_, numberOfTerminals_-1, numberOfTerminals_-1));
679 for(
LabelType i=0; i<gm_.numberOfLabels(var); ++i) {
680 c_[constraintCounter].setLinearCoef(x_[var*numberOfTerminals_+i],1);
685 for(
size_t i=0; i<(
size_t)(numberOfTerminals_*(numberOfTerminals_-1)/2); ++i) {
686 c_.add(IloRange(env_, 1, 1));
687 c_[constraintCounter].setLinearCoef(x_[numberOfTerminalEdges_+numberOfInternalEdges_+i],1);
695 for(
size_t i=0; i<higherOrderTerms.size(); ++i) {
696 size_t factorID = higherOrderTerms[i].factorID_;
697 size_t numVar = gm_[factorID].numberOfVariables();
700 if(higherOrderTerms[i].potts_) {
701 double b = higherOrderTerms[i].lpIndices_.size();
707 if(parameter_.reductionMode_ % 2 == 1){
708 c_.add(IloRange(env_, -b+1 , 0));
709 for(
size_t i1=0; i1<higherOrderTerms[i].lpIndices_.size();++i1) {
710 const LPIndexType edgeID = higherOrderTerms[i].lpIndices_[i1];
711 c_[constraintCounter].setLinearCoef(x_[edgeID],1);
713 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-b);
714 constraintCounter += 1;
718 if(parameter_.reductionMode_ % 4 >=2){
720 c_.add(IloRange(env_, -2.0*b, 0));
721 for(
size_t i1=0; i1<higherOrderTerms[i].lpIndices_.size();++i1) {
722 const LPIndexType edgeID = higherOrderTerms[i].lpIndices_[i1];
723 c_[constraintCounter].setLinearCoef(x_[edgeID],-1);
725 c_[constraintCounter].setLinearCoef(x_[values.size()+count],1);
726 constraintCounter += 1;
729 for(
size_t i1=0; i1<higherOrderTerms[i].lpIndices_.size();++i1) {
730 const LPIndexType edgeID = higherOrderTerms[i].lpIndices_[i1];
731 c_.add(IloRange(env_, 0 , 1));
732 c_[constraintCounter].setLinearCoef(x_[edgeID],-1);
733 c_[constraintCounter].setLinearCoef(x_[values.size()+count],1);
734 constraintCounter += 1;
740 OPENGM_ASSERT(higherOrderTerms[i].valueIndex_<=valuesHigherOrder.size());
741 LPIndexType edgeIDs[3];
742 edgeIDs[0] = neighbours[gm_[factorID].variableIndex(0)][gm_[factorID].variableIndex(1)];
743 edgeIDs[1] = neighbours[gm_[factorID].variableIndex(0)][gm_[factorID].variableIndex(2)];
744 edgeIDs[2] = neighbours[gm_[factorID].variableIndex(1)][gm_[factorID].variableIndex(2)];
746 const unsigned int P[] = {0,1,2,4,7,8,12,16,18,25,32,33,42,52,63};
749 c_.add(IloRange(env_, 1, 1));
751 for(
size_t p=0; p<5; p++){
752 if(
true || valuesHigherOrder[higherOrderTerms[i].valueIndex_+p]!=0){
753 c_[constraintCounter].setLinearCoef(x_[values.size()+count+lvc],1);
759 for(
size_t p=0; p<5; p++){
760 if(
true || valuesHigherOrder[higherOrderTerms[i].valueIndex_+p]!=0){
763 unsigned int mask = 1;
764 for(
size_t n=0; n<3; n++){
775 c_.add(IloRange(env_, lb, ub));
776 for(
size_t n=0; n<3; n++){
777 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],c[n]);
779 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
782 for(
size_t n=0; n<3; n++){
784 c_.add(IloRange(env_, 0, 1));
785 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],1);
786 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
789 c_.add(IloRange(env_, -1, 0));
790 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],-1);
791 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
800 OPENGM_ASSERT(higherOrderTerms[i].valueIndex_<=valuesHigherOrder.size());
801 LPIndexType edgeIDs[6];
802 edgeIDs[0] = neighbours[gm_[factorID].variableIndex(0)][gm_[factorID].variableIndex(1)];
803 edgeIDs[1] = neighbours[gm_[factorID].variableIndex(0)][gm_[factorID].variableIndex(2)];
804 edgeIDs[2] = neighbours[gm_[factorID].variableIndex(1)][gm_[factorID].variableIndex(2)];
805 edgeIDs[3] = neighbours[gm_[factorID].variableIndex(0)][gm_[factorID].variableIndex(3)];
806 edgeIDs[4] = neighbours[gm_[factorID].variableIndex(1)][gm_[factorID].variableIndex(3)];
807 edgeIDs[5] = neighbours[gm_[factorID].variableIndex(2)][gm_[factorID].variableIndex(3)];
810 const unsigned int P[] = {0,1,2,4,7,8,12,16,18,25,32,33,42,52,63};
813 c_.add(IloRange(env_, 1, 1));
815 for(
size_t p=0; p<15; p++){
816 if(
true ||valuesHigherOrder[higherOrderTerms[i].valueIndex_+p]!=0){
817 c_[constraintCounter].setLinearCoef(x_[values.size()+count+lvc],1);
824 for(
size_t p=0; p<15; p++){
827 unsigned int mask = 1;
828 for(
size_t n=0; n<6; n++){
839 c_.add(IloRange(env_, lb, ub));
840 for(
size_t n=0; n<6; n++){
841 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],c[n]);
843 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
846 for(
size_t n=0; n<6; n++){
848 c_.add(IloRange(env_, 0, 1));
849 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],1);
850 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
853 c_.add(IloRange(env_, -1, 0));
854 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],-1);
855 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
863 std::vector<LPIndexType> edgeIDs(P_.
BellNumber(numVar));
866 for(
size_t v1=1; v1<numVar; ++v1){
867 for(
size_t v2=0; v2<v1; ++v2){
868 edgeIDs[cc] = neighbours[gm_[factorID].variableIndex(v2)][gm_[factorID].variableIndex(v1)];
873 c_.add(IloRange(env_, 1, 1));
875 for(
size_t p=0; p<P_.
BellNumber(numVar); p++){
876 if(
true || valuesHigherOrder[higherOrderTerms[i].valueIndex_+p]!=0){
877 c_[constraintCounter].setLinearCoef(x_[values.size()+count+lvc],1);
883 std::vector<double> c(numVar*(numVar-1)/2,0);
884 for(
size_t p=0; p<P_.
BellNumber(numVar); p++){
885 double ub = numVar*(numVar-1)/2 -1;
887 unsigned int mask = 1;
889 for(
size_t n=0; n<numVar*(numVar-1)/2; n++){
900 c_.add(IloRange(env_, lb, ub));
901 for(
size_t n=0; n<numVar*(numVar-1)/2; n++){
902 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],c[n]);
904 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
907 for(
size_t n=0; n<numVar*(numVar-1)/2; n++){
909 c_.add(IloRange(env_, 0, 1));
910 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],1);
911 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
914 c_.add(IloRange(env_, -1, 0));
915 c_[constraintCounter].setLinearCoef(x_[edgeIDs[n]],-1);
916 c_[constraintCounter].setLinearCoef(x_[values.size()+count],-1);
928 if(constraintCounter>0) {
932 add3CycleConstraints();
936 cplex_ = IloCplex(model_);
940 template<
class GM,
class ACC>
943 for(
size_t f=0; f<gm_.numberOfFactors();++f) {
944 if(gm_[f].numberOfVariables()==1) {
947 if(gm_[f].numberOfVariables()>1) {
948 for(
size_t i=0; i<gm_[f].numberOfVariables();++i) {
949 if(gm_[f].numberOfLabels(i)<gm_.numberOfVariables()) {
954 if(gm_[f].numberOfVariables()==2 && gm_[f].numberOfLabels(0)==2 && gm_[f].numberOfLabels(1)==2){
959 if(gm_[f](l00)!=gm_[f](l11) || gm_[f](l01)!=gm_[f](l10))
962 else if(gm_[f].numberOfVariables()>1 && !gm_[f].isGeneralizedPotts()) {
963 problemType_ = INVALID;
969 if(problemType_ == MWC) {
970 numberOfTerminals_ = gm_.numberOfLabels(0);
971 numberOfInterTerminalEdges_ = (numberOfTerminals_*(numberOfTerminals_-1))/2;
972 numberOfTerminalEdges_ = 0;
973 for(IndexType i=0; i<gm_.numberOfVariables(); ++i) {
974 for(
LabelType j=0; j<gm_.numberOfLabels(i); ++j) {
975 ++numberOfTerminalEdges_;
980 numberOfTerminalEdges_ = 0;
981 numberOfTerminals_ = 0;
982 numberOfInterTerminalEdges_ = 0;
994 template<
class GM,
class ACC>
995 size_t Multicut<GM, ACC>::removeUnusedConstraints()
997 std::cout <<
"Not Implemented " <<std::endl ;
1003 template<
class GM,
class ACC>
1004 size_t Multicut<GM, ACC>::enforceIntegerConstraints()
1006 bool enforceIntegerConstraintsOnTerminalEdges =
true;
1007 bool enforceIntegerConstraintsOnInternalEdges =
false;
1009 if(numberOfTerminalEdges_ == 0 || parameter_.allowCutsWithin_.size() == numberOfTerminals_) {
1010 enforceIntegerConstraintsOnInternalEdges =
true;
1014 if (enforceIntegerConstraintsOnTerminalEdges)
1015 N += numberOfTerminalEdges_;
1016 if (enforceIntegerConstraintsOnInternalEdges)
1017 N += numberOfInternalEdges_;
1019 for(
size_t i=0; i<N; ++i)
1020 model_.add(IloConversion(env_, x_[i], ILOBOOL));
1022 for(
size_t i=0; i<numberOfHigherOrderValues_; ++i)
1023 model_.add(IloConversion(env_, x_[numberOfTerminalEdges_+numberOfInternalEdges_+numberOfInterTerminalEdges_+i], ILOBOOL));
1025 integerMode_ =
true;
1027 return N+numberOfHigherOrderValues_;
1036 template<
class GM,
class ACC>
1037 size_t Multicut<GM, ACC>::findTerminalTriangleConstraints(IloRangeArray& constraint)
1040 if(!(problemType_ == MWC))
return 0;
1041 size_t tempConstrainCounter = constraintCounter_;
1044 if(parameter_.allowCutsWithin_.size()!=numberOfTerminals_){
1045 for(
size_t i=0; i<numberOfInternalEdges_;++i) {
1046 u = edgeNodes_[i].first;
1047 v = edgeNodes_[i].second;
1048 for(
size_t l=0; l<numberOfTerminals_;++l) {
1049 if(-sol_[numberOfTerminalEdges_+i]+sol_[u*numberOfTerminals_+l]+sol_[v*numberOfTerminals_+l]<-EPS_) {
1050 constraint.add(IloRange(env_, 0 , 2));
1051 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],-1);
1052 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+l],1);
1053 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+l],1);
1054 ++constraintCounter_;
1056 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+l]+sol_[v*numberOfTerminals_+l]<-EPS_) {
1057 constraint.add(IloRange(env_, 0 , 2));
1058 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1059 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+l],-1);
1060 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+l],1);
1061 ++constraintCounter_;
1063 if(sol_[numberOfTerminalEdges_+i]+sol_[u*numberOfTerminals_+l]-sol_[v*numberOfTerminals_+l]<-EPS_) {
1064 constraint.add(IloRange(env_, 0 , 2));
1065 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1066 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+l],1);
1067 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+l],-1);
1068 ++constraintCounter_;
1071 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1076 for(
size_t i=0; i<numberOfInternalEdges_;++i) {
1077 u = edgeNodes_[i].first;
1078 v = edgeNodes_[i].second;
1079 for(
size_t l=0; l<numberOfTerminals_;++l) {
1080 if(parameter_.allowCutsWithin_[l])
1082 if(-sol_[numberOfTerminalEdges_+i]+sol_[u*numberOfTerminals_+l]+sol_[v*numberOfTerminals_+l]<-EPS_) {
1083 constraint.add(IloRange(env_, 0 , 2));
1084 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],-1);
1085 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+l],1);
1086 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+l],1);
1087 ++constraintCounter_;
1089 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+l]+sol_[v*numberOfTerminals_+l]<-EPS_) {
1090 constraint.add(IloRange(env_, 0 , 2));
1091 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1092 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+l],-1);
1093 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+l],1);
1094 ++constraintCounter_;
1096 if(sol_[numberOfTerminalEdges_+i]+sol_[u*numberOfTerminals_+l]-sol_[v*numberOfTerminals_+l]<-EPS_) {
1097 constraint.add(IloRange(env_, 0 , 2));
1098 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1099 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+l],1);
1100 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+l],-1);
1101 ++constraintCounter_;
1104 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1108 return constraintCounter_-tempConstrainCounter;
1117 template<
class GM,
class ACC>
1118 size_t Multicut<GM, ACC>::findMultiTerminalConstraints(IloRangeArray& constraint)
1121 if(!(problemType_ == MWC))
return 0;
1122 size_t tempConstrainCounter = constraintCounter_;
1123 if(parameter_.allowCutsWithin_.size()==numberOfTerminals_){
1124 for(
size_t i=0; i<parameter_.allowCutsWithin_.size();++i)
1125 if(parameter_.allowCutsWithin_[i])
1130 for(
size_t i=0; i<numberOfInternalEdges_;++i) {
1131 u = edgeNodes_[i].first;
1132 v = edgeNodes_[i].second;
1133 std::vector<size_t> terminals1;
1134 std::vector<size_t> terminals2;
1137 for(
size_t l=0; l<numberOfTerminals_;++l) {
1138 if(sol_[u*numberOfTerminals_+l]-sol_[v*numberOfTerminals_+l] > EPS_) {
1139 terminals1.push_back(l);
1140 sum1 += sol_[u*numberOfTerminals_+l]-sol_[v*numberOfTerminals_+l];
1142 if(sol_[v*numberOfTerminals_+l]-sol_[u*numberOfTerminals_+l] > EPS_) {
1143 terminals2.push_back(l);
1144 sum2 +=sol_[v*numberOfTerminals_+l]-sol_[u*numberOfTerminals_+l];
1147 if(sol_[numberOfTerminalEdges_+i]-sum1<-EPS_) {
1148 constraint.add(IloRange(env_, 0 , 200000));
1149 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1150 for(
size_t k=0; k<terminals1.size(); ++k) {
1151 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+terminals1[k]],-1);
1152 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+terminals1[k]],1);
1154 ++constraintCounter_;
1156 if(sol_[numberOfTerminalEdges_+i]-sum2<-EPS_) {
1157 constraint.add(IloRange(env_, 0 , 200000));
1158 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1159 for(
size_t k=0; k<terminals2.size(); ++k) {
1160 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+terminals2[k]],1);
1161 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+terminals2[k]],-1);
1163 ++constraintCounter_;
1165 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1168 return constraintCounter_-tempConstrainCounter;
1177 template<
class GM,
class ACC>
1178 size_t Multicut<GM, ACC>::findIntegerTerminalTriangleConstraints(IloRangeArray& constraint, std::vector<LabelType>& conf)
1182 if(!(problemType_ == MWC))
return 0;
1183 size_t tempConstrainCounter = constraintCounter_;
1186 if(parameter_.allowCutsWithin_.size()!=numberOfTerminals_){
1187 for(
size_t i=0; i<numberOfInternalEdges_;++i) {
1188 u = edgeNodes_[i].first;
1189 v = edgeNodes_[i].second;
1190 if(sol_[numberOfTerminalEdges_+i]<EPS_ && (conf[u]!=conf[v]) ) {
1191 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+conf[u]]+sol_[v*numberOfTerminals_+conf[u]]<=0) {
1192 constraint.add(IloRange(env_, 0 , 10));
1193 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1194 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[u]],-1);
1195 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[u]],1);
1196 ++constraintCounter_;
1198 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+conf[u]]+sol_[v*numberOfTerminals_+conf[u]]<=0) {
1199 constraint.add(IloRange(env_, 0 , 10));
1200 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1201 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[u]],1);
1202 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[u]],-1);
1203 ++constraintCounter_;
1205 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+conf[v]]+sol_[v*numberOfTerminals_+conf[v]]<=0) {
1206 constraint.add(IloRange(env_, 0 , 10));
1207 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1208 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[v]],-1);
1209 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[v]],1);
1210 ++constraintCounter_;
1212 if(sol_[numberOfTerminalEdges_+i]+sol_[u*numberOfTerminals_+conf[v]]-sol_[v*numberOfTerminals_+conf[v]]<=0) {
1213 constraint.add(IloRange(env_, 0 , 10));
1214 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1215 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[v]],1);
1216 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[v]],-1);
1217 ++constraintCounter_;
1220 if(sol_[numberOfTerminalEdges_+i]>1-EPS_ && (conf[u]==conf[v]) ) {
1221 constraint.add(IloRange(env_, 0 , 10));
1222 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],-1);
1223 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[u]],1);
1224 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[v]],1);
1225 ++constraintCounter_;
1227 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1232 for(
size_t i=0; i<numberOfInternalEdges_;++i) {
1233 u = edgeNodes_[i].first;
1234 v = edgeNodes_[i].second;
1235 if(sol_[numberOfTerminalEdges_+i]<EPS_ && (conf[u]!=conf[v]) ) {
1236 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+conf[u]]+sol_[v*numberOfTerminals_+conf[u]]<=0) {
1237 constraint.add(IloRange(env_, 0 , 10));
1238 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1239 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[u]],-1);
1240 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[u]],1);
1241 ++constraintCounter_;
1243 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+conf[u]]+sol_[v*numberOfTerminals_+conf[u]]<=0) {
1244 constraint.add(IloRange(env_, 0 , 10));
1245 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1246 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[u]],1);
1247 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[u]],-1);
1248 ++constraintCounter_;
1250 if(sol_[numberOfTerminalEdges_+i]-sol_[u*numberOfTerminals_+conf[v]]+sol_[v*numberOfTerminals_+conf[v]]<=0) {
1251 constraint.add(IloRange(env_, 0 , 10));
1252 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1253 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[v]],-1);
1254 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[v]],1);
1255 ++constraintCounter_;
1257 if(sol_[numberOfTerminalEdges_+i]+sol_[u*numberOfTerminals_+conf[v]]-sol_[v*numberOfTerminals_+conf[v]]<=0) {
1258 constraint.add(IloRange(env_, 0 , 10));
1259 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],1);
1260 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[v]],1);
1261 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[v]],-1);
1262 ++constraintCounter_;
1265 if(sol_[numberOfTerminalEdges_+i]>1-EPS_ && (conf[u]==conf[v]) && !parameter_.allowCutsWithin_[conf[u]] ) {
1266 constraint.add(IloRange(env_, 0 , 10));
1267 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],-1);
1268 constraint[constraintCounter_].setLinearCoef(x_[u*numberOfTerminals_+conf[u]],1);
1269 constraint[constraintCounter_].setLinearCoef(x_[v*numberOfTerminals_+conf[v]],1);
1270 ++constraintCounter_;
1272 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1277 return constraintCounter_-tempConstrainCounter;
1283 template<
class GM,
class ACC>
1284 size_t Multicut<GM, ACC>::add3CycleConstraints()
1287 IloRangeArray constraint = IloRangeArray(env_);
1288 size_t constraintCounter =0;
1289 LPIndexType edge1,edge2,edge3;
1290 typename EdgeMapType::const_iterator it2;
1291 typename EdgeMapType::const_iterator it3;
1292 typename EdgeMapType::const_iterator it4;
1293 for(IndexType node1=0; node1<numberOfNodes_; ++node1){
1294 for(it2=neighbours[node1].begin() ; it2 != neighbours[node1].end(); ++it2) {
1295 const IndexType node2=(*it2).first;
1296 edge1 = (*it2).second;
1297 if(node2<=node1)
continue;
1298 for(it3=neighbours[node1].begin() ; it3 != neighbours[node1].end(); ++it3) {
1299 const IndexType node3=(*it3).first;
1300 edge2 = (*it3).second;
1301 if(node3<=node1)
continue;
1302 if(node3<=node2)
continue;
1303 it4 = neighbours[node2].find(node3);
1304 if(it4 != neighbours[node2].end()) {
1305 edge3 = (*it4).second;
1307 constraint.add(IloRange(env_, 0 , 1000000000));
1308 constraint[constraintCounter].setLinearCoef(x_[edge1],-1);
1309 constraint[constraintCounter].setLinearCoef(x_[edge2],1);
1310 constraint[constraintCounter].setLinearCoef(x_[edge3],1);
1311 ++constraintCounter;
1313 constraint.add(IloRange(env_, 0 , 1000000000));
1314 constraint[constraintCounter].setLinearCoef(x_[edge1],1);
1315 constraint[constraintCounter].setLinearCoef(x_[edge2],-1);
1316 constraint[constraintCounter].setLinearCoef(x_[edge3],1);
1317 ++constraintCounter;
1319 constraint.add(IloRange(env_, 0 , 1000000000));
1320 constraint[constraintCounter].setLinearCoef(x_[edge1],1);
1321 constraint[constraintCounter].setLinearCoef(x_[edge2],1);
1322 constraint[constraintCounter].setLinearCoef(x_[edge3],-1);
1323 ++constraintCounter;
1328 if(constraintCounter>0){
1329 std::cout <<
"Add "<<constraintCounter<<
" constraints for the initial relaxation"<<std::endl;
1330 model_.add(constraint);
1332 return constraintCounter;
1339 template<
class GM,
class ACC>
1340 size_t Multicut<GM, ACC>::findCycleConstraints(
1341 IloRangeArray& constraint,
1342 bool addOnlyFacetDefiningConstraints,
1346 std::vector<LabelType> partit;
1347 std::vector<std::list<size_t> > neighbours0;
1349 size_t tempConstrainCounter = constraintCounter_;
1352 partition(partit,neighbours0,1-EPS_);
1355 std::map<std::pair<IndexType,IndexType>,
size_t> counter;
1357 if(!parameter_.useOldPriorityQueue_){
1358 std::vector<IndexType> prev(neighbours.size());
1360 std::vector<IndexType> path;
1361 path.reserve(neighbours.size());
1362 for(
size_t i=0; i<numberOfInternalEdges_;++i) {
1364 IndexType u = edgeNodes_[i].first;
1365 IndexType v = edgeNodes_[i].second;
1367 if(usePreBounding && partit[u] != partit[v])
1370 OPENGM_ASSERT(i+numberOfTerminalEdges_ == neighbours[u][v]);
1371 OPENGM_ASSERT(i+numberOfTerminalEdges_ == neighbours[v][u]);
1373 if(sol_[numberOfTerminalEdges_+i]>EPS_){
1376 pathLength = shortestPath2(u,v,neighbours,sol_,path,prev,openNodes,sol_[numberOfTerminalEdges_+i],addOnlyFacetDefiningConstraints && parameter_.useChordalSearch_);
1379 if(sol_[numberOfTerminalEdges_+i]-EPS_>pathLength){
1380 bool postChordlessCheck = addOnlyFacetDefiningConstraints && !parameter_.useChordalSearch_;
1381 bool chordless =
true;
1382 if(postChordlessCheck){
1383 for(
size_t n1=0;n1<path.size();++n1){
1384 for(
size_t n2=n1+2;n2<path.size();++n2){
1385 if(path[n1]==v && path[n2]==u)
continue;
1386 if(neighbours[path[n2]].find(path[n1])!=neighbours[path[n2]].end()) {
1397 constraint.add(IloRange(env_, 0 , 1000000000));
1399 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],-1);
1400 for(
size_t n=0;n<path.size()-1;++n){
1401 constraint[constraintCounter_].setLinearCoef(x_[neighbours[path[n]][path[n+1]]],1);
1403 ++constraintCounter_;
1407 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1412 for(
size_t i=0; i<numberOfInternalEdges_;++i) {
1414 IndexType u = edgeNodes_[i].first;
1415 IndexType v = edgeNodes_[i].second;
1417 if(usePreBounding && partit[u] != partit[v])
1420 OPENGM_ASSERT(i+numberOfTerminalEdges_ == neighbours[u][v]);
1421 OPENGM_ASSERT(i+numberOfTerminalEdges_ == neighbours[v][u]);
1423 if(sol_[numberOfTerminalEdges_+i]>EPS_){
1425 std::vector<IndexType> path;
1427 pathLength = shortestPath(u,v,neighbours,sol_,path,sol_[numberOfTerminalEdges_+i],addOnlyFacetDefiningConstraints);
1428 if(sol_[numberOfTerminalEdges_+i]-EPS_>pathLength){
1430 constraint.add(IloRange(env_, 0 , 1000000000));
1432 constraint[constraintCounter_].setLinearCoef(x_[numberOfTerminalEdges_+i],-1);
1433 for(
size_t n=0;n<path.size()-1;++n){
1434 constraint[constraintCounter_].setLinearCoef(x_[neighbours[path[n]][path[n+1]]],1);
1436 ++constraintCounter_;
1439 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1443 return constraintCounter_-tempConstrainCounter;
1446 template<
class GM,
class ACC>
1447 size_t Multicut<GM, ACC>::findOddWheelConstraints(IloRangeArray& constraints){
1448 size_t tempConstrainCounter = constraintCounter_;
1449 std::vector<IndexType> var2node(gm_.numberOfVariables(),std::numeric_limits<IndexType>::max());
1450 for(
size_t center=0; center<gm_.numberOfVariables();++center){
1451 var2node.assign(gm_.numberOfVariables(),std::numeric_limits<IndexType>::max());
1452 size_t N = neighbours[center].size();
1453 std::vector<IndexType> node2var(N);
1454 std::vector<EdgeMapType> E(2*N);
1455 std::vector<double> w;
1456 typename EdgeMapType::const_iterator it;
1458 for(it=neighbours[center].begin() ; it != neighbours[center].end(); ++it) {
1459 IndexType var = (*it).first;
1461 var2node[var] =
id++;
1464 for(it=neighbours[center].begin() ; it != neighbours[center].end(); ++it) {
1465 const IndexType var1 = (*it).first;
1466 const LPIndexType u = var2node[var1];
1467 typename EdgeMapType::const_iterator it2;
1468 for(it2=neighbours[var1].begin() ; it2 != neighbours[var1].end(); ++it2) {
1469 const IndexType var2 = (*it2).first;
1470 const LPIndexType v = var2node[var2];
1471 if( v != std::numeric_limits<IndexType>::max()){
1473 E[2*u][2*v+1]=w.size();
1474 E[2*v+1][2*u]=w.size();
1475 E[2*u+1][2*v]=w.size();
1476 E[2*v][2*u+1]=w.size();
1477 double weight = 0.5-sol_[neighbours[var1][var2]]+0.5*(sol_[neighbours[center][var1]]+sol_[neighbours[center][var2]]);
1479 if(weight<0) weight=0;
1480 w.push_back(weight);
1488 for(
size_t n=0; n<N;++n) {
1489 std::vector<IndexType> path;
1491 if(!parameter_.useOldPriorityQueue_){
1492 std::vector<IndexType> prev(2*N);
1494 pathLength = shortestPath2(2*n,2*n+1,E,w,path,prev,openNodes,1e22,
false);
1496 pathLength = shortestPath(2*n,2*n+1,E,w,path,1e22,
false);
1498 if(pathLength<0.5-EPS_*path.size()){
1502 constraints.add(IloRange(env_, -100000 , (path.size()-2)/2 ));
1503 for(
size_t k=0;k<path.size()-1;++k){
1504 constraints[constraintCounter_].setLinearCoef(x_[neighbours[center][node2var[path[k]/2]]],-1);
1506 for(
size_t k=0;k<path.size()-1;++k){
1507 const IndexType u= node2var[path[k]/2];
1508 const IndexType v= node2var[path[k+1]/2];
1509 constraints[constraintCounter_].setLinearCoef(x_[neighbours[u][v]],1);
1511 ++constraintCounter_;
1513 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1518 for(it=neighbours[center].begin() ; it != neighbours[center].end(); ++it) {
1519 var2node[(*it).first] = std::numeric_limits<IndexType>::max();
1524 return constraintCounter_-tempConstrainCounter;
1532 template<
class GM,
class ACC>
1533 size_t Multicut<GM, ACC>::findIntegerCycleConstraints(
1534 IloRangeArray& constraint,
1535 bool addFacetDefiningConstraintsOnly
1539 std::vector<LabelType> partit(numberOfNodes_,0);
1540 std::vector<std::list<size_t> > neighbours0;
1541 partition(partit,neighbours0);
1542 size_t tempConstrainCounter = constraintCounter_;
1547 std::vector<size_t> path(numberOfNodes_,std::numeric_limits<size_t>::max());
1548 for(
size_t i=0; i<numberOfInternalEdges_;++i) {
1549 u = edgeNodes_[i].first;
1550 v = edgeNodes_[i].second;
1552 if(sol_[numberOfTerminalEdges_+i]>=EPS_ && partit[u] == partit[v]) {
1558 std::fill(path.begin(),path.end(),std::numeric_limits<size_t>::max());
1560 const bool preChordalcheck =addFacetDefiningConstraintsOnly && parameter_.useChordalSearch_;
1562 std::list<size_t>::iterator it;
1563 for(it=neighbours0[n].begin() ; it != neighbours0[n].end(); ++it) {
1564 if(path[*it]==std::numeric_limits<size_t>::max()) {
1566 if(preChordalcheck) {
1567 bool isChordless =
true;
1569 const size_t c = *it;
1572 if(s==u && c==v)
continue;
1573 if(neighbours[c].find(s)!=neighbours[c].end()) {
1574 isChordless =
false;
1590 if(nodeList.empty())
1592 n = nodeList.front(); nodeList.pop();
1594 if(path[v] != std::numeric_limits<size_t>::max()){
1598 w += sol_[neighbours[n][path[n]]];
1601 if(sol_[neighbours[u][v]]-EPS_<w)
1604 const bool postChordlessCheck = addFacetDefiningConstraintsOnly && !parameter_.useChordalSearch_;
1605 bool chordless =
true;
1606 if(postChordlessCheck){
1611 size_t t = path[path[s]];
1613 if(s==v && t==u)
break;
1614 if(neighbours[t].find(s)!=neighbours[t].end()) {
1627 constraint.add(IloRange(env_, 0 , 1000000000));
1628 constraint[constraintCounter_].setLinearCoef(x_[neighbours[u][v]],-1);
1630 constraint[constraintCounter_].setLinearCoef(x_[neighbours[n][path[n]]],1);
1633 ++constraintCounter_;
1636 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1639 if(constraintCounter_-tempConstrainCounter >= parameter_.maximalNumberOfConstraintsPerRound_)
1642 return constraintCounter_-tempConstrainCounter;
1646 template <
class GM,
class ACC>
1650 EmptyVisitorType mcv;
1654 template <
class GM,
class ACC>
1659 cplex_.setParam(IloCplex::Threads, parameter_.numThreads_);
1660 cplex_.setParam(IloCplex::CutUp, parameter_.cutUp_);
1661 cplex_.setParam(IloCplex::MIPDisplay,0);
1662 cplex_.setParam(IloCplex::BarDisplay,0);
1663 cplex_.setParam(IloCplex::NetDisplay,0);
1664 cplex_.setParam(IloCplex::SiftDisplay,0);
1665 cplex_.setParam(IloCplex::SimDisplay,0);
1667 cplex_.setParam(IloCplex::EpOpt,1e-9);
1668 cplex_.setParam(IloCplex::EpRHS,1e-8);
1669 cplex_.setParam(IloCplex::EpInt,0);
1670 cplex_.setParam(IloCplex::EpAGap,0);
1671 cplex_.setParam(IloCplex::EpGap,0);
1673 if(parameter_.verbose_ ==
true && parameter_.verboseCPLEX_) {
1674 cplex_.setParam(IloCplex::MIPDisplay,2);
1675 cplex_.setParam(IloCplex::BarDisplay,1);
1676 cplex_.setParam(IloCplex::NetDisplay,1);
1677 cplex_.setParam(IloCplex::SiftDisplay,1);
1678 cplex_.setParam(IloCplex::SimDisplay,1);
1683 template <
class GM,
class ACC>
1684 template<
class VisitorType>
1688 std::vector<LabelType> conf(gm_.numberOfVariables());
1692 if(problemType_ == INVALID){
1695 else if(!readWorkFlow(parameter_.workFlow_)){
1696 if(parameter_.workFlow_.size()>0){
1697 std::cout <<
"Warning: can not parse workflow : " << parameter_.workFlow_ <<std::endl;
1698 std::cout <<
"Using default workflow ";
1700 if(problemType_ == MWC){
1702 readWorkFlow(
"(TTC)(MTC)(IC)(CC-IFD,TTC-I)");
1704 else if(problemType_ == MC){
1706 readWorkFlow(
"(CC-FDB)(IC)(CC-I)");
1716 size_t workingState = 0;
1717 while(workingState<workFlow_.size()){
1718 protocolateTiming_.push_back(std::vector<double>(20,0));
1719 protocolateConstraints_.push_back(std::vector<size_t>(20,0));
1720 std::vector<double>& T = protocolateTiming_.back();
1721 std::vector<size_t>& C = protocolateConstraints_.back();
1729 for (
size_t it=1; it<10000000000; ++it) {
1730 cplex_.setParam(IloCplex::Threads, parameter_.numThreads_);
1731 cplex_.setParam(IloCplex::TiLim, parameter_.timeOut_-timer.
elapsedTime());
1733 if(!cplex_.solve()) {
1734 if(cplex_.getStatus() != IloAlgorithm::Unbounded){
1735 std::cout <<
"failed to optimize. " <<cplex_.getStatus()<< std::endl;
1744 if(cplex_.getStatus()!= IloAlgorithm::Unbounded){
1746 bound_ = cplex_.getObjValue()+constant_;
1748 bound_ = cplex_.getBestObjValue()+constant_;
1749 if(!cplex_.solveFixed()) {
1750 std::cout <<
"failed to fixed optimize." << std::endl;
1759 try{ cplex_.getValues(sol_, x_);}
1760 catch(IloAlgorithm::NotExtractedException e) {
1764 for(IndexType v=0; v<numberOfTerminalEdges_+numberOfInternalEdges_+numberOfInterTerminalEdges_ + numberOfHigherOrderValues_; ++v){
1766 sol_.add(cplex_.getValue(x_[v]));
1767 }
catch(IloAlgorithm::NotExtractedException e) {
1772 if(parameter_.useBufferedStates_){
1773 std::vector<LabelType> s(gm_.numberOfVariables());
1774 parameter_.useBufferedStates_ =
false;
1776 parameter_.useBufferedStates_ =
true;
1778 if(bufferedValue_ > v){
1780 bufferedStates_.assign(s.begin(), s.end());
1787 workingState = workFlow_.size();
1794 IloRangeArray constraint = IloRangeArray(env_);
1795 constraintCounter_ = 0;
1800 size_t cycleConstraints = std::numeric_limits<size_t>::max();
1801 bool constraintAdded =
false;
1802 for(std::vector<size_t>::iterator it=workFlow_[workingState].begin() ; it != workFlow_[workingState].end(); it++ ){
1804 size_t protocol_ID = Protocol_ID_Unknown;
1806 if(*it == Action_ID_TTC){
1807 if(parameter_.verbose_) std::cout <<
"* Add terminal triangle constraints: " << std::flush;
1808 n = findTerminalTriangleConstraints(constraint);
1809 if(parameter_.verbose_) std::cout << n << std::endl;
1810 protocol_ID = Protocol_ID_TTC;
1812 else if(*it == Action_ID_TTC_I){
1814 throw RuntimeError(
"Error: Calling integer terminal triangle constraint (TTC-I) seperation provedure before switching in integer mode (IC)");
1816 if(parameter_.verbose_) std::cout <<
"* Add integer terminal triangle constraints: " << std::flush;
1818 n = findIntegerTerminalTriangleConstraints(constraint, conf);
1819 if(parameter_.verbose_) std::cout << n << std::endl;
1820 protocol_ID = Protocol_ID_TTC;
1823 else if(*it == Action_ID_MTC){
1824 if(parameter_.verbose_) std::cout <<
"* Add multi terminal constraints: " << std::flush;
1825 n = findMultiTerminalConstraints(constraint);
1826 if(parameter_.verbose_) std::cout << n << std::endl;
1827 protocol_ID = Protocol_ID_MTC;
1830 else if(*it == Action_ID_CC_I){
1832 throw RuntimeError(
"Error: Calling integer cycle constraints (CC-I) seperation provedure before switching in integer mode (IC)");
1834 if(parameter_.verbose_) std::cout <<
"Add integer cycle constraints: " << std::flush;
1835 n = findIntegerCycleConstraints(constraint,
false);
1836 if(parameter_.verbose_) std::cout << n << std::endl;
1837 protocol_ID = Protocol_ID_CC;
1839 else if(*it == Action_ID_CC_IFD){
1841 throw RuntimeError(
"Error: Calling facet defining integer cycle constraints (CC-IFD) seperation provedure before switching in integer mode (IC)");
1843 if(parameter_.verbose_) std::cout <<
"Add facet defining integer cycle constraints: " << std::flush;
1844 n = findIntegerCycleConstraints(constraint,
true);
1845 if(parameter_.verbose_) std::cout << n << std::endl;
1846 protocol_ID = Protocol_ID_CC;
1848 else if(*it == Action_ID_CC){
1849 if(parameter_.verbose_) std::cout <<
"Add cycle constraints: " << std::flush;
1850 n = findCycleConstraints(constraint,
false,
false);
1852 if(parameter_.verbose_) std::cout << n << std::endl;
1853 protocol_ID = Protocol_ID_CC;
1855 else if(*it == Action_ID_CC_FD){
1856 if(parameter_.verbose_) std::cout <<
"Add facet defining cycle constraints: " << std::flush;
1857 n = findCycleConstraints(constraint,
true,
false);
1859 if(parameter_.verbose_) std::cout << n << std::endl;
1860 protocol_ID = Protocol_ID_CC;
1862 else if(*it == Action_ID_CC_FDB){
1863 if(parameter_.verbose_) std::cout <<
"Add facet defining cycle constraints (with bounding): " << std::flush;
1864 n = findCycleConstraints(constraint,
true,
true);
1866 if(parameter_.verbose_) std::cout << n << std::endl;
1867 protocol_ID = Protocol_ID_CC;
1869 else if(*it == Action_ID_CC_B){
1870 if(parameter_.verbose_) std::cout <<
"Add cycle constraints (with bounding): " << std::flush;
1871 n = findCycleConstraints(constraint,
false,
true);
1873 if(parameter_.verbose_) std::cout << n << std::endl;
1874 protocol_ID = Protocol_ID_CC;
1876 else if(*it == Action_ID_RemoveConstraints){
1877 if(parameter_.verbose_) std::cout <<
"Remove unused constraints: " << std::flush;
1878 n = removeUnusedConstraints();
1879 if(parameter_.verbose_) std::cout << n << std::endl;
1880 protocol_ID = Protocol_ID_RemoveConstraints;
1882 else if(*it == Action_ID_IntegerConstraints){
1883 if(integerMode_)
continue;
1884 if(parameter_.verbose_) std::cout <<
"Add integer constraints: " << std::flush;
1885 n = enforceIntegerConstraints();
1886 if(parameter_.verbose_) std::cout << n << std::endl;
1887 protocol_ID = Protocol_ID_IntegerConstraints;
1889 else if(*it == Action_ID_OWC){
1890 if(cycleConstraints== std::numeric_limits<size_t>::max()){
1891 std::cout <<
"WARNING: using Odd Wheel Contraints without Cycle Constrains! -> Use CC,OWC!"<<std::endl;
1894 else if(cycleConstraints==0){
1895 if(parameter_.verbose_) std::cout <<
"Add odd wheel constraints: " << std::flush;
1896 n = findOddWheelConstraints(constraint);
1897 if(parameter_.verbose_) std::cout << n << std::endl;
1902 protocol_ID = Protocol_ID_OWC;
1905 std::cout <<
"Unknown Inference State "<<*it<<std::endl;
1909 C[protocol_ID] += n;
1910 if(n>0) constraintAdded =
true;
1916 if(!constraintAdded){
1919 if(workingState<workFlow_.size())
1920 if(parameter_.verbose_) std::cout <<std::endl<<
"** Switching into next state ( "<< workingState <<
" )**" << std::endl;
1926 model_.add(constraint);
1929 T[Protocol_ID_AddConstraints] += timer2.
elapsedTime();
1942 if(parameter_.verbose_){
1943 std::cout <<
"end normal"<<std::endl;
1944 std::cout <<
"Protokoll:"<<std::endl;
1945 std::cout <<
"=========="<<std::endl;
1946 std::cout <<
" i | SOLVE | ADD | CC | OWC | TTC | MTV | IC " <<std::endl;
1947 std::cout <<
"-----+----------+----------+----------+----------+----------+----------+-----------" <<std::endl;
1949 std::vector<size_t> IDS;
1950 IDS.push_back(Protocol_ID_Solve);
1951 IDS.push_back(Protocol_ID_AddConstraints);
1952 IDS.push_back(Protocol_ID_CC);
1953 IDS.push_back(Protocol_ID_OWC);
1954 IDS.push_back(Protocol_ID_TTC);
1955 IDS.push_back(Protocol_ID_MTC);
1956 IDS.push_back(Protocol_ID_IntegerConstraints);
1958 if(parameter_.verbose_){
1959 for(
size_t i=0; i<protocolateTiming_.size(); ++i){
1960 std::cout << std::setw(5)<< i ;
1961 for(
size_t n=0; n<IDS.size(); ++n){
1962 std::cout <<
"|"<< std::setw(10) << setiosflags(std::ios::fixed)<< std::setprecision(4) << protocolateConstraints_[i][IDS[n]];
1964 std::cout << std::endl;
1966 for(
size_t n=0; n<IDS.size(); ++n){
1967 std::cout <<
"|"<< std::setw(10) << setiosflags(std::ios::fixed)<< std::setprecision(4) << protocolateTiming_[i][IDS[n]];
1969 std::cout << std::endl;
1970 std::cout <<
"-----+----------+----------+----------+----------+----------+----------+-----------" <<std::endl;
1972 std::cout <<
"sum ";
1974 for(
size_t n=0; n<IDS.size(); ++n){
1976 for(
size_t i=0; i<protocolateTiming_.size(); ++i){
1977 t_one += protocolateTiming_[i][IDS[n]];
1979 std::cout <<
"|"<< std::setw(10) << setiosflags(std::ios::fixed)<< std::setprecision(4) << t_one;
1982 std::cout <<
" | " <<t_all <<std::endl;
1983 std::cout <<
"-----+----------+----------+----------+----------+----------+----------+-----------" <<std::endl;
1988 template <
class GM,
class ACC>
2000 if(parameter_.useBufferedStates_){
2001 x.assign(bufferedStates_.begin(),bufferedStates_.end());
2005 if(problemType_ == MWC) {
2006 if(parameter_.MWCRounding_== parameter_.NEAREST){
2007 x.resize(gm_.numberOfVariables());
2008 for(IndexType node = 0; node<gm_.numberOfVariables(); ++node) {
2009 double v = sol_[numberOfTerminals_*node+0];
2011 for(
LabelType i=0; i<gm_.numberOfLabels(node); ++i) {
2012 if(sol_[numberOfTerminals_*node+i]<v) {
2019 else if(parameter_.MWCRounding_==Parameter::DERANDOMIZED){
2020 return derandomizedRounding(x);
2022 else if(parameter_.MWCRounding_==Parameter::PSEUDODERANDOMIZED){
2023 return pseudoDerandomizedRounding(x,1000);
2030 std::vector<std::list<size_t> > neighbours0;
2036 template <
class GM,
class ACC>
2039 std::vector<size_t> seg;
2040 std::vector<std::list<size_t> > neighbours0;
2041 partition(seg, neighbours0, 0.3);
2046 template <
class GM,
class ACC>
2054 std::vector<bool> processedBins(bins+1,
false);
2055 std::vector<LabelType> temp;
2056 double value = 1000000000000.0;
2057 std::vector<LabelType> labelorder1(numberOfTerminals_,numberOfTerminals_-1);
2058 std::vector<LabelType> labelorder2(numberOfTerminals_,numberOfTerminals_-1);
2059 for(
LabelType i=0; i<numberOfTerminals_-1;++i){
2061 labelorder2[i]=numberOfTerminals_-2-i;
2063 for(
size_t i=0; i<numberOfTerminals_*gm_.numberOfVariables();++i){
2070 else if(sol_[i]>=1){
2075 bin = (
size_t)(sol_[i]*bins)%bins;
2078 if(!processedBins[bin]){
2079 processedBins[bin]=
true;
2080 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder1,sol_[i]))){
2084 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder2,sol_[i]))){
2093 template <
class GM,
class ACC>
2095 Multicut<GM,ACC>::derandomizedRounding
2097 std::vector<
typename Multicut<GM,ACC>::LabelType>& x
2100 std::vector<LabelType> temp;
2101 double value = 1000000000000.0;
2102 std::vector<LabelType> labelorder1(numberOfTerminals_,numberOfTerminals_-1);
2103 std::vector<LabelType> labelorder2(numberOfTerminals_,numberOfTerminals_-1);
2104 for(
LabelType i=0; i<numberOfTerminals_-1;++i){
2106 labelorder2[i]=numberOfTerminals_-2-i;
2110 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder1,1e-8))){
2114 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder2,1e-8))){
2118 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder1,1-1e-8))){
2122 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder2,1-1e-8))){
2126 for(
size_t i=0; i<numberOfTerminals_*gm_.numberOfVariables();++i){
2127 if( sol_[i]>1e-8 && sol_[i]<1-1e-8){
2128 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder1,sol_[i]))){
2132 if(value>(d=derandomizedRoundingSubProcedure(temp,labelorder2,sol_[i]))){
2141 template <
class GM,
class ACC>
2143 Multicut<GM,ACC>::derandomizedRoundingSubProcedure
2145 std::vector<
typename Multicut<GM,ACC>::LabelType>& x,
2146 const std::vector<
typename Multicut<GM,ACC>::LabelType>& labelorder,
2147 const double threshold
2150 const LabelType lastLabel = labelorder.back();
2151 const IndexType numVar = gm_.numberOfVariables();
2153 x.assign(numVar,lastLabel);
2155 for(
size_t i=0; i<labelorder.size()-1; ++i){
2156 for(IndexType v=0; v<numVar; ++v){
2157 if(x[v]==lastLabel && sol_[numberOfTerminals_*v+i]<=threshold){
2162 return gm_.evaluate(x);
2168 template <
class GM,
class ACC>
2170 Multicut<GM,ACC>::partition
2172 std::vector<LabelType>& partit,
2173 std::vector<std::list<size_t> >& neighbours0,
2178 partit.resize(numberOfNodes_,0);
2179 neighbours0.resize(numberOfNodes_, std::list<size_t>());
2182 for(
size_t i=0; i<numberOfInternalEdges_; ++i) {
2183 IndexType u = edgeNodes_[i].first;
2184 IndexType v = edgeNodes_[i].second;
2185 if(sol_[numberOfTerminalEdges_+counter] <= threshold) {
2186 neighbours0[u].push_back(v);
2187 neighbours0[v].push_back(u);
2193 std::vector<bool> assigned(numberOfNodes_,
false);
2194 for(
size_t node=0; node<numberOfNodes_; ++node) {
2198 std::list<size_t> nodeList;
2200 assigned[node] =
true;
2201 nodeList.push_back(node);
2202 while(!nodeList.empty()) {
2203 size_t n=nodeList.front(); nodeList.pop_front();
2204 std::list<size_t>::const_iterator it;
2205 for(it=neighbours0[n].begin() ; it != neighbours0[n].end(); ++it) {
2206 if(!assigned[*it]) {
2208 assigned[*it] =
true;
2209 nodeList.push_back(*it);
2220 template <
class GM,
class ACC>
2221 typename Multicut<GM,ACC>::ValueType
2224 std::vector<LabelType>& conf
2228 return gm_.evaluate(conf);
2231 template<
class GM,
class ACC>
2238 template<
class GM,
class ACC>
2244 template<
class GM,
class ACC>
2247 std::vector<LabelType> c;
2253 template<
class GM,
class ACC>
2256 if(s[0]!=
'(' || s[s.size()-1] !=
')')
2260 std::string sepString;
2264 if(s[n]==
',' || s[n]==
')'){
2265 if(sepString.compare(
"CC")==0)
2266 workFlow_.back().push_back(Action_ID_CC);
2267 else if(sepString.compare(
"CC-I")==0)
2268 workFlow_.back().push_back(Action_ID_CC_I);
2269 else if(sepString.compare(
"CC-IFD")==0)
2270 workFlow_.back().push_back(Action_ID_CC_IFD);
2271 else if(sepString.compare(
"CC-B")==0)
2272 workFlow_.back().push_back(Action_ID_CC_B);
2273 else if(sepString.compare(
"CC-FDB")==0)
2274 workFlow_.back().push_back(Action_ID_CC_FDB);
2275 else if(sepString.compare(
"CC-FD")==0)
2276 workFlow_.back().push_back(Action_ID_CC_FD);
2277 else if(sepString.compare(
"TTC")==0)
2278 workFlow_.back().push_back(Action_ID_TTC);
2279 else if(sepString.compare(
"TTC-I")==0)
2280 workFlow_.back().push_back(Action_ID_TTC_I);
2281 else if(sepString.compare(
"MTC")==0)
2282 workFlow_.back().push_back(Action_ID_MTC);
2283 else if(sepString.compare(
"OWC")==0)
2284 workFlow_.back().push_back(Action_ID_OWC);
2285 else if(sepString.compare(
"IC")==0)
2286 workFlow_.back().push_back(Action_ID_IntegerConstraints);
2288 std::cout <<
"WARNING: Unknown Seperation Procedure ' "<<sepString<<
"' is skipped!"<<std::endl;
2292 workFlow_.push_back(std::vector<size_t>());
2308 template<
class GM,
class ACC>
2309 template<
class DOUBLEVECTOR>
2310 inline double Multicut<GM, ACC>::shortestPath(
2311 const IndexType startNode,
2312 const IndexType endNode,
2313 const std::vector<EdgeMapType >& E,
2314 const DOUBLEVECTOR& w,
2315 std::vector<IndexType>& shortestPath,
2316 const double maxLength,
2321 const IndexType numberOfNodes = E.size();
2322 const double inf = std::numeric_limits<double>::infinity();
2323 const IndexType nonePrev = endNode;
2325 std::vector<IndexType> prev(numberOfNodes,nonePrev);
2326 std::vector<double> dist(numberOfNodes,inf);
2329 openNodes.insert(startNode);
2330 dist[startNode]=0.0;
2332 while(!openNodes.empty()){
2336 typename MYSET::iterator it, itMin;
2337 double v = std::numeric_limits<double>::infinity();
2338 for(it = openNodes.begin(); it!= openNodes.end(); ++it){
2345 openNodes.erase(itMin);
2352 typename EdgeMapType::const_iterator it;
2353 for(it=E[node].begin() ; it != E[node].end(); ++it) {
2354 const IndexType node2 = (*it).first;
2355 const LPIndexType weighId = (*it).second;
2356 double cuttedWeight = std::max(0.0,w[weighId]);
2357 const double weight2 = dist[node]+cuttedWeight;
2360 if(dist[node2] > weight2 && weight2 < maxLength){
2362 bool updateNode =
true;
2365 while(s!=startNode){
2367 if(s==startNode && node2==endNode)
continue;
2368 if(neighbours[node2].find(s)!=neighbours[node2].end()) {
2376 dist[node2] = weight2;
2377 openNodes.insert(node2);
2384 if(prev[endNode] != nonePrev){
2385 shortestPath.clear();
2386 shortestPath.push_back(endNode);
2387 IndexType n = endNode;
2390 shortestPath.push_back(n);
2391 }
while(n!=startNode);
2398 return dist[endNode];
2402 template<
class GM,
class ACC>
2403 template<
class DOUBLEVECTOR>
2404 inline double Multicut<GM, ACC>::shortestPath2(
2405 const IndexType startNode,
2406 const IndexType endNode,
2407 const std::vector<EdgeMapType >& E,
2408 const DOUBLEVECTOR& w,
2409 std::vector<IndexType>& shortestPath,
2410 std::vector<IndexType>& prev,
2412 const double maxLength,
2417 const IndexType numberOfNodes = E.size();
2418 const IndexType nonePrev = endNode;
2424 openNodes.
push(startNode,0.0);
2425 prev[endNode] = nonePrev;
2430 while(!openNodes.
empty()){
2432 node = openNodes.
top();
2442 typename EdgeMapType::const_iterator it;
2443 for(it=E[node].begin() ; it != E[node].end(); ++it) {
2444 const IndexType node2 = (*it).first;
2445 const LPIndexType weighId = (*it).second;
2446 double cuttedWeight = std::max(0.0,w[weighId]);
2447 const double weight2 = priority+cuttedWeight;
2451 if(openNodes.
priority(node2) > weight2 && weight2 < maxLength ){
2453 bool updateNode =
true;
2456 while(s!=startNode){
2458 if(s==startNode && node2==endNode)
continue;
2459 if(neighbours[node2].find(s)!=neighbours[node2].end()) {
2466 openNodes.
push(node2,weight2);
2474 if(prev[endNode] != nonePrev){
2475 shortestPath.resize(0);
2476 shortestPath.push_back(endNode);
2477 IndexType n = endNode;
2480 shortestPath.push_back(n);
2481 }
while(n!=startNode);
2487 return openNodes.
priority(endNode);
2491 template<
class GM,
class ACC>
2496 std::vector<double> l(numberOfInternalEdges_,0);
2497 for(
size_t i=0; i<numberOfInternalEdges_; ++i) {
2498 l[i] = sol_[numberOfTerminalEdges_+i];
2507 template<
class GM,
class ACC>
2508 template<
class LPVariableIndexIterator,
class CoefficientIterator>
2511 LPVariableIndexIterator viBegin,
2512 LPVariableIndexIterator viEnd,
2513 CoefficientIterator coefficient,
2517 IloRange constraint(env_, lowerBound, upperBound);
2518 while(viBegin != viEnd) {
2519 constraint.setLinearCoef(x_[*viBegin], *coefficient);
2523 model_.add(constraint);
void reset()
reset heap - priorities are not changed
virtual InferenceTermination infer()
ValueType bound() const
return a bound on the solution
EdgeLabelType getPartition(size_t n)
Addition as a binary operation.
void pop()
Remove the current top element.
size_t constraintCounter_
virtual InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a 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) .
const GraphicalModelType & graphicalModel() const
priority_type priority(const value_type i) const
returns the value associated with index i
__gnu_cxx::hash_set< IndexType > MYSET
std::vector< double > getEdgeLabeling() const
size_t BellNumber(size_t N)
Heap-based changable priority queue with a maximum number of elemements.
Platform-independent runtime measurements.
#define OPENGM_ASSERT(expression)
ParamHeper::MWCRounding MWCRounding_
bool empty() const
check if the PQ is empty
size_t getLPIndex(IT a, IT b)
detail_types::UInt64Type UInt64Type
uint64
GraphicalModelType::OperatorType OperatorType
void push(const value_type i, const priority_type p)
Insert a index with a given priority.
GraphicalModelType::IndexType IndexType
virtual std::string name() const
std::vector< bool > allowCutsWithin_
double elapsedTime() const
__gnu_cxx::hash_map< IndexType, LPIndexType > EdgeMapType
priority_type topPriority() const
get top priority
visitors::TimingVisitor< Multicut< GM, ACC > > TimingVisitorType
GraphicalModelType::ValueType ValueType
Inference algorithm interface.
void addConstraint(LPVariableIndexIterator, LPVariableIndexIterator, CoefficientIterator, const ValueType &, const ValueType &)
std::vector< size_t > getSegmentation() const
size_t maximalNumberOfConstraintsPerRound_
#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
ValueType evaluate(std::vector< LabelType > &) const
Parameter(int numThreads=0, double cutUp=1.0e+75)
GraphicalModelType::LabelType LabelType
Minimization as a unary accumulation.
visitors::VerboseVisitor< Multicut< GM, ACC > > VerboseVisitorType
ValueType value() const
return the solution (value)
Multicut(const GraphicalModelType &, Parameter para=Parameter())
const_reference top() const
get index with top priority
bool initializeWith3Cycles_
double edgeRoundingValue_