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
00039
00040
00041 #include <algorithm>
00042
00043 namespace Gecode {
00044
00045 template<class A>
00046 inline
00047 Slice<A>::Slice(const Matrix<A>& a, int fc, int tc, int fr, int tr)
00048 : _r(0), _fc(fc), _tc(tc), _fr(fr), _tr(tr) {
00049 if (tc > a.width() || tr > a.height())
00050 throw MiniModel::ArgumentOutOfRange("Slice::Slice");
00051 if (fc >= tc || fr >= tr) {
00052 _fc=0; _tc=0; _fr=0; _tr=0;
00053 return;
00054 }
00055
00056 _r = ArgsType((tc-fc)*(tr-fr));
00057
00058 int i = 0;
00059 for (int h = fr; h < tr; h++)
00060 for (int w = fc; w < tc; w++)
00061 _r[i++] = a(w, h);
00062 }
00063
00064 template<class A>
00065 Slice<A>&
00066 Slice<A>::reverse(void) {
00067 for (int i = 0; i < _r.size()/2; i++)
00068 std::swap(_r[i], _r[_r.size()-i-1]);
00069 return *this;
00070 }
00071
00072 template<class A>
00073 forceinline
00074 Slice<A>::operator ArgsType(void) {
00075 return _r;
00076 }
00077 template<class A>
00078 forceinline
00079 Slice<A>::operator Matrix<typename Slice<A>::ArgsType>(void) {
00080 return Matrix<ArgsType>(_r, _tc-_fc, _tr-_fr);
00081 }
00082 template<class A>
00083 forceinline
00084 Slice<A>::operator const typename Slice<A>::ArgsType(void) const {
00085 return _r;
00086 }
00087 template<class A>
00088 forceinline
00089 Slice<A>::operator const Matrix<typename Slice<A>::ArgsType>(void) const {
00090 return Matrix<ArgsType>(_r, _tc-_fc, _tr-_fr);
00091 }
00092
00093 template<class A>
00094 typename Slice<A>::ArgsType
00095 operator+(const Slice<A>& x, const Slice<A>& y) {
00096 typename Slice<A>::ArgsType xx = x;
00097 typename Slice<A>::ArgsType yy = y;
00098 return xx+yy;
00099 }
00100
00101 template<class A>
00102 typename Slice<A>::ArgsType
00103 operator+(const Slice<A>& x, const typename ArrayTraits<A>::ArgsType& y) {
00104 typename Slice<A>::ArgsType xx = x;
00105 return xx+y;
00106 }
00107
00108 template<class A>
00109 typename Slice<A>::ArgsType
00110 operator+(const typename ArrayTraits<A>::ArgsType& x, const Slice<A>& y) {
00111 typename Slice<A>::ArgsType yy = y;
00112 return x+yy;
00113 }
00114
00115 template<class A>
00116 typename Slice<A>::ArgsType
00117 operator+(const Slice<A>& x, const typename ArrayTraits<A>::ValueType& y) {
00118 typename Slice<A>::ArgsType xx = x;
00119 return xx+y;
00120 }
00121
00122 template<class A>
00123 typename Slice<A>::ArgsType
00124 operator+(const typename ArrayTraits<A>::ValueType& x, const Slice<A>& y) {
00125 typename Slice<A>::ArgsType yy = y;
00126 return x+yy;
00127 }
00128
00129 template<class A>
00130 forceinline
00131 Matrix<A>::Matrix(A a, int w, int h)
00132 : _a(a), _w(w), _h(h) {
00133 if ((_w * _h) != _a.size())
00134 throw MiniModel::ArgumentSizeMismatch("Matrix::Matrix(A, w, h)");
00135 }
00136
00137 template<class A>
00138 forceinline
00139 Matrix<A>::Matrix(A a, int n)
00140 : _a(a), _w(n), _h(n) {
00141 if (n*n != _a.size())
00142 throw MiniModel::ArgumentSizeMismatch("Matrix::Matrix(A, n)");
00143 }
00144
00145 template<class A>
00146 forceinline int
00147 Matrix<A>::width(void) const { return _w; }
00148 template<class A>
00149 forceinline int
00150 Matrix<A>::height(void) const { return _h; }
00151 template<class A>
00152 inline typename Matrix<A>::ArgsType const
00153 Matrix<A>::get_array(void) const {
00154 return ArgsType(_a);
00155 }
00156
00157 template<class A>
00158 forceinline typename Matrix<A>::ValueType&
00159 Matrix<A>::operator ()(int c, int r) {
00160 if ((c >= _w) || (r >= _h))
00161 throw MiniModel::ArgumentOutOfRange("Matrix::operator ()");
00162 return _a[r*_w + c];
00163 }
00164
00165 template<class A>
00166 forceinline const typename Matrix<A>::ValueType&
00167 Matrix<A>::operator ()(int c, int r) const {
00168 if ((c >= _w) || (r >= _h))
00169 throw MiniModel::ArgumentOutOfRange("Matrix::operator ()");
00170 return _a[r*_w + c];
00171 }
00172
00173 template<class A>
00174 forceinline Slice<A>
00175 Matrix<A>::slice(int fc, int tc, int fr, int tr) const {
00176 return Slice<A>(*this, fc, tc, fr, tr);
00177 }
00178
00179 template<class A>
00180 forceinline Slice<A>
00181 Matrix<A>::row(int r) const {
00182 return slice(0, width(), r, r+1);
00183 }
00184
00185 template<class A>
00186 forceinline Slice<A>
00187 Matrix<A>::col(int c) const {
00188 return slice(c, c+1, 0, height());
00189 }
00190
00191 template<class Char, class Traits, class A>
00192 std::basic_ostream<Char,Traits>&
00193 operator <<(std::basic_ostream<Char,Traits>& os, const Matrix<A>& m) {
00194 std::basic_ostringstream<Char,Traits> s;
00195 s.copyfmt(os); s.width(0);
00196 for (int i=0; i<m.height(); i++) {
00197 for (int j=0; j<m.width(); j++) {
00198 s << m(j,i) << "\t";
00199 }
00200 s << std::endl;
00201 }
00202 return os << s.str();
00203 }
00204
00205 template<class Char, class Traits, class A>
00206 std::basic_ostream<Char,Traits>&
00207 operator <<(std::basic_ostream<Char,Traits>& os, const Slice<A>& s) {
00208 return os << static_cast<typename Slice<A>::ArgsType>(s);
00209 }
00210
00211 forceinline void
00212 element(Home home, const Matrix<IntArgs>& m, IntVar x, IntVar y,
00213 IntVar z, IntConLevel icl) {
00214 element(home, m.get_array(), x, m.width(), y, m.height(), z, icl);
00215 }
00216 forceinline void
00217 element(Home home, const Matrix<IntArgs>& m, IntVar x, IntVar y,
00218 BoolVar z, IntConLevel icl) {
00219 element(home, m.get_array(), x, m.width(), y, m.height(), z, icl);
00220 }
00221 forceinline void
00222 element(Home home, const Matrix<IntVarArgs>& m, IntVar x, IntVar y,
00223 IntVar z, IntConLevel icl) {
00224 element(home, m.get_array(), x, m.width(), y, m.height(), z, icl);
00225 }
00226 forceinline void
00227 element(Home home, const Matrix<BoolVarArgs>& m, IntVar x, IntVar y,
00228 BoolVar z, IntConLevel icl) {
00229 element(home, m.get_array(), x, m.width(), y, m.height(), z, icl);
00230 }
00231
00232 #ifdef GECODE_HAS_SET_VARS
00233 forceinline void
00234 element(Home home, const Matrix<IntSetArgs>& m, IntVar x, IntVar y,
00235 SetVar z) {
00236 element(home, m.get_array(), x, m.width(), y, m.height(), z);
00237 }
00238 forceinline void
00239 element(Home home, const Matrix<SetVarArgs>& m, IntVar x, IntVar y,
00240 SetVar z) {
00241 element(home, m.get_array(), x, m.width(), y, m.height(), z);
00242 }
00243 #endif
00244
00245 }
00246
00247