You are on page 1of 8

Ministerul Educaţiei al Republicii Moldova

Universitatea Tehnică a Moldovei

Raport
Lucrarea de laborator Nr.4
la Matematica Discreta

Algoritmii Ford și Bellman-Kalaba de determinare a


drumului minim/maxim în graf

A efectuat: st. gr. RM-201 Ghirea Gabriel

A verificat: conf. univ. Gorban Maria

Chişinău, 2021
Lucrare de laborator Nr.4

Listing-ul programului

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

#define MAX 999

struct list {
int v;
int pondere;
struct list* urmator;
};

struct graph {
int h;
int p;
struct list *primul;
struct list *ultimul;
};

typedef struct list List;


typedef struct graph Graph;

Graph *creaza_un_graf(int *virf);


void ford(Graph* graph, int* virf);
void ford_road(Graph* graph, int n);
void bellman_kalaba(Graph *graph, int *virf);
void stergere_graf(Graph *graph, int *virf);

Graph *creaza_un_graf(int *virf)


{
printf("Dati nr. de virfuri a grafului: ");
scanf("%d", virf);
int v, pondere;
Graph* graph = malloc(*virf * sizeof(Graph));
printf("Introduceti lista de adiacenta: \n");
for (int i = 0; i < *virf; i++)
{
printf("%d| ", i + 1);
graph[i].primul = (List*)malloc(sizeof(List));
graph[i].ultimul = graph[i].primul;
graph[i].ultimul->urmator = NULL;
graph[i].ultimul->v = -1;
scanf("%d", &v);
if (*virf < v || v < 0)
{
printf("\nEroare!");
getch();
}
while (v)
{
graph[i].ultimul->v = v - 1;
graph[i].ultimul->urmator = (List*)malloc(sizeof(List));
graph[i].ultimul = graph[i].ultimul->urmator;
graph[i].ultimul->urmator = NULL;
graph[i].ultimul->v = -1;
scanf("%d", &v);
if (*virf < v || v < 0) {
printf("\neroare");
getch();
}
}
}
printf("\nIntroduceti ponderile pentru fiecare arc\n");
for (int i = 0; i < *virf; i++)
{
graph[i].ultimul = graph[i].primul;
while (graph[i].ultimul->v + 1) {
printf("arc%d%d| ", i + 1, graph[i].ultimul->v + 1);
scanf("%d", &pondere);
graph[i].ultimul->pondere = pondere;
graph[i].ultimul = graph[i].ultimul->urmator;
}
}
return graph;
}

void ford_road(Graph* graph, int n)


{
int temp;
if (n != 0) {
temp = n;
ford_road(graph, graph[n].p);
}
if (temp != n)
printf(": %d", n + 1);
else {
printf("->%d", n + 1);
temp++;
}
}

void ford(Graph* graph, int* virf)


{
int good = 1;
if (!graph) return;
List* list = NULL;
for (int i = 0; i < *virf; i++)
{
graph[i].p = -1;
graph[i].h = MAX;
}
graph[0].h = 0;
while (good) {
good = 0;
for (int i = 0; i < *virf; i++)
{
list = graph[i].primul;
while (list != graph[i].ultimul)
{
if (graph[list->v].h > graph[i].h + list->pondere)
{
graph[list->v].h = graph[i].h + list->pondere;
graph[list->v].p = i;
good = 1;
}
list = list->urmator;
}
}
}
int temp;
for (int i = 0; i < *virf; i++)
{
printf("\nDrum minim din %d in %d este: ", 0 + 1, i + 1);
if (graph[i].h == MAX)
printf("nu exista");
else
{
ford_road(graph, i);
printf("Lungimea %d: ", graph[i].h);
}
}
}

void bellman_kalaba(Graph *graph, int *virf)


{
int *t = NULL;
int good = 1;
List *current = NULL;
int *arr = malloc(*virf * sizeof(int));
int *arr1 = malloc(*virf * sizeof(int));
int *P = malloc(*virf * sizeof(int));
int **M = malloc(*virf * sizeof(int*));
for (int i = 0; i < *virf; i++)
M[i] = (int*)malloc(*virf * sizeof(int));

for (int i = 0; i < *virf; i++)


for (int j = 0; j < *virf; j++)
M[i][j] = (i == j) ? 0 : MAX;

for (int i = 0; i < *virf; i++)


{
current = graph[i].primul;
while (current != graph[i].ultimul)
{
M[i][current->v] = current->pondere;
current = current->urmator;
}
}

int vert = *virf - 1;


for (int i = 0; i < vert; i++)
{
arr1[i] = M[i][vert];
P[i] = -1;
}

while (good)
{
for (int i = 0; i < *virf; i++)
{
arr[i] = MAX;
for (int j = 0; j < *virf; j++)
if (i != j && arr[i] > arr1[j] + M[i][j])
{
arr[i] = arr1[j] + M[i][j];
P[i] = j;
}
}

arr[vert] = 0;
int i;
for (i = 0; i < *virf && arr[i] == arr1[i]; i++);
good = (i == *virf) ? 0 : 1;
t = arr1; arr1 = arr; arr = t;
}
for (int i = 0; i < *virf; i++)
{
printf("\nDrumul min din %d in %d este: ", i + 1, vert + 1);
if (arr1[i] == MAX) printf("\nnu exista");
else
{
for (int k = i, j = 0; j < *virf && P[k] != -1 && k != vert; j++)
{
if (!j) printf(": %d", k + 1);
else
printf("->%d", k + 1);
k = P[k];
}
if (i < *virf - 1) printf("->%d", vert + 1);
else
printf(": %d", vert + 1);
printf(" : Lungimea: %d", arr1[i]);
}
}
for (int i = 0; i < vert; i++)
free(M[i]);

free(P); free(M); free(arr); free(arr1);


}

void stergere_graf(Graph *graph, int *virf)


{
List *current, *temp;
while ((*virf)--)
{
current = graph[*virf].primul;
while (current != graph[*virf].ultimul)
{
temp = current->urmator;
free(current);
current = temp;
}
}
}

int main()
{
int optiune;
int virf;
Graph *graph = NULL;
while(1)
{
system("cls");
printf(" 1. Introducerea grafului \n");
printf(" 2. Drum minim - Ford \n");
printf(" 3. Drum minim - Belman-Kalaba \n");
printf(" 0. Iesire \n");
printf("\n> ");
scanf("%d", &optiune);
switch(optiune){
case 1:
graph = creaza_un_graf(&virf);
getch();
break;
case 2:
ford(graph, &virf);
getch();
break;
case 3:
bellman_kalaba(graph, &virf);
getch();
break;
case 0:
stergere_graf(graph, &virf);
exit(1);
default:
printf("\nAlegeti optiunea corecta!");
getch();
}
}
return 0;
}
Dati nr. de virfuri a grafului: 8
Introduceti lista de adiacenta:
1| 2 3 5 0
2| 3 4 0
3| 5 7 0
4| 6 0
5| 4 8 0
6| 8 0
7| 8 0
8| 0

Introduceti ponderile pentru fiecare arc


arc12| 6
arc13| 10
arc15| 8
arc23| 4
arc24| 4
arc35| 2
arc37| 3
arc46| 4
arc54| 2
arc58| 10
arc68| 4
arc78| 5

Ford
Belman-Kalaba

You might also like