Sunteți pe pagina 1din 10

Seminar 01 Tehnici de programare Tehnici de programare

Inteligenta Artificiala

1. Greedy
Problema platii unei sume: Se considera n monede avand valorile o 1, o 2, ..., o n. Sa se foloseasca un numar minim de monede pentru a plati suma S. void greedyPlataSuma(int n, int o[], int S, int m, int sol[]){ sortare(n, o); //sortam monedele in ordine descrescatoare crtSum = 0; i = 0; m = -1; while ((i < n) && (crtSum < S)){ if (crtSum + o[i] <= S){ m++; sol[m] = o[i]; crtSum = crtSum + o[i]; } i++; } //while } //greedy Problema rucsacului: un rucsac de o anumita capacitate (C) si o multime de obiecte de diferite greutati (n, g1, g2, ..., gn). Se cere sa se gaseasca cea mai eficienta modalitate de umplere a rucsacului cu obiecte. void greedyRucsac(int n, int g[], int C, int m, int sol[]){ sortare(n, g); //sortam obiectele in ordine crescatoare crtCap = 0; i = 0; m = -1; while ((i < n) && (crtCap < C)){ if (crtCap + g[i] <= C){ m++; sol[m] = g[i]; crtCap = crtCap + o[i]; } i++; } //while } // greedy Problema numerelor naturale prime i neprime. Avnd un set de numere naturale (n, a 1, a2, ..., a n), se cere s alegem dintre acestea ct mai multe, dar cel mult k (dat) numere prime astfel nct suma acestora s depeasc suma celor neprime. ALGORITM PROBLEMA

ALGORITM

PROBLEMA

PROBLEMA

Laura Dioan

lauras@cs.ubbcluj.ro

www.cs.ubbcluj.ro/~lauras

Seminar 01 Tehnici de programare

Inteligenta Artificiala

void greedyPrimeNeprime(int n, int a[], int k, int m, int sol[]){ sortare(n, a); //sortam numerele prime in ordine descrescatoare, urmate de nr ne//prime in ordine crescatoare sumPrime = 0; sumneprime = 0 i = 0; m = -1; nrPrime = 0; while ((i < n) && (sumPrime > sumNeprime)){ if (estePrim(a[i]) && (nrPrime <= k){ m++; sol[m] = a[i]; sumPrime += a[i]; k++; } else{ if (sumNeprime + a[i] < sumPrime){ m++; sol[m] = a[i]; sumNeprime += a[i]; } //if } //else i++; } //while } // greedy

ALGORITM

PROBLEMA Problema baloanelor: Avnd n baloane rotunde (pentru fiecare balon se cunosc coordonatele centrului si raza lui) care se deplaseaz pe vertical se cere s se aleag un numr ct mai mare dintre acestea astfel nct s nu se loveasc ntre ele Struct { Int x; int y; }Punct; Struct { Punct centru; int raza; }Balon; Balon b[100]; int n; //nr de baloane ALGORITM

Laura Dioan

lauras@cs.ubbcluj.ro

www.cs.ubbcluj.ro/~lauras

Seminar 01 Tehnici de programare

Inteligenta Artificiala

void sortareMargineDreapta(int n, int b[]){ for (int i = 1 ; i < n ; i++) for(int j = i + 1; j <= n; j++) if (b[i].centru.x + b[i].raza > b[j].centru.x + b[j].raza){ auz = b[i]; b[i] = b[j]; b[j] = aux; } } void greedyBaloane(int n, int b[], int m, int sol[]){ sortareMargineDreapta (n, b); //sortam baloanele crescator dupa marginea din dreapta m = 1; sol[1] = b[1]; i = 2; while (i <= n) { if (sol[m].centru.x + sol[m].raza < b[i].centru.x + b[i],raza){ m++; sol[m] = b[i]; } i++; } //while } // greedy PROBLEMA Problema comisului voiajor: Se considera n orase intre oricare doua existand legaturi directe. Distantele dintre orase sunt numere reale pozitive cunoscute. Se cere sa se determine un drum de lungime minima care pleaca dintr-unul dintre orase, le parcurge pe toate celelalte o singura data si se intoarce din orasul de plecare. greedyTSP(G(V, E)){ vizitate = {start}; nevizitate = V {start}; nodCrt = start; while (nevizitate != ){ nodUrm = celMaiApropiatVecinNevizitat(nodCrt); vizitate = vizitate U {nodUrm}; nevizitate = nevizitate {nodUrm}; nodCrt = nodUrm; } //while } //greedy ALGORITM

Laura Dioan

lauras@cs.ubbcluj.ro

www.cs.ubbcluj.ro/~lauras

Seminar 01 Tehnici de programare

Inteligenta Artificiala

2. Programare dinamica
Problema platii unei sume: Se considera m monede avand valorile o1, o2, ..., on. Sa se foloseasca un numar minim de monede pentru a plati suma SMAX Notam sum[k,s] = nr de monezi de valoare o[k] cu care se poate plati suma s Putem folosi recurenta: c(k,s) = min{c(k, s-o(k)) + 1, c(k-1, s)}, unde s = 0, 1, 2, , SMAX, iar k = 0, 1, 2, , n drum(k,s) = (k,s-o(k)), daca min{c(k, s-o(k)) + 1, c(k-1, s)} = c(k, s-o(k)) (k-1, s), altfel Fie SMAX =7 si 4 monezi de valaori 1, 3, 4 si 6. Notam cu x valaorea lui plus infinit. S=0 0 0 0 0 S=1 X 1 1 1 S=2 x 2 2 2 S=3 x 3 1 1 S=4 x 4 2 1 S=5 x 5 3 2 S=6 x 6 2 2 S=7 x 7 3 2

PROBLEMA

ALGORITM

K=0 K=1 K=2 K=3

Problema triunghiului: se da un triunghi isoscel de latura n care contine n(n+1)/2 numere (similar jumatatii unei matrici plasate sub diagnala principala). Exista un pion calator care pleaca din casuta cea mai de sus a triunghiului si care se poate deplasa fie pe verticala in jos, fie pe diagonala la dreapta. Sa se gaseasca succesiunea de pasi realizati de pion, astea incat suma numerelor din casutele vizitate de pion sa fie maxima. sum[1,1] = a[1,1]; drum[1,1] = 0; for(i=2; i <= n; i++){ mat[i,1] = sum[i-1, 1] + a[i,1]; drum[i,1] = 1; for (j =2; j <= i; j++){ if (sum[i-1,j-1] > sum [i-1, j]){ sum[i,j] = sum[i-1,j-1] + a[i,j]; drum[i,j] = j 1; } else{ sum[i,j] = sum[i-1,j] + a[i,j]; drum[i,j] = j ; } } }

PROBLEMA

ALGORITM

Laura Dioan

lauras@cs.ubbcluj.ro

www.cs.ubbcluj.ro/~lauras

Seminar 01 Tehnici de programare

Inteligenta Artificiala

Problema hotelului: ntr-un hotel cu m etaje i n camere pe fiecare etaj, se va trage (mergnd orizontal sau vertical) un cablu prin camere succesive nvecinate. Cum se va ntinde acest cablu (de lungime minim) plecnd din camera stnga-sus pn n camera dreapta-jos astfel nct numrul de clieni care au cablu n camer s fie maxim? Evident, se cunoate (se d) numrul de clieni din fiecare camer sum[1,1] = a[1,1]; drum[1,1] = (0,0); for(j=2; j<= m; j++){ sum[1, j] = sum[1, j-1] + a[i,j]; drum[1,j] = (1, j-1); } for(i=2; j<= n; i++){ sum[i, 1] = sum[i-1, 1] + a[i,j]; drum[1,j] = (i-1, 1); } for(i=2; i <= n; i++){ for (j =2; j <= m; j++){ if (sum[i,j-1] > sum [i-1, j]){ sum[i,j] = sum[i,j-1] + a[i,j]; drum[i,j] = (i,j 1); } else{ sum[i,j] = sum[i-1,j] + a[i,j]; drum[i,j] = (i,j) ; } } } Inmultire optima de matrici: dandu-se n matrici de numere reale, sa se calculeze matricea produs. Ai M[pi-1, pi] A1 * A2 * A3 * ... * An = A1->n => A1->n = A1->k * Ak+1->n Cost(A1->n) = cost(A1->k) + cost(Ak+1->n) + p 0 * pk * pn => Cost(Ai->j) = min (i<= k < j){cost(Ai->k) + cost(Ak+1->j) + pi-1 * pk * p j for(i=1; I <= n; i++) cost[i,i] = 0; for(l=2; l<= n; l++){ // l lungimea lantului de matrici for(i=1; i<= n l + 1; i++){ j = i + l 1; cost[i,j] = MAXINT; for(k=I; k <= j-1; k++){ aux = cost[i,k] + cost[k+1,j] + p[i-1] * p[k] * p[j]; if (aux < cost[i,j]){ cost[I,j] = aux; pozitieParanteza[i,j] = k; Laura Dioan lauras@cs.ubbcluj.ro 5 www.cs.ubbcluj.ro/~lauras

PROBLEMA

ALGORITM

PROBLEMA

ALGORITM

Seminar 01 Tehnici de programare } } } }

Inteligenta Artificiala

Problema subsirului crescator: Pentru un sir cu n numere, sa se determine cel mai lung subsir de numere crescatoare. Ex: a = (2, 1, 9, 6 , 11) => 2, 9, 11 sau 2, 6, 11 sau 1, 6, 11 General: n, a = (a1, a2, ..., an) Fie doi vectori auxiliari: l = (l1, l2, ...ln) unde li = lungimea celui mai lung subsir de numere crescatoare care incepe cu elementul ai si p = (p1, p2, ..., pn) unde pi = pozitia urmatorului element dupa ai din cel mai lung subsir de numere crescatoare care incepe cu elementul ai, iar pn = 0 l = (3 3 2 2 1) p = (3 3 5 5 0) pentru a determina fiecare element li folosim relatia: ln = 1 li = max{1+lj, unde lj este lungimea secventei care incepe cu elementul aj, unde aj >= ai, iar i+1 <= j <= n}, unde i = n-1, n-2, ...., 2, 1

PROBLEMA

Ex: n = 5 => l5 = 1; n = 4 => l4 = max{ 1 + l5, pentru ca a5 = 11 > a4 = 6} = max{1+1} = 2 ! Nu consideram si 1+l4, n = 3 => l3 = max{ 1+ l5, pentru ca a5 = 11 > a3 = 9} = max{1+1} = 2 pentru ca a4 = 6 < a3 = 9 n = 2 => l2 = max{ 1+ l3, pentru ca a3 = 9 > a2 = 1, 1 + l4, pentru ca a4 = 6 > a2 = 1, 1 + l5, pentru ca a5 = 11 > a2 = 1} = max{1+2, 1+2, 1 + 1} = 3 n = 1 => l1 = max{ 1+ l3, pentru ca a3 = 9 > a1 = 2, 1 + l4, pentru ca a4 = 6 > a1 = 2, 1 + l5, pentru ca a5 = 11 > a1 = 2} = max{1+2, 1+2, 1 + 1} = 3 Identificarea elementelor din cel mai lung subsir de nr crescatoare: i(1) = posElementuluiMaxim(l); i(j) = pi(j-1), daca i(j) != 0, j =2, 3, ..., lungimeaSubsirului

i(1) =1 i(2) = pi(1) = p 1 = 3 i(3) = pi(2) = p 3 = 5 Laura Dioan lauras@cs.ubbcluj.ro 6 www.cs.ubbcluj.ro/~lauras

Seminar 01 Tehnici de programare i(4) = pi(3) = p 5 = 0

Inteligenta Artificiala

3. Divide et Impera
Ghicitoare numar: O persoana cere alteia sa ghiceasca un numar. Dupa prima incercare se poate ca cel care a ascuns numarul sa spuna este prea mare sau este prea mic sau felicitari! Ai ghicit!. Sa se simuleze un astfel de joc. Verifica(el){ Start = 1; Sfarsit = 10000; gasit = false; while ((!gasit) && (start < sfarsit)){ mijloc = start + (sfarsit start)/2; if (el = mijloc) gasit = true; else{ if (el < mijloc) sfarsit = mijloc 1; else //el > mijloc start = mijloc + 1; } } if (gasit) printf(nr cautat este %d, mijloc);

PROBLEMA

ALGORITM

Problema patinoarului: un patinoar de forma dreptunghiulara prezinta defecte ale ghetii datorita temperaturilor ridicate, dar si a antrenamentelor numeroase. Proprietarii doresc sa evite accidentele prin delimitarea unei zone fara probleme pentru patinatori, astfel incat sa acopere o suprafata cat mai mare din cea initiala. Laturile zonei ingradite pot fi realizate doar prin garduri paralele cu laturile patinoarului. Se cunosc coordonatele in plan ale patinoarului, precum si ale zonelor cu probleme (considerate punctiforme). Sa se determine coordonatele unei zone dreptunghiulare de arie maxima care nu prezinta nici un risc.

PROBLEMA

Laura Dioan

lauras@cs.ubbcluj.ro

www.cs.ubbcluj.ro/~lauras

Seminar 01 Tehnici de programare

Inteligenta Artificiala

Laura Dioan

lauras@cs.ubbcluj.ro

www.cs.ubbcluj.ro/~lauras

Seminar 01 Tehnici de programare Struct { Int x; int y; }Punct; Struct { Punct soltStangaSus; int lungime; int latime; }Dreptunghi;

Inteligenta Artificiala

ALGORITM

DivideEtImpera (Dreptunghi d, Puncte p[], int nrPuncte, Dreptunghi rez){ pos = alegeUnPunct(d, p, nrPuncte); if (pos = -1) { if ((d.lungime * d.latime) > (rez.lungime * rez.latime)) { rez = d; } } else{ ConstruiesteDreptunghiuri(d, p[pos], d1, d2, d3, d4); DivideEtImpera(d1, p, nrpuncte, rez); DivideEtImpera(d2, p, nrpuncte, rez); DivideEtImpera(d3, p, nrpuncte, rez); DivideEtImpera(d4, p, nrpuncte, rez); } }

4. Brach and bound


Problema masinutelor: Dou coloane de (m respectiv n) maini se ntlnesc pe un drum n lucru ngustat la o distan egal cu lungimea unei maini. O main poate nainta doar dac are un loc liber n faa ei, sau poate depi la un moment dat o singur main din coloana opus dac exist loc liber n spatele mainii din fa. Cum coopereaz oferii pentru a-i putea continua drumul far a merge cu spatele branch and bound. Presupunem configuratia initiala pt n=m=3 masinute: aaa_bbb. Configuratia finala va fi bbb_aaa. Arborele asociat spatiului de cautare va fi de forma: aaa_bbb / \ aa_abbb / \ / a_aabbb aaba_bb aa_babb | / \ / \ Laura Dioan lauras@cs.ubbcluj.ro 9 PROBLEMA

aaab_bb \ aaabb_b | www.cs.ubbcluj.ro/~lauras

Seminar 01 Tehnici de programare

Inteligenta Artificiala

_aaabbb aab_abb aabab_b a_ababb aab_abb aaabbb_ .............................................................................................................................. asociem fiecarui nod o fucntie de cost f formata din doua componente: f = g + h, unde : - g functie care masoara distanta intre configuratia initiala si configuratia curenta (respectiv adancimea nodului curent in arbore) - h functie care masoara distanta intre configuratia curenta si configuratia finala (respectiv nr de masinute incorect plasate in configuratia/nodul curent) De ex, pt nodul/configuratia: aaba_bb avem: - g = 2 (adancimea) - h = 6 (doar masinuta b de pe pozitia a 3-a este plasata corect din cele 7 elemente) explorarea nodurilor din arbore se va face pe baza unei ordini date de aceasta functie de cost f. Algorithm B&B{ //folosim o lista pentru a retine nodurile/configuratiile ConfiguratieInitiala.g = 0; ConfiguratieInitiala.h = nrDiferente; LIST = {ConfiguratiaInitiala}; While ((exista noduri ne-expandate in LIST) && (nuAmAjunsLaConfiguratiaFinala)){ nodeCrt = getNodeFromListWithMinimalCostF(LIST); succesoriLIST = expandare(nodeCrt); nodeCrt.expandat = true; for (fiecare succesor din succesorList){ successor.g = nodeCrt.g + 1; //avansam cu cautarea in adancime succesor.h = nrDiferente; if (successor ! LIST){ //nu a mai fost generate //configuratia resp la un pas anterior LIST = LIST U {succesor}; //LIST tb sa fie ordonata Succesor.expandat = false; } else{ //succesor = nodeGasit in LIST if (succesor.g < nodeGasit.g){ predecessor(nodeGasit) = nodeCrt; nodeGasit.g = successor.g; if (nodeGasit.expandat == true) nodegasit.expandat = false; } //if } //if } //for } //while } //alg

Laura Dioan

lauras@cs.ubbcluj.ro

10

www.cs.ubbcluj.ro/~lauras

S-ar putea să vă placă și