Sunteți pe pagina 1din 12

Tehnici de

elaborare a
algoritmilor

1.Metoda trierii
Fie

P o problem, soluia creia se


afl printre elementele mulimii S cu
un numr finit de elemente.

S={s1, s2 , s3 , ... , sn}


Soluia

se determin prin analiza


fiecrui element si din mulimea S.

Exemplu de problema :

S se scrie un program care determin toate secvenele binare


de lungime n, fiecare din ele coninnd nu mai puin de k cifre
de 1.
Intrare: numere naturale n, 1<n<20, i k, k<n, se citesc de la
tastatur.
Ieire: fiecare linie a fiierului text OUT.TXT va conine cte o secven binar
distinct, ce corespunde condiiilor din enunul problemei

Elementele mulimii S pot fi interpretate ca numere {0, 1, 2, ..., 2n-1},


reprezentate pe n poziii binare.
Pentru generarea consecutiv a secvenelor binare se va utiliza formula:
s0 = 0;
si = si-1 + 1; i=1, ..., 2n-1

Algoritm

Iniializm variabilele n i k, fiierul de ieire, tabloul B.


Pasul 1. Cercetarea secvenei curente

Se calculeaz numrul de uniti (r) n secvena curent B

Pasul 2. Prelucrarea soluiei

Dac r k, secvena curent B este nscris n fiierul de ieire.

Pasul 3. verificarea prezenei secvenelor necercetate


Dac r = n se nchide fiierul de ieire, apoi STOP.

Pasul 4. Generarea secvenei urmtoare

Dac B[n]=0 atunci B[n] 1


n caz contrar:
in
att timp ct B[i] = 1 repetm
B[i] 0; i i1;
pentru indicele curent i B[i] 1
Revenim la Pasul 1.

Rezolvare :
Program Triere;
const nmax=20;
type secventa01=array[1..nmax] of 0..1;
var b:secventa01;
r,i,n,k:integer; f:text;

procedure scrie;
var j: integer;
begin
for j:=1 to n do write (f,b[j]);
writeln(f);
end;
procedure urmator (var x:secventa01);
j:integer;
begin j:=n;
while x[j]=1 do
begin x[j]:=0; j:=j-1; end;
end;
begin
readln(n,k);
assign(f,'OUT.TXT');rewrite(f);
for i:=1 to n do b[i]:=0;
repeat
r:= numara1;
if r >= k then scrie;
if r < n then urmator(b);
until r=n;
close(f);
end.

var

x[j]:=1;

2.Tehnica Greedy

Este o optiune ce tine de specificul problemei cu implicatii asupra


complexitatii. Se bazeaza pe statistica datelor de la intrare din care se
extrag caracteristici ale datelor=>alegerea strategiei.
Strategia Greedy=strategia in care optimul local se considera optim
general. Este o strategie constructiva prin adaugarea treptata de solutii
locale care construiesc solutia.
Pentru a rezolva o problem cu Greedy, soluia se construiete, dup regula:
Pentru fiecare element care urmez s fie adugat soluiei finale, se
efectueaz o alegere a sa din elementele mulimii A (dup un mecanism specific
fiecrei probleme n parte), iar dac este posibil, aceasta este adugat.
Algoritmul se termin fie cnd a fost gsit soluia cerut, fie cnd s-a constatat
inexistena acesteia.
Pentru a evita trierea tuturor submultimilor multimii A n metoda Greedy se
utilizeaz un criteriu (o regul) care asigur alegerea direct a elementelor necesare.
De obicei regulile de selecie nu sunt indicate n mod explicit n condiia problemei si
totul depinde de ingeniozitatea programatorului.

Exemplu de problema:
Problema banilor:
Scriei un program, care afieaz modalitatea de plat, folosind un numr minim
de bancnote, a unei sume ntregi S de lei (S<20000). Plata se efectueaz
folosind bancnote cu valoarea 1, 5, 10, 50, 100, 200 i 500 de lei. Numrul
de bancnote de fiecare valoare se citete din fiierul text BANI.IN, care
conine 7 rnduri, n fiecare din care sunt indicate numrul de bancnote
respectiv de 1, 5, 10, 50, 100, 200 i 500 de lei.
Intrare: Fiierul text BANI.IN i de la tastatur se citete suma S.
Ieire: Dac e posibil de pltit aceast sum S, atunci la ecran se va afia
valoarea bancnotei i numrul de bancnote respective utilizate la plat. Dac
bancnote de careva valoare nu se folosesc, atunci nu se afieaz aceast
valoare. Dac nu este posibil de efectuat plata cu bancnotele indicate
afiai mesajul respectiv. . De obicei se presupune c bancnote de fiecare fel
avem orict de multe. Aceast problem ne limiteaz numrul de bancnote.
Ideea algoritmului de rezolvare a aceste probleme const n faptul c trebuie
s ncepem eliberarea restului de la cea mai mare bancnot. Exist 2
variante, dac suma necesar e mai mare ca produsul dintre numrul de
bancnote i nominalul atunci se iau toate bancnotele de acest nominal, dac
nu atunci se iau attea bancnote, cte ncap, care se afl prin mprirea
sumei rmase la nominal. Pentru rezolvare se folosete un tablou cu 3
rnduri i 7 coloane (pentru fiecare nominal cte o coloan). n primul rnd
al tabloului vom pstra nominalul bancnotelor, n al doilea rnd - numrul
bancnotelor citite din fiier i n al treilea rnd - numrul bancnotelor
obinute la schimb, practice ceea ce aflm.
Calculul se va ncepe cu coloana a 7, adic ncepem de la sfrit.

Rezolvare:
Program V3P7_02;
type tablou=array[1..3,1..7] of integer;
var s,ss,i : integer;
a:tablou;
f:text;
{In primul rind al tabelului vom pastra nominalul bancnotelor}
{In al doilea rind - numarul bancnotelor citite din fisier}
{In al treilea rind - numarul bancnotelor obtinute la schimb}
Procedure Afisare(sa:integer);
begin writeln('suma ',s);
if sa<>0
then writeln('nu poate fi transformata cu bancnotele date ')
else begin writeln('se plateste cu urmatoarele bancnote');
for i:=1 to 7 do
If a[3,i]<>0
then writeln('bancnote de ',a[1,i]:6,' sau folosit ',a[3,i]);
end; { Afisare }
Procedure calcul(var sa:integer);
var nb:integer
begin
i:=7;
while (i>=1) and (sa>0) do
begin nb:=sa div a[1,i];
if nb<>0 then if nb>= a[2,i]
then a[3,i]:=a[2,i]
a[3,i]:=a[2,i]
else a[3,i]:=nb;
sa:=sa-a[3,i]*a[1,i];
i:=i-1;
end;
end; { calcul }
begin
a[1,1]:=1; a[1,2]:=5; a[1,3]:=10; a[1,4]:=50;
a[1,5]:=100; a[1,6]:=200; a[1,7]:=500;
assign (f,'bani.in'); reset(f);
for i:=1 to 7 do readln(f,a[2,i]);
write ('introduceti suma de lei S ');readln(s);
ss:=s;
calcul(ss); Afisare(ss);
end.

end

3.Metoda reluarii
Ideea metodei reluarii:
1. Presupunem c la pasul k am calculat deja valorile:

( x1 , x2 , , xk )
2. Selectm din mulimea Ak+1 valoarea xk+1:

( x1 , x2 , , xk , xk 1 )
3. Dac

( x1 , x2 , , xk , xk 1 ) satisface condiiile

problemei, trecem la pasul k+2.

Exemplu de problema:
Se consider mulimile A1, A2, ..., An,
fiecare mulime fiind format din mk
numere naturale. Selectai din
fiecare mulime cte un numr n aa
mod nct suma lor s fie egal cu q.

Rezolvare:
const mmax=50; { numrul maximal de mulimi }
nmax=50; { numrul maximal de elemente }
type Natural = 0..MaxInt;
Multime = array[1..nmax] of Natural;
var A : array[1..nmax] of Multime;
n : 1..nmax;
{ numrul de mulimi }
M : array[1..nmax] of 1..mmax; { cardinalul mulimii S[k] }
X : array[1..nmax] of 1..mmax; { indicii elementelor selectate }
q : Natural;
k, j : integer;
Indicator : boolean;
function PrimulElement(k : integer) : Natural;
begin
PrimulElement:=1;
end; {PrimulElement }
function Continuare(k : integer) : boolean;
var j : integer;
suma : Natural;
begin
suma:=0;
for j:=1 to k do suma:=suma+A[j, X[j]];
if ((k<n) and (suma<q)) or ((k=n) and (suma=q))
then Continuare:=true
else Continuare:=false;
end; { Continuare }


function ExistaSuccesor(k : integer) : boolean;
begin
ExistaSuccesor:=(X[k]<M[k]);
end; { ExistaSuccesor }
procedure Reluare(k : integer);
{ Metoda reluarii - varianta recursiva }
begin
if k<=n then
begin
X[k]:=PrimulElement(k);
if Continuare(k) then Reluare(k+1);
while ExistaSuccesor(k) do
begin
X[k]:=Succesor(k);
if Continuare(k) then Reluare(k+1);
end { while }
end { then }
else PrelucrareaSolutiei;
end; { Reluare }

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