00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 namespace Gecode { namespace Int { namespace Branch {
00039
00045 template<class ViewSel, class View>
00046 class PosValuesChoice : public PosChoice<ViewSel> {
00047 private:
00049 class PosMin {
00050 public:
00052 unsigned int pos;
00054 int min;
00055 };
00057 unsigned int n;
00059 PosMin* pm;
00060 public:
00062 PosValuesChoice(const Brancher& b, const Pos& p,
00063 const typename ViewSel::Choice& viewc, View x);
00065 PosValuesChoice(const Brancher& b, unsigned int alt, Pos p,
00066 const typename ViewSel::Choice& viewc,
00067 Archive& e);
00069 int val(unsigned int a) const;
00071 virtual size_t size(void) const;
00073 virtual ~PosValuesChoice(void);
00075 virtual void archive(Archive& e) const;
00076 };
00077
00078
00079 template<class ViewSel, class View>
00080 forceinline
00081 PosValuesChoice<ViewSel,View>::
00082 PosValuesChoice(const Brancher& b, const Pos& p,
00083 const typename ViewSel::Choice& viewc, View x)
00084 : PosChoice<ViewSel>(b,x.size(),p,viewc), n(0) {
00085 for (ViewRanges<View> r(x); r(); ++r)
00086 n++;
00087 pm = heap.alloc<PosMin>(n+1);
00088 unsigned int w=0;
00089 int i=0;
00090 for (ViewRanges<View> r(x); r(); ++r) {
00091 pm[i].min = r.min();
00092 pm[i].pos = w;
00093 w += r.width(); i++;
00094 }
00095 pm[i].pos = w;
00096 }
00097
00098 template<class ViewSel, class View>
00099 forceinline
00100 PosValuesChoice<ViewSel,View>::
00101 PosValuesChoice(const Brancher& b, unsigned int alt, Pos p,
00102 const typename ViewSel::Choice& viewc, Archive& e)
00103 : PosChoice<ViewSel>(b,alt,p,viewc) {
00104 e >> n;
00105 pm = heap.alloc<PosMin>(n+1);
00106 for (unsigned int i=0; i<n+1; i++) {
00107 e >> pm[i].pos;
00108 e >> pm[i].min;
00109 }
00110 }
00111
00112 template<class ViewSel, class View>
00113 forceinline int
00114 PosValuesChoice<ViewSel,View>::val(unsigned int a) const {
00115 PosMin* l = &pm[0];
00116 PosMin* r = &pm[n-1];
00117 while (true) {
00118 PosMin* m = l + (r-l)/2;
00119 if (a < m->pos) {
00120 r=m-1;
00121 } else if (a >= (m+1)->pos) {
00122 l=m+1;
00123 } else {
00124 return m->min + static_cast<int>(a - m->pos);
00125 }
00126 }
00127 GECODE_NEVER;
00128 return 0;
00129 }
00130
00131 template<class ViewSel, class View>
00132 size_t
00133 PosValuesChoice<ViewSel,View>::size(void) const {
00134 return sizeof(PosValuesChoice<ViewSel,View>)+(n+1)*sizeof(PosMin);
00135 }
00136
00137 template<class ViewSel, class View>
00138 PosValuesChoice<ViewSel,View>::~PosValuesChoice(void) {
00139 heap.free<PosMin>(pm,n+1);
00140 }
00141
00142 template<class ViewSel, class View>
00143 forceinline void
00144 PosValuesChoice<ViewSel,View>::archive(Archive& e) const {
00145 PosChoice<ViewSel>::archive(e);
00146 e << this->alternatives() << n;
00147 for (unsigned int i=0; i<n+1; i++) {
00148 e << pm[i].pos;
00149 e << pm[i].min;
00150 }
00151 }
00152
00153 template<class ViewSel, class View>
00154 forceinline
00155 ViewValuesBrancher<ViewSel,View>::
00156 ViewValuesBrancher(Home home, ViewArray<typename ViewSel::View>& x,
00157 ViewSel& vi_s, BranchFilter bf)
00158 : ViewBrancher<ViewSel>(home,x,vi_s,bf) {}
00159
00160 template<class ViewSel, class View>
00161 void
00162 ViewValuesBrancher<ViewSel,View>::
00163 post(Home home, ViewArray<typename ViewSel::View>& x, ViewSel& vi_s,
00164 BranchFilter bf) {
00165 (void) new (home) ViewValuesBrancher<ViewSel,View>(home,x,vi_s,bf);
00166 }
00167
00168 template<class ViewSel, class View>
00169 forceinline
00170 ViewValuesBrancher<ViewSel,View>::
00171 ViewValuesBrancher(Space& home, bool share, ViewValuesBrancher& b)
00172 : ViewBrancher<ViewSel>(home,share,b) {}
00173
00174 template<class ViewSel, class View>
00175 Actor*
00176 ViewValuesBrancher<ViewSel,View>::copy(Space& home, bool share) {
00177 return new (home)
00178 ViewValuesBrancher<ViewSel,View>(home,share,*this);
00179 }
00180
00181 template<class ViewSel, class View>
00182 const Choice*
00183 ViewValuesBrancher<ViewSel,View>::choice(Space& home) {
00184 Pos p = ViewBrancher<ViewSel>::pos(home);
00185 View v(ViewBrancher<ViewSel>::view(p).varimp());
00186 return new PosValuesChoice<ViewSel,View>
00187 (*this,p,viewsel.choice(home),v);
00188 }
00189
00190 template<class ViewSel, class View>
00191 const Choice*
00192 ViewValuesBrancher<ViewSel,View>::choice(const Space& home, Archive& e) {
00193 int p;
00194 unsigned int alt;
00195 e >> p >> alt;
00196 return new PosValuesChoice<ViewSel,View>
00197 (*this,alt,p,viewsel.choice(home,e),e);
00198 }
00199
00200 template<class ViewSel, class View>
00201 ExecStatus
00202 ViewValuesBrancher<ViewSel,View>
00203 ::commit(Space& home, const Choice& c, unsigned int a) {
00204 const PosValuesChoice<ViewSel,View>& pvc
00205 = static_cast<const PosValuesChoice<ViewSel,View>&>(c);
00206 View v(ViewBrancher<ViewSel>::view(pvc.pos()).varimp());
00207 viewsel.commit(home, pvc.viewchoice(), a);
00208 return me_failed(v.eq(home,pvc.val(a))) ? ES_FAILED : ES_OK;
00209 }
00210
00211 }}}
00212
00213