Raport la matematica discret Tema: Pstrarea grafului n memoria calculatorului
A efectuat: st. gr.MN -131 Lupanciuc L. A verificat: Dr. conf. univ. Marusic G.
Chiinu 2014
Lucrare de laborator 1. Tema: Pstrarea grafului n memoria calculatorului 2.SCOPUL LUCRRII: Studierea metodelor de definire a unui graf: matrice de inciden, matrice de adiacen, liste; Elaborarea unor proceduri de introducere, extragere i transformare a diferitor forme de reprezentare intern a grafurilor cu scoaterea rezultatelor la display i imprimant.
4. NOTE DE CURS Metode de reprezentare a grafului Exist trei metode de baz de definire a unui graf: 1. Matricea de inciden; 2. Matricea de adiacen; 3. Lista de adiacen (inciden). Vom face cunotin cu fiecare dintre aceste metode. Matricea de inciden Este o matrice de tipul mxn, n care m este numrul de muchii sau arce (pentru un graf orientat), iar n este numrul vrfurilor. La intersecia liniei i cu coloana j se vor considera valori de 0 sau 1 n conformitate cu urmtoarea regul: 1 - dac muchia i este incident cu vrful j (dac arcul i "intr" n vrful j n cazul unui graf orientat); 0 - dac muchia (arcul) i i vrful j nu sunt incidente; -1 - numai pentru grafuri orientate, dac arcul i "iese" din vrful j.
X 1 X 4 X 2 X 5 X 3 X 6
x 1
x 2
x 3
x 4
x 5
X 6
u 1 -1 0 1 0 0 0 u 2 0 1 -1 0 0 0 u 3 0 -1 0 1 0 0 u 4 0 0 1 -1 0 0 u 5 0 0 0 -1 1 0 u 6 0
0
1
0 -1
0
Fig. 3. Exemplu de matrice din exemplu de mai sus. (v.fig.1) Este uor de observat c aceast metod este de o eficacitate mic n sensul utilizrii memoriei calculatorului: fiecare linie conine doar dou elemente diferite de zero (o muchie poate fi incident cu nu mai mult de dou vrfuri). Matricea de adiacen Este o matrice ptrat nxn, aici n este numrul de vrfuri. Fiecare element poate fi 0, dac vrfurile respective nu sunt adiacente, sau 1, n caz contrar. Pentru un graf fr bucle putem observa urmtoarele: diagonala principal este format numai din zerouri; pentru grafuri neorientate matricea este simetric fa de diagonala principal. x 1 x 2 x 3 x 4 x 5 x 6
x 1 0 0 1 0 0 0 x 2 0 0 0 1 0 0 x 3 0 1 0 0 0 0 x 4 0 0 1 0 1 0 x 5 0 0 1 0 0 0 x 6 0 0 0 0 0 0 Fig. 4. Exemplu de matrice de adiacen din exemplu de mai sus.(v.fig.1) Dup cum este lesne de observat i n acest caz memoria calculatorului este utilizat nu prea eficace din care cauz matricea de adiacen ca i matricea de inciden se vor utiliza de obicei doar n cazul n care se va rezolva o problem concret pentru care reprezentarea grafului n aceast form aduce unele faciliti algoritmului respectiv. Pentru pstrarea grafurilor n memoria calculatorului (n deosebi, memoria extern) se va utiliza una din posibilitile de mai jos.
Lista de adiacen i lista de inciden Lista de adiacen este o list cu n linii (dup numrul de vrfuri n), n linia cu numrul i vor fi scrise numerele vrfurilor adiacente cu vrful i. Lista de inciden se definete analogic cu deosebirea c n linia i vor fi scrise numerele muchiilor (arcelor) incidente cu vrful i. Reprezentarea grafurilor prin intermediul acestor liste permite utilizarea mai eficace a memoriei calculatorului, ns aceste forme sunt mai complicate att n realizare, ct i n timpul procesrii. Pentru a lua n consideraie lungimea variabil a liniilor vor fi utilizate variabile dinamice i pointeri.Vom exemplifica pentru un graf cu n vrfuri. Deoarece fiecare element al listei conine numere de vrfuri este evident s considerm c vom avea un ir de variabile dinamice de tip INTEGER care se vor afla n relaia respectiv de precedare (succedare). Aceast relaie se va realiza prin pointeri, unii mpreun cu variabila de tip ntreg n nregistrarea (Pascal: record). Pentru a pstra indicatorii de intrare n aceste iruri se va folosi un tablou unidimensional de indicatori de lungime n. n calitate de simbol de terminare a irului se va utiliza un simbol care nu a fost folosit la numeraia vrfurilor (de exemplu 0), care va fi introdus n calitate de variabil de tip ntreg al ultimului bloc. De exemplu, lista de adiacen (fig.1.1): 1 - 3, 0 2 4, 0 3 - 2, 0 4 3, 5,0 5 3,0 6 - 0
5.Programul in C: 1. #include <conio.h> 2. #include <stdio.h> 3. #include <stdlib.h> 4. #define L 100
5. int matr_incid[L][L],n,m; 6. int matr_adiac[L][L]; 7. int list_adiac[L][L];
35. fp=fopen("meniu_principal.txt","r"); 36. system("cls"); 37. while ((ch=fgetc(fp))!=EOF) 38. printf ("%c",ch);
39. optiunea=getch(); 40. switch(optiunea) 41. { 42. case'1':meniu_introducere();break; 43. case'2':meniu_afisare();break; 44. case'3':meniu_modificare();break; 45. case'0':exit(0);break; 46. default:printf("\n\n Ati ales o optiune gresita!!!Apasati orice tasta pentru a alege alta..");getch(); 47. }
52. fp=fopen("meniu_introducere.txt","r"); 53. system("cls"); 54. while ((ch=fgetc(fp))!=EOF) 55. printf ("%c",ch);
56. optiunea=getch(); 57. switch(optiunea) 58. { a. case'1':introducerea_matr_incid();break; b. case'2':introducerea_matr_adiac();break; c. case'3':introducerea_list_adiac();break; d. case'4':meniu_principal();break; e. case'0':exit(0);break; f. default:printf("\n\nAti ales o optiune gresita!!! Apasati orice tasta pentru a alege alta");getch();
59. }}
60. void meniu_afisare() 61. { 62. char optiunea; 63. do{ 64. system("cls"); 65. printf("\n\n\n\n" 66. "\n IN CE FORMA DRITI SA AFISEZE GRAFUL" 67. "\n\n 1.Matricea de incidenta" 68. "\n\n 2.Matricea de adiacenta" 69. "\n\n 3.Lista de adiacenta" 70. "\n\n " 71. "\n\n 4.Modificarea grafului" 72. "\n\n 5.Meniul principal" 73. "\n\n " 74. "\n\n 0.Iesire " 75. "\n\n Alegeti optiunea"); 76. optiunea=getch(); 77. switch(optiunea) 78. { 79. case'1':afisarea_matr_incid();break; 80. case'2':afisarea_matr_adiac();break; 81. case'3':afisarea_list_adiac();break; 82. case'4':meniu_modificare();break; 83. case'5':meniu_principal();break; 84. case'0':exit(0);break; 85. default:printf("\n\nAti ales optiune gresita!!!Apasati orice tasta pentru a alege alta");getch(); 86. } 87. }while(1); 88. } 89. void meniu_modificare() 90. { 91. char optiunea; 92. do{ 93. system("cls"); 94. printf("\n\n\n\n" 95. "\n CE MODIFICARI DORITI SA EFECTUATI" 96. "\n\n 1.Adaugarea unui virf" 97. "\n\n 2.Stergerea unui virf" 98. "\n\n 3.Adaugarea unui arc" 99. "\n\n 4.Stergerea unui arc" 100. "\n\n " 101. "\n\n 5.Meniu principal" 102. "\n\n " 103. "\n\n 0.iesire " 104. "\n\n Alegeti optiunea:"); 105. optiunea=getch(); 106. switch(optiunea) 107. { a. case'1':adaugarea_virf();break; b. case'2':stergerea_virf();break; c. case'3':adaugarea_arc();break; d. case'4':stergerea_arc();break; e. case'5':meniu_principal();break; f. case'0':exit(0);break; g. default:printf("\n\nAti ales o optiune gresita!!!Apasati orice tasta pentru a alege alta optiune");
289. int i,j; 290. printf("\n\t\t Lista de adiacenta:\n\n\n"); 291. for(i=1;i<=n;i++) 292. { 293. printf("\n%2d|",i); 294. for(j=1;j<=n;j++) a. if(list_adiac[i][j]==0) b. { c. printf("%2d",list_adiac[i][j]); d. break; e. } f. else printf("%2d",list_adiac[i][j]); 295. } 296. getch(); 297. meniu_afisare(); 298. }
299. /* ********Modificarea grafului******** */ 300. void adaugarea_virf() 301. { 302. system("cls"); 303. int i,j,k,i1,j1; 304. n++; 305. printf("\n Cite arce doriti sa adaugati pentru noul virf:"); 306. scanf("%d",&k); 307. m=m+k; 308. for(i=1;i<=n;i++) 309. { 310. matr_adiac[i][n]=0; 311. matr_adiac[n][i]=0; 312. } 313. for(i=1;i<=k;i++) 314. { 315. printf("\n Din care virf iese arcul:"); 316. scanf("%d",&i1); 317. printf("\n\nIn care virf pleaca arcul:"); 318. scanf("%d",&j1); 319. matr_adiac[i1][j1]=1;}
320. transfer_matra_lista(); 321. transfer_matra_matri(); 322. printf("\n\nApasati orice tasta pentru a continua"); 323. getch(); 324. meniu_modificare(); 325. }
339. transfer_matra_lista(); 340. transfer_matra_matri(); 341. printf("\n\nApasati orice tasta pentru a continua"); 342. getch(); 343. meniu_modificare(); 344. }
345. void adaugarea_arc() 346. { 347. system("cls"); 348. int i1,j1; 349. printf("\t\tAdaugarea arcelor\n\n\n\n"); 350. printf("\nDin care virf iese arcul:"); 351. scanf("%d",&i1); 352. printf ("\nIn care virf intra arcul:"); 353. scanf("%d",&j1); 354. matr_adiac[i1][j1]=1;
355. transfer_matra_lista(); 356. transfer_matra_matri(); 357. printf("\n\nApasati orice tasta pentru a continua"); 358. getch(); 359. meniu_modificare(); 360. } 361. void stergerea_arc() 362. { 363. system("cls"); 364. int i1,j1; 365. printf("\t\tStergerea arcelor\n\n\n\n"); 366. printf("\n Din care virf iese arcul:"); 367. scanf("%d",&i1); 368. printf("\n\nIn care virf pleaca arcul"); 369. scanf("%d",&j1); 370. matr_adiac[i1][j1]=0; 371. transfer_matra_lista(); 372. transfer_matra_matri(); 373. printf("\n\nApasati orice tasta pentru a continua"); 374. getch(); 375. meniu_modificare(); 376. }
Rezultatul:
Concluzie:In aceasta lucrare de laborator am elaborat un program in limbajul de programe C.In care am eloborat algoritmi in care graful sa poata fi posibil de transformat in matrice de incidenta,adiacenta si lista.Ce mai eficace metoda de utilizare a memoriei calculatorului este lista insa este mai dificil in realizare.Celalte doua metoda se pot realiza cu ajutorul matricilor,fiecare linie conine doar dou elemente diferite de zero (o muchie poate fi incident cu nu mai mult de dou vrfuri)..Deasemenea programul este capabil sa mai adauge un arc,virf sau chiar si procesul invers de a sterge un arc sau virf.Acem program poate fi realizat in oricisice alt limbaj.Imaginile care le-am adaugat demostreaza starea de functionalitate a programului