Non-optimized simplex algorithm.
This version is supposed to work on all problems (please, let me know if this is not so), but is not optimized yet in terms of numerical stability and performance. Bland's rule is implemented as well, so algorithm is supposed to allow no cycling. Additional check for multiple solutions is added (in case of multiple solutions algorithm returns an appropriate return code of 1 and returns arbitrary optimal solution). Finally, now we have 5 tests. Before Thursday we have 4 directions that can be tackled in parallel: *) Prepare the pull request! *) Make the code more clear and readable (refactoring) *) Wrap the core solveLP() procedure in OOP-style interface *) Test solveLP on non-trivial tests (possibly test against http://www.coin-or.org/Clp/)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#include "test_precomp.hpp"
|
||||
#include "opencv2/optim.hpp"
|
||||
|
||||
TEST(Optim_LpSolver, regression)
|
||||
TEST(Optim_LpSolver, regression_basic)
|
||||
{
|
||||
cv::Mat A,B,z,etalon_z;
|
||||
|
||||
@@ -36,26 +36,99 @@ TEST(Optim_LpSolver, regression)
|
||||
std::cout<<"here z goes\n"<<z<<"\n";
|
||||
etalon_z=(cv::Mat_<double>(1,2)<<1,0);
|
||||
ASSERT_EQ(cv::countNonZero(z!=etalon_z),0);
|
||||
|
||||
}
|
||||
if(false){
|
||||
}
|
||||
|
||||
TEST(Optim_LpSolver, regression_init_unfeasible){
|
||||
cv::Mat A,B,z,etalon_z;
|
||||
|
||||
if(true){
|
||||
//cormen's example #4 - unfeasible
|
||||
A=(cv::Mat_<double>(1,3)<<-1,-1,-1);
|
||||
B=(cv::Mat_<double>(2,4)<<-2,-7.5,-3,-10000,-20,-5,-10,-30000);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
cv::optim::solveLP(A,B,z);
|
||||
std::cout<<"here z goes\n"<<z<<"\n";
|
||||
etalon_z=(cv::Mat_<double>(1,2)<<1,0);
|
||||
etalon_z=(cv::Mat_<double>(1,3)<<1250,1000,0);
|
||||
ASSERT_EQ(cv::countNonZero(z!=etalon_z),0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Optim_LpSolver, regression_absolutely_unfeasible){
|
||||
cv::Mat A,B,z,etalon_z;
|
||||
|
||||
if(true){
|
||||
//trivial absolutely unfeasible example
|
||||
A=(cv::Mat_<double>(1,1)<<1);
|
||||
B=(cv::Mat_<double>(2,2)<<1,-1);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
int res=cv::optim::solveLP(A,B,z);
|
||||
ASSERT_EQ(res,-1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Optim_LpSolver, regression_multiple_solutions){
|
||||
cv::Mat A,B,z,etalon_z;
|
||||
|
||||
if(true){
|
||||
//trivial example with multiple solutions
|
||||
A=(cv::Mat_<double>(1,2)<<1,1);
|
||||
B=(cv::Mat_<double>(1,3)<<1,1,1);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
int res=cv::optim::solveLP(A,B,z);
|
||||
printf("res=%d\n",res);
|
||||
printf("scalar %g\n",z.dot(A));
|
||||
std::cout<<"here z goes\n"<<z<<"\n";
|
||||
ASSERT_EQ(res,1);
|
||||
ASSERT_EQ(z.dot(A),1);
|
||||
}
|
||||
|
||||
if(false){
|
||||
//cormen's example from chapter about initialize_simplex
|
||||
//online solver told it has inf many solutions, but I'm not sure
|
||||
A=(cv::Mat_<double>(1,2)<<2,-1);
|
||||
B=(cv::Mat_<double>(2,3)<<2,-1,2,1,-5,-4);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
int res=cv::optim::solveLP(A,B,z);
|
||||
printf("res=%d\n",res);
|
||||
printf("scalar %g\n",z.dot(A));
|
||||
std::cout<<"here z goes\n"<<z<<"\n";
|
||||
ASSERT_EQ(res,1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Optim_LpSolver, regression_cycling){
|
||||
cv::Mat A,B,z,etalon_z;
|
||||
|
||||
if(true){
|
||||
//example with cycling from http://people.orie.cornell.edu/miketodd/or630/SimplexCyclingExample.pdf
|
||||
A=(cv::Mat_<double>(1,4)<<10,-57,-9,-24);
|
||||
B=(cv::Mat_<double>(3,5)<<0.5,-5.5,-2.5,9,0,0.5,-1.5,-0.5,1,0,1,0,0,0,1);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
int res=cv::optim::solveLP(A,B,z);
|
||||
printf("res=%d\n",res);
|
||||
printf("scalar %g\n",z.dot(A));
|
||||
std::cout<<"here z goes\n"<<z<<"\n";
|
||||
ASSERT_EQ(z.dot(A),1);
|
||||
//ASSERT_EQ(res,1);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO
|
||||
// get optimal solution from initial (0,0,...,0) - DONE
|
||||
// milestone: pass first test (wo initial solution) - DONE
|
||||
// learn how to get initial solution
|
||||
// Blands_rule
|
||||
// 1_more_test & make_more_clear
|
||||
// -> **contact_Vadim**: min_l2_norm, init_optional_fsbl_check, error_codes, comment_style-too_many?, copyTo temp headers
|
||||
//
|
||||
// ??how_check_multiple_solutions & pass_test - DONE
|
||||
// Blands_rule - DONE
|
||||
// (&1tests on cycling)
|
||||
//
|
||||
// make_more_clear (assert, assign)
|
||||
// wrap in OOP
|
||||
//
|
||||
// non-trivial tests
|
||||
// pull-request
|
||||
//
|
||||
// study hill and other algos
|
||||
//
|
||||
// ??how to get smallest l2 norm
|
||||
// FUTURE: compress&debug-> more_tests(Cormen) -> readNumRecipes-> fast&stable || hill_climbing
|
||||
|
Reference in New Issue
Block a user