DevioLab CRYPTO TRADING AUTOMATION
LIVE
AUTOMATED CRYPTO TRADING • BINANCE
Автоматизуйте свій криптопортфель
Торгові боти DevioLab аналізують крипторинок, автоматично відкривають і закривають позиції та керують вашим портфелем на Binance 24/7.
CRYPTO 80 Bots
BINANCE Spot Trading
TRADING 24 / 7
Спробувати DevioLab
deviolab.com

Лабораторна №3

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
Не вказано
Факультет:
КН
Кафедра:
Кафедра СКС

Інформація про роботу

Рік:
2013
Тип роботи:
Лабораторна робота
Предмет:
Дискретна математика

Частина тексту файла (без зображень, графіків і формул):

Міністерство освіти і науки України Національний університет „Львівська політехніка” Кафедра СКС Звіт з лабораторної роботи № 3 з дисципліни: “Дискретна матетематика” на тему: “ Знаходження максимальної пропускної спроможності графа” Львів 2013 Мета: навчитися створювати програму яка обчислює максимальну прупускну спроможність графа Теоретичні відомості АЛГОРИТМ ФОРДА-ФАЛКЕРСОНА ДЛЯ ЗНАХОДЖЕННЯ ПОТОКУНАЙБІЛЬШОЇ ВЕЛЕЧИНИ Розглянемо алгоритм Форда на прикладі графа зображеного на мал.1 .  Припустимо, у нас витік буде в 1 вузлі, а стік в 4 вузлі. Алгоритм можна розбити на три кроки: 1.Пошук довільного шляху з витоку до стоку. Якщо такого немає, то видаємо значення максимальної пропускної спроможності і алгоритм завершується. 2.Знаходження в обраному шляху ребра з мінімальною пропускною здатністю. Додаємо значення цього ребра до пропускної спроможності, яка на початку виконання алгоритму дорівнює 0. 3.Віднімання з усіх значень ребер шляху, значення мінімального ребра цього шляху. При цьому саме ребро звернутися в 0 і його вже не можна враховувати в подальшому. Далі продовжуємо з кроку 1. На початку у нас пропускна здатність дорівнює 0 (P = 0). Припустимо, ми знайшли шлях з витоку 1 в стік 4 через вершини 2 і 3, тобто весь шлях можна записати як (1-2-3-4). У цьому шляху мінімальне ребро з'єднує вершини 2 і 3, його значення 5, збільшуємо пропускну спроможність на 5 (Р = 5). Віднімаємо 5 з ребер з'єднують вершини 1 і 2, 2 і 3, 3 і 4. З вихідного графа у нас випало ребро з'єднує вершини 2 і 3. Вийшов граф зображений на мал.2.  У цьому графі знову шукаємо довільний шлях з 1 в 4. Знайшли (1-2-5-4), де мінімальне ребро з'єднує 2 і 5, його значення 6. Збільшуємо пропускну здатність на 6 (P = 5 +6 = 11). Віднімаємо 6 з усіх ребер шляху, випадає ребро 2-5 (мал.3).  На наступному кроці знаходимо шлях (1-6-5-4), мінімальне ребро 1-6 дорівнює 7, тоді P = 11 +7 = 18. Віднімаємо з ребер шляху 6, при цьому випадає ребро 1-6 і граф розпадається на дві компоненти мал.4.Ми не знаходимо шляху з витоку в стіл і алгоритм завершено. Отримуємо максимальну пропуснну здатність 18 .   Повний потік . Застосовуючи правила 4, 5 алгоритму Форда-Фалкерсона, отримаємо . Варіант 21 11 18 4 10 7 9 18 19 7 6 5 11 7 9 15 17 19 Код програми: unit Unit8; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids,Math; type TForm8 = class(TForm) Label1: TLabel; Edit1: TEdit; Label2: TLabel; Edit2: TEdit; Button1: TButton; StringGrid1: TStringGrid; Label3: TLabel; Edit3: TEdit; Label4: TLabel; Edit4: TEdit; Label5: TLabel; Memo1: TMemo; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Edit2Exit(Sender: TObject); procedure DrawGraph; procedure DrawLine(a1,a2,c: integer); procedure FormPaint(Sender: TObject); procedure StringGrid1SetEditText(Sender: TObject; ACol, ARow: Integer; const Value: String); private { Private declarations } public { Public declarations } end; TMyPoint=record x:integer; y:integer; name:string end; const MaxV=1000; MaxE=30000; free_ = 0; bisy_ = 1; Great=MaxLongint; var Form8: TForm8; MyPoint:array[1..10] of TMyPoint; koef:integer; implementation {$R *.dfm} procedure DrawArrowHead(Canvas: TCanvas; X,Y: Integer; Angle,LW: Extended); var A1,A2: Extended; Arrow: array[0..3] of TPoint; OldWidth: Integer; const Beta=0.322; LineLen=4.74; CentLen=3; begin Angle:=Pi+Angle; Arrow[0]:=Point(X,Y); A1:=Angle-Beta; A2:=Angle+Beta; Arrow[1]:=Point(X+Round(LineLen*LW*Cos(A1)),Y-Round(LineLen*LW*Sin(A1))); Arrow[2]:=Point(X+Round(CentLen*LW*Cos(Angle)),Y-Round(CentLen*LW*Sin(Angle))); Arrow[3]:=Point(X+Round(LineLen*LW*Cos(A2)),Y-Round(LineLen*LW*Sin(A2))); OldWidth:=Canvas.Pen.Width; Canvas.Pen.Width:=1; Canvas.Polygon(Arrow); Canvas.Pen.Width:=OldWidth end; procedure DrawArrow(Canvas: TCanvas; X1,Y1,X2,Y2: Integer; LW: Extended); var Angle: Extended; begin Angle:=ArcTan2(Y1-Y2,X2-X1); Canvas.MoveTo(X1,Y1); Canvas.LineTo(X2-Round(2*LW*Cos(Angle)),Y2+Round(2*LW*Sin(Angle))); DrawArrowHead(Canvas,X2,Y2,Angle,LW); end; procedure TForm8.DrawGraph; var x,kx,ky,a,b:integer; begin Form8.Refresh; for x:=1 to 10 do begin kx:=3*MyPoint[x].x+koef; ky:=3*MyPoint[x].y+koef-90; Form8.Canvas.Ellipse(kx,ky,kx+10,ky+10); Form8.Canvas.TextOut(kx,ky-15,MyPoint[x].name); end; for x := 1 to Pred(StringGrid1.RowCount) do begin if (StringGrid1.Cells[1,x]='') or (StringGrid1.Cells[2,x]='') or (StringGrid1.Cells[3,x]='') then continue; a:= StrToInt(StringGrid1.Cells[1,x]); b:= StrToInt(StringGrid1.Cells[2,x]); if (a=b) then continue; DrawLine (a,b,1); end; end; procedure TForm8.DrawLine(a1,a2,c: integer); var x1,y1,x2,y2:integer; begin if c=1 then Form8.Canvas.Pen.Color:=clBlack; if c=2 then Form8.Canvas.Pen.Color:=clRed; x1:=3*MyPoint[a1].x+koef+5; y1:=3*MyPoint[a1].y+koef+5-90; //Form8.Canvas.MoveTo(x1,y1); x2:=3*MyPoint[a2].x+koef+5; y2:=3*MyPoint[a2].y+koef+5-90; //Form8.Canvas.LineTo(x2,y2); DrawArrow(Form8.Canvas,x1,y1,x2,y2,2); Form8.Canvas.Pen.Color:=clBlack; end; procedure TForm8.FormCreate(Sender: TObject); var i: integer; begin Randomize; StringGrid1.Cells[0, 0] := 'Ðåáðî'; StringGrid1.Cells[1, 0] := 'Âèò³ê'; StringGrid1.Cells[2, 0] := 'Ñò³ê'; StringGrid1.Cells[3, 0] := 'Âàãà'; for i := 1 to Pred(StringGrid1.RowCount) do begin StringGrid1.Cells[0, i] := IntToStr(i); //StringGrid1.Cells[1, i] := IntToStr(Random(10)+1); // StringGrid1.Cells[2, i] := IntToStr(Random(10)+1); // StringGrid1.Cells[3, i] := IntToStr(Random(30)+1); end; StringGrid1.Cells[1, 1] := IntToStr(1); StringGrid1.Cells[2, 1] := IntToStr(2); StringGrid1.Cells[3, 1] := IntToStr(11); StringGrid1.Cells[1, 2] := IntToStr(2); StringGrid1.Cells[2, 2] := IntToStr(3); StringGrid1.Cells[3, 2] := IntToStr(17); StringGrid1.Cells[1, 3] := IntToStr(3); StringGrid1.Cells[2, 3] := IntToStr(4); StringGrid1.Cells[3, 3] := IntToStr(18); StringGrid1.Cells[1, 4] := IntToStr(2); StringGrid1.Cells[2, 4] := IntToStr(6); StringGrid1.Cells[3, 4] := IntToStr(4); StringGrid1.Cells[1, 5] := IntToStr(1); StringGrid1.Cells[2, 5] := IntToStr(6); StringGrid1.Cells[3, 5] := IntToStr(10); StringGrid1.Cells[1, 6] := IntToStr(1); StringGrid1.Cells[2, 6] := IntToStr(7); StringGrid1.Cells[3, 6] := IntToStr(7); StringGrid1.Cells[1, 7] := IntToStr(2); StringGrid1.Cells[2, 7] := IntToStr(7); StringGrid1.Cells[3, 7] := IntToStr(9); StringGrid1.Cells[1, 8] := IntToStr(6); StringGrid1.Cells[2, 8] := IntToStr(8); StringGrid1.Cells[3, 8] := IntToStr(8); StringGrid1.Cells[1, 9] := IntToStr(7); StringGrid1.Cells[2, 9] := IntToStr(6); StringGrid1.Cells[3, 9] := IntToStr(19); StringGrid1.Cells[1, 10] := IntToStr(8); StringGrid1.Cells[2, 10] := IntToStr(2); StringGrid1.Cells[3, 10] := IntToStr(7); StringGrid1.Cells[1, 11] := IntToStr(4); StringGrid1.Cells[2, 11] := IntToStr(8); StringGrid1.Cells[3, 11] := IntToStr(6); StringGrid1.Cells[1, 12] := IntToStr(4); StringGrid1.Cells[2, 12] := IntToStr(6); StringGrid1.Cells[3, 12] := IntToStr(5); StringGrid1.Cells[1, 13] := IntToStr(8); StringGrid1.Cells[2, 13] := IntToStr(5); StringGrid1.Cells[3, 13] := IntToStr(11); StringGrid1.Cells[1, 14] := IntToStr(5); StringGrid1.Cells[2, 14] := IntToStr(9); StringGrid1.Cells[3, 14] := IntToStr(7); StringGrid1.Cells[1, 15] := IntToStr(5); StringGrid1.Cells[2, 15] := IntToStr(10); StringGrid1.Cells[3, 15] := IntToStr(9); StringGrid1.Cells[1, 16] := IntToStr(9); StringGrid1.Cells[2, 16] := IntToStr(10); StringGrid1.Cells[3, 16] := IntToStr(16); StringGrid1.Cells[1, 17] := IntToStr(5); StringGrid1.Cells[2, 17] := IntToStr(8); StringGrid1.Cells[3, 17] := IntToStr(17); StringGrid1.Cells[1, 18] := IntToStr(10); StringGrid1.Cells[2, 18] := IntToStr(3); StringGrid1.Cells[3, 18] := IntToStr(19); MyPoint[1].x:=10; MyPoint[1].y:=70; MyPoint[1].name:='1'; MyPoint[2].x:=30; MyPoint[2].y:=100; MyPoint[2].name:='2'; MyPoint[3].x:=50; MyPoint[3].y:=50; MyPoint[3].name:='3'; MyPoint[4].x:=70; MyPoint[4].y:=120; MyPoint[4].name:='4'; MyPoint[5].x:=90; MyPoint[5].y:=30; MyPoint[5].name:='5'; MyPoint[6].x:=110; MyPoint[6].y:=90; MyPoint[6].name:='6'; MyPoint[7].x:=130; MyPoint[7].y:=60; MyPoint[7].name:='7'; MyPoint[8].x:=150; MyPoint[8].y:=110; MyPoint[8].name:='8'; MyPoint[9].x:=170; MyPoint[9].y:=40; MyPoint[9].name:='9'; //MyPoint[10].x:=190; //MyPoint[10].y:=100; //MyPoint[10].name:='10'; MyPoint[10].x:=210; MyPoint[10].y:=70; MyPoint[10].name:='10'; DrawGraph; koef:=260; end; procedure TForm8.Button1Click(Sender: TObject); var i: integer; n, m, last, s, t, x, y, z: longint; v,l: array[1..MaxV] of longint; adj, next, c, f: array[1..MaxE] of longint; found: boolean; MaxPOTOK: longint; prev: array [1..MaxV] of longint; Marked: array [1..MaxV] of byte; que,poz: array [1..MaxE] of longint; qb,qe: longint; procedure Init(n,m: longint); var i: longint; begin for i:=1 to n do begin v[i] := free_; l[i] := free_; end; for i:=1 to 2*m do begin adj[i] := free_; c[i] := free_; next[i] := free_; f[i] := free_; end; last := 0; end; procedure AddEdge(x,y,z: longint); begin inc(last); adj[last] := y; c[last] := z; if v[x] = free_ then begin v[x] := last; end else begin next[l[x]] := last; end; l[x] := last; end; procedure ErrorMes; begin ShowMessage('Íåâ³ðí³ ââåäåí³ âõ³äí³ äàí³!'); exit end; procedure Put(x: longint); begin inc(qe); que[qe]:=x; Marked[x]:=bisy_; prev[x]:=que[qb]; end; procedure InitQue(x: longint); var i: longint; begin for i:=1 to 2*m do begin Marked[i]:=free_; poz[i]:=0; end; qb:=1; qe:=1; que[qe] := x; Marked[x] := bisy_; end; procedure FindWay; var x,Min,cf: longint; begin InitQue(s); while (qb<=qe)and(Marked[t]<>bisy_) do begin x:=v[que[qb]]; while adj[x]<>free_ do begin if (Marked[adj[x]]<>bisy_)and(c[x]-f[x]>0) then begin Put(adj[x]); poz[adj[x]]:=x; end; x:=next[x]; end; inc(qb); end; if Marked[t]=free_ Then begin Found:=False; Exit; end; Min:=Great; x:=t; while prev[x]<>free_ do begin cf:=c[poz[x]]-f[poz[x]]{!}; Memo1.Lines.Add(InttoStr(cf) + ' - '+ inttostr(x));//+' - '+ inttostr(f[poz[x]])) ; if cf<Min Then Min:=cf; x:=prev[x]; //Memo1.Lines.Add('--'+InttoStr(poz[x])); end; Memo1.Lines.Add(' -> '+inttostr(x)); Memo1.Lines.Add(' '); x:=t; while prev[x]<>free_ do begin f[poz[x]]:=f[poz[x]]+Min; if c[poz[x]]<>free_ then f[poz[x]+1]:=-f[poz[x]] else f[poz[x]-1]:=-f[poz[x]]; x:=prev[x]; //Memo1.Lines.Add(InttoStr(x)); end; end; begin //Ââ³ä äàíèõ //ê³ëüê³ñòü âåðøèí n := StrToIntDef(Edit1.Text, 0); m := StrToIntDef(Edit2.Text, 0); if (n = 0) or (m = 0) then ErrorMes; Init(n,m); //Ìàòðèöÿ for i := 1 to m do begin x := StrToIntDef(StringGrid1.Cells[1, i], 0); y := StrToIntDef(StringGrid1.Cells[2, i], 0); z := StrToIntDef(StringGrid1.Cells[3, i], 0); if (x <= 0) or (y <= 0) or (z <= 0) then ErrorMes; AddEdge(x,y,z); AddEdge(y,x,0); end; //âõ³ä ³ âèõ³ä s := StrToIntDef(Edit3.Text, 0); t := StrToIntDef(Edit4.Text, 0); if (s > n) or (s <= 0) or (t > n) or (t <= 0) then ErrorMes; //Îá÷èñëåííÿ ïî àëãîðèòìó Ôîðäà-Ôàëêåðñîíà found:=true; while found do FindWay; MaxPOTOK := 0; x := v[s]; while x <> free_ do begin if f[x] > 0 then MaxPOTOK := MaxPotok + f[x]; x:=next[x]; end; Label5.Caption:='Ðåçóëüòàò: '+ IntToStr(MaxPotok); end; procedure TForm8.Edit2Exit(Sender: TObject); var i: integer; m: longint; begin m := StrToIntDef(Edit2.Text, 0); if m = 0 then begin ShowMessage('Íåâ³ðí³ ââåäåí³ âõ³äí³ äàí³!'); exit end; StringGrid1.RowCount := m + 1; for I := 1 to Pred(StringGrid1.RowCount) do StringGrid1.Cells[0, i] := IntToStr(i); end; procedure TForm8.FormPaint(Sender: TObject); var x,kx,ky:integer; begin for x:=1 to 10 do begin kx:=3*MyPoint[x].x+koef; ky:=3*MyPoint[x].y+koef-90; Form8.Canvas.Ellipse(kx,ky,kx+10,ky+10); Form8.Canvas.TextOut(kx,ky-15,MyPoint[x].name); end; end; procedure TForm8.StringGrid1SetEditText(Sender: TObject; ACol, ARow: Integer; const Value: String); begin DrawGraph; end; end. Результат:  Висновок: на даній лабораторній роботі я ознайомився з алгоритмом Форда-Фалкерсона, та навчися розв*язувати задачі на знаходження пропускної спроможності графа.
Антиботан аватар за замовчуванням

15.10.2013 11:49

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!