Sunteți pe pagina 1din 5

Drumuri minime si maxime

În cazul problemelor de minim, matricea costurilor asociata grafului G=(V,U) este definiă astfel:
Cij=cost t, daca intre i si j exista un arc cu costul t
0, daca i=j
Infinit, daca i diferit de j si nu exista un arc intre i j.
In cazul problemelor de maxim, matricea costurilor asociata grafului G=(V,U) este definita astfel
Cij=cost t,
0
- Infinit daca i diferit de j si nu exista arc intre i si j
Algoritmul lui Roy Floyd
Acest algoritm se aplica in cazul problemelor în care se dă un graf G=(V,U) care are
matricea costurilorC și se cere să se determine lungimea drumurilor minime (maxime) și in unel
e cazuri și a nodurilor care constituie drumurile respective, intre oricare 2 noduri ale grafului.
Algoritmul are baza urmatoarea idee:
„Daca drumul minim de la nodul i la nodul j trece prin nodul k, atunci si drumul de la nodul i la
nodul k, precum și drumul de la nodul k la nodul j este minim.”
Si constă într o serie de n transformări aplicate matricei costurilor.
Descrierea detaliata a algoritmului.
Pas1: Pentru etichete ale nodului k de la 1 la n executa
Pas 2: Pentru orice pereche de noduri din graf i și j executa
Pas3: Daca suma dintre costul drumului de la i la k și costul drumului de la k la j este mai mica
decat costul drumului de la nodul i la nodul j atunci in matricea costurilor costul drumului direct
de la i la j este inlocuit cu costul drumului care trece prin nodul k.
In finalul algoritmului, costurile drumurilor minime se gasesc în matricea costurilor, ale căror
elemente au următoarea semnificație:

Cij=costul drumului de la i la j daca exista


+infinit in caz contrar.
Cele spuse se pot implementa astfel:
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(c[i][k]+c[k][j]<c[i][j])
c[i][j]=c[i][k]+c[k][j];

Implementare.
#include <iostream>
#include<fstream>
using namespace std;
int c[100][100],n;
int const INF=50000;
ifstream f("date.in");
void init()
{
int i,j;
f>>n;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(i==j) c[i][j]=0;
else
c[i][j]=INF;

}
void citire()
{
int i,j,cost;
while(f>>i>>j>>cost)
c[i][j]=cost;
}

void transformare()
{
int i,j,k;
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(c[i][j]>c[i][k]+c[k][j])
c[i][j]=c[i][k]+c[k][j];
}

int main()
{
int i,j;
init();
citire();
transformare();
for(int i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
cout<<c[i][j]<<" ";
cout<< endl;
}
return 0;
}
Algoritmul lui Dijkstra
Acest algoritm se aplica în cazul problemelor în care se dă un graf G=(V,U) CARE ARE
matricea COSTURILOR C și se cere să se determine lungimea drumurilor minime (maXIMe) și
in unele cazuri și a nodurilor care constituie drumurile respective, intre un nod și oricare alt nod
al grafului.

În procesul de prelucrare, se folosesc 3 vectori: D, S şi T.

Vectorul D este vectorul lungimii drumurilor de la vârful x la toate celelalte vârfuri ale
grafului. Prin D[i], unde i∈{1,..., n}, se înţelege costul drumului găsit la un moment dat, între
vârful x şi vârful i.
Vectorul T indică drumurile găsite între nodul x şi celelalte noduri ale grafului. Pentru
aceasta se utilizează o memorare specială a drumurilor, numită legătura de tip “tata”, în care
pentru nodul i se reţine nodul precedent pe unde trece drumul de la x la i. Pentru x se memorează
0.
Vectorul S, numit şi vector caracteristic, indică mulţimea S a nodurilor selectate: S[i]=0
dacă nodul i este neselectat şi S[i]=1 dacă nodul i este selectat.
Prezentarea algoritmului
Pasul 1. Vârful x este adăugat mulţimii S iniţial vidă (S[x]=1);
- costurile drumurilor de la x la fiecare nod al grafului se preiau în vectorul D de pe linia x a
matricei A;
- pentru toate nodurile i, având un cost al drumului de la x la ele, finit, se pune T(i)=x.
Pas2: Se executa de n-1 ori secventa:
- printre nodurile neselectate se caută cel aflat la distanţa minimă faţă de x şi se selectează,
adăugându-l mulţimii S. Fie poz acest vârf.
- pentru nodurile neselectate, j, se actualizează în D costul drumurilor de la x la ele, utilizând ca
nod intermediar nodul selectat, poz, procedând în felul următor:
se compară costul existent în vectorul D, pentru j, D(j), cu suma dintre costul existent
în D pentru nodul selectat, poz, şi distanţa de la nodul selectat, poz, la nodul pentru care se face
actualizarea distanţei, j: D(poz)+A(poz,j). În cazul în care suma este mai mică, elementul din D
corespunzător nodului pentru care se face actualizarea, j, reţine suma (D(j)←D(poz)+A(poz,j) şi
elementul din T corespunzător aceluiaşi vârf, iar valoarea vârfului selectat: T(j)←poz (drumul
trece prin acest vârf).
Pasul 3. Pentru fiecare vârf al grafului, cu excepţia lui x, se trasează drumul de la x la el.

Implementare
#include <iostream>
#include<fstream>
using namespace std;
int t[100],d[100],s[100],n,c[100][100];
int const INF=50000;
ifstream f("date.in");
void init()
{
int i,j;
f>>n;
for(i=1;i<=n;i++)
for(j=1;j<=n;i++)
if(i==j)
c[i][j]=0;
else
c[i][j]=INF;
}
void citire()
{
int i,j,cost;
while(f>>i>>j>>cost)
c[i][j]=cost;
}
void drum(int i)
{
if(t[i]!=0) drum(t[i]);
cout<<i<<" ";
}
void generare_drum(int x)
{ int i,j,poz,Min;
s[x]=1;
for(i=1;i<=n;i++)
{d[i]=c[x][i];
if(i!=x && d[i]<INF) t[i]=x;
}
for(i=1;i<=n;i++)
{
Min=50000;
for(j=1;j<=n;j++)
if(s[j]==0 && d[j]<Min)
{
Min=d[j];
poz=j;
}
s[poz]=1;
for(j=1;j<=n;j++)
if(s[j]==0 && d[j]>d[poz]+c[poz][j])
{
d[j]=d[poz]+c[poz][j];
t[j]=poz;
}
}
}
void afisare(int x)
{
int i;
for(i=1;i<=n;i++)
if(i!=x)
if(t[i]!=0)
{
cout<<"drumul de la nodul "<<x<<" la nodul"<<i<<"are costul "<<d[i]<<endl;
drum(i);
cout<<endl;
}
else
cout<<"nu exista drum de la nodul "<<x<<" la nodul "<<i<<endl;
}
int main()
{
int x;
cin>>x;
init();
citire();
generare_drum(x);
afisare(x);
return 0;
}

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