std::vector<Plane_3> correctPlanes(const std::vector<Plane_3> &planes, const std::vector<EdgeInfo> &data) { bool doEdgeScaling = (getenv("DISABLE_EDGE_SCALING") == nullptr); EdgeCorrector *EC = new EdgeCorrector(doEdgeScaling, planes, data); Ipopt::IpoptApplication *app = IpoptApplicationFactory(); /* Intialize the IpoptApplication and process the options */ if (app->Initialize() != Ipopt::Solve_Succeeded) { MAIN_PRINT("*** Error during initialization!"); exit(EXIT_FAILURE); } setParameters(app->Options()); /* Ask Ipopt to solve the problem */ auto status = app->OptimizeTNLP(EC); if (status != Ipopt::Solve_Succeeded && status != Ipopt::Solved_To_Acceptable_Level) { MAIN_PRINT("** The problem FAILED!"); exit(EXIT_FAILURE); } MAIN_PRINT("*** The problem solved!"); return EC->getResultingPlanes(); }
bool IASolverRelaxed::solve() { // solve the nlp to get a non-integral solution, which we hope is close to a good integer solution // adapted from HS071 ipopt example // p_norm set in constructor. 3 seems to work well, comes close to lex-max-min // smaller p has the effect of valuing the fidelity of shorter curves over longer curves more // larger p approaches min max IANlp *myianlp = new IANlp(iaData, iaSolution, silent); Ipopt::SmartPtr<TNLP> mynlp = myianlp; // Ipopt requires the use of smartptrs! Ipopt::SmartPtr<Ipopt::IpoptApplication> app = IpoptApplicationFactory(); app->Options()->SetNumericValue("tol", 1e-7); // 2 seems close enough, could do less, say .1 app->Options()->SetStringValue("mu_strategy", "adaptive"); // print level 0 to 12, most. Ipopt Default is 5 int print_level = (silent) ? 0 : 1; // 1, 5 // int print_level = 5; app->Options()->SetIntegerValue("print_level", print_level); // uncomment next line to write the solution to an output file // app->Options()->SetStringValue("output_file", "IA.out"); // The following overwrites the default name (ipopt.opt) of the options file // app->Options()->SetStringValue("option_file_name", "IA.opt"); // Intialize the IpoptApplication and process the options Ipopt::ApplicationReturnStatus status; status = app->Initialize(); if (status != Ipopt::Solve_Succeeded) { if (!silent) printf("\n\n*** Error during ipopt initialization!\n"); return (int) status; } // Ask Ipopt to solve the problem status = app->OptimizeTNLP(mynlp); // the inherited IANlp // todo: also check for a valid solution even if ! Solve_Succeeded, such as a sub-optimal time-out bool is_solved = (status == Ipopt::Solve_Succeeded); bool is_satisfied = is_solved && equal_constraints( false, debugging ); // don't check even-ness, as those are like the integrality constraints and are not solved here if (!silent) { if (is_solved) { printf("\n\n*** The relaxed problem solved!"); if (!is_satisfied) printf(" But equality-constraints were VIOLATED!"); printf("\n"); } else { printf("\n\n*** The relaxed problem FAILED!\n"); } } return is_satisfied; }
//============================================================================== IpoptSolver::IpoptSolver(std::shared_ptr<Problem> _problem) : Solver(_problem) { assert(_problem); // Create a new instance of nlp (use a SmartPtr, not raw) mNlp = new DartTNLP(this); // Create a new instance of IpoptApplication (use a SmartPtr, not raw). We are // using the factory, since this allows us to compile this with an Ipopt // Windows DLL. mIpoptApp = IpoptApplicationFactory(); mIpoptApp->Options()->SetStringValue("mu_strategy", "adaptive"); mIpoptApp->Options()->SetStringValue("hessian_approximation", "limited-memory"); }
//============================================================================== IpoptSolver::IpoptSolver(const Solver::Properties& _properties) : Solver(_properties) { mNlp = new DartTNLP(this); mIpoptApp = IpoptApplicationFactory(); }
Polyhedron_3 EdgeCorrector::run() { DEBUG_START; std::map<int, int> halfedgesMap; std::vector<SimpleEdge_3> edges = getEdges(initialP, halfedgesMap); associateEdges(edges, SData); printAssociatedEdges(initialP, edges, halfedgesMap); std::vector<SimpleEdge_3> mainEdges = extractEdges(edges); std::cout << "Number of extracted edges: " << mainEdges.size() << std::endl; if (mainEdges.size() == 0) { DEBUG_END; return initialP; } printColouredExtractedPolyhedron(initialP, mainEdges); std::vector<Vector_3> u, U, points; std::vector<double> h, H; std::map<int, int> map; FixedTopology *FT = buildTopology(initialP, mainEdges, u, U, points, h, H, map); IpoptTopologicalCorrector *FTNLP = new IpoptTopologicalCorrector( u, h, U, H, points, FT); FTNLP->enableModeZfixed(); IpoptApplication *app = IpoptApplicationFactory(); /* Intialize the IpoptApplication and process the options */ if (app->Initialize() != Solve_Succeeded) { MAIN_PRINT("*** Error during initialization!"); return initialP; } app->Options()->SetStringValue("linear_solver", "ma57"); if (getenv("DERIVATIVE_TEST_FIRST")) app->Options()->SetStringValue("derivative_test", "first-order"); else if (getenv("DERIVATIVE_TEST_SECOND")) app->Options()->SetStringValue("derivative_test", "second-order"); else if (getenv("DERIVATIVE_TEST_ONLY_SECOND")) app->Options()->SetStringValue("derivative_test", "only-second-order"); if (getenv("HESSIAN_APPROX")) app->Options()->SetStringValue("hessian_approximation", "limited-memory"); /* Ask Ipopt to solve the problem */ auto status = app->OptimizeTNLP(FTNLP); if (status != Solve_Succeeded && status != Solved_To_Acceptable_Level) { MAIN_PRINT("** The problem FAILED!"); DEBUG_END; return initialP; } MAIN_PRINT("*** The problem solved!"); globalPCLDumper(PCL_DUMPER_LEVEL_DEBUG, "INSIDE_FT_NLP-initial.ply") << initialP; Polyhedron_3 correctedP = obtainPolyhedron(initialP, map, FTNLP); globalPCLDumper(PCL_DUMPER_LEVEL_DEBUG, "INSIDE_FT_NLP-from-planes.ply") << correctedP; delete FTNLP; DEBUG_END; return correctedP; }
bool IASolverInt::solve_wave_workhorse(IAIntWaveNlp *mynlp) { if (debugging) { printf("IASolverInt::solve_wave() - "); printf("Attempting to enforce an integer and even solution to the relaxed NLP by adding constraints that repeat wave-like at each integer lattice point.\n"); } // solver setup Ipopt::SmartPtr<Ipopt::IpoptApplication> app = IpoptApplicationFactory(); /* try leaving defaults // convergence parameters // see $IPOPTDIR/Ipopt/src/Interfaces/IpIpoptApplication.cpp // our real criteria are: all integer, constraints satisfied. How to test the "all_integer" part? app->Options()->SetNumericValue("tol", 1e-6); //"converged" if NLP error<this, default is 1e-7. Obj are scaled to be >1, so e-2 is plenty // was 1e-2 app->Options()->SetNumericValue("max_cpu_time", sqrt( iaData->num_variables() ) ); // max time allowed in seconds app->Options()->SetIntegerValue("max_iter", 3 * (10 + iaData->num_variables() ) ); // max number of iterations // app->Options()->SetNumericValue("primal_inf_tol", 1e-2 ); app->Options()->SetNumericValue("dual_inf_tol", 1e-2 ); // how close to infeasibility? // was 1e-2 app->Options()->SetNumericValue("constr_viol_tol", 1e-2 ); // by how much can constraints be violated? app->Options()->SetNumericValue("compl_inf_tol", 1e-6 ); // max norm of complementary condition // was 1e-2 // second criteria convergence parameters: quit if within this tol for many iterations // was app->Options()->SetIntegerValue("acceptable_iter", 4 + sqrt( iaData->num_variables() ) ); //as "tol" app->Options()->SetNumericValue("acceptable_tol", 1e-6 ); //as "tol" was 1e-1 app->Options()->SetStringValue("mu_strategy", "adaptive"); // print level 0 to 12, Ipopt default is 5 const int print_level = (silent) ? 0 : 1; // simple info is 1, debug at other values app->Options()->SetIntegerValue("print_level", print_level); // uncomment next line to write the solution to an output file // app->Options()->SetStringValue("output_file", "IA.out"); // The following overwrites the default name (ipopt.opt) of the options file // app->Options()->SetStringValue("option_file_name", "IA.opt"); */ // Intialize the IpoptApplication and process the options Ipopt::ApplicationReturnStatus status; status = app->Initialize(); if (status != Ipopt::Solve_Succeeded) { if (!silent) printf("\n\n*** Error during initialization!\n"); return (int) status; } bool try_again = true; int iter = 0; // print(); bool solution_ok = false; do { if (debugging) { print(); printf("%d IntWave iteration\n", iter ); // build the hessian, evaluate it and f at the current solution? } // Ask Ipopt to solve the problem status = app->OptimizeTNLP(mynlp); // the inherited IANlp // see /CoinIpopt/build/include/coin/IpReturnCodes_inc.h /* Solve_Succeeded=0, Solved_To_Acceptable_Level=1, Infeasible_Problem_Detected=2, Search_Direction_Becomes_Too_Small=3, Diverging_Iterates=4, User_Requested_Stop=5, Feasible_Point_Found=6, Maximum_Iterations_Exceeded=-1, Restoration_Failed=-2, Error_In_Step_Computation=-3, Maximum_CpuTime_Exceeded=-4, Not_Enough_Degrees_Of_Freedom=-10, Invalid_Problem_Definition=-11, Invalid_Option=-12, Invalid_Number_Detected=-13, Unrecoverable_Exception=-100, NonIpopt_Exception_Thrown=-101, Insufficient_Memory=-102, Internal_Error=-199 */ bool solved_full = false; bool solved_partial = false; bool solver_failed = false; bool bad_problem = false; switch (status) { case Ipopt::Solve_Succeeded: case Ipopt::Solved_To_Acceptable_Level: case Ipopt::Feasible_Point_Found: solved_full = true; break; case Ipopt::Maximum_Iterations_Exceeded: case Ipopt::User_Requested_Stop: case Ipopt::Maximum_CpuTime_Exceeded: solved_partial = true; break; case Ipopt::Infeasible_Problem_Detected: case Ipopt::Not_Enough_Degrees_Of_Freedom: case Ipopt::Invalid_Problem_Definition: case Ipopt::Invalid_Option: case Ipopt::Invalid_Number_Detected: bad_problem = true; break; case Ipopt::Search_Direction_Becomes_Too_Small: case Ipopt::Restoration_Failed: case Ipopt::Diverging_Iterates: case Ipopt::Error_In_Step_Computation: case Ipopt::Unrecoverable_Exception: case Ipopt::NonIpopt_Exception_Thrown: case Ipopt::Insufficient_Memory: case Ipopt::Internal_Error: solver_failed = true; break; default: break; } if (!silent) { if (solved_full) { printf("\n\n*** IntWave solved!\n"); } else { printf("\n\n*** IntWave FAILED!\n"); } } if (debugging) { printf("\nChecking solution.\n"); bool integer_sat = solution_is_integer(true); bool even_sat = even_constraints( false, true); bool equal_sat = equal_constraints( false, true ); printf("IntWave solution summary, %s, equal-constraints %s, even-constraints %s.\n", integer_sat ? "integer" : "NON-INTEGER", equal_sat ? "satisfied" : "VIOLATED", even_sat ? "satisfied" : "VIOLATED" ); if (!integer_sat) printf("investigate integer neighborhood\n"); if (!even_sat) printf("investigate even neighborhood\n"); if (!equal_sat) printf("investigate equal neighborhood\n"); } IASolution nlp_solution; nlp_solution.x_solution = ia_solution()->x_solution; // vector copy IASolverToolInt sti( ia_data(), &nlp_solution ); sti.round_solution(); if (debugging) printf("Checking rounded solution, ignoring even constraints.\n"); if (sti.equal_constraints(false, debugging)) { // also even constraints if (debugging) printf("Rounding worked.\n"); // rounding was a valid integer solution ia_solution()->x_solution.swap( nlp_solution.x_solution ); // ia_solution()->obj_value is no longer accurate, as it was for the non-rounded solution return true; } // todo: detect and act // may have converged to a locally optimal, but non-feasible solution // if so, try a new starting point // check solution feasibility, even when not debugging if ( solved_full || solved_partial ) { bool integer_sat = solution_is_integer(false); bool even_sat = even_constraints( false, false); bool equal_sat = equal_constraints( false, false ); if ( integer_sat && even_sat && equal_sat ) return true; } // find out which vars were not integer, // try moving to a farther starting point resolving try_again = false; } while (try_again); // now // As the SmartPtrs go out of scope, the reference count // will be decremented and the objects will automatically // be deleted. return solution_ok; }
bool IASolverInt::solve_round() { // set up and call the separate IARoundingNlp, which has a linear objective to get a natural integer solution // the intuition is this will solve integrality for most variables all at once if (debugging) { printf("IASolverInt::solve_bend_workhorse() - "); } // solver setup Ipopt::SmartPtr<Ipopt::IpoptApplication> app = IpoptApplicationFactory(); // convergence parameters // see $IPOPTDIR/Ipopt/src/Interfaces/IpIpoptApplication.cpp // our real criteria are: all integer, constraints satisfied. How to test the "all_integer" part? app->Options()->SetNumericValue("tol", 1e-6); //"converged" if NLP error<this, default is 1e-7. Obj are scaled to be >1, so e-2 is plenty // was 1e-2 app->Options()->SetNumericValue("max_cpu_time", sqrt( iaData->num_variables() ) ); // max time allowed in seconds app->Options()->SetIntegerValue("max_iter", 3 * iaData->num_variables() ); // max number of iterations // app->Options()->SetNumericValue("primal_inf_tol", 1e-2 ); app->Options()->SetNumericValue("dual_inf_tol", 1e-6 ); // how close to infeasibility? // was 1e-2 app->Options()->SetNumericValue("constr_viol_tol", 1e-6 ); // by how much can constraints be violated? app->Options()->SetNumericValue("compl_inf_tol", 1e-6 ); // max norm of complementary condition // was 1e-2 // second criteria convergence parameters: quit if within this tol for many iterations // was app->Options()->SetIntegerValue("acceptable_iter", 4 + sqrt( iaData->num_variables() ) ); //as "tol" app->Options()->SetNumericValue("acceptable_tol", 1e-6 ); //as "tol" was 1e-1 app->Options()->SetStringValue("mu_strategy", "adaptive"); // print level 0 to 12, Ipopt default is 5 const int print_level = (silent) ? 0 : 1; app->Options()->SetIntegerValue("print_level", print_level); // uncomment next line to write the solution to an output file // app->Options()->SetStringValue("output_file", "IA.out"); // The following overwrites the default name (ipopt.opt) of the options file // app->Options()->SetStringValue("option_file_name", "IA.opt"); // Intialize the IpoptApplication and process the options Ipopt::ApplicationReturnStatus status; status = app->Initialize(); if (status != Ipopt::Solve_Succeeded) { if (!silent) printf("\n\n*** Error during initialization!\n"); return (int) status; } Ipopt::TNLP *tnlp = NULL; IARoundingNlp *myianlp = new IARoundingNlp(iaData, ipData, iaSolution, silent); if (debugging) { printf("ROUNDING problem formulation\n"); printf("Attempting to find a naturally-integer solution by linearizing the objective function.\n"); printf("Variables are constrained within [floor,ceil] of relaxed solution.\n"); } // problem setup // a couple of different models, simplest to more complex // IARoundingFarNlp *myianlp = new IARoundingFarNlp(iaData, ipData, this); // IARoundingFar3StepNlp *myianlp = new IARoundingFar3StepNlp(iaData, ipData, this); // haven't tested this. It compiles and runs but perhaps isn't correct // IAIntWaveNlp *myianlp = new IAIntWaveNlp(iaData, ipData, this); // haven't tested this. It compiles and runs but perhaps isn't correct tnlp = myianlp; Ipopt::SmartPtr<Ipopt::TNLP> mynlp = tnlp; // Ipopt requires the use of smartptrs! bool try_again = true; int iter = 0; do { printf("%d rounding iteration\n", iter ); // Ask Ipopt to solve the problem status = app->OptimizeTNLP(mynlp); // the inherited IANlp if (!silent) { if (status == Ipopt::Solve_Succeeded) { printf("\n\n*** The problem solved!\n"); } else { printf("\n\n*** The problem FAILED!\n"); } } // The problem should have been feasible, but it is possible that it had no integer solution. // figure out which variables are still integer // check solution for integrality and constraint satified if (debugging) { printf("\nChecking Natural (non-rounded) solution.\n"); bool integer_sat = solution_is_integer(true); bool even_sat = even_constraints( false, true); bool equal_sat = equal_constraints( false, true ); printf("Natural solution summary, %s, equal-constraints %s, even-constraints %s.\n", integer_sat ? "integer" : "NON-INTEGER", equal_sat ? "satisfied" : "VIOLATED", even_sat ? "satisfied" : "VIOLATED" ); if (!integer_sat) printf("investigate this\n"); } IASolution nlp_solution; nlp_solution.x_solution = ia_solution()->x_solution; // vector copy IASolverToolInt sti( ia_data(), &nlp_solution ); sti.round_solution(); if (debugging) printf("Checking rounded solution, ignoring even constraints.\n"); if (sti.equal_constraints(false, debugging)) { // also even constraints if (debugging) printf("Rounding worked.\n"); // rounding was a valid integer solution ia_solution()->x_solution.swap( nlp_solution.x_solution ); // ia_solution()->obj_value is no longer accurate, as it was for the non-rounded solution return true; } // find out which vars were not integer, // try rounding their weights and resolving // bool int_sat = solution_is_integer(); ++iter; try_again = iter < 4 + sqrt(iaData->num_variables()); if (try_again) { if (debugging) printf("rounding failed, randomizing weights\n"); myianlp->randomize_weights_of_non_int(); // try again? debug } else if (debugging) printf("giving up on rounding to non-integer solution\n"); // try_again = false; // debug } while (try_again); // todo: update partially-integer solution, perhaps using ipData - figure out how we're going to use it, first, for what structure makes sense. // As the SmartPtrs go out of scope, the reference count // will be decremented and the objects will automatically // be deleted. return status == Ipopt::Solve_Succeeded; }