| 
									
										
										
										
											2016-06-17 06:22:02 +08:00
										 |  |  | /* ----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * GTSAM Copyright 2010, Georgia Tech Research Corporation, | 
					
						
							|  |  |  |  * Atlanta, Georgia 30332-0415 | 
					
						
							|  |  |  |  * All Rights Reserved | 
					
						
							|  |  |  |  * Authors: Frank Dellaert, et al. (see THANKS for the full author list) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * See LICENSE for the license information | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * -------------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-25 08:58:42 +08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * @file     LPSolver.h | 
					
						
							| 
									
										
										
										
											2016-06-17 11:49:14 +08:00
										 |  |  |  * @brief    Policy of ActiveSetSolver to solve Linear Programming Problems | 
					
						
							| 
									
										
										
										
											2016-01-30 01:07:14 +08:00
										 |  |  |  * @author   Duy Nguyen Ta | 
					
						
							| 
									
										
										
										
											2016-02-12 13:57:37 +08:00
										 |  |  |  * @author   Ivan Dario Jimenez | 
					
						
							| 
									
										
										
										
											2016-06-17 11:49:14 +08:00
										 |  |  |  * @date     6/16/16 | 
					
						
							| 
									
										
										
										
											2016-01-25 08:58:42 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-25 09:08:14 +08:00
										 |  |  | #include <gtsam_unstable/linear/LP.h>
 | 
					
						
							| 
									
										
										
										
											2016-01-26 08:24:37 +08:00
										 |  |  | #include <gtsam_unstable/linear/ActiveSetSolver.h>
 | 
					
						
							| 
									
										
										
										
											2016-06-17 11:49:14 +08:00
										 |  |  | #include <gtsam_unstable/linear/LPInitSolver.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <limits>
 | 
					
						
							|  |  |  | #include <algorithm>
 | 
					
						
							| 
									
										
										
										
											2016-01-25 09:08:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-25 08:58:42 +08:00
										 |  |  | namespace gtsam { | 
					
						
							| 
									
										
										
										
											2016-01-26 22:34:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-17 11:49:14 +08:00
										 |  |  | /// Policy for ActivetSetSolver to solve Linear Programming \sa LP problems
 | 
					
						
							|  |  |  | struct LPPolicy { | 
					
						
							| 
									
										
										
										
											2016-06-17 18:54:18 +08:00
										 |  |  |   /// Maximum alpha for line search x'=xk + alpha*p, where p is the cost gradient
 | 
					
						
							|  |  |  |   /// For LP, maxAlpha = Infinity
 | 
					
						
							| 
									
										
										
										
											2016-06-17 11:49:14 +08:00
										 |  |  |   static constexpr double maxAlpha = std::numeric_limits<double>::infinity(); | 
					
						
							| 
									
										
										
										
											2016-01-25 08:58:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Create the factor ||x-xk - (-g)||^2 where xk is the current feasible solution | 
					
						
							|  |  |  |    * on the constraint surface and g is the gradient of the linear cost, | 
					
						
							|  |  |  |    * i.e. -g is the direction we wish to follow to decrease the cost. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * Essentially, we try to match the direction d = x-xk with -g as much as possible | 
					
						
							|  |  |  |    * subject to the condition that x needs to be on the constraint surface, i.e., d is | 
					
						
							|  |  |  |    * along the surface's subspace. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * The least-square solution of this quadratic subject to a set of linear constraints | 
					
						
							|  |  |  |    * is the projection of the gradient onto the constraints' subspace | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2016-06-17 11:49:14 +08:00
										 |  |  |   static GaussianFactorGraph buildCostFunction(const LP& lp, | 
					
						
							|  |  |  |                                                const VectorValues& xk) { | 
					
						
							|  |  |  |     GaussianFactorGraph graph; | 
					
						
							|  |  |  |     for (LinearCost::const_iterator it = lp.cost.begin(); it != lp.cost.end(); | 
					
						
							|  |  |  |          ++it) { | 
					
						
							|  |  |  |       size_t dim = lp.cost.getDim(it); | 
					
						
							|  |  |  |       Vector b = xk.at(*it) - lp.cost.getA(it).transpose();  // b = xk-g
 | 
					
						
							| 
									
										
										
										
											2016-10-01 23:17:41 +08:00
										 |  |  |       graph.emplace_shared<JacobianFactor>(*it, Matrix::Identity(dim, dim), b); | 
					
						
							| 
									
										
										
										
											2016-06-17 11:49:14 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     KeySet allKeys = lp.inequalities.keys(); | 
					
						
							|  |  |  |     allKeys.merge(lp.equalities.keys()); | 
					
						
							|  |  |  |     allKeys.merge(KeySet(lp.cost.keys())); | 
					
						
							|  |  |  |     // Add corresponding factors for all variables that are not explicitly in
 | 
					
						
							| 
									
										
										
										
											2019-02-11 22:39:48 +08:00
										 |  |  |     // the cost function. Gradients of the cost function wrt to these variables
 | 
					
						
							| 
									
										
										
										
											2016-06-17 11:49:14 +08:00
										 |  |  |     // are zero (g=0), so b=xk
 | 
					
						
							|  |  |  |     if (lp.cost.keys().size() != allKeys.size()) { | 
					
						
							|  |  |  |       KeySet difference; | 
					
						
							|  |  |  |       std::set_difference(allKeys.begin(), allKeys.end(), lp.cost.begin(), | 
					
						
							|  |  |  |                           lp.cost.end(), | 
					
						
							|  |  |  |                           std::inserter(difference, difference.end())); | 
					
						
							|  |  |  |       for (Key k : difference) { | 
					
						
							|  |  |  |         size_t dim = lp.constrainedKeyDimMap().at(k); | 
					
						
							| 
									
										
										
										
											2016-10-01 23:17:41 +08:00
										 |  |  |         graph.emplace_shared<JacobianFactor>(k, Matrix::Identity(dim, dim), xk.at(k)); | 
					
						
							| 
									
										
										
										
											2016-06-17 11:49:14 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return graph; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2016-01-25 08:58:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-17 11:49:14 +08:00
										 |  |  | using LPSolver = ActiveSetSolver<LP, LPPolicy, LPInitSolver>; | 
					
						
							| 
									
										
										
										
											2016-01-25 08:58:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-01 23:17:41 +08:00
										 |  |  | } |