44 #ifndef ROL_PROGRESSIVEHEDGING_H 45 #define ROL_PROGRESSIVEHEDGING_H 89 const Ptr<OptimizationProblem<Real>>
input_;
111 std::vector<Ptr<Vector<Real>>>
wvec_;
115 for (
int j = 0; j < sampler_->numMySamples(); ++j) {
116 input_->getObjective()->setParameter(sampler_->getMyPoint(j));
117 if (input_->getConstraint() != nullPtr) {
118 input_->getConstraint()->setParameter(sampler_->getMyPoint(j));
121 z_psum_->axpy(sampler_->getMyWeight(j),*input_->getSolutionVector());
126 sampler_->sumAll(*z_psum_,*z_gsum_);
132 ParameterList &parlist)
133 : input_(input), sampler_(sampler), parlist_(parlist), hasStat_(false) {
135 usePresolve_ = parlist.sublist(
"SOL").sublist(
"Progressive Hedging").get(
"Use Presolve",
true);
136 useInexact_ = parlist.sublist(
"SOL").sublist(
"Progressive Hedging").get(
"Use Inexact Solve",
true);
137 penaltyParam_ = parlist.sublist(
"SOL").sublist(
"Progressive Hedging").get(
"Initial Penalty Parameter",10.0);
138 maxPen_ = parlist.sublist(
"SOL").sublist(
"Progressive Hedging").get(
"Maximum Penalty Parameter",-1.0);
139 update_ = parlist.sublist(
"SOL").sublist(
"Progressive Hedging").get(
"Penalty Update Scale",10.0);
140 freq_ = parlist.sublist(
"SOL").sublist(
"Progressive Hedging").get(
"Penalty Update Frequency",0);
141 ztol_ = parlist.sublist(
"SOL").sublist(
"Progressive Hedging").get(
"Nonanticipativity Constraint Tolerance",1e-4);
142 maxit_ = parlist.sublist(
"SOL").sublist(
"Progressive Hedging").get(
"Iteration Limit",100);
143 print_ = parlist.sublist(
"SOL").sublist(
"Progressive Hedging").get(
"Print Subproblem Solve History",
false);
144 maxPen_ = (maxPen_ <= static_cast<Real>(0) ? ROL_INF<Real>() :
maxPen_);
145 penaltyParam_ = std::min(penaltyParam_,maxPen_);
147 std::string type = parlist.sublist(
"SOL").get(
"Stochastic Component Type",
"Risk Neutral");
148 std::string prob = parlist.sublist(
"SOL").sublist(
"Probability").get(
"Name",
"bPOE");
149 hasStat_ = ((type==
"Risk Averse") ||
150 (type==
"Deviation") ||
151 (type==
"Probability" && prob==
"bPOE"));
152 Ptr<ParameterList> parlistptr = makePtrFromRef<ParameterList>(parlist);
154 ph_vector_ = makePtr<RiskVector<Real>>(parlistptr,
155 input_->getSolutionVector());
158 ph_vector_ = input_->getSolutionVector();
161 ph_objective_ = makePtr<PH_Objective<Real>>(input_->getObjective(),
167 ph_bound_ = makePtr<RiskBoundConstraint<Real>>(parlistptr,
168 input_->getBoundConstraint());
171 ph_bound_ = input_->getBoundConstraint();
174 ph_constraint_ = nullPtr;
175 if (input_->getConstraint() != nullPtr) {
177 ph_constraint_ = makePtr<RiskLessConstraint<Real>>(input_->getConstraint());
180 ph_constraint_ = input_->getConstraint();
184 ph_problem_ = makePtr<OptimizationProblem<Real>>(
ph_objective_,
188 input_->getMultiplierVector());
190 ph_solver_ = makePtr<OptimizationSolver<Real>>(*
ph_problem_, parlist);
193 ph_status_ = makePtr<PH_StatusTest<Real>>(parlist,
198 ph_status_ = nullPtr;
201 z_psum_ = ph_problem_->getSolutionVector()->clone();
202 z_gsum_ = ph_problem_->getSolutionVector()->clone();
203 z_gsum_->set(*ph_problem_->getSolutionVector());
204 wvec_.resize(sampler_->numMySamples());
205 for (
int i = 0; i < sampler_->numMySamples(); ++i) {
206 wvec_[i] = z_psum_->clone(); wvec_[i]->zero();
213 void check(std::ostream &outStream = std::cout,
const int numSamples = 1) {
214 int nsamp = std::min(sampler_->numMySamples(),numSamples);
215 for (
int i = 0; i < nsamp; ++i) {
216 ph_objective_->setParameter(sampler_->getMyPoint(i));
217 ph_objective_->setData(z_gsum_,wvec_[i],penaltyParam_);
218 if (ph_constraint_ != nullPtr) {
219 ph_constraint_->setParameter(sampler_->getMyPoint(i));
221 ph_problem_->check(outStream);
225 void run(std::ostream &outStream = std::cout) {
227 std::vector<Real> vec_p(2), vec_g(2);
228 Real znorm(ROL_INF<Real>()), zdotz(0);
229 int iter(0), tspiter(0), flag = 1;
230 bool converged =
true;
232 outStream << std::scientific << std::setprecision(6);
233 outStream << std::endl <<
"Progressive Hedging" 235 << std::setw(8) << std::left <<
"iter" 236 << std::setw(15) << std::left <<
"||z-Ez||" 237 << std::setw(15) << std::left <<
"penalty" 238 << std::setw(10) << std::left <<
"subiter" 239 << std::setw(8) << std::left <<
"success" 241 for (iter = 0; iter <
maxit_; ++iter) {
242 z_psum_->zero(); vec_p[0] =
zero; vec_p[1] =
zero;
243 ph_problem_->getSolutionVector()->
set(*z_gsum_);
245 for (
int j = 0; j < sampler_->numMySamples(); ++j) {
246 ph_objective_->setData(z_gsum_,wvec_[j],penaltyParam_);
247 ph_problem_->getObjective()->setParameter(sampler_->getMyPoint(j));
249 ph_status_->setData(iter,z_gsum_);
251 if (ph_problem_->getConstraint() != nullPtr) {
252 ph_problem_->getConstraint()->setParameter(sampler_->getMyPoint(j));
255 ph_solver_->solve(outStream,ph_status_,
true);
258 ph_solver_->solve(ph_status_,
true);
260 wvec_[j]->axpy(penaltyParam_,*ph_problem_->getSolutionVector());
261 vec_p[0] += sampler_->getMyWeight(j)
262 * ph_problem_->getSolutionVector()->dot(
263 *ph_problem_->getSolutionVector());
264 vec_p[1] +=
static_cast<Real
>(ph_solver_->getAlgorithmState()->iter);
265 z_psum_->axpy(sampler_->getMyWeight(j),*ph_problem_->getSolutionVector());
268 ? converged :
false);
272 z_gsum_->zero(); vec_g[0] =
zero; vec_g[1] =
zero;
273 sampler_->sumAll(*z_psum_,*z_gsum_);
274 sampler_->sumAll(&vec_p[0],&vec_g[0],2);
276 for (
int j = 0; j < sampler_->numMySamples(); ++j) {
277 wvec_[j]->
axpy(-penaltyParam_,*z_gsum_);
279 zdotz = z_gsum_->dot(*z_gsum_);
280 znorm = std::sqrt(std::abs(vec_g[0] - zdotz));
281 tspiter +=
static_cast<int>(vec_g[1]);
284 << std::setw(8) << std::left << iter
285 << std::setw(15) << std::left << znorm
286 << std::setw(15) << std::left << penaltyParam_
287 << std::setw(10) << std::left << static_cast<int>(vec_g[1])
288 << std::setw(8) << std::left << converged
291 if (znorm <= ztol_ && converged) {
293 outStream <<
"Converged: Nonanticipativity constraint tolerance satisfied!" << std::endl;
298 if (freq_ > 0 && iter%freq_ == 0) {
301 penaltyParam_ = std::min(penaltyParam_,maxPen_);
304 input_->getSolutionVector()->set(*dynamicPtrCast<
RiskVector<Real>>(z_gsum_)->getVector());
307 input_->getSolutionVector()->set(*z_gsum_);
310 if (iter >= maxit_ && flag != 0) {
311 outStream <<
"Maximum number of iterations exceeded" << std::endl;
313 outStream <<
"Total number of subproblem iterations per sample: " 314 << tspiter <<
" / " << sampler_->numGlobalSamples()
315 <<
" ~ " <<
static_cast<int>(std::ceil(static_cast<Real>(tspiter)/static_cast<Real>(sampler_->numGlobalSamples())))
ProgressiveHedging(const Ptr< OptimizationProblem< Real >> &input, const Ptr< SampleGenerator< Real >> &sampler, ParameterList &parlist)
Ptr< BoundConstraint< Real > > ph_bound_
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
Ptr< Vector< Real > > ph_vector_
Ptr< Vector< Real > > z_psum_
Provides the interface to solve a stochastic program using progressive hedging.
void check(std::ostream &outStream=std::cout, const int numSamples=1)
Ptr< OptimizationProblem< Real > > ph_problem_
Ptr< Constraint< Real > > ph_constraint_
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0_ zero()
Ptr< PH_StatusTest< Real > > ph_status_
const Ptr< SampleGenerator< Real > > sampler_
Ptr< OptimizationSolver< Real > > ph_solver_
void reset(const bool resetAlgo=true)
Reset both Algorithm and Step.
std::vector< Ptr< Vector< Real > > > wvec_
Provides a simplified interface for solving a wide range of optimization problems.
Ptr< Vector< Real > > z_gsum_
virtual void set(const Vector &x)
Set where .
int solve(const ROL::Ptr< StatusTest< Real > > &status=ROL::nullPtr, const bool combineStatus=true)
Solve optimization problem with no iteration output.
const Ptr< OptimizationProblem< Real > > input_
void run(std::ostream &outStream=std::cout)
Ptr< PH_Objective< Real > > ph_objective_