| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Domain.cpp | 
					
						
							|  |  |  |  * @brief Domain restriction constraint | 
					
						
							|  |  |  |  * @date Feb 13, 2012 | 
					
						
							|  |  |  |  * @author Frank Dellaert | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 08:47:19 +08:00
										 |  |  | #include <gtsam_unstable/discrete/Domain.h>
 | 
					
						
							| 
									
										
										
										
											2012-04-16 07:12:17 +08:00
										 |  |  | #include <gtsam/discrete/DecisionTreeFactor.h>
 | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | #include <gtsam/base/Testable.h>
 | 
					
						
							|  |  |  | #include <boost/make_shared.hpp>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   using namespace std; | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   void Domain::print(const string& s, | 
					
						
							| 
									
										
										
										
											2013-11-09 00:35:28 +08:00
										 |  |  |       const KeyFormatter& formatter) const { | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  | //    cout << s << ": Domain on " << formatter(keys_[0]) << " (j=" <<
 | 
					
						
							|  |  |  | //    formatter(keys_[0]) << ") with values";
 | 
					
						
							| 
									
										
										
										
											2016-05-21 11:41:41 +08:00
										 |  |  | //    for (size_t v: values_) cout << " " << v;
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  | //    cout << endl;
 | 
					
						
							| 
									
										
										
										
											2016-05-21 11:41:41 +08:00
										 |  |  |     for (size_t v: values_) cout << v; | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   double Domain::operator()(const Values& values) const { | 
					
						
							|  |  |  |     return contains(values.at(keys_[0])); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   DecisionTreeFactor Domain::toDecisionTreeFactor() const { | 
					
						
							|  |  |  |     DiscreteKeys keys; | 
					
						
							|  |  |  |     keys += DiscreteKey(keys_[0],cardinality_); | 
					
						
							|  |  |  |     vector<double> table; | 
					
						
							|  |  |  |     for (size_t i1 = 0; i1 < cardinality_; ++i1) | 
					
						
							|  |  |  |       table.push_back(contains(i1)); | 
					
						
							|  |  |  |     DecisionTreeFactor converted(keys, table); | 
					
						
							|  |  |  |     return converted; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   DecisionTreeFactor Domain::operator*(const DecisionTreeFactor& f) const { | 
					
						
							|  |  |  |     // TODO: can we do this more efficiently?
 | 
					
						
							|  |  |  |     return toDecisionTreeFactor() * f; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   bool Domain::ensureArcConsistency(size_t j, vector<Domain>& domains) const { | 
					
						
							|  |  |  |     if (j != keys_[0]) throw invalid_argument("Domain check on wrong domain"); | 
					
						
							|  |  |  |     Domain& D = domains[j]; | 
					
						
							| 
									
										
										
										
											2016-05-21 11:41:41 +08:00
										 |  |  |     for(size_t value: values_) | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |       if (!D.contains(value)) throw runtime_error("Unsatisfiable"); | 
					
						
							|  |  |  |     D = *this; | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2018-11-08 13:58:50 +08:00
										 |  |  |   bool Domain::checkAllDiff(const KeyVector keys, vector<Domain>& domains) { | 
					
						
							| 
									
										
										
										
											2013-11-09 00:35:28 +08:00
										 |  |  |     Key j = keys_[0]; | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |     // for all values in this domain
 | 
					
						
							| 
									
										
										
										
											2016-05-21 11:41:41 +08:00
										 |  |  |     for(size_t value: values_) { | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |       // for all connected domains
 | 
					
						
							| 
									
										
										
										
											2016-05-21 11:41:41 +08:00
										 |  |  |       for(Key k: keys) | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |         // if any domain contains the value we cannot make this domain singleton
 | 
					
						
							|  |  |  |         if (k!=j && domains[k].contains(value)) | 
					
						
							|  |  |  |           goto found; | 
					
						
							|  |  |  |       values_.clear(); | 
					
						
							|  |  |  |       values_.insert(value); | 
					
						
							|  |  |  |       return true; // we changed it
 | 
					
						
							|  |  |  |       found:; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; // we did not change it
 | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   Constraint::shared_ptr Domain::partiallyApply( | 
					
						
							|  |  |  |       const Values& values) const { | 
					
						
							|  |  |  |     Values::const_iterator it = values.find(keys_[0]); | 
					
						
							|  |  |  |     if (it != values.end() && !contains(it->second)) throw runtime_error( | 
					
						
							|  |  |  |         "Domain::partiallyApply: unsatisfiable"); | 
					
						
							|  |  |  |     return boost::make_shared < Domain > (*this); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   Constraint::shared_ptr Domain::partiallyApply( | 
					
						
							|  |  |  |       const vector<Domain>& domains) const { | 
					
						
							|  |  |  |     const Domain& Dk = domains[keys_[0]]; | 
					
						
							|  |  |  |     if (Dk.isSingleton() && !contains(*Dk.begin())) throw runtime_error( | 
					
						
							|  |  |  |         "Domain::partiallyApply: unsatisfiable"); | 
					
						
							|  |  |  |     return boost::make_shared < Domain > (Dk); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | } // namespace gtsam
 |