Documente Academic
Documente Profesional
Documente Cultură
MDlab4 5
MDlab4 5
Lucrare de laborator la
Matematica discretă
Chişinău 2015
1. Scopul lucrării:
Studierea algoritmilor de determinare a drumurilor minime într-un graf.
Elaborarea programelor de determinare a drumului minim într-un graf ponderat.
2.Sarcina de bază
1. Elaboraţi procedura introducerii unui graf ponderat;
2. Elaboraţi procedurile determinării drumului minim;
3. Realizaţi un program cu următoarele funcţii:
introducerea grafului ponderat cu posibilităţi de analiză sintactică şi semantică;
determinarea drumului minim;
extragerea informaţiei la display sau imprimantă (valoarea drumului minim şi succesiunea vârfurilor care formează
acest drum).
3.Listingul programului
//Lucrare de laborator Nr4.
// Tema:Drum minim (Alg. Ford si Belman-Kalaba).
=
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
int main()
{
list **adi_list;
int n, k, v_pon, v_fin, val_init, lun_dr, nr_lin, v_start, opt, ex_max;
int **mat_ini, mat_res[100][100];
FILE *fp;
printf("Introduceti numarul de virfuri: ");
scanf("%d", &n);
adi_list = saveList(n, adi_list);
mat_ini = matInitiala(mat_ini, n, k, adi_list);
ex_max = matDr(n, k, mat_ini);
system("cls");
do
{
printf("||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n");
printf("| Algoritmul Ford si Algoritmul Bellman Kalaba |\n");
printf("||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n");
printf("| 1.Afisarea listei de adiacenta |\n");
printf("| 2.Afisarea drumului minim(FORD) |\n");
printf("| 3.Afisarea drumului maxim(FORD) |\n");
printf("| 4.Afisarea drumului minim(Bellman Kalaba) |\n");
printf("| 5.Afisarea drumului maxim(Bellman Kalaba) |\n");
printf("| 0.Iesire |\n");
printf("| |\n");
printf("||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n");
printf("Introduceti optiunea dorita: ");
fflush(stdin);
opt = getche();
switch(opt)
{
case '1':
printf("\n");
viewList(n, adi_list);
printf("Pentru a reveni apasa-ti orice tasta...");
fp = fopen("md_saveL4.txt", "w");
fputs("<=====Lista de adiacenta=====>\n", fp);
saveFileList(n, adi_list, fp);
fclose(fp);
getch();
system("cls");
break;
case '2':
printf("\nIntroduce-ti virful pina in care trebuie calculat dr.minim: ");
scanf("%d", &v_fin);
val_init = 2147483600;
drFord(v_fin, mat_ini, mat_res, k, val_init, lun_dr, nr_lin, n);
printf("\nLungimea drumului = %d\n", lun_dr);
printf("\n");
afisDrFord(mat_res, nr_lin);
printf("Pentru a reveni apasa-ti orice tasta...");
fp = fopen("md_saveL4.txt", "a");
fprintf(fp, "\nDrumul minim pina in virful %d (Alg.Ford):", v_fin);
fprintf(fp, "\nLungimea drumului = %d\n", lun_dr);
saveDrFord(mat_res, nr_lin, fp);
fclose(fp);
getch();
system("cls");
break;
case '3':
if(ex_max == 0)
{
printf("\nDrum maxim nu exista, pentru ca graful este cu circuite!");
printf("Pentru a reveni apasa-ti orice tasta...");
getch();
system("cls");
break;
}
printf("\nIntroduce-ti virful pina in care trebuie calculat dr.maxim: ");
scanf("%d", &v_fin);
val_init = -2147483600;
drFord(v_fin, mat_ini, mat_res, k, val_init, lun_dr, nr_lin, n);
printf("\nLungimea drumului = %d\n", lun_dr);
printf("\n");
afisDrFord(mat_res, nr_lin);
printf("Pentru a reveni apasa-ti orice tasta...");
fp = fopen("md_saveL4.txt", "a");
fprintf(fp, "\nDrumul maxim pina in virful %d (Alg.Ford):", v_fin);
fprintf(fp, "\nLungimea drumului = %d\n", lun_dr);
saveDrFord(mat_res, nr_lin, fp);
fclose(fp);
getch();
system("cls");
break;
case '4':
printf("\nIntroduce-ti virful din care trebuie calculat dr.minim: ");
scanf("%d", &v_start);
val_init = 2147483600;
algBK(mat_ini, val_init, v_start, mat_res, n, k, lun_dr, nr_lin);
printf("\nLungimea drumului = %d\n", lun_dr);
printf("\n");
afisDrBK(mat_res, nr_lin);
printf("Pentru a reveni apasa-ti orice tasta...");
fp = fopen("md_saveL4.txt", "a");
fprintf(fp, "\nDrumul minim din virful %d (Alg.B-K):", v_fin);
fprintf(fp, "\nLungimea drumului = %d\n", lun_dr);
saveDrBK(mat_res, nr_lin, fp);
fclose(fp);
getch();
system("cls");
break;
case '5':
if(ex_max == 0)
{
printf("\nDrum maxim nu exista, pentru ca graful este cu circuite!");
printf("Pentru a reveni apasa-ti orice tasta...");
getch();
system("cls");
break;
}
printf("\nIntroduce-ti virful din care trebuie calculat dr.maxim: ");
scanf("%d", &v_start);
val_init = -2147483600;
algBK(mat_ini, val_init, v_start, mat_res, n, k, lun_dr, nr_lin);
printf("\nLungimea drumului = %d\n", lun_dr);
printf("\n");
afisDrBK(mat_res, nr_lin);
printf("Pentru a reveni apasa-ti orice tasta...");
fp = fopen("md_saveL4.txt", "a");
fprintf(fp, "\nDrumul maxim din virful %d (Alg.B-K):", v_fin);
fprintf(fp, "\nLungimea drumului = %d\n", lun_dr);
saveDrBK(mat_res, nr_lin, fp);
fclose(fp);
getch();
system("cls");
break;
default:
system("cls");
}
}while(opt != '0');
return 0;
}
//Functia pentru adaugarea unui element intr-o lista cu parcurgerea de la inceput spre sfirsit
list* pushList(list *prev_el, list *&head_el, int inf)
{
list *tmp = (list *)malloc(sizeof(list));
tmp->info = inf;
tmp->adr = 0;
if(prev_el == 0)
head_el = tmp;
else
prev_el->adr = tmp;
prev_el = tmp;
return prev_el;
}
//Functia pentru generarea matricei initiale cu care mai apoi vom lucra
void algBK(int **mat_ini, int val_init, int v_start, int mat_res[100][100], int n, int k, int &lun_dr, int
&nr_lin)
{
int i, j, ii, con, n_v, min, max, nr_dr, nr_el, nr_ap, pos_v, aux;
int mat_luc[100][n];
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
if(i == j)
mat_luc[i][j] = 0;
else{
for(ii = 0; ii < k; ii++)
{
con = 0;
if(mat_ini[ii][0] == i + 1 && mat_ini[ii][1] == j + 1)
{
mat_luc[i][j] = mat_ini[ii][2];
con = 1;
break;
}
}
if(con == 0)
mat_luc[i][j] = val_init;
}
}
}
n_v = n;
for(i = 0; i < n; i++)
mat_luc[n_v][i] = mat_luc[i][n - 1];
con = 0;
if(val_init > 0)
{
do
{
n_v++;
for(j = 0; j < n - 1; j++)
{
min = val_init;
for(i = 0; i < n; i++)
if(i != j)
if(mat_luc[j][i] != val_init && mat_luc[n_v - 1][i] != val_init)
if(min > mat_luc[j][i] + mat_luc[n_v - 1][i])
min = mat_luc[j][i] + mat_luc[n_v - 1][i];
mat_luc[n_v][j] = min;
}
mat_luc[n_v][n - 1] = 0;
con = 1;
for(i = 0; i < n; i++)
if(mat_luc[n_v - 1][i] != mat_luc[n_v][i])
{
con = 0;
break;
}
}while(con != 1);
}else{
do
{
n_v++;
for(j = 0; j < n - 1; j++)
{
max = val_init;
for(i = 0; i < n; i++)
if(i != j)
if(mat_luc[j][i] != val_init && mat_luc[n_v - 1][i] != val_init)
if(max < mat_luc[j][i] + mat_luc[n_v - 1][i])
max = mat_luc[j][i] + mat_luc[n_v - 1][i];
mat_luc[n_v][j] = max;
}
mat_luc[n_v][n - 1] = 0;
con = 1;
for(i = 0; i < n; i++)
if(mat_luc[n_v - 1][i] != mat_luc[n_v][i])
{
con = 0;
break;
}
}while(con != 1);
}
lun_dr = mat_luc[n_v][v_start - 1];
nr_dr = 0;
nr_el = 1;
nr_lin = 0;
mat_res[nr_dr][1] = v_start;
do
{
do
{
nr_ap = 0;
pos_v = -1;
for(i = 0; i < n; i++)
if(i != v_start - 1)
if(mat_luc[n_v][v_start - 1] - mat_luc[v_start - 1][i] == mat_luc[n_v]
[i])
{
nr_ap++;
if(pos_v == -1)
pos_v = i;
}
if(v_start != n)
if(nr_ap > 1)
{
nr_el++;
mat_res[nr_dr][nr_el] = pos_v + 1;
mat_res[nr_dr][0] = nr_el;
do
{
nr_lin++;
for(j = 0; j <= mat_res[nr_dr][0]; j++)
mat_res[nr_lin][j] = mat_res[nr_dr][j];
aux = pos_v + 1;
for(i = aux; i < n; i++)
{
if(mat_luc[n_v][v_start - 1] - mat_luc[v_start -
1][i] == mat_luc[n_v][i])
break;
}
pos_v = i;
mat_res[nr_lin][mat_res[nr_dr][0]] = pos_v + 1;
nr_ap--;
}while(nr_ap != 1);
v_start = mat_res[nr_dr][mat_res[nr_dr][0]];
}else{
nr_el++;
v_start = pos_v + 1;
mat_res[nr_dr][nr_el] = pos_v + 1;
mat_res[nr_dr][0] = nr_el;
}
}while(v_start != n);
nr_dr++;
nr_el = mat_res[nr_dr][0];
v_start = mat_res[nr_dr][nr_el];
}while(nr_dr != nr_lin + 1);
}
void drFord(int v_fin, int **mat_ini, int mat_res[100][100], int k, int val_init, int &lun_dr, int &nr_lin, int
n)
{
int vect_h[n + 1], v_e, i, nr_dr, nr_ap, nr_el, j, pos_v, c, aux, aux2;
vect_h[1] = 0;
for(i = 2; i <= n; i++)
vect_h[i] = val_init;
if(val_init > 0)
{
do
{
v_e = 0;
for(i = 0; i < k; i++)
{
if((vect_h[mat_ini[i][1]] - vect_h[mat_ini[i][0]]) > mat_ini[i][2])
{
vect_h[mat_ini[i][1]] = vect_h[mat_ini[i][0]] + mat_ini[i][2];
v_e++;
}
if(vect_h[mat_ini[i][1]] != val_init && (vect_h[mat_ini[i][1]] -
vect_h[mat_ini[i][0]]) == mat_ini[i][2])
{
mat_ini[i][3] = 1;
}
else
{
mat_ini[i][3] = 0;
}
}
}while(v_e != 0);
}else{
do
{
v_e = 0;
for(i = 0; i < k; i++)
{
if((vect_h[mat_ini[i][1]] - vect_h[mat_ini[i][0]]) < mat_ini[i][2])
{
vect_h[mat_ini[i][1]] = vect_h[mat_ini[i][0]] + mat_ini[i][2];
v_e++;
}
if((vect_h[mat_ini[i][1]] - vect_h[mat_ini[i][0]]) == mat_ini[i][2])
mat_ini[i][3] = 1;
else
mat_ini[i][3] = 0;
}
}while(v_e != 0);
}
lun_dr = vect_h[v_fin];
nr_dr = 0;
nr_el = 1;
nr_lin = 0;
mat_res[nr_dr][1] = v_fin;
do
{
do
{
nr_ap = 0;
pos_v = -1;
for(i = k - 1; i >= 0; i--)
if(v_fin == mat_ini[i][1] && mat_ini[i][3] == 1)
{
nr_ap++;
if(pos_v == -1)
pos_v = i;
}
if(v_fin != 1)
if(nr_ap > 1)
{
nr_el++;
mat_res[nr_dr][nr_el] = mat_ini[pos_v][0];
mat_res[nr_dr][0] = nr_el;
do
{
nr_lin++;
for(j = 0; j < mat_res[nr_dr][0]; j++)
mat_res[nr_lin][j] = mat_res[nr_dr][j];
aux = pos_v - 1;
for(i = aux; i >= 0; i--)
{
if(v_fin == mat_ini[i][1] && mat_ini[i][3] ==
1)
break;
}
pos_v = i;
mat_res[nr_lin][mat_res[nr_dr][0]] = mat_ini[pos_v][0];
nr_ap--;
}while(nr_ap != 1);
v_fin = mat_res[nr_dr][mat_res[nr_dr][0]];
}else{
nr_el++;
mat_res[nr_dr][nr_el] = mat_ini[pos_v][0];
mat_res[nr_dr][0] = nr_el;
v_fin = mat_ini[pos_v][0];
}
}while(v_fin != 1);
nr_dr++;
nr_el = mat_res[nr_dr][0];
v_fin = mat_res[nr_dr][nr_el];
}while(nr_dr != nr_lin + 1);
}
Concluzie: Efectuind aceasta lucrare , neam familiarizat cu algoritmul aflarii drumului minim.Acest
algoritm ne permite de a afla drumul minim intre orce doua vurfuri prin metoda lui Ford
si prin metoda lui Bellman-Kalaba.Acest algoritm se aplică pe larg în practică de exem-
plu laproectarea şoselelor sau a diferitor tipuri de comunicaţii,deci studiind teoretic acum
acest algoritm pe viitotr e posibil să-l aplicăm pentru un caz real.