/Users/jamian/Desktop/gecode-2.0.1/contribs/qecode/examples/MatrixGame.cpp

Go to the documentation of this file.
00001 /****   , [ MatrixGame.cpp ], 
00002 Copyright (c) 2007 Universite d'Orleans - Arnaud Lallouet 
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a copy
00005 of this software and associated documentation files (the "Software"), to deal
00006 in the Software without restriction, including without limitation the rights
00007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008 copies of the Software, and to permit persons to whom the Software is
00009 furnished to do so, subject to the following conditions:
00010 
00011 The above copyright notice and this permission notice shall be included in
00012 all copies or substantial portions of the Software.
00013 
00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020 THE SOFTWARE.
00021  *************************************************************************/
00022 
00023 #include <cstdlib> /* pour srand, rand et RAND_MAX */
00024 #include <ctime> /* pour time */
00025 #include <math.h> /* pour pow */
00026 
00027 #include <iostream>
00028 
00029 #include "gecode/minimodel.hh"
00030 #include "gecode/int/element.hh"
00031 
00032 #include "qsolver.hh"
00033 #include "implicative.hh"
00034 #include "SDFVariableHeuristic.hh"
00035 #include "NaiveValueHeuristics.hh"
00036 
00037 #define UNIVERSAL true
00038 #define EXISTENTIAL false
00039 
00040 // The Matrix game consists in a square boolean matrix of size 2^depth. First player cuts it vertically in two parts and removes one half,
00041 // while secodn player do the same, but cutting the matrix horizontally. The game ends when there are only one cell left in the matrix. 
00042 // If this last cell has value 1, the first player wins. If it has value 0, the second player wins. 
00043 
00044 // The present model of this game is pure QBF, that QeCode can handle (though not as fast as QBF solvers...)
00045 
00046 using namespace MiniModel;
00047 
00048 int main (int argc, char * const argv[]) {
00049     
00050     int depth = 6;  // Size of the matrix is 2^depth. Larger values may take long to solve...
00051     int nbDecisionVar = 2*depth;
00052     int nbScope = nbDecisionVar+1;
00053     int boardSize = (int)pow((double)2,(double)depth);
00054     
00055     std::srand(std::time(NULL));
00056     
00057     IntArgs board(boardSize*boardSize);
00058     for (int i=0; i<boardSize; i++)
00059         for (int j=0; j<boardSize; j++)
00060             board[j*boardSize+i] = (int)( (double)rand()  /  ((double)RAND_MAX + 1) * 50 ) < 25 ? 0:1;
00061     
00062     IntArgs access(nbDecisionVar);
00063     access[nbDecisionVar-1]=1;
00064     access[nbDecisionVar-2]=boardSize;
00065     for (int i=nbDecisionVar-3; i>=0; i--)
00066         access[i]=access[i+2]*2;
00067          
00068     // debug
00069     for (int i=0; i<boardSize; i++)
00070     {
00071         for (int j=0; j<boardSize; j++)
00072             cout << board[j*boardSize+i] << " ";
00073         cout << endl;
00074          }
00075     cout  << endl;
00076     for (int i=0; i<nbDecisionVar; i++)
00077         cout << access[i] << " ";
00078     cout << endl;
00079     // end debug
00080     
00081     int *scopesSize = new int[nbScope];
00082     for (int i=0; i<nbScope-1; i++)
00083         scopesSize[i]=1;
00084     scopesSize[nbScope-1]=2;
00085     
00086     Implicative p(nbScope, QECODE_EXISTENTIAL, scopesSize);
00087     
00088     // Defining the variable of the n first scopes ...
00089     for (int i=0; i<nbDecisionVar; i++)
00090     {
00091         p.QIntVar(i, 0, 1);
00092         p.nextScope();
00093     }
00094          
00095     // Declaring last scope variables ...
00096     
00097     p.QIntVar(nbDecisionVar, 0, 1);
00098     p.QIntVar(nbDecisionVar+1, 0, boardSize*boardSize);
00099     p.nextScope();
00100     // Body
00101     
00102     post(p.space(), p.var(nbDecisionVar) == 1);
00103     
00104     IntVarArgs X(nbDecisionVar);
00105     for (int i=0; i<nbDecisionVar; i++)
00106         X[i]=p.var(i);
00107     
00108     linear(p.space(), access, X, IRT_EQ, p.var(nbDecisionVar+1));
00109     //  MiniModel::LinRel R(E, IRT_EQ, MiniModel::LinExpr(p.var(nbDecisionVar+1)));
00110     element(p.space(), board, p.var(nbDecisionVar+1), p.var(nbDecisionVar));
00111     
00112     // When every variables and constraints have been declared, the makeStructure method
00113     // must be called in order to lead the problem ready for solving.
00114     p.makeStructure();
00115     
00116     /*
00117      cout << (p.quantification(0)==UNIVERSAL? "universal" : "existential") << "-0\n";
00118      cout << "  " << (p.quantification(1)==UNIVERSAL? "universal" : "existential") << "-1\n";
00119      cout << "    " << (p.quantification(2)==UNIVERSAL? "universal" : "existential") << "-2\n";
00120      cout << "      " << (p.quantification(3)==UNIVERSAL? "universal" : "existential") << "-3\n";
00121      cout << "        " << (p.quantification(4)==UNIVERSAL? "universal" : "existential") << "-4\n";
00122      
00123      */
00124     
00125     // We will use a Smallest Domain First branching heuristic for solving this problem.
00126     SmallestDomainFirst heur;
00127     SmallestValueFirst v_heur;
00128     
00129     // So, we build a quantified solver for our problem p, using the heuristic we just created.
00130     QSolver solver(&p,&heur, &v_heur);
00131     
00132     unsigned long int nodes=0;
00133     unsigned long int steps=0;
00134     
00135     // then we solve the problem. Nodes and Steps will contain the number of nodes encountered and
00136     // of propagation steps achieved during the solving.
00137     bool outcome = solver.solve(nodes,steps);
00138     
00139     cout << "  outcome: " << ( outcome? "TRUE" : "FALSE") << endl;
00140     cout << "  nodes visited: " << nodes << " " << steps << endl;
00141     
00142     return outcome? 10:20;
00143     
00144 }

Generated on Thu Feb 7 14:33:45 2008 for qecode by  doxygen 1.5.2