#################################################################################
print "Chargement du module variable et noeud pour PSC"
print "\t@version: 1.0 date: 1/05/2006 modified by the vincent.schickel-zuber@epfl.ch"
print "\t@author: vincent.schickel-zuber@epfl.ch date: 1/05/2006"
print "\t@copyright: EPFL-IC-IIF-LIA 2006"
#################################################################################
import copy
import libPSC
import PSC
##le symbol vide dans la grille = 0
X = 0
##le domaine des variables
DOMAINE=range(1,10)
##contient l'ennonce de depart
PROBLEME=[]
##defini la grille du sudoku
GRILLE=[[]]
##nombre de collone de la grille
NBCOL=9
##nombre de ligne de la grille
NBLGN=9
NOEUDS = PSC.Noeuds()
ARCS = PSC.Arcs()
##taille des sous grille
TAILLESOUSGRILLE=3
##retourne la position de la ss_grille correspondant a la position absolue
##@pos la position absolue
def retournePosSSGille(pos):
return pos/TAILLESOUSGRILLE
##retourne la position DANS dans la ss_grille correspondant a la position absolue
##@pos la position absolue
def retournePosINSSGille(pos):
return pos%TAILLESOUSGRILLE
## verifie si un symbole passe en parametre = symbole vide
def estVide(symb):
return symb==X
##definit une sous grille (qui fera partie de la grille)
class SSGrille:
##constructeur
##@param posL la position sur la ligne[0..2]
##@param posC la position dans la colonne[0..2]
def __init__(self, posL,posC):
global X
global DOMAINE
self.posL=posL
self.posC=posC
self.ssgrille=[]
self.notPossible=[]
##self.domaine=copy.deepcopy(DOMAINE)
for i in range(0,TAILLESOUSGRILLE):
self.ssgrille.append([])
for i in range(0,TAILLESOUSGRILLE):
for j in range(0,TAILLESOUSGRILLE):
id="v["+str(self.posL)+","+str(self.posC)+"]["+str(i)+","+str(j)+"]"
noeud = libPSC.Noeud(libPSC.Variable(id,DOMAINE))
self.ssgrille[i].append(noeud)
NOEUDS.ajouteNoeud(noeud)
##met a jour la valeur du noeud dans la sous grille a un endroit specifique
##@param valeur la valeur de la variable
##@param domaine le domaine de la variable
##@param posX la position en X
##@param posY la position en Y
def ajouteNoeud(self, valeur, domaine , posX,posY):
global X
self.ssgrille[posX][posY].refVar.metAJourValeur(valeur)
if valeur in DOMAINE:
##self.domaine.remove(valeur)
self.ssgrille[posX][posY].refVar.domaine=[valeur]
self.notPossible.append(valeur)
else:
self.ssgrille[posX][posY].refVar.domaine=copy.deepcopy(DOMAINE)
##retourne la coordonne absolue d'un element dans la grille
##@param x la position en axe x dans la sous-grille
##@param y la position en axe y dans la sous-grille
##@ret (x_abolue,y_abolue)
def positionAbolue(self,x,y):
global TAILLESOUSGRILLE
posx=self.posL*TAILLESOUSGRILLE+x
posy=self.posC*TAILLESOUSGRILLE+y
return (posx,posy)
##retourne la valeur a une position donnee
def valeur(self,posX,posY):
return self.ssgrille[posX][posY].refVar.valeur
## genre toutes les contraintes de groupes
def genereContraintesSSGrille(self):
global NBLGN
for i in range(0,TAILLESOUSGRILLE):
for j in range(0,TAILLESOUSGRILLE):
for k in range(0,TAILLESOUSGRILLE):
for l in range(0,TAILLESOUSGRILLE):
if i<>k and j<>l:
n1=self.ssgrille[i][j]
n2=self.ssgrille[k][l]
c=libPSC.ContrainteBinaire(n1.refVar,"<>",n2.refVar)
c2=libPSC.ContrainteBinaire(n2.refVar,"<>",n1.refVar)
ARCS.ajouteArc(libPSC.Arc(c2))
ARCS.ajouteArc(libPSC.Arc(c))
##definit la grille, qui est faite de 9 sous grille
class Grille:
##constructeur
##initilaise la variable globale GRILLE
def __init__(self):
self.init()
##initialise la grille avec le contenu du probleme
def init(self):
global GRILLE
global PROBLEME
global TAILLESOUSGRILLE
global GRILLE
global NBLGN
global NBCOL
del GRILLE[:]
for i in range(0,TAILLESOUSGRILLE):
GRILLE.append([])
##remplit la grille de sous-grille
ssgrillecol=0
ssgrillelgn=0
for i in range(0,TAILLESOUSGRILLE):
for j in range(0,TAILLESOUSGRILLE):
GRILLE[i].append(SSGrille(i,j))
##remplit les sous-grille
ssgrillecol=0
ssgrillelgn=0
for i in range(0,NBLGN):
ssgrillecol=0
if i>0 and i%TAILLESOUSGRILLE==0:
ssgrillelgn+=1
for j in range(0,NBCOL):
if j>0 and j%TAILLESOUSGRILLE==0:
ssgrillecol+=1
if not (PROBLEME[i][j]==X):
GRILLE[retournePosSSGille(i)][retournePosSSGille(j)].ajouteNoeud(PROBLEME[i][j],[PROBLEME[i][j]],retournePosINSSGille(i),retournePosINSSGille(j))
else:
GRILLE[retournePosSSGille(i)][retournePosSSGille(j)].ajouteNoeud(PROBLEME[i][j],DOMAINE,retournePosINSSGille(i),retournePosINSSGille(j))
##GRILLE[retournePosSSGille(i)][retournePosSSGille(j)].ssgrille[retournePosINSSGille(i)][retournePosINSSGille(j)].refVar.metAJourValeur(PROBLEME[i][j])
self.retourneNoeud(i,j).refVar.metAJourValeur(PROBLEME[i][j])
##retourne la grille en string
def __str__(self):
global NBLGN
global NBCOL
global GRILLE
ssgrillecol=0
ssgrillelgn=0
ligne=""
for i in range(0,NBLGN):
ssgrillecol=0
if i>0 and i%TAILLESOUSGRILLE==0:
ssgrillelgn+=1
ligne+="\t"
for j in range(0,NBCOL):
if j>0 and j%TAILLESOUSGRILLE==0:
ssgrillecol+=1
ligne+=str(GRILLE[retournePosSSGille(i)][retournePosSSGille(j)].valeur(retournePosINSSGille(i),retournePosINSSGille(j)))+" "
ligne+="\n"
return ligne
##retourne un noeud se trouvant une position en valeur absolue
##@param posX la position absolue X
##@param posY la position absolue Y
def retourneNoeud(self,posX,posY):
n=GRILLE[retournePosSSGille(posX)][retournePosSSGille(posY)].ssgrille[retournePosINSSGille(posX)][retournePosINSSGille(posY)]
return n
## genere toutes les contraintes de lignes
def genereContraintesLignes(self):
global NBLGN
for i in range(0,NBCOL):
for j in range(0,NBLGN):
for k in range(j+1,NBLGN):
n1=self.retourneNoeud(j,i)
n2=self.retourneNoeud(k,i)
c=libPSC.ContrainteBinaire(n1.refVar,"<>",n2.refVar)
c2=libPSC.ContrainteBinaire(n2.refVar,"<>",n1.refVar)
ARCS.ajouteArc(libPSC.Arc(c2))
ARCS.ajouteArc(libPSC.Arc(c))
## genere toutes les contraintes de colonne
def genereContraintesColonnes(self):
global NBLGN
for i in range(0,NBLGN):
for j in range(0,NBCOL):
for k in range(j+1,NBCOL):
n1=self.retourneNoeud(i,j)
n2=self.retourneNoeud(i,k)
c=libPSC.ContrainteBinaire(n1.refVar,"<>",n2.refVar)
c2=libPSC.ContrainteBinaire(n2.refVar,"<>",n1.refVar)
ARCS.ajouteArc(libPSC.Arc(c2))
ARCS.ajouteArc(libPSC.Arc(c))
##genere toutes les contraintes de sous-grille
def genereContraintesSSGrilles(self):
for i in range(0,TAILLESOUSGRILLE):
for j in range(0,TAILLESOUSGRILLE):
GRILLE[i][j].genereContraintesSSGrille()
## initialise le jeu (la grille) et trouve la solution
def run(algo,grille):
print "|+| Chargement du probleme"
global PROBLEME
if grille=="A":
PROBLEME=[[9,X,X,X,X,X,X,X,2],
[3,X,7,1,X,X,4,X,8],
[X,1,X,X,5,4,X,6,X],
[X,X,1,X,X,X,X,7,X],
[X,X,4,X,X,X,9,X,X],
[X,2,X,X,X,X,8,X,X],
[X,8,X,3,2,X,X,4,X],
[7,X,3,X,X,6,2,X,1],
[4,X,X,X,X,X,X,X,5]]
elif grille=="B":
PROBLEME=[[1,X,4,X,X,8,X,5,2],
[8,X,X,4,X,X,9,X,X],
[X,5,X,X,9,1,X,X,8],
[3,X,2,7,X,5,X,1,X],
[X,X,6,X,X,X,5,X,X],
[X,7,X,1,X,2,8,X,4],
[7,X,X,3,8,X,X,9,X],
[X,X,5,X,X,4,X,X,6],
[9,6,X,5,X,X,1,X,3]]
else:
print "|-| Grille" ,grille,"pas definit"
global NOEUDS
global ARCS
NOEUDS = PSC.Noeuds()
ARCS = PSC.Arcs()
print "|+| Initialisation de la grille"
grille = Grille()
print grille
print "|+| Ajoute les contraintes"
grille.genereContraintesLignes()
grille.genereContraintesColonnes()
grille.genereContraintesSSGrilles()
print "|+| Fait la consitance des noeuds"
NOEUDS.consistanceDesNoeuds()
##print NOEUDS
print "|+| Fait la consitance des arcs"
ARCS.consistanceDesArcs()
##print ARCS
print grille
PSC.variableOrdering()
if algo=="FC":
sol=PSC.forwardChecking(NOEUDS.instances(),0,False,True)
else:
sol=PSC.backtrack(NOEUDS.instances(),0,False,True)
print grille
## genre toutes les contraintes de lignes
## @param grille l'objet
#################################################################################################################
##run
run("FC","A")