/** * Will return the average across the entire population of the convergence metric * * @param[in] pop population to be assigned a pareto distance * * @see problem::base_unc_mo::p_distance virtual method. */ double base_unc_mo::p_distance(const pagmo::population &pop) const { double c = 0.0; for (population::size_type i = 0; i < pop.size(); ++i) { c += convergence_metric(pop.get_individual(i).cur_x); } return c / pop.size(); }
//============================================================================== Population PagmoTypes::convertPopulation( const ::pagmo::population& pagmoPop, std::shared_ptr<MultiObjectiveProblem> problem) { Population pop(problem, pagmoPop.size()); const auto& pagmoX = pagmoPop.get_x(); const auto& pagmoF = pagmoPop.get_f(); for (std::size_t i = 0u; i < pagmoPop.size(); ++i) { const Eigen::VectorXd x = convertVector(pagmoX[i]); const Eigen::VectorXd f = convertVector(pagmoF[i]); pop.set(i, x, f); } return pop; }
/** * Run the WORHP algorithm. * * @param[in,out] pop input/output pagmo::population to be evolved. */ void worhp::evolve(pagmo::population& pop) const { if (pop.size() == 0) { return; } const auto& prob = pop.problem(); if (prob.get_i_dimension() != 0) { pagmo_throw(value_error, "The problem has an integer part and WORHP is not suitable to solve it."); } if (prob.get_f_dimension() != 1) { pagmo_throw(value_error, "The problem is not single objective and WORHP is not suitable to solve it"); } // We check the screen output again as the user may have changed it if (m_screen_output) { SetWorhpPrint(default_output); } else { SetWorhpPrint(no_screen_output); } OptVar opt; Control control; Params params; Workspace workspace; opt.initialised = false; control.initialised = false; params.initialised = false; workspace.initialised = false; opt.n = prob.get_dimension(); // number of variables opt.m = prob.get_c_dimension(); // number of constraints auto n_eq = prob.get_c_dimension() - prob.get_ic_dimension(); // number of equality constraints // specify nonzeros of derivative matrixes workspace.DF.nnz = opt.n; // dense workspace.DG.nnz = opt.n * opt.m; // dense workspace.HM.nnz = opt.n; WorhpInit(&opt, &workspace, ¶ms, &control); assert(control.status == FirstCall); params = m_params; // Specify a derivative free case params.UserDF = false; params.UserDG = false; params.UserHM = false; params.initialised = true; // Initialization of variables const auto best_idx = pop.get_best_idx(); pagmo::decision_vector x = pop.get_individual(best_idx).cur_x; for (int i = 0; i < opt.n; ++i) { opt.X[i] = x[i]; opt.Lambda[i] = 0; opt.XL[i] = prob.get_lb()[i]; opt.XU[i] = prob.get_ub()[i]; } // Equality constraints for (auto i = 0u; i < n_eq; ++i) { opt.Mu[i] = 0; opt.GL[i] = 0; opt.GU[i] = 0; } // Inequality constraints for (auto i = n_eq; i < unsigned(opt.m); ++i) { opt.Mu[i] = 0; opt.GL[i] = -params.Infty; opt.GU[i] = 0; } // Define HM as a diagonal LT-CS-matrix, but only if needed by WORHP // Not sure if this is needed at all if (workspace.HM.NeedStructure) { for(int i = 0; i < workspace.HM.nnz; ++i) { workspace.HM.row[i] = i + 1; workspace.HM.col[i] = i + 1; } } while (control.status < TerminateSuccess && control.status > TerminateError) { if (GetUserAction(&control, callWorhp)) { Worhp(&opt, &workspace, ¶ms, &control); } if (GetUserAction(&control, iterOutput)) { IterationOutput(&opt, &workspace, ¶ms, &control); DoneUserAction(&control, iterOutput); } if (GetUserAction(&control, evalF)) { for (int i = 0; i < opt.n; ++i) { x[i] = opt.X[i]; } auto f = prob.objfun(x); opt.F = workspace.ScaleObj * f[0]; DoneUserAction(&control, evalF); } if (GetUserAction(&control, evalG)) { for (int i = 0; i < opt.n; ++i) { x[i] = opt.X[i]; } auto g = prob.compute_constraints(x); for (int i = 0; i < opt.m; ++i) { opt.G[i] = g[i]; } DoneUserAction(&control, evalG); } if (GetUserAction(&control, fidif)) { WorhpFidif(&opt, &workspace, ¶ms, &control); } } for (int i = 0; i < opt.n; ++i) { x[i] = opt.X[i]; } pop.set_x(best_idx, x); StatusMsg(&opt, &workspace, ¶ms, &control); WorhpFree(&opt, &workspace, ¶ms, &control); }