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 {
00039
00047
00048 class Pos {
00049 public:
00051 const int pos;
00053 Pos(int p);
00054 };
00055
00057 class GECODE_VTABLE_EXPORT PosChoice : public Choice {
00058 private:
00060 const Pos _pos;
00061 public:
00063 PosChoice(const Brancher& b, unsigned int a, const Pos& p);
00065 const Pos& pos(void) const;
00067 virtual size_t size(void) const;
00069 virtual void archive(Archive& e) const;
00070 };
00071
00078 template<class View, int n>
00079 class ViewBrancher : public Brancher {
00080 protected:
00082 typedef typename BranchTraits<typename View::VarType>::Filter BranchFilter;
00084 ViewArray<View> x;
00086 mutable int start;
00088 ViewSel<View>* vs[n];
00090 BranchFilter bf;
00092 Pos pos(Space& home);
00094 View view(const Pos& p) const;
00096 ViewBrancher(Space& home, bool shared, ViewBrancher<View,n>& b);
00098 ViewBrancher(Home home, ViewArray<View>& x,
00099 ViewSel<View>* vs[n], BranchFilter bf);
00100 public:
00102 virtual bool status(const Space& home) const;
00104 virtual size_t dispose(Space& home);
00105 };
00106
00108
00109
00110
00111
00112
00113
00114 forceinline
00115 Pos::Pos(int p) : pos(p) {}
00116
00117
00118
00119
00120
00121 forceinline
00122 PosChoice::PosChoice(const Brancher& b, unsigned int a, const Pos& p)
00123 : Choice(b,a), _pos(p) {}
00124 forceinline const Pos&
00125 PosChoice::pos(void) const {
00126 return _pos;
00127 }
00128 forceinline size_t
00129 PosChoice::size(void) const {
00130 return sizeof(PosChoice);
00131 }
00132 forceinline void
00133 PosChoice::archive(Archive& e) const {
00134 Choice::archive(e);
00135 e << _pos.pos;
00136 }
00137
00138 template<class View, int n>
00139 forceinline
00140 ViewBrancher<View,n>::ViewBrancher(Home home, ViewArray<View>& x0,
00141 ViewSel<View>* vs0[n], BranchFilter bf0)
00142 : Brancher(home), x(x0), start(0), bf(bf0) {
00143 for (int i=0; i<n; i++)
00144 vs[i] = vs0[i];
00145 for (int i=0; i<n; i++)
00146 if (vs[i]->notice()) {
00147 home.notice(*this,AP_DISPOSE);
00148 break;
00149 }
00150 }
00151
00152 template<class View, int n>
00153 forceinline
00154 ViewBrancher<View,n>::ViewBrancher(Space& home, bool shared,
00155 ViewBrancher<View,n>& vb)
00156 : Brancher(home,shared,vb), start(vb.start), bf(vb.bf) {
00157 x.update(home,shared,vb.x);
00158 for (int i=0; i<n; i++)
00159 vs[i] = vb.vs[i]->copy(home,shared);
00160 }
00161
00162 template<class View, int n>
00163 bool
00164 ViewBrancher<View,n>::status(const Space& home) const {
00165 if (bf == NULL) {
00166 for (int i=start; i < x.size(); i++)
00167 if (!x[i].assigned()) {
00168 start = i;
00169 return true;
00170 }
00171 } else {
00172 for (int i=start; i < x.size(); i++) {
00173 typename View::VarType y(x[i].varimp());
00174 if (!x[i].assigned() && bf(home,y,i)) {
00175 start = i;
00176 return true;
00177 }
00178 }
00179 }
00180 return false;
00181 }
00182
00183 template<class View, int n>
00184 inline Pos
00185 ViewBrancher<View,n>::pos(Space& home) {
00186 assert(!x[start].assigned());
00187 int s;
00188 if (bf == NULL) {
00189 if (n == 1) {
00190 s = vs[0]->select(home,x,start);
00191 } else {
00192 Region r(home);
00193 int* ties = r.alloc<int>(x.size()-start+1);
00194 int n_ties;
00195 vs[0]->ties(home,x,start,ties,n_ties);
00196 for (int i=1; (i < n-1) && (n_ties > 1); i++)
00197 vs[i]->brk(home,x,ties,n_ties);
00198 if (n_ties > 1)
00199 s = vs[n-1]->select(home,x,ties,n_ties);
00200 else
00201 s = ties[0];
00202 }
00203 } else {
00204 if (n == 1) {
00205 s = vs[0]->select(home,x,start,bf);
00206 } else {
00207 Region r(home);
00208 int* ties = r.alloc<int>(x.size()-start+1);
00209 int n_ties;
00210 vs[0]->ties(home,x,start,ties,n_ties,bf);
00211 for (int i=1; (i < n-1) && (n_ties > 1); i++)
00212 vs[i]->brk(home,x,ties,n_ties);
00213 if (n_ties > 1)
00214 s = vs[n-1]->select(home,x,ties,n_ties);
00215 else
00216 s = ties[0];
00217 }
00218 }
00219 Pos p(s);
00220 return p;
00221 }
00222
00223 template<class View, int n>
00224 forceinline View
00225 ViewBrancher<View,n>::view(const Pos& p) const {
00226 return x[p.pos];
00227 }
00228
00229 template<class View, int n>
00230 forceinline size_t
00231 ViewBrancher<View,n>::dispose(Space& home) {
00232 for (int i=0; i<n; i++)
00233 if (vs[i]->notice()) {
00234 home.ignore(*this,AP_DISPOSE,true);
00235 break;
00236 }
00237 for (int i=0; i<n; i++)
00238 vs[i]->dispose(home);
00239 (void) Brancher::dispose(home);
00240 return sizeof(ViewBrancher<View,n>);
00241 }
00242
00243 }
00244
00245