1 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2 /* 3 * Main authors: 4 * Christopher Mears <chris.mears@monash.edu> 5 * 6 * Copyright: 7 * Christopher Mears, 2012 8 * 9 * This file is part of Gecode, the generic constraint 10 * development environment: 11 * http://www.gecode.org 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining 14 * a copy of this software and associated documentation files (the 15 * "Software"), to deal in the Software without restriction, including 16 * without limitation the rights to use, copy, modify, merge, publish, 17 * distribute, sublicense, and/or sell copies of the Software, and to 18 * permit persons to whom the Software is furnished to do so, subject to 19 * the following conditions: 20 * 21 * The above copyright notice and this permission notice shall be 22 * included in all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 * 32 */ 33 34 namespace Gecode { 35 36 /** \brief Interchangeable rows symmetry specification. 37 */ 38 template<class A> 39 SymmetryHandle rows_interchange(const Matrix<A> & m)40 rows_interchange(const Matrix<A>& m) { 41 typename Matrix<A>::ArgsType xs; 42 for (int r = 0 ; r < m.height() ; r++) 43 xs << m.row(r); 44 return VariableSequenceSymmetry(xs, m.width()); 45 } 46 47 /** \brief Interchangeable columns symmetry specification. 48 */ 49 template<class A> 50 SymmetryHandle columns_interchange(const Matrix<A> & m)51 columns_interchange(const Matrix<A>& m) { 52 typename Matrix<A>::ArgsType xs; 53 for (int c = 0 ; c < m.width() ; c++) 54 xs << m.col(c); 55 return VariableSequenceSymmetry(xs, m.height()); 56 } 57 58 /** \brief Reflect rows symmetry specification. 59 */ 60 template<class A> 61 SymmetryHandle rows_reflect(const Matrix<A> & m)62 rows_reflect(const Matrix<A>& m) { 63 int nrows = m.height(); 64 int ncols = m.width(); 65 // Length of each sequence in the symmetry. 66 int length = (nrows/2) * ncols; 67 typename Matrix<A>::ArgsType xs(length * 2); 68 for (int i = 0 ; i < length ; i++) { 69 // Break position i into its coordinates 70 int r1 = i/ncols; 71 int c1 = i%ncols; 72 // r2 is the row symmetric with r1 73 int r2 = nrows - r1 - 1; 74 // The column remains the same 75 int c2 = c1; 76 xs[i] = m(c1,r1); 77 xs[length+i] = m(c2,r2); 78 } 79 return VariableSequenceSymmetry(xs, length); 80 } 81 82 /** \brief Reflect columns symmetry specification. 83 */ 84 template<class A> columns_reflect(const Matrix<A> & m)85 SymmetryHandle columns_reflect(const Matrix<A>& m) { 86 int nrows = m.height(); 87 int ncols = m.width(); 88 // Length of each sequence in the symmetry. 89 int length = (ncols/2) * nrows; 90 typename Matrix<A>::ArgsType xs(length * 2); 91 for (int i = 0 ; i < length ; i++) { 92 // Break position i into its coordinates 93 int r1 = i/ncols; 94 int c1 = i%ncols; 95 // c2 is the column symmetric with c1 96 int c2 = ncols - c1 - 1; 97 // The row remains the same 98 int r2 = r1; 99 xs[i] = m(c1,r1); 100 xs[length+i] = m(c2,r2); 101 } 102 return VariableSequenceSymmetry(xs, length); 103 } 104 105 /** \brief Reflect around main diagonal symmetry specification. 106 */ 107 template<class A> diagonal_reflect(const Matrix<A> & m)108 SymmetryHandle diagonal_reflect(const Matrix<A>& m) { 109 int nrows = m.height(); 110 int ncols = m.width(); 111 112 typename Matrix<A>::ArgsType a1; 113 typename Matrix<A>::ArgsType a2; 114 115 for (int i = 0 ; i < nrows ; i++) { 116 for (int j = i+1 ; j < ncols ; j++) { 117 a1 << m(j,i); 118 a2 << m(i,j); 119 } 120 } 121 122 typename Matrix<A>::ArgsType aboth; 123 aboth << a1; 124 aboth << a2; 125 return VariableSequenceSymmetry(aboth, a1.size()); 126 } 127 } 128 129 // STATISTICS: minimodel-any 130