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

Queens.h

00001 // Queens.h -- The Queens problem represented as a CSP.
00002 
00003 /*
00004  * Copyright (C) 1997,1998,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: Queens_8h-source.html,v 1.1 2005/05/25 12:37:18 tudor Exp $
00023 
00024 #ifndef _CSP_EXAMPLES_Queens_H
00025 #define _CSP_EXAMPLES_Queens_H
00026 
00027 
00028 #ifndef __cplusplus
00029 #error Must use C++ for the type Queens.
00030 #endif
00031 
00032 
00033 #include "values/Int.h"
00034 #include "variables/Int.h"
00035 
00036 
00037 CSP_NAMESPACE_BEGIN(Queens)
00038 
00039 
00040 using namespace std;
00041 
00042 
00043 #ifdef __GNUG__
00044 using namespace __gnu_cxx;
00045 #endif
00046 
00047 #if defined(_MSC_VER) && (_MSC_VER == 1310)
00048 using namespace stdext;
00049 #endif
00050 
00051 
00052 typedef csp::values::Int Value;
00053 typedef csp::Domain Domain;
00054 class Variable;
00055 
00056 
00058 class Constraint :
00059     public csp::Constraint
00060 {
00061   public:
00062     Constraint(int queens = 0) : csp::Constraint()
00063     {
00064         m_queens = queens;
00065     }
00066 
00067     virtual bool check() const;
00068 
00069   private:
00070     /* We need this only when eliminating symmetries.  `m_queens'==0
00071        means that we won't eliminate symmetries.  */
00072     int m_queens;
00073 };
00074 
00075 
00077 class VerticalConstraint :
00078     public csp::Constraint
00079 {
00080   public:
00081     VerticalConstraint(int /*queens*/ = 0) : csp::Constraint() {}
00082     virtual bool check() const;
00083     virtual wstring name() const { return L"|"; }
00084     virtual wstring color() const { return L"black"; }
00085     virtual wstring textColor() const { return L"black"; }
00086 };
00087 
00088 
00090 class DiagonalConstraint :
00091     public csp::Constraint
00092 {
00093   public:
00094     DiagonalConstraint() : csp::Constraint() {}
00095     virtual bool check() const;
00096     virtual wstring name() const { return L"X"; }
00097     virtual wstring color() const { return L"red"; }
00098     virtual wstring textColor() const { return L"red"; }
00099 };
00100 
00101 
00103 class SymmetryConstraint :
00104     public csp::Constraint
00105 {
00106   public:
00107     SymmetryConstraint(int queens) : csp::Constraint()
00108     {
00109         m_queens = queens;
00110     }
00111 
00112     virtual bool check() const;
00113     virtual wstring name() const { return L"<->"; }
00114     virtual wstring color() const { return L"blue"; }
00115     virtual wstring textColor() const { return L"blue"; }
00116 
00117   private:
00118     /* We need this only when eliminating symmetries.  `m_queens'==0
00119        means that we won't eliminate symmetries.  */
00120     int m_queens;
00121 };
00122 
00123 
00124 class Problem :
00125     public csp::Problem
00126 {
00127   public:
00128     Problem(
00129         csp::RandomSequence& randomSequence,
00130         int queens,
00131         bool compact = false,
00132         bool symmetry = true);
00133     Problem(const Problem& problem);
00134 
00135     virtual wstring name() const { return L"Queens"; }
00136 
00137     virtual wostream& printSolution(wostream& wos) const;
00138 
00139     virtual wostream& print(wostream& wos) const
00140     {
00141         wos << L"Problem: Queens" << endl;
00142         return csp::Problem::print(wos);
00143     }
00144 
00145   protected:
00146     void addConstraint(
00147         csp::Variable& variable0,
00148         csp::Variable& variable1,
00149         int queens);
00150     void addVerticalConstraint(
00151         csp::Variable& variable0,
00152         csp::Variable& variable1);
00153     void addDiagonalConstraint(
00154         csp::Variable& variable0,
00155         csp::Variable& variable1);
00156     void addSymmetryConstraint(
00157         csp::Variable& variable0,
00158         csp::Variable& variable1,
00159         int queens);
00160 
00161   private:
00162     void constructor(int nVariables, bool compact, bool symmetry);
00163 
00164     int m_nVariables;
00165     bool m_compact;
00166     bool m_symmetry;
00167 };
00168 
00169 
00170 class Variable :
00171     public csp::variables::Int
00172 {
00173   public:
00174     Variable(const Problem& problem, int min, int max, int index) :
00175         csp::variables::Int(problem, min, max),
00176         m_index(index),
00177         m_isBackdoor(false),
00178         m_isBackdoorKey(false),
00179         m_isBranching(false)
00180     {}
00181 
00182     int index() const { return m_index; }
00183 
00184     virtual wstring color() const
00185     {
00186         // It's important that the isBackdoor test comes last, as both
00187         // branching variables (those involved in branching
00188         // assignments) and backdoor keys are in the backdoor.
00189         if (m_isBranching)
00190             return L"pink";
00191         if (m_isBackdoorKey)
00192             return L"orange";
00193         if (m_isBackdoor)
00194             return L"red";
00195         return L"orange";
00196     }
00197 
00198     virtual wstring textColor() const { return L"white"; }
00199 
00200     virtual wstring shape() const
00201     {
00202         if (m_isBackdoor || m_isBackdoorKey || m_isBranching)
00203             return L"rectangle";
00204         return csp::Variable::shape();
00205     }
00206 
00207     virtual void setBackdoorStatus(bool status) { m_isBackdoor = status; }
00208     virtual void setBackdoorKeyStatus(bool status) { m_isBackdoorKey = status; }
00209     virtual void setBranchingStatus(bool status) { m_isBranching = status; }
00210 
00211   private:
00212     int m_index;
00213     bool m_isBackdoor;
00214     bool m_isBackdoorKey;
00215     bool m_isBranching;
00216 };
00217 
00218 
00219 class MinimumValueCache
00220 {
00221   public:
00222     MinimumValueCache() {}
00223 
00232     size_t minimumValue(const csp::Variable& variable);
00233 
00235     void clear() { m_minimumValues.clear(); }
00236 
00237   private:
00239     MinimumValueCache(const MinimumValueCache&);
00240 
00242     MinimumValueCache& operator=(const MinimumValueCache&);
00243 
00244     size_t computeMinimumValue(const Variable& variable);
00245 
00246     typedef hash_map<const csp::Variable*, size_t> mv_type;
00247 
00249     mv_type m_minimumValues;
00250 };
00251 
00252 
00253 class ValueLT :
00254     public csp::StrictWeakVariableOrdering
00255 {
00256   public:
00257     ValueLT(MinimumValueCache& minimumValues) :
00258         m_minimumValues(minimumValues) {}
00259 
00260     bool operator()(
00261         const csp::Variable* variable0,
00262         const csp::Variable* variable1)
00263     {
00264         return
00265             m_minimumValues.minimumValue(*variable0) <
00266             m_minimumValues.minimumValue(*variable1);
00267     }
00268 
00269   private:
00270     MinimumValueCache& m_minimumValues;
00271 };
00272 
00273 
00274 class ValueEQ :
00275     public csp::StrictWeakVariableOrdering
00276 {
00277   public:
00278     ValueEQ(MinimumValueCache& minimumValues) :
00279         m_minimumValues(minimumValues) {}
00280 
00281     bool operator()(
00282         const csp::Variable* variable0,
00283         const csp::Variable* variable1);
00284 
00285   private:
00286     MinimumValueCache& m_minimumValues;
00287 
00288     Variable* m_previousVariable0;
00289     Variable* m_previousVariable1;
00290 
00291     size_t m_previousMinimumValue0;
00292     size_t m_previousMinimumValue1;
00293 };
00294 
00295 
00296 class MinValue :
00297     public csp::VariableOH
00298 {
00299   public:
00301     MinValue(
00302         csp::Decomposition& decomposition,
00303         const vector<pair<double, double> >& intervals,
00304         double quality = 1);
00305 
00306     /*
00307      * This is a very good variable order heuristic for the Queens
00308      * problem.  It selects the variables that have the smallest number
00309      * in their domain.
00310      */
00311     void select(csp::vlist_type& vlist, csp::vlist_type& selected);
00312 
00313   private:
00315     MinimumValueCache m_minimumValues;
00316 
00319     ValueLT m_compareLT;
00320 
00323     ValueEQ m_compareEQ;
00324 };
00325 
00326 
00327 CSP_NAMESPACE_END(Queens)
00328 
00329 
00330 #endif // _CSP_EXAMPLES_Queens_H
00331 
00332 // Local Variables:
00333 // mode: C++
00334 // End:

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