/Users/jamian/Desktop/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 
00035 #define UNIVERSAL true
00036 #define EXISTENTIAL false
00037 
00038 // 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,
00039 // while secodn player do the same, but cutting the matrix horizontally. The game ends when there are only one cell left in the matrix. 
00040 // If this last cell has value 1, the first player wins. If it has value 0, the second player wins. 
00041 
00042 // The present model of this game is pure QBF, that QeCode can handle (though not as fast as QBF solvers...)
00043 
00044 using namespace MiniModel;
00045 
00046 int main (int argc, char * const argv[]) {
00047     
00048     int depth = 5;  // Size of the matrix is 2^depth. Larger values may take long to solve...
00049     int nbDecisionVar = 2*depth;
00050     int nbScope = nbDecisionVar+1;
00051     bool* qtScopes = new bool[nbScope];
00052     for (int i=0;i<nbScope;i++) { 
00053         qtScopes[i] = ((i%2) != 0);
00054         cout << (((i%2) != 0)?"true":"false")<<endl;
00055     }
00056     int boardSize = (int)pow((double)2,(double)depth);
00057     
00058     std::srand(std::time(NULL));
00059     
00060     IntArgs board(boardSize*boardSize);
00061     for (int i=0; i<boardSize; i++)
00062         for (int j=0; j<boardSize; j++)
00063             board[j*boardSize+i] = (int)( (double)rand()  /  ((double)RAND_MAX + 1) * 50 ) < 25 ? 0:1;
00064     
00065     IntArgs access(nbDecisionVar);
00066     access[nbDecisionVar-1]=1;
00067     access[nbDecisionVar-2]=boardSize;
00068     for (int i=nbDecisionVar-3; i>=0; i--)
00069         access[i]=access[i+2]*2;
00070          
00071     // debug
00072     for (int i=0; i<boardSize; i++)
00073     {
00074         for (int j=0; j<boardSize; j++)
00075             cout << board[j*boardSize+i] << " ";
00076         cout << endl;
00077          }
00078     cout  << endl;
00079     for (int i=0; i<nbDecisionVar; i++)
00080         cout << access[i] << " ";
00081     cout << endl;
00082     // end debug
00083     
00084     int *scopesSize = new int[nbScope];
00085     for (int i=0; i<nbScope-1; i++)
00086         scopesSize[i]=1;
00087     scopesSize[nbScope-1]=2;
00088     
00089     Implicative p(nbScope, qtScopes, scopesSize);
00090     
00091     // Defining the variable of the n first scopes ...
00092     for (int i=0; i<nbDecisionVar; i++)
00093     {
00094         p.QIntVar(i, 0, 1);
00095         IntVarArgs b(i+1);
00096         for (int plop=0;plop<(i+1);plop++) 
00097             b[plop] = p.var(plop);
00098         branch(p.space(),b,INT_VAR_SIZE_MIN,INT_VAL_MIN);
00099         p.nextScope();
00100     }
00101          
00102     // Declaring last scope variables ...
00103     
00104     p.QIntVar(nbDecisionVar, 0, 1);
00105     p.QIntVar(nbDecisionVar+1, 0, boardSize*boardSize);
00106     IntVarArgs b(nbDecisionVar+2);
00107     for (int plop=0;plop<(nbDecisionVar+2);plop++) 
00108         b[plop] = p.var(plop);
00109     branch(p.space(),b,INT_VAR_SIZE_MIN,INT_VAL_MIN);
00110     
00111     p.nextScope();
00112     // Body
00113     
00114     post(p.space(), p.var(nbDecisionVar) == 1);
00115     
00116     IntVarArgs X(nbDecisionVar);
00117     for (int i=0; i<nbDecisionVar; i++)
00118         X[i]=p.var(i);
00119     
00120     linear(p.space(), access, X, IRT_EQ, p.var(nbDecisionVar+1));
00121     //  MiniModel::LinRel R(E, IRT_EQ, MiniModel::LinExpr(p.var(nbDecisionVar+1)));
00122     element(p.space(), board, p.var(nbDecisionVar+1), p.var(nbDecisionVar));
00123     
00124     // When every variables and constraints have been declared, the makeStructure method
00125     // must be called in order to lead the problem ready for solving.
00126     p.makeStructure();
00127     
00128     // So, we build a quantified solver for our problem p, using the heuristic we just created.
00129     QSolver solver(&p);
00130     
00131     unsigned long int nodes=0;
00132     
00133     // then we solve the problem. Nodes and Steps will contain the number of nodes encountered and
00134     // of propagation steps achieved during the solving.
00135     Strategy outcome = solver.solve(nodes);
00136     
00137     cout << "  outcome: " << ( outcome.isFalse()? "FALSE" : "TRUE") << endl;
00138     cout << "  nodes visited: " << nodes << endl;
00139     
00140 }

Generated on Tue Jun 10 18:31:30 2008 for qecode by  doxygen 1.5.2