1 // @HEADER 2 // ************************************************************************ 3 // 4 // Rapid Optimization Library (ROL) Package 5 // Copyright (2014) Sandia Corporation 6 // 7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 8 // license for use of this work by or on behalf of the U.S. Government. 9 // 10 // Redistribution and use in source and binary forms, with or without 11 // modification, are permitted provided that the following conditions are 12 // met: 13 // 14 // 1. Redistributions of source code must retain the above copyright 15 // notice, this list of conditions and the following disclaimer. 16 // 17 // 2. Redistributions in binary form must reproduce the above copyright 18 // notice, this list of conditions and the following disclaimer in the 19 // documentation and/or other materials provided with the distribution. 20 // 21 // 3. Neither the name of the Corporation nor the names of the 22 // contributors may be used to endorse or promote products derived from 23 // this software without specific prior written permission. 24 // 25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 // 37 // Questions? Contact lead developers: 38 // Drew Kouri (dpkouri@sandia.gov) and 39 // Denis Ridzal (dridzal@sandia.gov) 40 // 41 // ************************************************************************ 42 // @HEADER 43 44 #ifndef ROL_PDEOPT_BRANCHING_PEBBL_H 45 #define ROL_PDEOPT_BRANCHING_PEBBL_H 46 47 #include "ROL_PEBBL_Interface.hpp" 48 49 template<class Real> 50 class ADVDIFF_BranchSub; 51 52 template<class Real> 53 class ADVDIFF_Branching : public ROL::ROL_PEBBL_Branching<Real> { 54 private: 55 const int method_; 56 ROL::Ptr<ROL::Vector<Real>> z0_; 57 58 using ROL::ROL_PEBBL_Branching<Real>::verbosity_; 59 using ROL::ROL_PEBBL_Branching<Real>::outStream_; 60 using ROL::ROL_PEBBL_Branching<Real>::parlist_; 61 62 public: ADVDIFF_Branching(const ROL::Ptr<BinaryAdvDiffFactory<Real>> & factory,const ROL::Ptr<ROL::ParameterList> & parlist,const ROL::Ptr<ROL::BranchHelper_PEBBL<Real>> & bHelper,int verbosity=0,const ROL::Ptr<std::ostream> & outStream=ROL::nullPtr,int method=0)63 ADVDIFF_Branching(const ROL::Ptr<BinaryAdvDiffFactory<Real>> &factory, 64 const ROL::Ptr<ROL::ParameterList> &parlist, 65 const ROL::Ptr<ROL::BranchHelper_PEBBL<Real>> &bHelper, 66 int verbosity = 0, 67 const ROL::Ptr<std::ostream> &outStream = ROL::nullPtr, 68 int method = 0) 69 : ROL::ROL_PEBBL_Branching<Real>::ROL_PEBBL_Branching(factory,parlist,bHelper,verbosity,outStream), 70 method_(method) { 71 z0_ = factory->buildSolutionVector(); 72 } 73 blankSub()74 pebbl::branchSub* blankSub() { 75 return new ADVDIFF_BranchSub<Real>(ROL::makePtrFromRef<ADVDIFF_Branching<Real>>(*this),verbosity_,outStream_,method_); 76 } 77 78 // pebbl::solution* iniitalGuess() { 79 // 80 // } 81 }; // ADVDIFF_Branching 82 83 template <class Real> 84 class ADVDIFF_BranchSub : public ROL::ROL_PEBBL_BranchSub<Real> { 85 private: 86 const int method_; 87 std::string methodName_; 88 89 using ROL::ROL_PEBBL_BranchSub<Real>::branching_; 90 using ROL::ROL_PEBBL_BranchSub<Real>::problem0_; 91 using ROL::ROL_PEBBL_BranchSub<Real>::solution_; 92 using ROL::ROL_PEBBL_BranchSub<Real>::rndSolution_; 93 using ROL::ROL_PEBBL_BranchSub<Real>::verbosity_; 94 using ROL::ROL_PEBBL_BranchSub<Real>::outStream_; 95 round(ROL::Vector<Real> & rx,const ROL::Vector<Real> & x,Real t) const96 void round(ROL::Vector<Real> &rx, const ROL::Vector<Real> &x, Real t) const { 97 rx.set(x); 98 ROL::Ptr<std::vector<Real>> data = getParameter(rx); 99 Real val(0); 100 for (auto it = data->begin(); it != data->end(); ++it) { 101 val = *it; 102 *it = (val < t ? std::floor(val) : std::ceil(val)); 103 } 104 } 105 getParameter(const ROL::Vector<Real> & x) const106 ROL::Ptr<const std::vector<Real>> getParameter(const ROL::Vector<Real> &x) const { 107 try { 108 return dynamic_cast<const ROL::StdVector<Real>&>(x).getVector(); 109 } 110 catch (std::exception &e) { 111 return dynamic_cast<const PDE_OptVector<Real>&>(x).getParameter()->getVector(); 112 } 113 } 114 getParameter(ROL::Vector<Real> & x) const115 ROL::Ptr<std::vector<Real>> getParameter(ROL::Vector<Real> &x) const { 116 try { 117 return dynamic_cast<ROL::StdVector<Real>&>(x).getVector(); 118 } 119 catch (std::exception &e) { 120 return dynamic_cast<PDE_OptVector<Real>&>(x).getParameter()->getVector(); 121 } 122 } 123 124 public: ADVDIFF_BranchSub(const ROL::Ptr<ROL::ROL_PEBBL_Branching<Real>> & branching,int verbosity=0,const ROL::Ptr<std::ostream> & outStream=ROL::nullPtr,int method=0)125 ADVDIFF_BranchSub(const ROL::Ptr<ROL::ROL_PEBBL_Branching<Real>> &branching, 126 int verbosity = 0, 127 const ROL::Ptr<std::ostream> &outStream = ROL::nullPtr, 128 int method = 0) 129 : ROL::ROL_PEBBL_BranchSub<Real>(branching, verbosity, outStream), method_(method) { 130 switch (method_) { 131 case 1: methodName_ = "Mass Preserving Rounding"; break; 132 case 2: methodName_ = "Objective Gap Rounding"; break; 133 default: methodName_ = "Naive Rounding"; 134 } 135 } 136 ADVDIFF_BranchSub(const ADVDIFF_BranchSub & rpbs)137 ADVDIFF_BranchSub(const ADVDIFF_BranchSub &rpbs) 138 : ROL::ROL_PEBBL_BranchSub<Real>(rpbs), method_(rpbs.method_) {} 139 incumbentHeuristic()140 void incumbentHeuristic() { 141 Real tol = std::sqrt(ROL::ROL_EPSILON<Real>()); 142 Real t(0), val(0); 143 if (method_==1) { // mass preserving rounding 144 const Real zero(0), one(1); 145 rndSolution_->set(*solution_); 146 ROL::Ptr<std::vector<Real>> data = getParameter(*rndSolution_); 147 std::map<Real,size_t> sdata; 148 Real sum(0); 149 for (size_t i = 0; i < data->size(); ++i) { 150 sdata.insert(std::pair<Real,size_t>((*data)[i],i)); 151 sum += (*data)[i]; 152 } 153 int rsum = static_cast<int>(std::round(sum)), psum(0); 154 for (auto it = sdata.rbegin(); it != sdata.rend(); ++it) { 155 (*data)[it->second] = (psum < rsum ? one : zero); 156 t = (psum < rsum ? it->first : t); 157 psum++; 158 } 159 } 160 else if (method_==2) { // objective gap rounding 161 const Real invphi(0.5*(std::sqrt(5.0)-1.0)); 162 const Real invphi2(0.5*(3.0-std::sqrt(5.0))); 163 const Real itol(std::sqrt(ROL::ROL_EPSILON<Real>())); 164 Real a(0), b(1), c(0), d(1), h(b-a), fc(0), fd(0); 165 // Evaluate at c 166 c = a + invphi2 * h; 167 round(*rndSolution_,*solution_,c); 168 problem0_->getObjective()->update(*rndSolution_); 169 fc = problem0_->getObjective()->value(*rndSolution_,tol); 170 // Evaluate at d 171 d = a + invphi * h; 172 round(*rndSolution_,*solution_,d); 173 problem0_->getObjective()->update(*rndSolution_); 174 fd = problem0_->getObjective()->value(*rndSolution_,tol); 175 while (std::abs(c-d) > itol) { 176 h *= invphi; 177 if (fc < fd) { 178 b = d; 179 d = c; 180 fd = fc; 181 c = a + invphi2 * h; 182 round(*rndSolution_,*solution_,c); 183 problem0_->getObjective()->update(*rndSolution_); 184 fc = problem0_->getObjective()->value(*rndSolution_,tol); 185 } 186 else { 187 a = c; 188 c = d; 189 fc = fd; 190 d = a + invphi * h; 191 round(*rndSolution_,*solution_,d); 192 problem0_->getObjective()->update(*rndSolution_); 193 fd = problem0_->getObjective()->value(*rndSolution_,tol); 194 } 195 } 196 t = static_cast<Real>(0.5)*(a+b); 197 round(*rndSolution_,*solution_,t); 198 } 199 else { // naive rounding 200 t = static_cast<Real>(0.5); 201 round(*rndSolution_,*solution_,t); 202 } 203 problem0_->getObjective()->update(*rndSolution_); 204 val = problem0_->getObjective()->value(*rndSolution_,tol); 205 branching_->foundSolution(new ROL::ROL_PEBBL_Solution<Real>(*rndSolution_,val)); 206 if (verbosity_ > 0) { 207 *outStream_ << "ADVDIFF_BranchSub::incumbentHeuristic: " << methodName_ << std::endl; 208 *outStream_ << " Incumbent Value: " << val << std::endl; 209 *outStream_ << " Rounding Threshold: " << t << std::endl; 210 } 211 }; 212 213 }; // class ADVDIFF_BranchSub 214 215 #endif 216