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