| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * BinaryAllDiff.h | 
					
						
							|  |  |  |  * @brief Binary "all-different" constraint | 
					
						
							|  |  |  |  * @date Feb 6, 2012 | 
					
						
							|  |  |  |  * @author Frank Dellaert | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 17:51:26 +08:00
										 |  |  | #include <gtsam_unstable/discrete/Domain.h>
 | 
					
						
							|  |  |  | #include <gtsam_unstable/discrete/Constraint.h>
 | 
					
						
							| 
									
										
										
										
											2012-04-16 07:12:17 +08:00
										 |  |  | #include <gtsam/discrete/DecisionTreeFactor.h>
 | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/**
 | 
					
						
							|  |  |  | 	 * Binary AllDiff constraint | 
					
						
							|  |  |  | 	 * Returns 1 if values for two keys are different, 0 otherwise | 
					
						
							|  |  |  | 	 * DiscreteFactors are all awkward in that they have to store two types of keys: | 
					
						
							|  |  |  | 	 * for each variable we have a Index and an Index. In this factor, we | 
					
						
							|  |  |  | 	 * keep the Indices locally, and the Indices are stored in IndexFactor. | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2012-05-15 17:51:26 +08:00
										 |  |  | 	class BinaryAllDiff: public Constraint { | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		size_t cardinality0_, cardinality1_; /// cardinality
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/// Constructor
 | 
					
						
							|  |  |  | 		BinaryAllDiff(const DiscreteKey& key1, const DiscreteKey& key2) : | 
					
						
							| 
									
										
										
										
											2012-05-15 17:51:26 +08:00
										 |  |  | 			Constraint(key1.first, key2.first), | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 				cardinality0_(key1.second), cardinality1_(key2.second) { | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// print
 | 
					
						
							| 
									
										
										
										
											2012-06-30 18:30:06 +08:00
										 |  |  | 		virtual void print(const std::string& s = "", | 
					
						
							|  |  |  | 				const IndexFormatter& formatter = DefaultIndexFormatter) const { | 
					
						
							|  |  |  | 			std::cout << s << "BinaryAllDiff on " << formatter(keys_[0]) << " and " | 
					
						
							|  |  |  | 					<< formatter(keys_[1]) << std::endl; | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/// Calculate value
 | 
					
						
							|  |  |  | 		virtual double operator()(const Values& values) const { | 
					
						
							|  |  |  | 			return (double) (values.at(keys_[0]) != values.at(keys_[1])); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/// Convert into a decisiontree
 | 
					
						
							| 
									
										
										
										
											2012-06-23 05:45:36 +08:00
										 |  |  | 		virtual DecisionTreeFactor toDecisionTreeFactor() const { | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 			DiscreteKeys keys; | 
					
						
							|  |  |  | 			keys.push_back(DiscreteKey(keys_[0],cardinality0_)); | 
					
						
							|  |  |  | 			keys.push_back(DiscreteKey(keys_[1],cardinality1_)); | 
					
						
							|  |  |  | 			std::vector<double> table; | 
					
						
							|  |  |  | 			for (size_t i1 = 0; i1 < cardinality0_; i1++) | 
					
						
							|  |  |  | 				for (size_t i2 = 0; i2 < cardinality1_; i2++) | 
					
						
							|  |  |  | 					table.push_back(i1 != i2); | 
					
						
							|  |  |  | 			DecisionTreeFactor converted(keys, table); | 
					
						
							|  |  |  | 			return converted; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/// Multiply into a decisiontree
 | 
					
						
							|  |  |  | 		virtual DecisionTreeFactor operator*(const DecisionTreeFactor& f) const { | 
					
						
							|  |  |  | 			// TODO: can we do this more efficiently?
 | 
					
						
							| 
									
										
										
										
											2012-06-23 05:45:36 +08:00
										 |  |  | 			return toDecisionTreeFactor() * f; | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/*
 | 
					
						
							|  |  |  | 		 * Ensure Arc-consistency | 
					
						
							|  |  |  | 		 * @param j domain to be checked | 
					
						
							|  |  |  | 		 * @param domains all other domains | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		///
 | 
					
						
							|  |  |  | 		bool ensureArcConsistency(size_t j, std::vector<Domain>& domains) const { | 
					
						
							|  |  |  | //			throw std::runtime_error(
 | 
					
						
							|  |  |  | //					"BinaryAllDiff::ensureArcConsistency not implemented");
 | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/// Partially apply known values
 | 
					
						
							| 
									
										
										
										
											2012-05-15 17:51:26 +08:00
										 |  |  | 		virtual Constraint::shared_ptr partiallyApply(const Values&) const { | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 			throw std::runtime_error("BinaryAllDiff::partiallyApply not implemented"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/// Partially apply known values, domain version
 | 
					
						
							| 
									
										
										
										
											2012-05-15 17:51:26 +08:00
										 |  |  | 		virtual Constraint::shared_ptr partiallyApply( | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 				const std::vector<Domain>&) const { | 
					
						
							|  |  |  | 			throw std::runtime_error("BinaryAllDiff::partiallyApply not implemented"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace gtsam
 |