22
Module 2: Algorithmique et Programmation : Notions de base pour les biologistes Objectif: Initiation à la programmation et à l'algorithmique. Faisabilité d'un algorithme : les problèmes simples et les problèmes complexes. Présentation des algorithmes classiques pour l'optimisation et le traitement des données. Contenu : Qu'est ce qu'un algorithme ? Analyse d'un problème. Représentation et structures de données. Liaisons entre les structures de données et les algorithmes. Complexité d'un algorithme. Résolutions exactes et heuristiques. La mise en oeuvre sera faite dans un langage de programmation interprété et souple (Python). Jour 1: cours: notions générales d'algorithmique et de programmation (variables, structure de contrôle, fonctions). Voyageur de commerce – NP complet (factorielle) Heuristique (planche à clous, savon – MonteCarlo) Programmation dynamique – Camions (tranches) Présentation du langage Python (Interprété/Interactif) Variables: type implicite liste, tuple et string sont des séquences. Indentation délimite les blocs d'instructions – instruction vide "pass" Listes: a = [] # déclaration d'une liste T-uples: a = (4, ‘titi’,3.14159) # déclaration d'un t-uple (un t-uple est non modifiable) Les listes et t-uples commencent à 0, coordonnées négatives == permutations circulaires –1 == dernière case (maximum négatif = -longueur, dernière case +1 : erreur,, types différents autorisés. Donc les coordonnées vont de –longueur à +(longueur –1) a.append("toto") a[3:10] # extrait éléments 3 à 9 for i in liste: # i prend successivement les valeurs de la liste for i in range(debut, fin, step): # i prend les valeurs de "debut à ("fin"-1) par pas de "step". while <test> :

cours général du module OBI2

  • Upload
    doannhu

  • View
    215

  • Download
    1

Embed Size (px)

Citation preview

Page 1: cours général du module OBI2

Module 2: Algorithmique et Programmation : Notions debase pour les biologistesObjectif:Initiation à la programmation et à l'algorithmique. Faisabilité d'un algorithme : les problèmessimples et les problèmes complexes. Présentation des algorithmes classiques pour l'optimisationet le traitement des données.Contenu :Qu'est ce qu'un algorithme  ? Analyse d'un problème.Représentation et structures de données.Liaisons entre les structures de données et les algorithmes.Complexité d'un algorithme. Résolutions exactes et heuristiques.La mise en oeuvre sera faite dans un langage de programmation interprété et souple (Python).

Jour 1:cours:notions générales d'algorithmique et de programmation (variables, structure de contrôle,fonctions).Voyageur de commerce – NP complet (factorielle)Heuristique (planche à clous, savon – MonteCarlo)Programmation dynamique – Camions (tranches)

Présentation du langage Python (Interprété/Interactif)Variables: type impliciteliste, tuple et string sont des séquences.Indentation délimite les blocs d'instructions – instruction vide "pass"Listes:a = [] # déclaration d'une listeT-uples:a = (4, ‘titi’,3.14159) # déclaration d'un t-uple (un t-uple est nonmodifiable)

Les listes et t-uples commencent à 0, coordonnées négatives == permutations circulaires –1 ==dernière case (maximum négatif = -longueur, dernière case +1 : erreur,, types différentsautorisés. Donc les coordonnées vont de –longueur à +(longueur –1)a.append("toto")a[3:10] # extrait éléments 3 à 9

for i in liste: # i prend successivement les valeurs de la liste

for i in range(debut, fin, step):# i prend les valeurs de "debut à ("fin"-1) par pas de "step".

while <test> :

Page 2: cours général du module OBI2

def foo(arguments):# indentation nécessaire

Fonctions : attention, passage par valeur, sauf les listes, strings et tuples.Cela veut dire une variable est copiée dans la fonction : la fonction ne peut donc modifier lavariable de l’appelant.Mais dans le cas des listes, strings et tuples, le nom de la variable est une référence, donc laréférence n’est pas modifiable, mais l’objet référencé peut l’être (puisqu’on a la référence !).Références :Voir l’exemple suivant :>>> x=[1,2,3]>>> x[1, 2, 3]>>> y=x>>> y[1, 2, 3]>>> x[2]=-1>>> x[1, 2, -1]>>> y[1, 2, -1]

y est donc bien une référence à x, y et x désignent un même objet (une liste)Pour copier une liste, il faut l’expliciter, avec par exemple les index de début et de fin, commeici :>>> z=x[:]>>> z[1, 2, -1]>>> x[2]=-2>>> x[1, 2, -2]>>> z[1, 2, -1]

Là, x a été copiée dans z, et si on touche à x, on ne touche pas à z.Si on ne veut pas qu’une liste soit touchée dans une fonction, il faudrait alors faire :>>> def foo(l):... l[2]=-5... print l

>>> foo(x)[1, 2, -5]>>> x[1, 2, -5] # là, x est touchée>>> foo(z[:])[1, 2, -5]>>> z[1, 2, -1] # là, y n’est pas touchée

# lister les méthodes liées a un objetrange(4)liste[0, 1, 2, 3]liste=dir(liste)['__add__', '__class__', '__contains__', '__delattr__', '__delitem__','__eq__', '__ge__', '__getattribute__', '__getitem__', '__getslice__',

Page 3: cours général du module OBI2

'__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__le__', '__len__','__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__repr__','__rmul__', '__setattr__', '__setitem__', '__setslice__', '__str__', 'append','count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']map, reduce, filterreduce(plus,liste) # f(f(f(liste[0],liste[1]),liste[2]), liste[3])..etc6map(carre,liste)[0, 1, 4, 9]map(plus, liste,liste)[0, 2, 4, 6]map(None, liste1,liste2): applique None aux doublets d'une liste constituéede chacune des paires des éléments de liste1 et liste2filter(f,liste): retourne la sous liste de liste constituée de chacun deséléments pour lesquels f est vraie.

TP:Utilisation des structures de données et des structures de contrôles de Python, fonctions.

Boucle TestsCalcul moyennemoyenne cumulative selon formule: mi = mi-1 + vi*i/(i-1)

mi: moyenne au "temps" i, vi ième valeur

calcul varianceFaire avec programmation impérative (boucle) et fonctionnelle (reduce).fichier python "fonctions"def somme(a, b):

return a+b

def carre(n):return n*n

def sommeseq(seq): # somme d'une séquences=0for x in seq:

s=s+xreturn s

# somme par reduce (programmation fonctionnelle)def sum(liste): # somme d'une liste

return reduce(somme,liste)

def moyenne(liste):return float(sommeseq(liste))/len(liste)

# variancedef var(liste):

return (moyenne(map(carre,liste))-carre(moyenne(liste))*(float(len(liste))/(len(liste)-1)))

Page 4: cours général du module OBI2

def admis(s): return (s[-1]>=10)

# retourne une liste de n-uplets qui sont les mots des lignes# du fichier fdef readfile(f): t= [] fil = open(f,'r') tmp= fil.readlines() for x in tmp: t.append(x.split()) # fil.close() return t

# retourne 0 si a==b, -1 si a<b, + 1 si a>bdef compare(a,b): if a>b: return 1 elif a<b: return -1 else : return 0

=================

Page 5: cours général du module OBI2

fichier "notes":Terrieur Alain 12 4 16Potanpoche Jessica 0 12 4Chemonfis Thierry 8.5 14 17Bonnot Jean 18 12Kiroul Pierre 10 4.5 15...

#!/usr/local/bin/python2.1

import fonctions

f=open('notes','r')ll=f.readlines()

t=[]

for x in ll:t.append(x.split())

et=[]etud=[]for x in t:

et=x[0:2]et.append(fonctions.moyenne(map(float,x[2:])))etud.append(et)

w=open('moys','w')for x in etud:

w.write(x[0]+" "+x[1]+" "+"%2.2f" % x[2]+"\n")

# afficher à l'écra les admis:print "etudiants admis :listeadmis = filter(fonctions.admis,etud)

for x in listeadmis : print x[0], x[1], '%2.2f' % x[2]

w.close()

Page 6: cours général du module OBI2

Jour 2 :

Cours:Récursivité (Cf document recursif.pdf)Algorithmes de tri. TP: tri (insertion, sélection, bulle, merge)Sur le net : applications graphiques en java :http://java.sun.com/applets/jdk/1.4/demo/applets/SortDemo/example1.htmlhttp://www.cs.ubc.ca/spider/harrison/Java/http://lwh.free.fr/pages/algo/tri/tri.htm

TP:Recherche séquentielle dans une liste triée.C’est l’algorithme de recherche le plus élémentaire qui parcourt la listejusqu’à ce qu’un objet soittrouvé ou bien que la fin du tableau soit atteinte. Nous allons appliquer cela à la liste obtenueaprès lecture du fichier notes en cherchant la ligne correspondant à un étudiant sur la base de sonnom de famille.

def rec_seq(tab, name): cpt = 0 for i in tab: test = compare(i[0], name) cpt = cpt+1 if test ==0 : return i, cpt print "pas trouve"

Le nombre maximum de comparaisons d’objets effectuées par cette algorithme est N le nombred’éléments de la liste, ce maximum étant atteint lorsque l’élément n’est pas trouvé. En moyenneil procède à N/2 comparaisons. Cela est très mauvais et on sait faire beaucoup mieux.

Recherche dichotomique dans une liste triée.Un supplément d’information, permet souvent de réduire la complexité d’un problème.L’algorithme de recherche séquentielle n’utilisait que le test d’égalité avec deux réponsespossibles (oui/non). Comme les éléments (les noms) sont triés par ordre croissant. On peutréaliser un test avec trois résultats : égalité, inférieur, supérieur.

Page 7: cours général du module OBI2

#!/prog/seq_analysis/pythonimport fonctions

# t est une liste de triplets (nom, prenom, notes) triée sur les noms# v est le nom recherchédef dicho(t,v): g=0 d=len(t)-1

while g<=d: m=(g+d)/2 test = fonctions.compare(v,t[m][0]) if test == 1: g=m+1 elif test == -1: d=m-1 else: print 'trouve en position',m return print 'pas trouve'# 'notes' est le fichier du jour 1note = fonctions.readfile('notes')dicho (note,'Grange')

- Ouvrir un texte (nedit) pour le programme "tri.py"# "driver" pour les tris en interactifimport tri # la première foisreload(tri) # les autres fois

# création du fichier de nombres aléatoiresimport randomf=open("random","w")i = 0while i < 100: f.write("%f " % random.random()) i=i+1f.close()

f=open("random","r") # lecture du fichier de nombres aléatoiresll=f.readline() # ll est une string avec toutes les valeurs

t=[] # création du tableau de valeursfor x in string.split(ll):

t.append(float(x))(ensuite trier...)

Page 8: cours général du module OBI2

====== tri.py#!/usr/bin/python

import sysfrom copy import deepcopyimport randomimport pdb#----------------def Compare(x,y):

p=0if y < x :

p = -1elif x < y :

p = 1return p

#----------------def Echange(Tr,x,y):

#Copie en dur, par valeur pas par adresseT=deepcopy(Tr)temp=T[x]T[x]=T[y]T[y]=tempreturn T

#----------------def RechSeq(T,x):

if T[0] == x :return 0

else:L=len(T)i=0while i < L and T[i] != x :

i=i+1if i < L :

return ielse:

return -1

Page 9: cours général du module OBI2

#----------------def RechDich(T,x):

trouve = -1i = 0j=len(T)while i <= j and trouve == -1 :

mid=int((i+j)/2)if x == T[mid] :

trouve = midelse :

if x > T[mid] :i = mid + 1

else:j = mid - 1

return trouve

#----------------def PosMin(T,x,y):

mini=xfor i in xrange(x+1,y):

if Compare(T[i],T[min]) == 1 :mini=i

return mini

#----------------def TriSeq(T):

i=0L = len(T)Trie=deepcopy(T)while i < L-1 :

min = PosMin(i,L)if i != min :

Trie=Echange(Trie,i,min)i=i+1

return Trie

Page 10: cours général du module OBI2

#----------------def TriBulle(Tr):

permut=1L = len(Tr)T=deepcopy(Tr)i=ntot=0comp=ech=0while permut > 0 : if i == L-1 :

print "Bulle ",ntotif ntot == 0 :

permut = 0else:

i = 0ntot = 0

#pdb.set_trace() else:

p=Compare(T[i],T[i+1])comp+=1if p == -1 : ntot+=1 Trie=Echange(T,i,i+1) ech+=1i=i+1

return T,comp,ech

Page 11: cours général du module OBI2

#----------------def TriIns(Tr):

i=1L = len(Tr)T=deepcopy(Tr)while i < L :

p=Compare(T[i-1],T[i])if p == -1 :

pos=0j=0while j < i and T[i] > T[j] :

j=j+1pos = jif pos == 0 :

temp=T[0:i]temf=T[i+1:L]T=[T[i]]+temp+temf

elif pos < i :temp=T[0:pos]temf=T[pos:i]tem2=T[i+1:L]T=temp+[T[i]]+temf+tem2

i=i+1print "TriIns ",T

return T

#----------------def TriShell(Tr) :

T=deepcopy(Tr)#Calcul du pas

h=0while h < L :

h = 3*h + 1print hwhile h > 0 :

i=hwhile i < L : valeur=T[i] j=i-h while j >= 0 and T[j] > valeur :

T=Echange(T,j,j+h)j=j-h

i+=1print h," ** ",Th = h/3

return T

Page 12: cours général du module OBI2

#----------------def Fusion(T1,T2) :

L1=len(T1)L2=len(T2)Fus=[]i=j=0while i < L1 and j < L2 :

if T1[i] < T2[j] :Fus.append(T1[i])i+=1

else :Fus.append(T2[j])j+=1

if i == L1 :Fus.extend(T2[j:])

else :Fus.extend(T1[i:])

return Fus

#----------------def TriFusion(T) :

if len(T) == 1 :return T

else:mid=int(len(T)/2)Tfus=Fusion( TriFusion(T[:mid]) , TriFusion(T[mid:]) )return Tfus

Page 13: cours général du module OBI2

#----------------def TriRapide(Tr,deb,fin) :

T=deepcopy(Tr)if deb < fin :

#Definition du pivot au milieupivot = (deb+fin)/2#On place le pivot au debut du tableau pour faire une

comparaison continueT=Echange(T,deb,pivot)#Comparaison des valeurs % pivot et range val inf au

debutposinf=debfor k in xrange(deb+1,fin) :

if Compare(T[k],T[deb]) == 1:posinf+=1T=Echange(T,k,posinf)

#Mettre le pivot à sa position, donc à la suite deselements qui lui sont inferieurs

T=Echange(T,deb,posinf)#Tri sous tableau gaucheT=TriRapide(T,deb,posinf)#Tri sous tableau droitT=TriRapide(T,posinf+1,fin)

return T

#----------------def main():

x=10T=[]for i in range(x) :

T.append(int(10*random.random()))#T=[2, 3, 4, 3, 5, 9, 3, 4, 1, 6]print TT=TriRapide(T,0,x)print T

main()

Jour 3 :

CoursCours optimisation (simplexe, monte carlo et méthodes dérivées (recuit simulé), gradients)

Page 14: cours général du module OBI2

Optimisation numérique:(Cf document Minimisation numérique.doc)

- monte carlo: exemple du calcul de π

Optimisation combinatoire (Pierre)(Cf document Optimisation_combinatoire.doc)

Page 15: cours général du module OBI2

TP: dénombrement des mono et dinucléotides (comparaison)–les dictionnaires- comptage dans les séquences des mots de longueur 1 et 2- calcul du CG skew le long d’un génome

séquence au format fasta:>NC_002162 Ureaplasma urealyticum, complete genome.atggctaataattatcaaactttatatgattcagcaataaaaaggattccatacgatcttatttctgatcaagcttatgcaattctacaaaatgctaaaactcataaagtttgcgatggtgttttatatataattgtagccaatgcctttgaaaaaagtattattaacggtaattttatt...Programme pour compter les mononucléotides, les dinucléotides, et calculer le GC Skew sur unefenêtre de longueur w avec sortie dans un fichier (lignes : <position> <GCskew>) à plotter dansgnuplot (avec plot "plotgc.txt" )

#!/usr/bin/python

# ---------------------------------------------------------def readfasta(nf):

f=open("seq.fst","r")nf="seq.fst"seq=""line=f.readline()while (line!=""):

line=f.readline()seq=seq+line[:-1]

return seq

# ---------------------------------------------------------def dico(nf):

dico={}for x in nf:

if dico.has_key(x):dico[x]=dico[x]+1

else:dico[x]=1

return dico

# ---------------------------------------------------------def dicodi(nf):

dicodi={}for i in range(len(seq[:-2])):

dicodi[seq[i:i+2]]=dicodi.get(seq[i:i+2],0)+1

for j in dicodi.keys():dicodi[j]=float(dicodi[j])/float(len(seq))

return dicodi

# ---------------------------------------------------------def compare(dico_mono,dico_dinuc):

for i in dico_dinuc.keys():fmono=float(dico_mono[i[0]]*dico_mono[i[1]])fdinuc=dico_dinuc[i]print "%s %f %f" %(i,fmono,fdinuc)

Page 16: cours général du module OBI2

# ---------------------------------------------------------def calcgc(dicogc):

return float((dicogc["G"]-dicogc["C"]))/(dicogc["G"]+dicogc["C"])

# ---------------------------------------------------------def gc(seq,w):

gc={}gc=dico(seq[0:w])

filout=open("plotgc.txt","w")filout.write("%d %.3f\n" %(0, calcgc(gc)))

for i in range(1,len(seq)-w+1):gc[seq[i-1]]=gc[seq[i-1]]-1gc[seq[i+w-1]]=gc[seq[i+w-1]]+1

filout.write("%d %.3f\n" %(i, calcgc(gc)))

filout.close()return

# --------- MAIN ------------------------------------------seq=readfasta("seq.fst")m=dico(seq)d=dicodi(seq)

compare(m,d)

print "nombre de bases total",len(seq)

countbases=dico(seq)print countbases

dinucleotides=dicodi(seq)print dinucleotides

gc(seq,1000)

TP: camion, programmation dynamiquecamions (programmation dynamique). liens avec les séquencesprendre le fichier de villes sur le site de Joel

#---------------------------------------------------------------

#!/usr/local/bin/python

#!/usr/bin/pythonimport sys

def lit_fichier(fname):

""" A partir du nom de fichier contenant les distances entre les

Page 17: cours général du module OBI2

paires de villes sous le format: ville1 ville2 distance, cette fonction rend la ville de depart (premier champs de la premiere ligne ainsi qu'un dictionnaire de distance ou les cles sont les paires (ville1, ville2) et les valeurs sont les distances en reels. """

f=open(fname,'r') l=f.readlines() dico={} for x in l: t=x.split() dico[t[0],t[1]]=float(t[2]) deb=l[0].split()[0] return deb,dico

#---------------------------------------------------------------

def tranche(debut,dict): """ Cette fonction a partir de la ville de depart et des cles du dictionnaire dict rend une liste de listes ou le ieme element correspond aux villes de la ieme trance a traverser """ tv=[] dd=dict.keys() temp=[debut] while len(temp)!=0: tv.append(temp) temp=[] debut=tv[-1][0] for i in dict.keys(): if i[0]==debut: temp.append(i[1]) return tv

#---------------------------------------------------------------

def chemin(liste,dict, dep): """ Cette fonction determine le chemin minimum en passant par une ville et une seule de chaque tranche de villes contenues dans liste en partant de la ville dep et en fonction des distances contenues dans dict cour correspond au meilleur chemin courrant (donc il est remis a rien a chaque nouvelle tranche l etudiee). A chaque fois qu'une tranche est terminee,je mets dans chem1 le resultat de cour. Chem1 est donc le meilleur chemin pour les villes de la lieme tranche -1."""

depart = [(dep), 0] cour=[depart] # Remplissage de cour pour la tranche 0

for l in liste[1:]: # Pour chaque tranche de villes chem1 = cour cour=[] for i in l: # Pour chaque ville de la tranche l # on fixe arbitrairement le minimum # a la premiere distance mini=chem1[0][-1]+dict[(chem1[0][-2],i)] for j in chem1: # Pour chaque ville de la tranche l-1

Page 18: cours général du module OBI2

v=j[-2],i distemp=j[-1]+dict[v]

if distemp<=mini: mini = distemp cmini = j[:-1] cmini.append(i) cmini.append(mini) cour.append(cmini) return cour

#---------------------------------------------------------------

def main(): if len(sys.argv)!=2: print "entrez la commande sous la forme: camion.py fichier" else: fichier=sys.argv[1] dep,donnees=lit_fichier(fichier) tran=tranche(dep,donnees) #print tran print chemin(tran, donnees, dep)main()

#---------------------------------------------------------------

Jour 4 :TP: optimisation suite (recuit simulé à partir du montecarlo, gradient).Taboo search: grille à 2 dimensions

#!/usr/bin/python

import randomimport math

#fonction de rosenbroockdef rosen((x,y)):

return 100.0*(y-(x*x))*(y-(x*x))+(1-x)*(1-x)

# calcul du paysage de la fonction# sauvergarde dans fichier "paysage"# pour affichage dans gnuplot (sans "line")# Dans gnuplot, il suffira d'entrer# splot "paysage","recuit.xyz","taboo.xyz"# pour voir en 3D les chemins differe# (note: on peut aussi le faire directement# dans gnuplot, donc facultatif)def paysage(fun,xmin,xmax,ymin,ymax,pas):

f=open("paysage","w")x=xminwhile x<=xmax:

y=yminwhile y>=ymax:

f.write("%f %f%f\n" %(y,y,fun((x,y))))y=y+pas

Page 19: cours général du module OBI2

#print x,y,fun((x,y))x=x+pas

f.close()return

## recuit simule (fichier "recuit.py")# impression des points dans fichier "recuit.xyz" a# a tracer dans gnuplot avec l'option "with line"# arguments:# f: fonction# pstart: point 2D de depart (x,y)# tempinit: Temperature de depart# Tf: Temperature finale# npas: nombre de pas a chaque temperature# pas: longueur du pas#def recuit(f,(x,y),ti,tf,pas,npas):

t = tir= open("recuit.xyz",'w')# xmin,ymin vont etre les minima courantxmin,ymin=(x,y)# X,Y va etre le minimum minimorumX,Y = (xmin ,ymin)

while t>tf:for i in range(0,npas):

x = xmin + (random.random()*2 - 1)*pasy = ymin + (random.random()*2 - 1)*pasd = f((x,y)) - f((xmin,ymin))if (d < 0):

xmin ,ymin = x,yr.write("%f %f %f\n" % (xmin,ymin,f((xmin,ymin))))if f((xmin,ymin)) < f((X,Y)):

X,Y = (xmin ,ymin)elif math.exp((-d)/t) > random.random():

xmin ,ymin = x,yr.write("%f %f %f\n" %(xmin,ymin,f((xmin,ymin))))if f((xmin,ymin)) < f((X,Y)):

X,Y = (xmin ,ymin)t=t*0.7

return (X,Y)

## taboo search## NotInList:# fonction verifiant que l'element el# n'est pas dans la liste (retourne 1# si c'est vrai)#

def NotInList(el, liste): # liste est une liste de 2-uples d'entiers

# qui sont les arrondis de 10 fois les coordonnees # de maniere a ne pas repasser par un point proche # puisque les reels ne retomberaient jamais juste # el est le tuple des coordonnees reelles du point # dont on veut savoir si il est dans la liste taboo

Page 20: cours général du module OBI2

eli = (int(10*el[0]+5),int(10*el[1]+5)) for i in liste:

if eli == i: return 0

return 1

## taboo search: routine principale# impression des points dans fichier "taboo.xyz" a# tracer dans gnuplot avec l'option "with line"# arguments:# f: fonction# pstart: point 2D de depart (x,y)# npas: nombre de pas total a ne pas depasser# pas: longueur du pas# lentaboo: longueur de la liste tabou#def taboo(f,(x,y),npas,pas,lentaboo):

r= open("taboo.xyz",'w')n = 0listetaboo = [None]*lentaboolistetaboo[0] = (int(10*x+5),int(10*y+5))xmin,ymin = (x,y)solutions = 1while n < npas:

x = (random.random()*2 - 1)*pas + xy = (random.random()*2 - 1)*pas + yif NotInList((x,y),listetaboo) == 1 and f((x,y)) <f((xmin,ymin)) :

xmin,ymin = (x,y)solutions = solutions + 1r.write("%f %f %f\n" %(x,y,f((x,y))))listetaboo[solutions % lentaboo] = (int(10*x+5),int(10*y+5))n+=1

return (xmin,ymin)

s = recuit(rosen,(-2,2),1000,1,1.0,100)print "recuit: meilleure solution: ",s, rosen(s)

s = taboo(rosen,(-2,2),10000,1,30)print"taboo: meilleure solution: ", s, rosen(s)

Si on met les données du paysage dans « paysage », celle du trajet (x,y,f(x,y)) dans « recuit.xyz »(ou dans « taboo.xyz »), il suffit pour tracer le chemin de minimisation dans le paysage de donnerles ordres suivant dans gnuplot :splot "paysage","taboo.xyz" with line,"recuit.xyz" with line# ou mieux, on peut créer le « paysage » directement avec :set hidden3dset isosamples 30set view 60,30,1splot [-2.0:2] [-2:2] 100 * (y - (x*x))*(y - (x*x))+(1-x)*(1-x), "recuit.xyz"with line, "taboo.xyz" with line(* ceci figure la fontion de Rosenbrook en 3D avec les trajets par dessus *)

Page 21: cours général du module OBI2

ANNEXE

Affectation: Auction algorithm:

Personnes Voitures i -> A[i] u[i,j] pour chaque j appartenant a A[i]

Si C = MAX{u[i,j]: (i,j) appartenant a A}

A chaque pas, il existe un prix price [j] pour les voitures.Marginal utility de la personne i pour acheter j -> u[i,j] - price[j]A chaque itération, une personne "non assignée" choisit un j tel que u[i,j]-price[j] est maximumOn associe a chaque personne i une value[i], plafond sur la plus haute "marginal utility",cad value[i] >= MAX{u[i,j]: (i,j) appartenant a A}On dit que: Bid[i,j] est admissible si value[i] = u[i,j] - price[j] Bid[i,j] est inadmissible si value[i] sinon

Il faut pour l'algorithme que chaque Bid soit "admissible".Si la personne i est la prochaine à être traitée et qu'elle n'a pas de Bid "admissible",alors value[i] est trop haute, et on décroît cette valeur a: MAX{u[i,j]-price[j]: (i,j) appartenant a A}Donc, l'algorithme procède en personnes "préemptant" des voitures.Si une personne i préempte une voiture j, alors le prix de j augmente de 1F; ainsi lespréemptions suivantes seront plus élevées, et i est assigné à j.La personne k qui avait une préemption sur j (si elle existe) devient "inassignée",elle devra préempter une autre voiture par la suite.Tant que le marché continue, le prix des voitures augmente et les valeurs marginales despersonnes décroissent.L'algorithme s'arrête dès que chaque personne a une voiture.On atteint un assignement optimum.

Depart: price[j] = 0 pour chaque voiturevalue[i] = MAX{u[i,j]: (i,j) appartenant a A} (c'est suffisantpour une version pseudo-polynomiale)

exemple d'affectation:Min SOMME(i,j) (xiyj) y 6 12 15 15 x 4 8 9 11 10 5 7 8 12 10 6 9Resultat: (x1y1),(x2y4),(x3y2),(x4y3), SOMME=28

Page 22: cours général du module OBI2