Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Архив1 / docx53 / Отчет(2010)

.docx
Скачиваний:
24
Добавлен:
01.08.2013
Размер:
277.98 Кб
Скачать

Лабораторная работа № 4

Алгоритмы на графах

Выполнил: Студент группы ИВТ-21 Каменский И.А.

Условие задачи:

Минимальное остовное дерево. Алгоритм Прима

Код:

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, Menus, ExtCtrls, ToolWin, ComCtrls, ActnMan, ActnColorMaps,

ImgList, XPMan, StdCtrls, Grids;

type

TForm1 = class(TForm)

Image1: TImage;

ToolBar1: TToolBar;

ToolButton1: TToolButton;

ImageList1: TImageList;

ToolButton2: TToolButton;

StatusBar1: TStatusBar;

ToolButton3: TToolButton;

ToolButton4: TToolButton;

Panel1: TPanel;

StringGrid1: TStringGrid;

ToolButton5: TToolButton;

ToolButton6: TToolButton;

procedure ToolButton1Click(Sender: TObject);

procedure ToolButton2Click(Sender: TObject);

procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure ToolButton3Click(Sender: TObject);

procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure ToolButton4Click(Sender: TObject);

procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;

var CanSelect: Boolean);

procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;

Rect: TRect; State: TGridDrawState);

procedure StringGrid1KeyPress(Sender: TObject; var Key: Char);

procedure StringGrid1SetEditText(Sender: TObject; ACol, ARow: Integer;

const Value: String);

procedure ToolButton5Click(Sender: TObject);

procedure ToolButton6Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

rec = record

posx,posy : Integer;

end;

TVertex = Array of rec;

TMatrix = Array of array of integer;

const Radius = 30;

Diametr = 2*Radius;

var

Form1 : TForm1;

Vertex : TVertex;

Drawing : boolean = False;

FlagP : boolean = False;

FlagP2 : boolean = false;

nomP : integer;

A : TMatrix;

s : string; //Для остова

implementation

uses Math;

{$R *.dfm}

procedure DrawLine(Canvas: TCanvas; X1,Y1,X2,Y2, Text: Integer);

var

Angle: Extended;

b1x,b1y,b2x,b2y,L : integer;

begin

Angle:=ArcTan2(Y1-Y2,X2-X1);

b1x := X1+Round(Radius*Cos(Angle) );

b1y := Y1-Round(Radius*Sin(Angle) );

b2x := X2-Round(Radius*Cos(Angle) );

b2y := Y2+Round(Radius*Sin(Angle) );

L := Round( Sqrt(sqr(x1-x2) + sqr(y1-y2)) );

L := L div 2;

with Canvas do begin

MoveTo(b1x,b1y );

LineTo(b2x,b2y );

Brush.Color := clWhite;

TextOut(X1+ Round(L*cos(Angle) ), y1 - Round(L * Sin(Angle)), IntToStr(Text) );

end;

end;

procedure Prime(b : TMatrix; Var s : string);

Var SM,SP : set of 1..100;

min,i,j,l,t,L2 : integer;

begin

min := maxInt;

L2 := Length(b)-1;

SM := [1..L2];

SP := [];

l := 0;

t := 0;

S := '';

for i := 1 to L2-1 do

for j := i+1 to L2 do

if (a[i,j] < min) and (a[i,j] <> 0) then begin

min := a[i,j];

l := i;

t := j;

end;

SP := [l,t];

SM := SM - [l,t];

s := s+IntToStr(l) +'-'+IntToStr(t)+';';

While SM<>[] do begin

min := maxInt;

l := 0;

t := 0;

for i := 1 to L2 do

if not(i in SP) then

for j := 1 to L2 do

if (j in SP) and (a[i,j] < min) and (a[i,j] <>0) then begin

min := a[i,j];

l := i;

t := j;

end;

SP := SP + [l];

SM := SM - [l];

s := s+IntToStr(l) +'-'+ IntToStr(t)+';';

end;

end;

Procedure ClearHolst(Im : TImage);

begin

With Im.Canvas do begin

pen.Color := clBlack;

pen.Width := 1;

pen.Mode := pmCopy;

Brush.Color := clWhite;

Rectangle(0,0,Im.Width,im.Height);

end;

end;

procedure DrawEllipse(x,y : integer; Im : TImage; Color : TColor);

begin

with Im.Canvas do begin

pen.Color := clBlack;

pen.Width := 1;

if pen.Mode <> pmCopy then pen.Mode := pmCopy;

Brush.Color := Color;

Ellipse(x-Radius,y-Radius,x+Radius,y+Radius);

end;

end;

procedure DrawCarcas(s : string; Im : TImage);

var buf : String;

i,x1,x2 : integer;

begin

ClearHolst(Im);

With Im.Canvas do begin

TextOut(5,5,'Остов');

i := 0;

Repeat

inc(i);

buf := Copy(s,1,Pos(';',s) - 1);

Delete(S,1,Pos(';',S));

x1 := StrToInt( Copy(buf,1,Pos('-',buf)-1 ) ) - 1;

x2 := StrToInt( Copy(buf,Pos('-',buf)+ 1,Length(buf) ) ) - 1;

DrawEllipse(Vertex[x1].posx,Vertex[x1].posy, Im,clYellow);

DrawEllipse(Vertex[x2].posx,Vertex[x2].posy, Im,clYellow);

Im.Canvas.TextOut(Vertex[x1].posx,Vertex[x1].posy, IntToStr(x1 + 1) );

Im.Canvas.TextOut(Vertex[x2].posx,Vertex[x2].posy, IntToStr(x2 + 1) );

DrawLine(Im.Canvas,Vertex[x1].posx,Vertex[x1].posy, Vertex[x2].posx,Vertex[x2].posy , i);

until s = '';

end;

end;

procedure InitVertex(Var V : TVertex; n,MaxX,MaxY : integer);

var i : integer;

begin

SetLength(V,n);

Randomize;

for i := 0 to n - 1 do begin

V[i].posx := Radius + Random(maxX - Diametr);

V[i].posy := Radius + Random(maxY - Diametr);

end;

end;

procedure DrawVertex(V : TVertex;A : TMatrix ;Im : TImage);

var i,L,j : integer;

begin

ClearHolst(Im);

Im.Canvas.TextOut(5,5,'Граф');

L := length(V) - 1;

for i := 0 to L do begin

if V[i].posx = 0 then Continue;

DrawEllipse(V[i].posx,V[i].posy,Im,clSkyBlue);

Im.Canvas.TextOut(V[i].posx,V[i].posy,IntToStr(i+1));

end;

L := Length(A) - 1;

with Im.Canvas do

for i := 1 to L-1 do

for j := i to L do begin

if a[i,j] = 0 then Continue;

DrawLine(Im.Canvas,V[i-1].posx,V[i-1].posy, V[j-1].posx,V[j-1].posy,a[i,j]);

end;

end;

procedure DeleteInVertex(count : integer;var v : TVertex);

begin

V[count].posx := -500;

V[count].posy := -500;

end;

Function FindInVertexReturn(x,y : integer; V : TVertex;Var II : integer): boolean;

var n,i,Rast : integer;

begin

Result := false;

if v = nil then exit;

n := Length(V) - 1;

for i:= 0 to n do begin

Rast := Trunc( Sqrt(sqr(V[i].posx-x)+sqr(V[i].posy-y)) );

if Rast < Radius then begin

result := true;

II := i;

break;

end;

end;

end;

procedure InitStringGrid(Sg : TStringGrid; n : integer);

var i,j : integer;

begin

with SG do begin

ColCount := n + 1;

RowCount := n + 1;

cells[0,0] := 'X';

ColWidths[0] := 30;

for i := 1 to n do begin

cells[i,0] := 'X' + IntToStr(i);

cells[0,i] := 'X' + IntToStr(i);

ColWidths[i] := 30;

end;

For i := 1 to RowCount -1 do

for j := 1 to ColCount -1 do cells[i,j] := '0';

end;

end;

procedure AddToMatrix(Sg: TStringGrid;Var a : TMatrix);

var i,j,k : integer;

begin

k := 0;

with Sg do

for i := 1 to RowCount - 1 do

for j := 1 to ColCount - 1 do begin

if a[i,j] <> 0 then inc(k);

a[i,j] := StrToInt(cells[j,i] );

end;

Form1.StatusBar1.Panels[2].Text := 'Кол-во ребер = '+IntToStr(k div 2);

end;

procedure TForm1.ToolButton1Click(Sender: TObject);

var

value : string;

n : integer;

flag : boolean;

begin

flag := false;

repeat

if not InputQuery('Графы', 'Укажите количество вершин', value) then exit;

if (TryStrToInt(value,n)) and (n > 1) and (n < 100) then flag := true

else ShowMessage('Введите целое число и число больше 1 и меньше 100');

until flag;

StatusBar1.Panels[1].Text := 'Кол-во вершин = '+ IntToStr(n);

StatusBar1.Panels[2].Text := 'Кол-во ребер = 0';

InitVertex(Vertex,n, Image1.Width,Image1.Height);

InitStringGrid(StringGrid1,n);

SetLength(A,n+1,n+1);

DrawVertex(Vertex,A,Image1);

Drawing := true;

ToolButton3.Enabled := true;

ToolButton4.Enabled := true;

ToolButton5.Enabled := true;

end;

procedure TForm1.ToolButton2Click(Sender: TObject);

begin

FlagP := ToolButton2.Down;

StatusBar1.Panels[0].Text := '';

end;

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

if not Drawing then exit;

If not FlagP then exit;

if not FindInVertexReturn(x,y,Vertex,nomP) then exit;

FlagP2 := true;

StatusBar1.Panels[0].Text := 'Вершина '+IntToStr(nomP + 1) + ' выбрана';

end;

procedure TForm1.ToolButton3Click(Sender: TObject);

begin

Drawing := ToolButton3.Down;

ToolButton2.Enabled := Drawing;

ToolButton5.Enabled := not Drawing;

if Drawing then begin

ToolButton4.Down := false;

Panel1.Visible := false;

end;

end;

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

begin

if not Drawing then exit;

if FlagP then begin

DrawVertex(Vertex,A,Image1);

if FlagP2 then begin

DrawEllipse(x,y,Image1,clLime);

DeleteInVertex(nomP,Vertex);

Vertex[nomP].posx := x;

Vertex[nomP].posy := y;

end

else begin

if FindInVertexReturn(x,y,Vertex,nomP) then begin

StatusBar1.Panels[0].Text := 'Выделенная вершина '+IntToStr(nomP + 1);

DrawEllipse(Vertex[nomP].posx,Vertex[nomP].posy,Image1,ClRed);

end

else StatusBar1.Panels[0].Text := '';

end;

end;

end;

procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

if not Drawing then exit;

if FlagP then begin

if not FlagP2 then exit;

FlagP2 := false;

Vertex[nomP].posx := x;

Vertex[nomP].posy := y;

end;

end;

procedure TForm1.ToolButton4Click(Sender: TObject);

begin

Panel1.Visible := ToolButton4.Down;

if ToolButton3.Down then begin

ToolButton3.Down := false;

Drawing := ToolButton3.Down;

end;

if ToolButton2.Down then begin

ToolButton2.Down := false;

FlagP := false;

ToolButton5.Enabled := true;

end;

end;

procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol,

ARow: Integer; var CanSelect: Boolean);

begin

with StringGrid1 do begin

if(ARow = ACol) or (ARow > ACol) then begin

Options := Options-[goEditing];

end

else Options := Options+[goEditing];

end;

end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;

Rect: TRect; State: TGridDrawState);

const

clPaleRed = TColor($CCCCFF);

clPaleGreen = TColor($CCFFCC);

begin

with StringGrid1 do begin

if(ARow = ACol) and (ARow > 0) then begin

Canvas.Brush.color := clPaleRed;

canvas.fillRect(Rect);

canvas.TextOut(Rect.Left+2,Rect.Top+2,Cells[ACol,ARow]);

end;

if (aRow > ACol) and (aCol > 0) then begin

Canvas.Brush.color := clPaleGreen;

canvas.fillRect(Rect);

canvas.TextOut(Rect.Left+2,Rect.Top+2,Cells[ACol,ARow]);

end;

end;

end;

procedure TForm1.StringGrid1KeyPress(Sender: TObject; var Key: Char);

begin

case key of

'0'..'9',#8 : ;

else key := Chr(0);

end;

end;

procedure TForm1.StringGrid1SetEditText(Sender: TObject; ACol,

ARow: Integer; const Value: String);

begin

if Value = '' then exit;

StringGrid1.Cells[ARow,ACol] := StringGrid1.cells[ACol,ARow];

AddToMatrix(StringGrid1,A);

DrawVertex(Vertex,A,Image1);

end;

procedure TForm1.ToolButton5Click(Sender: TObject);

begin

Prime(A,S);

DrawCarcas(s,Image1);

ToolButton6.Enabled := true;

end;

procedure TForm1.ToolButton6Click(Sender: TObject);

begin

If ToolButton6.Down then DrawVertex(Vertex,A,Image1)

else DrawCarcas(S,Image1);

end;

end.

Результат:

Блок схема:

Соседние файлы в папке docx53