1
0
This repository has been archived on 2025-03-06. You can view files and clone it, but cannot push or open issues or pull requests.

244 lines
6.9 KiB
C++

/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Mikael Lagerkvist <lagerkvist@gecode.org>
*
* Copyright:
* Mikael Lagerkvist, 2005
*
* Bugfixes provided by:
* Olof Sivertsson <olof@olofsivertsson.com>
*
* This file is part of Gecode, the generic constraint
* development environment:
* http://www.gecode.org
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include <algorithm>
namespace Gecode {
template<class A>
inline
Slice<A>::Slice(const Matrix<A>& a, int fc, int tc, int fr, int tr)
: _r(0), _fc(fc), _tc(tc), _fr(fr), _tr(tr) {
if (tc > a.width() || tr > a.height())
throw MiniModel::ArgumentOutOfRange("Slice::Slice");
if (fc >= tc || fr >= tr) {
_fc=0; _tc=0; _fr=0; _tr=0;
return;
}
_r = ArgsType((tc-fc)*(tr-fr));
int i = 0;
for (int h = fr; h < tr; h++)
for (int w = fc; w < tc; w++)
_r[i++] = a(w, h);
}
template<class A>
Slice<A>&
Slice<A>::reverse(void) {
for (int i = 0; i < _r.size()/2; i++)
std::swap(_r[i], _r[_r.size()-i-1]);
return *this;
}
template<class A>
inline
Slice<A>::operator ArgsType(void) {
return _r;
}
template<class A>
inline
Slice<A>::operator Matrix<typename Slice<A>::ArgsType>(void) {
return Matrix<ArgsType>(_r, _tc-_fc, _tr-_fr);
}
template<class A>
inline
Slice<A>::operator const typename Slice<A>::ArgsType(void) const {
return _r;
}
template<class A>
inline
Slice<A>::operator const Matrix<typename Slice<A>::ArgsType>(void) const {
return Matrix<ArgsType>(_r, _tc-_fc, _tr-_fr);
}
template<class A>
typename Slice<A>::ArgsType
operator+(const Slice<A>& x, const Slice<A>& y) {
typename Slice<A>::ArgsType xx = x;
typename Slice<A>::ArgsType yy = y;
return xx+yy;
}
template<class A>
typename Slice<A>::ArgsType
operator+(const Slice<A>& x, const typename ArrayTraits<A>::ArgsType& y) {
typename Slice<A>::ArgsType xx = x;
return xx+y;
}
template<class A>
typename Slice<A>::ArgsType
operator+(const typename ArrayTraits<A>::ArgsType& x, const Slice<A>& y) {
typename Slice<A>::ArgsType yy = y;
return x+yy;
}
template<class A>
typename Slice<A>::ArgsType
operator+(const Slice<A>& x, const typename ArrayTraits<A>::ValueType& y) {
typename Slice<A>::ArgsType xx = x;
return xx+y;
}
template<class A>
typename Slice<A>::ArgsType
operator+(const typename ArrayTraits<A>::ValueType& x, const Slice<A>& y) {
typename Slice<A>::ArgsType yy = y;
return x+yy;
}
template<class A>
forceinline
Matrix<A>::Matrix(A a, int w, int h)
: _a(a), _w(w), _h(h) {
if ((_w * _h) != _a.size())
throw MiniModel::ArgumentSizeMismatch("Matrix::Matrix(A, w, h)");
}
template<class A>
forceinline
Matrix<A>::Matrix(A a, int n)
: _a(a), _w(n), _h(n) {
if (n*n != _a.size())
throw MiniModel::ArgumentSizeMismatch("Matrix::Matrix(A, n)");
}
template<class A>
forceinline int
Matrix<A>::width(void) const { return _w; }
template<class A>
forceinline int
Matrix<A>::height(void) const { return _h; }
template<class A>
inline typename Matrix<A>::ArgsType const
Matrix<A>::get_array(void) const {
return ArgsType(_a);
}
template<class A>
forceinline typename Matrix<A>::ValueType&
Matrix<A>::operator ()(int c, int r) {
if ((c >= _w) || (r >= _h))
throw MiniModel::ArgumentOutOfRange("Matrix::operator ()");
return _a[r*_w + c];
}
template<class A>
forceinline const typename Matrix<A>::ValueType&
Matrix<A>::operator ()(int c, int r) const {
if ((c >= _w) || (r >= _h))
throw MiniModel::ArgumentOutOfRange("Matrix::operator ()");
return _a[r*_w + c];
}
template<class A>
inline Slice<A>
Matrix<A>::slice(int fc, int tc, int fr, int tr) const {
return Slice<A>(*this, fc, tc, fr, tr);
}
template<class A>
inline Slice<A>
Matrix<A>::row(int r) const {
return slice(0, width(), r, r+1);
}
template<class A>
inline Slice<A>
Matrix<A>::col(int c) const {
return slice(c, c+1, 0, height());
}
template<class Char, class Traits, class A>
std::basic_ostream<Char,Traits>&
operator <<(std::basic_ostream<Char,Traits>& os, const Matrix<A>& m) {
std::basic_ostringstream<Char,Traits> s;
s.copyfmt(os); s.width(0);
for (int i=0; i<m.height(); i++) {
for (int j=0; j<m.width(); j++) {
s << m(j,i) << "\t";
}
s << std::endl;
}
return os << s.str();
}
template<class Char, class Traits, class A>
std::basic_ostream<Char,Traits>&
operator <<(std::basic_ostream<Char,Traits>& os, const Slice<A>& s) {
return os << static_cast<typename Slice<A>::ArgsType>(s);
}
forceinline void
element(Home home, const Matrix<IntArgs>& m, IntVar x, IntVar y,
IntVar z, IntPropLevel ipl) {
element(home, m.get_array(), x, m.width(), y, m.height(), z, ipl);
}
forceinline void
element(Home home, const Matrix<IntArgs>& m, IntVar x, IntVar y,
BoolVar z, IntPropLevel ipl) {
element(home, m.get_array(), x, m.width(), y, m.height(), z, ipl);
}
forceinline void
element(Home home, const Matrix<IntVarArgs>& m, IntVar x, IntVar y,
IntVar z, IntPropLevel ipl) {
element(home, m.get_array(), x, m.width(), y, m.height(), z, ipl);
}
forceinline void
element(Home home, const Matrix<BoolVarArgs>& m, IntVar x, IntVar y,
BoolVar z, IntPropLevel ipl) {
element(home, m.get_array(), x, m.width(), y, m.height(), z, ipl);
}
#ifdef GECODE_HAS_SET_VARS
forceinline void
element(Home home, const Matrix<IntSetArgs>& m, IntVar x, IntVar y,
SetVar z) {
element(home, m.get_array(), x, m.width(), y, m.height(), z);
}
forceinline void
element(Home home, const Matrix<SetVarArgs>& m, IntVar x, IntVar y,
SetVar z) {
element(home, m.get_array(), x, m.width(), y, m.height(), z);
}
#endif
}
// STATISTICS: minimodel-any