Main Page | Class Hierarchy | Class List | File List | Class Members

QuasiGroup.h

00001 // QuasiGroup.h -- The QuasiGroup problem represented as a CSP.
00002 
00003 /*
00004  * Copyright (C) 1998,2004-2005 Tudor Hulubei <tudor@hulubei.net>.
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as
00008  * published by the Free Software Foundation; either version 2, or (at
00009  * your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA,
00019  * 02111-1307, USA.
00020  */
00021 
00022 // $Id: QuasiGroup_8h-source.html,v 1.1 2005/05/25 12:37:18 tudor Exp $
00023 
00024 #ifndef _CSP_EXAMPLES_QuasiGroup_H
00025 #define _CSP_EXAMPLES_QuasiGroup_H
00026 
00027 
00028 #ifndef __cplusplus
00029 #error Must use C++ for the type QuasiGroup.
00030 #endif
00031 
00032 
00033 #include "values/Int.h"
00034 #include "variables/Int.h"
00035 
00036 
00037 CSP_NAMESPACE_BEGIN(QuasiGroup)
00038 
00039 
00040 using namespace std;
00041 
00042 
00043 typedef csp::values::Int Value;
00044 typedef csp::Domain Domain;
00045 class Variable;
00046 
00047 
00048 class ColumnZero :
00049   public csp::VariableOH
00050 {
00051   public:
00053     ColumnZero(
00054         csp::Decomposition& decomposition,
00055         const vector<pair<double, double> >& intervals,
00056         double quality = 1);
00057 
00058     /*
00059      * FIXME: Document.
00060      */
00061     void select(csp::vlist_type& vlist, csp::vlist_type& selected);
00062 };
00063 
00064 
00065 class Problem :
00066     public csp::Problem
00067 {
00068   public:
00069     Problem(
00070         csp::RandomSequence& randomSequence,
00071         int order,
00072         bool idempotency = false,
00073         bool symmetry = true,
00074         int holes = 0,
00075         bool balanced = true);
00076 
00077     Problem(const Problem& problem);
00078     Problem(csp::RandomSequence& randomSequence, wifstream& wifs);
00079 
00080     virtual wstring name() const { return L"QuasiGroup"; }
00081 
00082     Variable& variable(int row, int column) const
00083     {
00084         return *m_variables[row][column];
00085     }
00086 
00087     int order() const { return m_order; }
00088 
00089     virtual bool isSolution() const;
00090 
00096     virtual void save(wofstream& wofs) const;
00097 
00098     virtual wostream& printSolution(wostream& wos) const;
00099     virtual wostream& print(wostream& wos) const;
00100 
00101   private:
00102     void constructor(
00103         int order,
00104         bool idempotency,
00105         bool symmetry,
00106         int holes,
00107         bool balanced);
00108 
00109     void createVariables();
00110     void createConstraints();
00111     void createHoles();
00112     void resetIds(csp::Variable& variable);
00113 
00114     void newLatinSquare();
00115     void initIncidence();
00116     void shuffle(int times);
00117 
00118     int findColumn(int row, int value, int column);
00119     int findRow(int value, int column);
00120     int findValue(int row, int column);
00121     void generateRandomHoles(int holes);
00122     void generateBalancedHoles(int holes);
00123 
00124     // The order of the quasigroup.
00125     int m_order;
00126 
00127     // `true' if we want idempotent quasigroups.
00128     bool m_idempotency;
00129 
00130     // `true' if we allow symmetries.
00131     bool m_symmetry;
00132 
00133     // The number of holes when configured as quasi-groups with holes.
00134     int m_holes;
00135 
00136     // `true' if balanced holes should be generated, `false' for random.
00137     bool m_balanced;
00138 
00139     // The problem's MD5 signature-based checksum.
00140     wstring m_checksum;
00141     
00142     // The variables involved in the problem.
00143     vector<vector<Variable*> > m_variables;
00144 
00145     // These are for building quasigroups with holes.
00146     vector<vector<int> > m_values;
00147     vector<vector<int> > m_fixed;
00148     vector<vector<vector<int> > > m_incidence;
00149 };
00150 
00151 
00152 class Variable :
00153     public csp::variables::Int
00154 {
00155   public:
00156     Variable(
00157         const Problem& problem,
00158         int min, int max,
00159         int row, int column) :
00160         csp::variables::Int(problem, min, max),
00161         m_row(row),
00162         m_column(column),
00163         m_isBackdoor(false),
00164         m_isBackdoorKey(false),
00165         m_isBranching(false)
00166     {
00167     }
00168 
00169     Variable(
00170         const Problem& problem,
00171         const vector<csp::values::Int>& values,
00172         int row, int column) :
00173         csp::variables::Int(problem, values),
00174         m_row(row),
00175         m_column(column),
00176         m_isBackdoor(false),
00177         m_isBackdoorKey(false),
00178         m_isBranching(false)
00179     {
00180     }
00181 
00182     int row() const { return m_row; }
00183     int column() const { return m_column; }
00184 
00185     virtual wstring color() const
00186     {
00187         // It's important that the isBackdoor test comes last, as both
00188         // branching variables (those involved in branching
00189         // assignments) and backdoor keys are in the backdoor.
00190         if (m_isBranching)
00191             return L"pink";
00192         if (m_isBackdoorKey)
00193             return L"orange";
00194         if (m_isBackdoor)
00195             return L"red";
00196         return csp::Variable::color();
00197     }
00198 
00199     virtual wstring textColor() const { return csp::Variable::textColor(); }
00200 
00201     virtual wstring shape() const
00202     {
00203         if (m_isBackdoor || m_isBackdoorKey || m_isBranching)
00204             return L"rectangle";
00205         return csp::Variable::shape();
00206     }
00207 
00208     virtual void setBackdoorStatus(bool status) { m_isBackdoor = status; }
00209     virtual void setBackdoorKeyStatus(bool status) { m_isBackdoorKey = status; }
00210     virtual void setBranchingStatus(bool status) { m_isBranching = status; }
00211 
00212   private:
00213     int m_row;
00214     int m_column;
00215     bool m_isBackdoor;
00216     bool m_isBackdoorKey;
00217     bool m_isBranching;
00218 };
00219 
00220 
00221 class Different :
00222     public csp::Constraint
00223 {
00224   public:
00225     Different(Problem& problem) :
00226         csp::Constraint(), m_problem(problem) {}
00227 
00228     virtual bool check() const;
00229     virtual wstring name() const { return L"!="; }
00230     virtual wstring color() const { return L"red"; }
00231     virtual wstring textColor() const { return L"red"; }
00232 
00233   private:
00234     /* We need this here in order to be able to access the table of
00235        variables.  */
00236     Problem& m_problem;
00237 };
00238 
00239 
00240 CSP_NAMESPACE_END(QuasiGroup)
00241 
00242 
00243 #endif // _CSP_EXAMPLES_QuasiGroup_H
00244 
00245 // Local Variables:
00246 // mode: C++
00247 // End:

Generated on Wed May 25 12:21:14 2005 for csp.kdevelop by  doxygen 1.3.9.1