Sunteți pe pagina 1din 19

Sortare rapidă cu factor aleator.

Sortare Shell.

Metoda Greedy

Algoritmi și tehnici de
programare
Sortarea rapidă

int pozitionare(double *v, int p, int u)


{
int indi,indj,auxi;
void qsort(double *v, int p, int u) int i,j;
{ double aux;
int k; i=p;j=u; //pivotul este v[p]
if(p<u){ indi=0;indj=-1;
k=pozitionare(v,p,u); while(i<j)
qsort(v,p,k-1); {
qsort(v,k+1,u); if(v[i]>v[j]){
aux=v[i]; v[i]=v[j]; v[j]=aux;
}
auxi=indi; indi=-indj; indj=-auxi;
} }
i+=indi;
j+=indj;
}
return i;
}
Sortare rapidă cu factor aleator

 Sortare rapidă cu factor aleator

 Introducerea unui factor aleator înainte de sortare - evită apariția cazului


cel mai nefavorabil (chiar și apropiat de cel mai nefavorabil)

 Factor aleator în alegerea punctului de împărțire din secvența curentă


▪ Interschimbă primul element (pivotul) cu altul ales aleator
▪ Noul prim element din secvență este poziționat conform metodei quick
sort

 Cele două subsecvențe determinate de poziția pivotului sunt în medie


relativ echilibrate ca număr de elemente
Sortare rapidă cu factor aleator

void rqsort(double *v, int p, int u)


In apelator trebuie
{
utilizat
int k;
srand(time(0))
if(p<u){
k=pozitionare_rand(v,p,u);
rqsort(v,p,k-1);
rqsort(v,k+1,u);
int pozitionare_rand(double *v, int p, int u)
}
{
}
int nou=rand()%(u-p);
nou+=p; // noupozitia noului pivot
double aux=v[p];
v[p]=v[nou]; //v[p]  noul pivot
v[nou]=aux;
return pozitionare(v,p,u);
}
Sortarea Shell

   Sortare prin micșorarea incrementului (Shell sort)


 generalizare a sortării prin inserție
 vector k-sortat – elementele din k în k formează un vector sortat;
l<k, vectorul este l-sortat ⇒ este k-sortat
 secvență de pași : valori descrescătoare, ultima este 1 – de
exemplu pas parcurge

 Algoritm
pentru fiecare pas din secvență
pentru fiecare i=pas..n-1
aux=v[i]; j=i-pas
cât timp j>=0 și v[j]>aux
v[j+pas] v[j]
j-=pas
v[j+pas]=aux;
Sortarea Shell
Exemplu
indici 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
n=15 Initial: 38 13 85 98 5 70 45 44 68 71 40 44 9 10 3
Dupa pasul 7: 3 13 71 40 5 9 10 38 68 85 98 44 70 45 44
Dupa pasul 3: 3 5 9 10 13 44 40 38 44 70 45 68 85 98 71
Dupa pasul 1: 3 5 9 10 13 38 40 44 44 45 68 70 71 85 98

void shellsort(double *v, int n)


{
int pas,i,j;
double aux;
for(pas=n/2;pas>=1;pas/=2)
for(i=pas;i<n;i++){
aux=v[i];
for(j=i-pas;(j>=0)&&(v[j]>aux);j-=pas)
v[j+pas]=v[j];
v[j+pas]=aux;
}
}
Complexitatea algoritmilor

Algoritm de Cel mai Uzual Cel mai Pe loc


sortare favorabil nefavorabil
caz caz
Bule 

Selecție 

Inserare 

Shell 

Interclasare -
Heap 

Rapidă (Quick) 

Numărare – -
vector particular
Cupe– vector -
particular
Rădăcini– vector -
Spațiul soluțiilor

  
 În multe probleme soluțiile pot fi descrise ca vectori cu n elemente
unde
 spațiul soluțiilor

 Exemple

 Calculul soluțiilor ecuației , unde

 Soluțiile problemei (rezultat): toți acei cu


Spațiul soluțiilor
 
 Exemple

 Calculul tutor divizorilor proprii ai unui număr

 Soluțiile problemei (rezultat): toate numerele cu

 Calculul punctelor de minim local pentru funcția Ackley


Spațiul soluțiilor
 
 Exemple

 Soluțiile problemei (rezultat) : toate punctele cu – în acest caz

 Calculul punctelor de minim local pentru funcția Ackley cu

 Soluțiile problemei (rezultat) :


Spațiul soluțiilor
Spațiul soluțiilor

 
 În implementare - în ipoteza în care pentru , finită,

, și pe este definită o relație de ordine totală

 funcție de validare

 mulțimea soluțiilor rezultat

 funcții de validare parțială

 se poate adăuga un element cu

 nu se poate adăuga un element cu


Greedy – metoda optimului local

 Metodă rapidă, de complexitate redusă (în general liniară), ce produce o


soluție “acceptabilă”

◦ La fiecare pas se alege cea mai bună cale în contextul local, ignorînd
contextul general

◦ Uneori rezultatul optim


 Pentru unele probleme există algoritmi de tip Greedy care dau soluția
optimă

◦ Uneori soluția poate fi cea mai puțin dezirabilă

 Este folosită atunci când găsirea celei mai bune soluții este prea
costisitoare
Greedy – metoda optimului local
Soluție de tip
greedy

11 1, 3, 6, 2, 5, 9, 11 -> 124
5 15
2
1, 4, 8, 11 -> 45
22 44
33
32 26 7
9
47
88 Soluție
(optim global)
55 66
77 20
12
41 10
10
99 21
18
5
11
11
Greedy – metoda optimului local


  
Caracteristici ale problemelor rezolvate prin metoda Greedy

◦ Problema poate fi imaginată ca o mulțime cu elemente

◦ O soluție posibilă este o submulțime ( care îndeplinește o condiție


dată ( este acceptabilă)

◦ Pot exista mai multe submulțimi diferite acceptabile (soluții


posibile), dintre care una este considerată soluție optimă, pe baza
unui criteriu care trebuie maximizat (minimizat).
Greedy – metoda optimului local


  
Operații uzuale
◦ Alegerea unui element candidat din mulțimea (
◦ Verificarea acceptabilității elementului ales: adăugarea
elementului la soluția parțială construită o menține acceptabilă
sau o face inacceptabilă?
 este acceptabilă?

◦ Adăugarea elementului ales la soluția parțială, dacă ea rămîne


acceptabilă.
Greedy – metoda optimului local

Cum se verifică

  
Algoritm general
acceptabilitatea elementului
Cum se alege un element candidat? candidat?
◦ se primește mulțimea cu elemente
◦ se inițializează soluția ca mulțime vidă
◦ repetă de (maxim) ori
 alege un element candidat din mulțimea Variantă:
prelucrare
 verifică dacă este soluție parțială acceptabilă inițială a mulțimii
A (sortare)
 dacă da, adaugă la mulțimea :

◦ se trimite mulțimea ca soluție


Greedy – metoda optimului local

 Exemple de probleme rezolvate prin algoritmi tip Greedy:


◦ Determinarea arborelui parțial de cost minim (soluția e întotdeauna optimă)
 Algoritmul lui Kruskal, algoritmul lui Prim
◦ Problema rucsacului
 întreagă
 continuă
◦ Interclasarea optimă a n vectori
Enunțuri complete în manual
◦ Suma maximă dintr-o mulțime de numere
◦ Plata unei sume (cu bancnotă unitate)
◦ Problema paznicului
◦ Determinarea unui produs de transpoziții
◦ Cele mai scurte drumuri în graf: algoritmul Dijkstra
Problema rucsacului (continuă)

// I: capacitate totala (q), nr. obiecte (n), capacitate ocupata (c),


// [ cistig (v) ]
// E: solutia x
void Rucsac_c(float q, int n, float* c, float* x)
{ float qr;
int i,j;

qr=q;
for(i=0; i<n && qr>0; i++)
if(qr>=c[i])
{ x[i]=1;
qr-=c[i]; //qr-=c[i]*x[i]
}
else
{ x[i]=qr/c[i];
qr=0; //qr-=c[i]*x[i]
for(j=i+1;j<n;j++)
x[j]=0;
}
}

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