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