82 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			82 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C++
		
	
	
| /* ----------------------------------------------------------------------------
 | |
| 
 | |
|  * 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
 | |
| 
 | |
|  * -------------------------------------------------------------------------- */
 | |
| 
 | |
| /**
 | |
|  * @file     LPSolver.h
 | |
|  * @brief    Policy of ActiveSetSolver to solve Linear Programming Problems
 | |
|  * @author   Duy Nguyen Ta
 | |
|  * @author   Ivan Dario Jimenez
 | |
|  * @date     6/16/16
 | |
|  */
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include <gtsam_unstable/linear/LP.h>
 | |
| #include <gtsam_unstable/linear/ActiveSetSolver.h>
 | |
| #include <gtsam_unstable/linear/LPInitSolver.h>
 | |
| 
 | |
| #include <limits>
 | |
| #include <algorithm>
 | |
| 
 | |
| namespace gtsam {
 | |
| 
 | |
| /// Policy for ActivetSetSolver to solve Linear Programming \sa LP problems
 | |
| struct LPPolicy {
 | |
|   /// Maximum alpha for line search x'=xk + alpha*p, where p is the cost gradient
 | |
|   /// For LP, maxAlpha = Infinity
 | |
|   static constexpr double maxAlpha = std::numeric_limits<double>::infinity();
 | |
| 
 | |
|   /**
 | |
|    * 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
 | |
|    */
 | |
|   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
 | |
|       graph.emplace_shared<JacobianFactor>(*it, Matrix::Identity(dim, dim), b);
 | |
|     }
 | |
| 
 | |
|     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
 | |
|     // the cost function. Gradients of the cost function wrt to these variables
 | |
|     // 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);
 | |
|         graph.emplace_shared<JacobianFactor>(k, Matrix::Identity(dim, dim), xk.at(k));
 | |
|       }
 | |
|     }
 | |
|     return graph;
 | |
|   }
 | |
| };
 | |
| 
 | |
| using LPSolver = ActiveSetSolver<LP, LPPolicy, LPInitSolver>;
 | |
| 
 | |
| }
 |