Anda di halaman 1dari 9

UTM

Catedra Tehnologii Informationale

Referat
Lucrarea de laborator Nr 4,5
Tema: Algoritmul de cutare a grafului de acoperire i
a drumului minim ntr-un graf

A efectuat:

studentul Cacean Alexandru

A verificat:

lectorul Ceban G.

Chiinu 2004
Scopul lucrrii:

- Studierea algoritmilor de determinare a grafului de acoperire i


elaborarea programei ce va realiza acest algoritm.
-studierea algoritmilor de determinare a drumurilor minime ntr-un
graf.
- Elaborarea programei de determinare a drumului minim ntr-un
graf ponderat.

Enunul problemei:
1. S se elaboreze procedura introducerii unui graf ponderat;
2. S se elaboreze procedura determinrii drumului minim.
3. S se elaboreze programul procedurii de determinare a grafului
de acoperire cu posibiliti de pornire a procedurii din oricare
vrf al grafului

Textul programului :
Algoritmul de Cutare a grafului de acoperire:
#include<stdio.h>
#include<conio.h>
#define MAX_ARCURI 50
#define MAX_VARFURI 20
struct Elem {
int N;
struct Elem * P;
};
typedef Elem* ElemPtr;
typedef int MAdiacenta[MAX_VARFURI] [MAX_VARFURI];
typedef int MIncidenta[MAX_ARCURI] [MAX_VARFURI];
int cd[MAX_VARFURI];
int i;
int all; // variabila va contine numarul de noduri din graf
ElemPtr Pt; // pointer, va fi folosit pentru a accesa elementele listei de adiacenta
MAdiacenta MA;
MIncidenta MI;
ElemPtr T[MAX_VARFURI]; // declararea listei de adiacenta
// initializarea listei de adiacenta
void InitListAdiacenta(void)
// functia data este folosita pentru initializarea listei
{
int i;
for (i=0; i<MAX_VARFURI; i++)
while (T[i]->N !=0)
{
Pt=T[i];
T[i]=Pt->P;
delete Pt;
}
}

// Introducerea Listei de adiacenta


void InLA(void)
{
int i, top;
printf("Introducerea listei de adiacenta :\n");
printf("Numarul de varfuri :");
scanf("%d",&all); // all = numarul de varfuri
for (i=0; i<all; i++)
{
T[i] = new Elem;
// alocarea in memoriei pentru un nou element al listei
Pt=T[i];
Pt->N =0; // setarea valorii nodului ca 0
printf("varful %d :",i+1);
while (1)
// ciclu infinit pana la un break
{
scanf("%d",&top);
// citirea cate un element pana la intalnirea 0;
if (top != 0)
{
Pt->N = top; // adaugarea elementului la lista
Pt->P = new Elem; // alocarea memoriei pentru un nou element
Pt = Pt->P; //avansarea in lista
Pt->N =0; // setarea valorii ca 0
}
else break; // in caz cand intalnim 0 introducerea valorilor pentru
// varful curent ,i ia sfarsit
}
printf("\n");
}
printf("\n");
}
// Introducerea Matricei de adiacenta
void InMA(void)
{
int i, i1;
printf(" Introducerea Matricei de Adiacenta \n");
printf(" Numarul de varfuri : ");
scanf("%d",&all); // numarul de varfuri
for(i=0; i<all; i++)
for(i1=0; i1<all; i1++)
{
MA[i][i1]=0; // curatarea matricei
if (i != i1) // nu certam pentru bucle
{
printf("\n Din varful %d in %d :",i+1,i1+1);
scanf("%d",&MA[i][i1]); //citirea valorii a(i,j)
}
}
InitListAdiacenta(); //curatarea listei

for (i=0;i<all;i++)
{
Pt=T[i];
//pregatirea pentru a misca prin lista
for (i1=0;i1<all;i1++)
{
if (MA[i][i1]!=0)
{
Pt->N=i1+1; // settarea valorii nodului current
Pt->P = new Elem;
// alocarea memorie pentru un nou element al listei
Pt=Pt->P; // avansarea
Pt->N=0; //settarea sfarsitului
}
}
}
}
// introducerea matricei de incidenta
void InMI(void)
{
int AllLink;
int i,i1; // variabile contor
int Sr,Tg;
printf("Introducerea matricei de incidenta \n");
printf("Numarul de arcuri : ");
scanf("%d",&AllLink); // citirea numarului de arcuri
printf("\nNumarul de varfuri : ");
scanf("%d",&all); //citirea numarului de varfuri
for (i=0;i<all;i++)
for (i1=0;i1<AllLink;i1++)
{
printf("\nVarful %d si arcul %d ",i+1,i1+1);
scanf("%d",&MI[i][i1]); //citirea elementului dat
}
InitListAdiacenta(); //curatarea listei de adiacenta
for (i=0;i<AllLink;i++)
{
Sr=0; Tg=0;
for (i1=0;i1<all;i1++)
{
if (MI[i1][i]==1) Tg=i1;
//nodul - i1 este destinatia arcului
if (MI[i1][i]==-1) Sr=i1; //nodul - i1 este sursa arcului
}
if (Sr != 0)
{
Pt=T[Sr];
//adaugam nodul pentru elementul sursa
while (Pt->N != 0)
{
if (Pt->N==Tg) goto label1;
Pt= Pt->P;

}
Pt->N=Tg; //adaugarea nodului
Pt->P = new Elem; //alocarea memoriei
Pt->P->N=0; //setarea sfarsitului listei de noduri
label1:
;
}
}
}
char t[MAX_VARFURI];
void initT(void)
{
for (int i=0;i<MAX_VARFURI;i++) t[i]=0;
}
MAdiacenta a;
void createMA()
{
int i,i1;
for (i=0;i<MAX_VARFURI;i++) //curatarea matricei
for (i1=0;i1<MAX_VARFURI;i1++) a[i][i1]=0;
for (i=0;i<all;i++) //pentru toate varfurile
{
Pt=T[i]; //setam pointerul de parcurgere
while (Pt->N != 0) //pana nu s-a ajuns la sfarsit
{
if (a[i][Pt->N-1]==0) a[i][Pt->N-1]=1;
//crearea matricei
Pt=Pt->P; //avansarea in lista
}
}
}
MAdiacenta b;
void parcinadinc(int k) // parcurgerea in adancime
{
int i;
t[k]=1;
for (i=0;i<all;i++)
if ((a[k][i]==1) && (t[i]==0))
{
b[k][i]=1;
parcinadinc(i);
}
}
void grafacoperire()
{
int i,j;
for (i=0;i<all;i++)
for (j=0;j<all;j++) b[i][j]=0;
createMA();
initT();
parcinadinc(0);

printf("\n Graful de acoperire \n");


for (i=0;i<all;i++)
{
for (j=0;j<all;j++) printf("%3d",b[i][j]);
printf("\n");
}
}
void main(void) //programul principal
{
unsigned int ch; //variabile pentru meniu
clrscr();
for (int i=0;i<MAX_VARFURI;i++)
{
T[i]=new Elem;
T[i]->N=0;
}
do
{
printf(" ---Introduceti graful sub urmatoarele forme:1,2,3--- \n");
printf("1. Lista de Adiacenta\n");
printf("2. Matricea de Adiacenta\n");
printf("3. Matricea de Incidenta\n");
printf("4. Iesire\n");
printf("5. Graf de acoperire \n");
ch=getch();
switch (ch) {
case '1' :InLA();break; //introducerea listei de adiacenta
case '2' :InMA();break; //introducerea matricei de adiacenta
case '3' :InMI();break; //introducerea matricei de incidenta
case '5' :grafacoperire();break; //graf de acoperire
}
} while (ch != '4'); //repeta pana s-a ales Iesire
}

Algoritmul De Gsire A Drumului Minim:


#include<stdio.h>
#include<conio.h>
#include<process.h>
#include<values.h>
#define d 10000;
void Bel_Kal(int);
void Ford(int);
main()
{int n;
char dm;clrscr();
textcolor(10);
printf("Introduceti numarul de virfuri care le contine
graful:\n\r");scanf("%d",&n);
printf("Alegeti metoda pri care doriti sa lucrati?\n");
printf("a) Algoritmul Belman-Kalaba\n");

printf("b) Algoritmul Ford\n");


A1: scanf("%c",&dm);
switch(dm)
{case 'a':Bel_Kal(n);break;
case 'b':Ford(n);break;
default:printf("");goto A1;
}
getche();return 0;
}
void Bel_Kal(int n)
{int mat[25][25],ad[20][20],i,j,dm;
int V[15][10],t,l=0,k=0,s=0,min,D[3][10];
clrscr();
printf("Introdu matricea de adiacenta de ordinul %d\n",n);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&ad[i][j]);
printf("Din ce virf pina in punctul final doriti sa aflati drumul min?\n");
scanf("%d",&dm);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{if(i!=j)mat[i][j]=d
else mat[i][j]=0;}
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{if(ad[i][j]!=0)
if(i!=j)mat[i][j]=ad[i][j];}
for(i=0;i<n;i++)
V[0][i]=mat[i][n-1];
b1:for(i=0;i<n-1;i++)
{min=d;
for(j=0;j<n;j++)
if(j!=i)
{ t=mat[i][j]+V[k][j];
if(t<min)min=t;
}
V[k+1][i]=min;
}V[k+1][n-1]=0;
for(l=0;l<n;l++)
{if(V[k][l]==V[k+1][l])
s++;}
if(s!=n){k++;s=0;goto b1;}
printf("V=");
for(j=0;j<n;j++)printf(" %d ",V[k+1][j]);
printf("\n");D[0][0]=dm;t=1;l=dm-1;//s=0;
printf("Drumul minim din virful %d la virful %d este:%d\n",dm,n,V[k+1][dm-1]);
A3:for(j=0;j<n;j++)
if(j!=l)
{if(V[k+1][l]-ad[l][j]==V[k+1][j])
{D[0][t]=j+1;t++;l=j;if(l<n)goto A3;}

}
printf("Succesiunea de virfuri este:\n");
for(i=0;i<t;i++)
{printf("X[%d]",D[0][i]);if(i<t-1)printf(" > ");}
printf("\n");
getche();exit(n);
}
void Ford(int n)
{int H[20],i,j,ad[20][20];
int dr[10],l;clrscr();
printf("Introdu matricea de adiacenta:\n");
for(i=0;i<n;i++)
for(j=0;j<n;j++)scanf("%d",&ad[i][j]);
printf("Pina in ce virf doriti sa aflati drumul minim?\n");
scanf("%d",&l);
H[0]=0;
for(i=1;i<n;i++)
H[i]=d;
for(i=0;i<n-1;i++)
for(j=1;j<n;j++)
if((j!=i)&&(ad[i][j]!=0))
{if(H[j]-H[i]>ad[i][j])H[j]=H[i]+ad[i][j];}
for(i=0;i<n;i++)printf(" %d ",H[i]);dr[0]=l;i=1;
printf("\nDrumul minim din virful 1 pina in virful %d este:%d\n",l,H[l-1]);
printf("Succesiunea de drumuri este:\n");
A1:for(j=n-1;j>=0;j--)
if((j!=l-1)&&(ad[j][l-1]!=0))
{if(H[l-1]-H[j]==ad[j][l-1])
{dr[i]=j+1;i++;l=j+1;if(l>0)goto A1;else goto A2;}
}
A2: for(j=i-1;j>=0;j--)
{printf("X[%d]",dr[j]);if(j>0)printf(">");}
getche();exit(n);
}

Rezultatele Obinute:

Drumul Minim:

Concluzii: Efectund lucrarea dat ne-am fcut cunoscui cu metodele de prelucrare a


grafurilor i anume cu metoda de gsire a grafului de acoperire i a drumului minim.
Pentru prelucrarea grafurilor am folosit liste, ceea ce este mai eficient dect prelucrarea
grafurilor cu ajutorul matricelor.

Anda mungkin juga menyukai