Beispiel #1
0
 std::vector<T> Selector::select(const std::vector<T> &v) const {
   assert(v.size() == nvars_possible());
   if (include_all_ || nvars() == nvars_possible()) return v;
   std::vector<T> ans;
   ans.reserve(nvars());
   for (uint i = 0; i < nvars(); ++i) {
     ans.push_back(v[indx(i)]);
   }
   return ans;
 }
Beispiel #2
0
 std::vector<T> Selector::select(const std::vector<T> &v) const{
   assert(v.size()==nvars_possible());
   std::vector<T> ans;
   ans.reserve(nvars());
   for(uint i=0; i<nvars_possible(); ++i)
     if(inc(i))
       ans.push_back(v[i]);
   return ans;}
Beispiel #3
0
  T Selector::sub_select(const T &x, const Selector &rhs) const {
    assert(rhs.nvars() <= this->nvars());
    assert(this->covers(rhs));

    Selector tmp(nvars(), false);
    for (uint i = 0; i < rhs.nvars(); ++i) {
      tmp.add(INDX(rhs.indx(i)));
    }
    return tmp.select(x);
  }
	real PseudoBoolean<real>::minimize_reduction_M(vector<label>& x, int& nlabelled) const
	{
		//
		// Compute a large enough value for M
		//
		real M = 0;
		for (auto itr=aijkl.begin(); itr != aijkl.end(); ++itr) {
			real a = itr->second;
			M += abs(a);
		}
		for (auto itr=aijk.begin(); itr != aijk.end(); ++itr) {
			real a = itr->second;
			M += abs(a);
		}
		for (auto itr=aij.begin(); itr != aij.end(); ++itr) {
			real a = itr->second;
			M += abs(a);
		}
		for (auto itr=ai.begin(); itr != ai.end(); ++itr) {
			real a = itr->second;
			M += abs(a);
		} 

		// Copy of the polynomial. Will contain the reduced polynomial
		PseudoBoolean<real> pb = *this;
		// Number of variables (will be increased
		int n = nvars();
		int norg = n;

		//
		// Reduce the degree-4 terms 
		//
		double M2 = M;
		for (auto itr=pb.aijkl.begin(); itr != pb.aijkl.end(); ++itr) {
			int i = get_i(itr->first);
			int j = get_j(itr->first);
			int k = get_k(itr->first);
			int l = get_l(itr->first);
			real a = itr->second;

			// a*xi*xj*xk*xl  will be converted to
			// a*xi*xj*z + M( xk*xl - 2*xk*z - 2*xl*z + 3*z )
			int z = n++;

			pb.add_monomial(i,j,z, a);

			pb.add_monomial(k,l,M);
			pb.add_monomial(k,z, -2*M);
			pb.add_monomial(l,z, -2*M);
			pb.add_monomial(z, 3*M);

			M2 += a + 4*M;
		}
		
		// Remove all degree-4 terms.
		pb.aijkl.clear();

		//
		// Reduce the degree-3 terms
		//
		for (auto itr=pb.aijk.begin(); itr != pb.aijk.end(); ++itr) {
			int i = get_i(itr->first);
			int j = get_j(itr->first);
			int k = get_k(itr->first);
			real a = itr->second;

			// a*xi*xj*xk  will be converted to
			// a*xi*z + M( xj*xk -2*xj*z -2*xk*z + 3*z )
			int z = n++;

			pb.add_monomial(i,z, a);

			pb.add_monomial(j,k,M2);
			pb.add_monomial(j,z, -2*M2);
			pb.add_monomial(k,z, -2*M2);
			pb.add_monomial(z, 3*M2);
		}

		// Remove all degree-3 terms.
		pb.aijk.clear();

		//
		// Minimize the reduced polynomial
		//
		vector<label> xtmp(n,-1);
		real bound = pb.minimize(xtmp, HOCR);

		nlabelled = 0;
		for (int i=0;i<norg;++i) {
			x.at(i) = xtmp[i];
			if (x[i] >= 0) {
				nlabelled++;
			}
		}

		return bound;
	}
	real PseudoBoolean<real>::minimize_reduction(vector<label>& x, int& nlabelled) const
	{
		index nVars = index( x.size() );
		// Here it is important that all indices appear as pairs 
		// in aij or ai
		ASSERT_STR( nvars() <= nVars , "x too small");

		PBF<real, 4> hocr;
		map<int,bool> var_used;

		for (auto itr=ai.begin(); itr != ai.end(); ++itr) {
			int i = itr->first;
			real a = itr->second;
			hocr.AddUnaryTerm(i, 0, a);
			var_used[i] = true;
		}

		for (auto itr=aij.begin(); itr != aij.end(); ++itr) {
			int i = get_i(itr->first);
			int j = get_j(itr->first);
			real a = itr->second;
			hocr.AddPairwiseTerm(i,j, 0,0,0, a);
			var_used[i] = true;
			var_used[j] = true;
		}

		for (auto itr=aijk.begin(); itr != aijk.end(); ++itr) {
			int i = get_i(itr->first);
			int j = get_j(itr->first);
			int k = get_k(itr->first);
			real a = itr->second;
			int ind[] = {i,j,k};
			real E[8] = {0,0,0,0, 0,0,0,0};
			E[7] = a;
			hocr.AddHigherTerm(3, ind, E);
			var_used[i] = true;
			var_used[j] = true;
			var_used[k] = true;
		}

		for (auto itr=aijkl.begin(); itr != aijkl.end(); ++itr) {
			int i = get_i(itr->first);
			int j = get_j(itr->first);
			int k = get_k(itr->first);
			int l = get_l(itr->first);
			real a = itr->second;
			int ind[] = {i,j,k,l};
			real   E[16] = {0,0,0,0, 0,0,0,0,
			                0,0,0,0, 0,0,0,0};
			E[15] = a;
			hocr.AddHigherTerm(4, ind, E);
			var_used[i] = true;
			var_used[j] = true;
			var_used[k] = true;
			var_used[l] = true;
		}

		index nOptimizedVars = hocr.maxID() + 1;

		PBF<real,2> qpbf;
		hocr.toQuadratic(qpbf); 
		hocr.clear(); 
		QPBO<real> qpbo(nVars, qpbf.size(), err_function_qpbo); 
		convert(qpbo, qpbf);
		qpbo.MergeParallelEdges();
		qpbo.Solve();
		qpbo.ComputeWeakPersistencies();

		nlabelled = 0;
		for (int i=0; i < nOptimizedVars; ++i) {
			if (var_used[i] || x.at(i)<0) {
				x[i] = qpbo.GetLabel(i);
			}
			if (x[i] >= 0) {
				nlabelled++;
			}
		}

		// These variables were not part of the minimization
		ASSERT(nVars >= nOptimizedVars);
		nlabelled += nVars - nOptimizedVars;

		real energy = constant + qpbo.ComputeTwiceLowerBound()/2;
		//double energy = eval(x); //Only when x is fully labelled
		return energy;
	}