this repo has no description
1/**** , [ MatrixGame.cpp ], 2Copyright (c) 2007 Universite d'Orleans - Arnaud Lallouet 3 4Permission is hereby granted, free of charge, to any person obtaining a copy 5of this software and associated documentation files (the "Software"), to deal 6in the Software without restriction, including without limitation the rights 7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8copies of the Software, and to permit persons to whom the Software is 9furnished to do so, subject to the following conditions: 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20THE SOFTWARE. 21 *************************************************************************/ 22 23#include <cstdlib> /* for srand, rand et RAND_MAX */ 24#include <ctime> /* for time */ 25#include <math.h> /* for pow */ 26 27#include <iostream> 28 29#include <gecode/minimodel.hh> 30#include <gecode/int/element.hh> 31 32#include "qsolver_qcsp.hh" 33#include "QCOPPlus.hh" 34 35#define UNIVERSAL true 36#define EXISTENTIAL false 37 38// 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, 39// while secodn player do the same, but cutting the matrix horizontally. The game ends when there are only one cell left in the matrix. 40// If this last cell has value 1, the first player wins. If it has value 0, the second player wins. 41 42// The present model of this game is pure QBF, that QeCode can handle (though not as fast as QBF solvers...) 43 44using namespace MiniModel; 45 46int main (int argc, char * const argv[]) { 47 48 int depth = 5; // Size of the matrix is 2^depth. Larger values may take long to solve... 49 int nbDecisionVar = 2*depth; 50 int nbScope = nbDecisionVar+1; 51 bool* qtScopes = new bool[nbScope]; 52 for (int i=0;i<nbScope;i++) { 53 qtScopes[i] = ((i%2) != 0); 54// cout << (((i%2) != 0)?"true":"false")<<endl; 55 } 56 int boardSize = (int)pow((double)2,(double)depth); 57 58 std::srand(std::time(NULL)); 59 60 IntArgs board(boardSize*boardSize); 61 for (int i=0; i<boardSize; i++) 62 for (int j=0; j<boardSize; j++) 63 board[j*boardSize+i] = (int)( (double)rand() / ((double)RAND_MAX + 1) * 50 ) < 25 ? 0:1; 64 65 IntArgs access(nbDecisionVar); 66 access[nbDecisionVar-1]=1; 67 access[nbDecisionVar-2]=boardSize; 68 for (int i=nbDecisionVar-3; i>=0; i--) 69 access[i]=access[i+2]*2; 70 71 // debug 72 for (int i=0; i<boardSize; i++) 73 { 74 for (int j=0; j<boardSize; j++) 75 cout << board[j*boardSize+i] << " "; 76 cout << endl; 77 } 78 cout << endl; 79 // for (int i=0; i<nbDecisionVar; i++) 80// cout << access[i] << " "; 81// cout << endl; 82 // end debug 83 84 int * scopesSize = new int[nbScope]; 85 for (int i=0; i<nbScope-1; i++) 86 scopesSize[i]=1; 87 scopesSize[nbScope-1]=2; 88 89 Qcop p(nbScope, qtScopes, scopesSize); 90 91 // Defining the variable of the n first scopes ... 92 for (int i=0; i<nbDecisionVar; i++) 93 { 94 p.QIntVar(i, 0, 1); 95 IntVarArgs b(i+1); 96 for (int plop=0;plop<(i+1);plop++) 97 b[plop] = p.var(plop); 98 branch(*(p.space()),b,INT_VAR_SIZE_MIN(),INT_VAL_MIN()); 99 p.nextScope(); 100 } 101 102 // Declaring last scope variables ... 103 104 p.QIntVar(nbDecisionVar, 0, 1); 105 p.QIntVar(nbDecisionVar+1, 0, boardSize*boardSize); 106 IntVarArgs b(nbDecisionVar+2); 107 for (int plop=0;plop<(nbDecisionVar+2);plop++) 108 b[plop] = p.var(plop); 109 branch(*(p.space()),b,INT_VAR_SIZE_MIN(),INT_VAL_MIN()); 110 111 p.nextScope(); 112 // Body 113 114 rel(*(p.space()), p.var(nbDecisionVar) == 1); 115 116 IntVarArgs X(nbDecisionVar); 117 for (int i=0; i<nbDecisionVar; i++) 118 X[i]=p.var(i); 119 120 linear(*(p.space()), access, X, IRT_EQ, p.var(nbDecisionVar+1)); 121 // MiniModel::LinRel R(E, IRT_EQ, MiniModel::LinExpr(p.var(nbDecisionVar+1))); 122 element(*(p.space()), board, p.var(nbDecisionVar+1), p.var(nbDecisionVar)); 123 124 // Note : declaring a brancher for the goal is not mandatory, as the goal will be tested only when all variables are assigned. 125 126 // When every variables and constraints have been declared, the makeStructure method 127 // must be called in order to lead the problem ready for solving. 128 p.makeStructure(); 129 130 // So, we build a quantified solver for our problem p, using the heuristic we just created. 131 QCSP_Solver solver(&p); 132 133 unsigned long int nodes=0; 134 135 // then we solve the problem. Nodes and Steps will contain the number of nodes encountered and 136 // of propagation steps achieved during the solving. 137 Strategy outcome = solver.solve(nodes); 138 139 cout << " outcome: " << ( outcome.isFalse()? "FALSE" : "TRUE") << endl; 140 cout << " nodes visited: " << nodes << endl; 141 142}