############################################################################### # questions 1 a 5 ############################################################################### def lit_fichier (nom) : """cette fonction lit le contenu d'un fichier et retourne une liste contenant ses lignes""" f = open (nom, "r") li = f.readlines () f.close () r =[] for l in li : s = l.replace ("\n", "") s = s.replace ("\r", "") r.append (s) return r def genre (prenom, femme, homme) : """retourne le genre d'un prenom""" if prenom in femme : return True if prenom in homme : return False return None def contrainte (table, femme, homme) : """cette fonction verifie que la table obeit aux contrainte d'Harmonie : il ne peut y avoir trois personnes voisines du meme sexe qui se suivent""" ge = [ genre (t,femme, homme) for t in table ] for i in range (0,len (ge)) : if ge [i] == ge [ (i+1) % len (ge) ] == ge [(i+2) % len (ge) ] : return False return True def dominique (table, femme, homme) : """cette fonction dit si on peut placer dominique, deux schemas de figures possibles : 1- H F dominique H F 2- F H dominique F H """ ge = [ genre (t,femme, homme) for t in table ] for i in range (0,len (ge)) : if ge [i] != ge [ (i+1) % len (ge) ] and \ ge [(i+2) % len (ge)] != ge [ (i+3) % len (ge) ] and \ ge [i] == ge [ (i+2) % len (ge) ] : return True return False femme = lit_fichier ("femme.txt") homme = lit_fichier ("homme.txt") table = lit_fichier ("table.txt") r = contrainte (table, femme, homme) print "la table suit les desirs d'Harmonie : ", r r = dominique (table, femme, homme) print "peut-on ajouter Dominique : ", r ############################################################################### # question 6 ############################################################################### def contrainte_dominique (table, femme, homme) : """meme fonction que contrainte mais on tient aussi du fait que le genre peut etre indetermine (None), toute configuration incertaine est eliminee""" ge = [ genre (t,femme, homme) for t in table ] for i in range (0,len (ge)) : if ge [i] == ge [ (i+1) % len (ge) ] == ge [(i+2) % len (ge) ] : return False if ge [i] == None and ge [ (i+1) % len (ge) ] == ge [(i+2) % len (ge) ] : return False if ge [i] == ge [ (i+1) % len (ge) ] and ge [(i+2) % len (ge) ] == None : return False if ge [i] == ge [ (i+2) % len (ge) ] and ge [(i+1) % len (ge) ] == None : return False if ge [i] == None and ge [ (i+1) % len (ge) ] == None : return False if ge [i] == None and ge [ (i+2) % len (ge) ] == None : return False if ge [ (i+2) % len (ge) ] == None and ge [ (i+1) % len (ge) ] == None : return False return True def place_dominique (table, femme, homme) : """on cherche a inserer autant de dominique que possible""" nb = len (table) fin = False while not fin : fin = True for i in range (0, len (table)) : table.insert (i, "DOMINIQUE") r = contrainte_dominique (table, femme, homme) if r : fin = False break else : del table [i] return len (table) - nb print "-----------------------------------------------------------------" nb = place_dominique (table, femme, homme) print "nombre de dominique ", nb for p in table : print p ############################################################################### # question 7 ############################################################################### # # nombre minimal : partie entiere de (n+1)/2 # nombre maximal : 2n # ############################################################################### # question 8 ############################################################################### def trois_pareil (table) : """table est une suite booleens, on retourne True s'il n'y en a pas trois consecutifs""" for i in xrange (len (table)-2) : if table [i] == table [i+1] == table [i+2] : return False return True def trois_pareil_rond (table) : """table est une suite booleens, on retourne True s'il n'y en a pas trois consecutifs""" for i in xrange (len (table)) : if table [i] == table [ (i+1) % len (table)] == table [(i+2) % len (table)] : return False return True def compte (n) : """on parcours toutes les tables possibles et on compte les bonnes configurations""" table = [ False for i in range (0,n) ] nb = 0 bon = 0 while table [0] != None : nb += 1 if trois_pareil_rond (table) : bon += 1 for i in xrange (len (table)-1, -1, -1) : if not table [i] : table [i] = True break else : table [i] = False if i == 0 : table [0] = None return nb, bon print "-----------------------------------------------------------------" print "calcul en parcourant toutes les tables possibles" print "-----------------------------------------------------------------" for n in range (3, 15) : nb, bon = compte (n) print n, " nb = ", nb, " bon = ", bon, print " proba = ", float (bon) / float (nb), " \t", print bon, "/", nb ############################################################################### # question 8 # markov ############################################################################### # module pour le calcul matriciel import numpy import copy def construit_matrice () : """construit la matrice de transition, le vecteur des probabilites d'entrees dans chaque etat""" # construction des etats etat = [] for i in range (0,2) : for j in range (0,2) : for k in range (0,2) : etat.append ( (i,j,k) ) # construction de la matrice mat = [] for i in range (0, len (etat)) : l = [] for j in range (0, len (etat)) : if etat [i] [1:3] == etat [j] [0:2] : # (i,j,k) --> (j,k,0) ou (j,k,1) l.append (1) else : l.append (0) # on renormalise sur chaque ligne s = sum (l) for j in range (0, len (etat)) : l[j] /= float (s) mat.append (l) entree = [ 0.125 for i in range (0,8) ] return etat, numpy.matrix (mat), numpy.matrix (entree) def calcul_probabilite_droite (n, etat, mat_, entree) : """calcule les probabilites pour une table droite""" pos = [ etat.index ( (0,0,0) ), etat.index ( (1,1,1) ) ] temp = copy.deepcopy (entree) mat = copy.deepcopy (mat_) for p in pos : for i in range (0,8) : mat [ (p,i) ] = 0.0 mat [ (p,p) ] = 1.0 m = mat ** (n-1) sum = 0.0 for i in range (0,8) : for j in range (0,8) : if i not in pos and j not in pos : sum += m [ (i,j) ] * mat [ (j,i) ] return sum print "-----------------------------------------------------------------" print "calcul avec les chaines de Markov" print "-----------------------------------------------------------------" etat,mat,entree = construit_matrice () for n in range (3,15) : proba = calcul_probabilite_droite (n, etat, mat, entree) print n, " bon ", proba