Лабораторная работа №6 / MDLab6-MaxFlow
.DOCЦель работы: Изучение алгоритма определения максимального потока для транспортной сети. Разработка программы, реализующий данный алгоритм.
Транспортная сеть
Транспортной сетью называется связный орграф без петель, для которого выполнены следующие условия:
-
существует только одна вершина a, для которой d-(a) – пустое множество (а - исток);
2) существует только одна вершина b, для которой d+(b) – пустое множество (b - сток);
3) каждому ребру графа поставлено в соответствие целое неотрицательное число, называемое пропускной способностью данного ребра.
Потоком в транспортной сети называется целочисленная функция f(u), определенная на любых ребрах ТС
и удовлетворяющая следующим свойствам:
1) f(u)<=c(u), где с(u) – пропускная способность ребра;
2) условие сохранения потока: для каждой внутренней вершины V ТС, не равной а или b, суммарная функция потока по ребрам, входящим в вершину, равна суммарной функции потока по ребрам, исходящим из вершины.
5
1 4
8 3 1 9
1
5 4 Максимальный поток в данной
0 2 5 7 транспортной сети равен 19.
2
7 6 15
3 6
4
Исходный код программы определения максимального потока с использованием алгоритма Форда - Фулкерсона:
#include <stdio.h>
#include <alloc.h>
#include <conio.h>
struct List{
int v;
int w;
int f;
struct List *next;
};
struct Graph{
int p;
int c;
struct List *first;
struct List *last;
}*G;
int N;
int BFS();
void MaxFlow();
void MinCut();
void Menu();
void ListAdj();
void FreeList();
void main()
{
Menu();
}
void MaxFlow()
{
int u,v,addtoflow,maxflow=0;
struct List *c;
while(addtoflow=BFS()){
v=N-1;
u=G[v].p;
while(u!=-1){
c=G[u].first;
while(c->v!=v)
c=c->next;
c->f+=addtoflow;
v=u;
u=G[u].p;
}
}
MinCut();
}
void MinCut()
{
int i,maxflow=0;
struct List *c;
printf("Minumum cut: ");
for(i=0;i<N;i++)
if(!G[i].c){
c=G[i].first;
while(c!=G[i].last){
if(G[c->v].c){
printf("%d-%d(%d) ",i+1,c->v+1,c->f);
maxflow+=c->f;
}
c=c->next;
}
}
printf("\nMaximum flow is %d\n",maxflow);
}
int BFS()
{
int i,mw=0,v,u,qbeg=0,qend,*Q=(int *)malloc(N*sizeof(int ));
struct List *c;
for(i=0;i<N;i++){
G[i].c=1;
G[i].p=-1;
}
Q[qbeg]=0;
qend=1;
while(qbeg!=qend){
u=Q[qbeg++];
c=G[u].first;
while(c!=G[u].last){
if(G[c->v].c && c->w!=c->f){
G[c->v].c=0;
G[c->v].p=u;
Q[qend++]=c->v;
}
c=c->next;
}
}
v=N-1;
u=G[v].p;
while(u!=-1){
c=G[u].first;
while(c->v!=v)
c=c->next;
if(!mw || mw>c->w-c->f)
mw=c->w-c->f;
v=u;
u=G[u].p;
}
return mw;
}
void Menu()
{
int i;
char ch;
clrscr();
printf("1.To enter the graph\n");
printf("2.Maximum flow by Ford-Fulkerson's algorithm\n");
printf("3.Exit\n");
do
ch=getch();
while(ch<'1' || ch>'3');
clrscr();
switch (ch)
{
case '1': ListAdj();break;
case '2': MaxFlow();getch();break;
case '3': FreeList();return;
}
Menu();
}
void ListAdj()
{
int i,v,w;
struct List *c;
if(G)
FreeList();
printf("Enter number of vertexes of graph: ");
scanf("%d",&N);
G=(struct Graph *)malloc(N*sizeof(struct Graph));
printf("\n");
for(i=0;i<N;i++){
printf("%d->",i+1);
G[i].first=(struct List*)malloc(sizeof(struct 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->f=0;
G[i].last->next=(struct List*)malloc(sizeof(struct 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);
}
Вывод: В данной работе был рассмотрен алгоритм Форда – Фулкерсона для нахождения максимального потока в транспортной сети. Этот алгоритм находит широкое применение для решения многих практических задач, позволяющий оптимизировать тот или иной процесс.