diff --git a/lab6/PSC.py b/lab6/PSC.py new file mode 100644 index 0000000..da2a205 --- /dev/null +++ b/lab6/PSC.py @@ -0,0 +1,180 @@ +import libPSC +import copy +################################################################################# +print "Chargement du module PSC" +print "\t@version: 1.1 date: 24/04/2006 modified by the vincent.schickel-zuber@epfl.ch" +print "\t@author: vincent.schickel-zuber@epfl.ch date: 24/04/2006" +print "\t@copyright: EPFL-IC-IIF-LIA 2006" +################################################################################# + +##contient tous les noeuds +NOEUDS=[] + +##contient tous les arcs +ARCS=[] + +##valeur retournee en cas d'echec +ECHEC='echec' + +##contient le nombre d'iteration de l'algorithme +ITERATION = 0 + +##contient les solutions de l'algorithme +SOLUTION=[] + +##retourne toutes les contraintes unaires pour un noeud donnne +##@param noeud le noeud +def retourneContraintesUnaires(noeud): + contraintes=[] + for a in ARCS: + if a.refContrainte.depart==noeud.refVar and a.refContrainte.arrive==noeud.refVar: + contraintes.append(a.refContrainte) + return contraintes + +##retourne toutes les contraintes binaires pour deux noeuds donnnes +##@param noeud1 le noeud 1 +##@param noeud2 le noeud 2 +##@ret toutes les contraintes bineaires ente n1 et n2 +def retourneContraintesBinaires(noeud1,noeud2): + contraintes=[] + for a in ARCS: + if (a.refContrainte.depart==noeud1.refVar and a.refContrainte.arrive==noeud2.refVar) or (a.refContrainte.depart==noeud2.refVar and a.refContrainte.arrive==noeud1.refVar): + if a.refContrainte not in contraintes: + contraintes.append(a.refContrainte) + return contraintes + + + +##affiche la solution avec queques informations utile +##@param algo le nom de l'algo +##@param solution la solution trouvee +def afficheSolution(algo,solution): + print "\t",algo,": SOLUTION TROUVEE en ",ITERATION,"etapes et avec ",libPSC.NBCONTRAINTE," contraintes verifiees; SOLUTION=",solution + +##affiche le nombre d'iteration avec queques informations utile +##@param algo le nom de l'algo +##@param k la pronfondeur actuelle +def afficheNbIteration(algo,k): + print algo,": Ieration:=",ITERATION," pronfondeur actuelle:=",k ,"et",libPSC.NBCONTRAINTE," contraintes verifiees" + +##gere tous les noeuds dans NOEUDS +class Noeuds: + + ##initialise le tableau de noeuds + def __init__(self): + NOEUDS=[] + + ##retourne le noeud referencant le variable ayant un nom=nom + ##@param nom le nom de la variable + ##@ret le noeud, -1 si pas trouv�e + def retourneNoeud(self, nom): + for noeud in NOEUDS: + if noeud.refVar.nomEstEgalle(nom): + return noeud + return -1 + + ##ajoute un noeud a la lite + def ajouteNoeud(self,noeud): + NOEUDS.append(noeud) + + ##applique la consitance des noeuds + def consistanceDesNoeuds(self): + for n in NOEUDS: + n.consitanceDuNoeud(A COMPETER); + + ##affiche tous les noeuds + def __str__(self): + str = "Noeuds\n" + for n in NOEUDS: + str+="\t1. "+ n.__str__()+"\n" + return str + + +##gere tous les noeuds dans ARCS +class Arcs: + + ##initialise le tableau des ARCS + def __init__(self): + ARCS=[] + + ##ajoute un arc a la lite + def ajouteArc(self,arc): + ARCS.append(arc) + + ##retourne tous les arcs unaire pour un noeud donnne + ##@param noeud le noeud + def retourneArcs(noeud): + arcs2 + for a in ARCS: + if a.refContrainte.depart==noeud.refVar and a.refContrainte.arrive==noeud.refVar: + arcs2.append(a) + return arcs2 + + ##applique la consitance des arcs + def consistanceDesArcs(self): + .... A FAIRE + + ##affiche tous les noeuds + def __str__(self): + str = "Arcs\n" + for n in ARCS: + str+="\t1. "+ n.__str__()+"\n" + return str + +## Algorithme de Bactrack simple +## @param instances les n variables; rempli jusqu'a k +## @param k la pronfondeur de la recherce (commence a 0) +## @param toutesLesSolutions si True alors cherche TOUTES les solutions, sinon s'arrete a la premiere (valeur oar defaut) +## @param initialise initialise les variables gloabl ITEARTION et SOLUTION +## @ret instances contenant la solution OU echec si aucune solution trouv�e +def backtrack(instances, k, touteLesSoltuions=None, initialise=None): + algo="bt" + global ITERATION + global SOLUTION + + if touteLesSoltuions==None: + touteLesSoltuions=False + if initialise==None: + ITERATION=0 + SOLUTION=[] + libPSC.NBCONTRAINTE=0 + initialise=False + + ITERATION=ITERATION+1 + + print "....." + afficheSolution(algo,instances) + print "....." + + return ECHEC + + +## Algorithme de Forward Chekcing simple +## @param instances les n variables; rempli jusqu'a k +## @param k la pronfondeur de la recherce (commence a 0) +## @param toutesLesSolutions si True alors cherche TOUTES les solutions, sinon s'arrete a la premiere (valeur oar defaut) +## @param initialise initialise les variables gloabl ITEARTION et SOLUTION, et le laebl des noeuds +## @ret instances contenant la solution OU echec si aucune solution trouv�e +def forwardChecking(instances, k, touteLesSoltuions=None, initialise=None): + algo="ft" + global ITERATION + global SOLUTION + if touteLesSoltuions==None: + touteLesSoltuions=False + if initialise==None: + ITERATION=0 + SOLUTION=[] + libPSC.NBCONTRAINTE=0 + initLabelDesVarrables() + initialise=False + + ITERATION=ITERATION+1 + afficheNbIteration(algo,k) + print "....." + afficheSolution(algo,instances) + print "....." + + return ECHEC + +execfile("testConsistance.py") +##execfile("test.py") \ No newline at end of file diff --git a/lab6/libPSC.py b/lab6/libPSC.py new file mode 100644 index 0000000..39e7bc0 --- /dev/null +++ b/lab6/libPSC.py @@ -0,0 +1,220 @@ +################################################################################# +print "Chargement du module variable et noeud pour PSC" +print "\t@version: 1.1 date: 24/04/2006 modified by the vincent.schickel-zuber@epfl.ch" +print "\t@author: vincent.schickel-zuber@epfl.ch date: 24/04/2006" +print "\t@copyright: EPFL-IC-IIF-LIA 2006" +################################################################################# +import copy + +##contient le nombre de contraintes visitees +NBCONTRAINTE=0 + +##Classe modelisant une Variable +class Variable: + + ##Constructeur de la classe variable + ##INITIALISE valeur = -1 + ##@param nom le nom de la variable; sert d'identifiant + ##@param domaine le domaine de valeur sous fourme [] + def __init__(self, nom, domaine): + self.nom=nom + self.domaine=domaine + self.valeur=-1 + + + ##met a jour la valeur + ##@param valeur la nouvelle valeur + def metAJourValeur(self,valeur): + self.valeur=valeur + + ##Verifie que le nom est egalle a celui passe en parametre + ##@param nom un nom a verifier + ##@ret true <=>self.nom=nom + def nomEstEgalle(self,nom): + return self.nom==nom + + ## retourne la taille du domaine + def tailleDuDomaine(self): + return len(self.domaine) + + ## retourne true <=> le domaine est vide + def domaineEstVide(self): + self.tailleDuDomaine()==0; + + ##retourne une representation en String de la Variable + def __str__(self): + str = "var : < %s , %s >" %(self.nom, self.domaine) + return str + +##class Contrainte: +class Contrainte: + + ##constructeur + ##@param depart la variable de depart + ##@param arrive la variable d'arrive + def __init__(self,depart,arrive): + self.depart=depart + self.arrive=arrive + + ##retournce la dimension + def dimension(self): + return 0 + + ## verifie que la valeur de la variable 1 et 2 sont valide avec la contrainte + ## @return true <=> valide + def estValide(self): + print "coucou" + + ##retourne une representation en String de la contrainte + def __str__(self): + str = "contrainte : < %s , %s >" %(self.depart.nom, self.arrive.nom) + return str + +##Classe modelisant une contraite unaire +class ContrainteUnaire(Contrainte): + + ##constructeur + ##@param ref valeur de reference + ##@param op "<" || "<=" + ##@param refVar reference sur la variable + def __init__(self,refVar,op,ref): + Contrainte.__init__(self,refVar,refVar) + self.ref=ref + self.op=op + self.refVar=refVar + + ##retournce la dimension + def dimension(self): + return 1 + + ## verifie que la valeur de la variable est valide avec la contrainte + ## @param valeur la valeur a verifier + ## @return true <=> valide + def estValide(self): + global NBCONTRAINTE + NBCONTRAINTE+=1 + if (self.op=="<"): + return self.refVar.valeur" || "==" + ##@param refVar1 reference sur la variable 1 + ##@param refVar2 reference sur la variable 2 + def __init__(self,refVar1,op,refVar2): + Contrainte.__init__(self,refVar1,refVar2) + self.refVar1=refVar1 + self.op=op + self.refVar2=refVar2 + + ##retournce la dimension + def dimension(self): + return 2 + + ## verifie que la valeur de la variable 1 et 2 sont valide avec la contrainte + ## @return true <=> valide + def estValide(self): + global NBCONTRAINTE + NBCONTRAINTE+=1 + if (self.op=="<>"): + return self.refVar1.valeur<>self.refVar2.valeur + elif (self.op=="=="): + return self.refVar1.valeur==self.refVar2.valeur + else: + print "|-| Operateur", self.op, "non implemente" + return false + + ## verifie que si la valeur de la variable 1 , alors la contrainte n'es pas violee + ## @return true <=> possible + def estPossible(self): + global NBCONTRAINTE + uneVraie = lambda x, y : x or y + results=[] + if len(self.refVar2.domaine)==0 : + return False + for d in self.refVar2.domaine: + NBCONTRAINTE+=1 + self.refVar2.metAJourValeur(d) + if (self.op=="<>"): + results.append(self.refVar1.valeur<>self.refVar2.valeur) + elif (self.op=="=="): + results.append(self.refVar1.valeur==self.refVar2.valeur) + else: + print "|-| Operateur", self.op, "non implemente" + results.append(false) + return reduce(uneVraie,results) + + ## verifie que si la valeur de la variable 1 , alors la contrainte n'es pas violee + ## @return true <=> possible + def estPossibleAvecLabel(self): + global NBCONTRAINTE + uneVraie = lambda x, y : x or y + results=[] + if len(self.refVar2.label)==0: + return False + for d in self.refVar2.label: + NBCONTRAINTE+=1 + self.refVar2.metAJourValeur(d) + if (self.op=="<>"): + results.append(self.refVar1.valeur<>self.refVar2.valeur) + elif (self.op=="=="): + results.append(self.refVar1.valeur==self.refVar2.valeur) + else: + print "|-| Operateur", self.op, "non implemente" + results.append(false) + return reduce(uneVraie,results) + + ##retourne une representation en String de la contrainte + def __str__(self): + str = "contrainte : < %s , %s , %s >" %(self.refVar1.nom, self.op, self.refVar2.nom) + return str + +##Classe modelisant un Noeud +class Noeud: + + ##constructeur + ##l'attribut pos est initialise a 0 + ##@param variable la variable referencee + def __init__(self,variable): + self.refVar=variable + + + ##fait la consitance du noeud + ##@param contraintes la liste de contraintes unaires pour ce noeud + def consitanceDuNoeud(self,contraintes): + ... A IMPLEMENTER + + ##retourne une representation en String de la Variable + def __str__(self): + str = "Noeud -> %s " %(self.refVar) + return str + +##classe modelisant un arc +class Arc: + + ##constructeur + ##@param contrainte la contrainte referencee + def __init__(self,contrainte): + self.refContrainte=contrainte + + ##revise la consistance des valeurs de domaine piur la contrainte representee par cet arc + def reviser(self): + ... A IMPLEMENTER + + ##retourne une representation en String de l'arc + def __str__(self): + str = "Arc -> %s " %(self.refContrainte) + return str + \ No newline at end of file diff --git a/lab6/test.py b/lab6/test.py new file mode 100644 index 0000000..05abe7c --- /dev/null +++ b/lab6/test.py @@ -0,0 +1,47 @@ +noeuds = Noeuds() +arcs = Arcs() + +monDom = range(10) +monDom2 = range(11) +monDom3 = range(9) +v1=libPSC.Variable("a",monDom) +v2=libPSC.Variable("b",monDom2) +v3=libPSC.Variable("c",monDom3) + +noeuds.ajouteNoeud(libPSC.Noeud(v1)) +noeuds.ajouteNoeud(libPSC.Noeud(v2)) +noeuds.ajouteNoeud(libPSC.Noeud(v3)) +print noeuds +noeudb = noeuds.retourneNoeud("b") +print noeudb + +cv1= libPSC.ContrainteUnaire(v1,"<",2) +cv2= libPSC.ContrainteUnaire(v2,"<",3) +cv3= libPSC.ContrainteUnaire(v3,"<",3) +cv1v2= libPSC.ContrainteBinaire(v1,"<>",v2) +cv2v3= libPSC.ContrainteBinaire(v2,"<>",v3) +cv1v3= libPSC.ContrainteBinaire(v1,"<>",v3) +arcs.ajouteArc(libPSC.Arc(cv1)) +arcs.ajouteArc(libPSC.Arc(cv1)) +arcs.ajouteArc(libPSC.Arc(cv2)) +arcs.ajouteArc(libPSC.Arc(cv3)) +arcs.ajouteArc(libPSC.Arc(cv1v2)) +arcs.ajouteArc(libPSC.Arc(cv2v3)) +arcs.ajouteArc(libPSC.Arc(cv1v3)) +print arcs + + + +print "Fait la consitance des noeuds" +noeuds.consistanceDesNoeuds() +print noeuds + +print "Fait la consitance des arcs" +arcs.consistanceDesArcs() +print noeuds + +sol=backtrack([-1,-1,-1],0,True) +print "Solution trouv�e avec bt:=", SOLUTION + +sol=forwardChecking([-1,-1,-1],0,True) +print "Solution trouv�e avec fc:=", SOLUTION \ No newline at end of file diff --git a/lab6/testConsistance.py b/lab6/testConsistance.py new file mode 100644 index 0000000..a80dac5 --- /dev/null +++ b/lab6/testConsistance.py @@ -0,0 +1,41 @@ +print "TEST CONSISTANCE" +noeuds = Noeuds() +arcs = Arcs() + +monDom = range(10) +monDom2 = range(11) +monDom3 = range(9) +v1=libPSC.Variable("a",monDom) +v2=libPSC.Variable("b",monDom2) +v3=libPSC.Variable("c",monDom3) + +noeuds.ajouteNoeud(libPSC.Noeud(v1)) +noeuds.ajouteNoeud(libPSC.Noeud(v2)) +noeuds.ajouteNoeud(libPSC.Noeud(v3)) +print noeuds +noeudb = noeuds.retourneNoeud("b") +print noeudb + +cv1= libPSC.ContrainteUnaire(v1,"<",2) +cv2= libPSC.ContrainteUnaire(v2,"<",3) +cv3= libPSC.ContrainteUnaire(v3,"<",3) +cv1v2= libPSC.ContrainteBinaire(v1,"<>",v2) +cv2v3= libPSC.ContrainteBinaire(v2,"<>",v3) +cv1v3= libPSC.ContrainteBinaire(v1,"<>",v3) +arcs.ajouteArc(libPSC.Arc(cv1)) +arcs.ajouteArc(libPSC.Arc(cv1)) +arcs.ajouteArc(libPSC.Arc(cv2)) +arcs.ajouteArc(libPSC.Arc(cv3)) +arcs.ajouteArc(libPSC.Arc(cv1v2)) +arcs.ajouteArc(libPSC.Arc(cv2v3)) +arcs.ajouteArc(libPSC.Arc(cv1v3)) +print arcs + + +print "Fait la consitance des noeuds" +noeuds.consistanceDesNoeuds() +print noeuds + +print "Fait la consitance des arcs" +arcs.consistanceDesArcs() +print noeuds \ No newline at end of file