Департамент ISA
Отчет
по лабораторной работе № 3
по дискретной математике
Выполнил:
Проверила:
Кишинев 2017
Цель работы: Изучение алгоритмов поиска минимального пути в
графе. Разработка программы, реализующей данные алгоритмы
поиска минимального пути в взвешенном графе.
Алгоритм Форда
Код программы:
#define MAX 30000
using namespace std;
struct List{
int v;
int w;
struct List *next;
};
struct Graph{
int h;
int p;
struct List *first;
struct List *last;
}*G;
int maxFlag;
int N;
int V;
void Ford();
void BelmanKalab();
void PathFord(int );
void Menu();
void ListAdj();
void FreeList();
int main()
{
Menu();
return 0;
}
void BelmanKalab()
{
int i,j,k;
struct List *c;
int **M=(int **)malloc(N*sizeof(int *));
int *VK=(int *)malloc(N*sizeof(int ));
int *VK_1=(int *)malloc(N*sizeof(int ));
int *t,f=1;
int *P=(int *)malloc(N*sizeof(int ));
for(i=0;i<N;i++)
M[i]=(int *)malloc(N*sizeof(int));
for(i=0;i<N;i++)
for(j=0;j<N;j++)
M[i][j]=(i==j)?0:MAX;
for(i=0;i<N;i++){
c=G[i].first;
while(c!=G[i].last){
if(maxFlag){
M[i][c->v]= -(c->w);
} else{
M[i][c->v]=c->w;
}
c=c->next;
}
}
printf("Введите конечную вершину: ");
scanf("%d",&V);
V--;
for(i=0;i<N;i++){
VK_1[i]=M[i][V];
P[i]=-1;
}
while(f){
for(i=0;i<N;i++)
VK[i]=MAX;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
if(i!=j && VK[i]>VK_1[j]+M[i][j]){
VK[i]=VK_1[j]+M[i][j];
P[i]=j;
}
VK[V]=0;
for(i=0;i<N && VK[i]==VK_1[i];i++);
f=(i==N)?0:1;
t=VK_1;
VK_1=VK;
VK=t;
}
for(i=0;i<N;i++){
printf("\nПуть от %d до %d равен ", i+1, V+1);
if(VK_1[i] > 25000)
printf("Не существует.");
else {
for(k=i,j=0;j<N && P[k]!=-1 && k!=V;j++){
printf("->%d",k+1);
k=P[k];
}
printf("->%d",V+1);
if(maxFlag){
printf(" с длиной равной %d.", -VK_1[i]);
} else {
printf(" с длиной равной %d.", VK_1[i]);
}
}
}
for(i=0;i<N;i++)
free(M[i]);
free(P);
free(M);
printf("\nV : ");
free(VK);
if(maxFlag) {
for(i = 0; i < N; i++){
if(VK_1[i] > 25000) {
printf(" -inf ");
} else {
printf(" %d ", -VK_1[i]);
}
}
} else {
for(i = 0; i < N; i++){
if(VK_1[i] == MAX) {
printf(" inf ");
} else {
printf(" %d ", VK_1[i]);
}
}
}
free(VK_1);
}
void Ford()
{
int *VK = (int *)malloc(N * sizeof(int));
int i,f=1;
for(i = 0; i < N; i++)
VK[i] = 50000;
struct List *c;
if(G==NULL)
return;
for(i=0;i<N;i++){
G[i].p=-1;
G[i].h=MAX;
}
printf("Введите стартовую вершину: ");
scanf("%d",&V);
G[--V].h=0;
while(f){
f=0;
for(i=0;i<N;i++){
c=G[i].first;
if(maxFlag){
while(c!=G[i].last){
if(G[c->v].h>G[i].h-c->w){
G[c->v].h=G[i].h-c->w;
G[c->v].p=i;
f=1;
}
c=c->next;
}
} else{
while(c!=G[i].last){
if(G[c->v].h>G[i].h+c->w){
G[c->v].h=G[i].h+c->w;
G[c->v].p=i;
f=1;
}
c=c->next;
}
}
}
}
for(i=0;i<N;i++){
printf("\nПуть от %d до %d равен ",V+1,i+1);
if(G[i].h==MAX)
printf("Не существует.");
else{
PathFord(i);
if(maxFlag){
printf(" с длиной равной %d.", -G[i].h);
} else {
printf(" с длиной равной %d.", G[i].h);
}
VK[i] = G[i].h;
}
}
printf("\nV : ");
if(maxFlag){
for(i = 0; i < N; i++){
if(VK[i] > 30000 || VK[i] < -30000)
printf(" -inf ");
else
printf(" %d ", -VK[i]);
}
} else {
for(i = 0; i < N; i++){
if(VK[i] > 30000 || VK[i] < -30000)
printf(" inf ");
else
printf(" %d ", VK[i]);
}
}
}
void PathFord(int v)
{
if(v!=V)
PathFord(G[v].p);
printf("->%d",v+1);
}
void Menu()
{
int i;
char ch;
printf("\n--------------------\n");
printf("1.Ввести граф\n");
printf("2.Минимальный путь по алгоритму Форда\n");
printf("3.Максимальный путь по алгоритму Форда\n");
printf("4.Минимальный путь по алгоритму Белмана-Калаба\n");
printf("5.Максимальный путь по алгоритму Белмана-Калаба\n");
printf("0.Выход\n");
do
scanf("%c", &ch);
while(ch<'0' || ch>'7');
printf("\n--------------------\n");
switch (ch)
{
case '1': ListAdj();break;
case '2': maxFlag = 0; Ford();scanf("%c", &ch);break;
case '3': maxFlag = 1; Ford();scanf("%c", &ch);break;
case '4': maxFlag = 0;BelmanKalab();scanf("%c", &ch);break;
case '5': maxFlag = 1;BelmanKalab();scanf("%c", &ch);break;
case '0': FreeList();return;
}
Menu();
}
void ListAdj()
{
int i,v,w;
struct List *c;
if(G)
FreeList();
printf("Введите колличество вершин: ");
scanf("%d",&N);
G=(Graph *)malloc(N*sizeof(Graph));
printf("\n");
for(i=0;i<N;i++){
printf("%d->",i+1);
G[i].first=(List *)malloc(sizeof(List));
G[i].last=G[i].first;
G[i].last->next=NULL;
G[i].last->v=-1;
scanf("%d",&v);
while(v){
scanf("%d",&w);
G[i].last->v=v-1;
G[i].last->w=w;
G[i].last->next=(List *)malloc(sizeof(List));
G[i].last=G[i].last->next;
G[i].last->next=NULL;
G[i].last->v=-1;
scanf("%d",&v);
}
}
}
void FreeList()
{
struct List *c,*t;
while(N--){
c=G[N].first;
while(c!=G[N].last){
t=c->next;
free(c);
c=t;
}
}
free(G);
}
1->2 3
9 5
3 11
3 0
4 4->3
8 3
0 5
2->5 18
14 0
0 5->0
3->2
--------------------
1.Ввести граф
2.Минимальный путь по алгоритму Форда
3.Максимальный путь по алгоритму Форда
4.Минимальный путь по алгоритму Белмана-Калаба
5.Максимальный путь по алгоритму Белмана-Калаба
0.Выход
2
--------------------
Введите стартовую вершину: 1
--------------------
Введите конечную вершину: 5