Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- unit GraphUnit;
- interface
- uses Vcl.GRids, System.SysUtils, System.Generics.Collections;
- type
- TMatrix = array of array of integer;
- TVertex = record
- number, dist: Integer;
- end;
- TVertexArray = array of TVertex;
- TIncidentList = TList<TVertex>;
- TListArray = array of TIncidentList;
- TVertexPointer = ^TVertex;
- function IsValidStr(MaxVertexNumber: integer; const Buffer: string; CurrentVertex: integer): boolean;
- procedure ConvertGraphInString(var GraphText: string; var AdjacencyMatrix: TMatrix; var DistMatrix:
- TMatrix; var PrecMatrix: TMatrix; VertexNumber: integer);
- procedure SaveGraph(const GraphText: String);
- procedure receiveListArray(var ListArray: TListArray; IncidentListStringGrid: TStringGrid);
- procedure receiveArrayOfVertices(var VertexArray: TVertexArray; const Buffer: string);
- procedure receiveMatrices(var AdjacencyMatrix: TMatrix; var DistMatrix:
- TMatrix; var PrecMatrix: TMatrix);
- procedure receiveAdjacencyMatrix(var ListArray: TListArray; var AdjacencyMatrix: TMatrix);
- procedure receivePrecMatrix(Size: integer; var PrecMatrix: TMatrix);
- procedure receiveDistMatrix(Size: integer; var DistMatrix: TMatrix);
- var
- ListArray: TListArray;
- const
- INT_MAX = 100;
- GRAPH_FILE = 'C:\Users\user\Desktop\71del\7.1\GraphsFiles\text_graph.gv';
- GRAPH_PICTURE_FILE = 'C:\Users\user\Desktop\71del\7.1\GraphsFiles\picture.png';
- CREATE_GRAPH_PICTURE_COMMAND = '/C "C:\graphviz\bin\dot.exe" -Tpng C:\Users\user\Desktop\71del\7.1\GraphsFiles\text_graph.gv -o C:\Users\user\Desktop\71del\7.1\GraphsFiles\picture.png';
- implementation
- Var
- Time: Integer;
- procedure AddtoList(var ListArray: TListArray; Vertex: TVertex; Index: Integer);
- begin
- ListArray[Index].Add(Vertex);
- end;
- function IsValidStr(MaxVertexNumber: integer; const Buffer: string; CurrentVertex: integer): Boolean;
- Const
- MIN_V = 1;
- VALID_CHARS = ['0'..'9', ' ', '(', ')'];
- DIGITS = ['0'..'9'];
- function IsNumberCorrect(StartVertex: integer; MaxVertexNumber: integer; CurrentVertex: integer): Boolean;
- const
- MIN_VERTEX_NUMBER = 1;
- begin
- Result := (CurrentVertex <= MaxVertexNumber) and (CurrentVertex >= MIN_VERTEX_NUMBER)
- and (CurrentVertex <> StartVertex);
- end;
- var
- i, j, VertexNumber, Dist: Integer;
- IsCorrectString: Boolean;
- VertexNumberString, DistString: string;
- begin
- IsCorrectString := True;
- i := 1;
- while (i <= Length(Buffer)) and IsCorrectString do
- begin
- if not (Buffer[i] in VALID_CHARS) then
- IsCorrectString := false
- else
- begin
- if Buffer[i] <> ' ' then
- begin
- j := i;
- while (j <= Length(Buffer)) and IsCorrectString and (Buffer[j] <> '(') do
- if not (Buffer[j] in DIGITS) then
- IsCorrectString := false
- else
- begin
- VertexNumberString := VertexNumberString + Buffer[j];
- inc(j);
- end;
- inc(j);
- while (j <= Length(Buffer)) and IsCorrectString and (Buffer[j] <> ')') do
- if not (Buffer[j] in DIGITS) then
- IsCorrectString := false
- else
- begin
- DistString := DistString + Buffer[j];
- inc(j);
- end;
- if DistString = '' then
- IsCorrectString := false
- else
- begin
- try
- VertexNumber := strToInt(VertexNumberString);
- dist := strToInt(DistString);
- except
- IsCorrectString := false;
- end;
- if IsCorrectString then
- IsCorrectString := IsNumberCorrect(CurrentVertex,
- MaxVertexNumber, VertexNumber);
- VertexNumberString := '';
- DistString := '';
- i := j;
- inc(i);
- end;
- end;
- end;
- inc(i);
- end;
- Result := IsCorrectString;
- end;
- procedure receiveArrayOfVertices(var VertexArray: TVertexArray; const Buffer: string);
- var
- i, j, t, VertexNumber, Dist: integer;
- VertexNumberString, DistString: string;
- CurrentVertex: TVertex;
- begin
- i := 1;
- t := 0;
- while (i <= Length(Buffer)) do
- begin
- if Buffer[i] <> ' ' then
- begin
- j := i;
- while (j <= Length(Buffer)) and (Buffer[j] <> '(') do
- begin
- VertexNumberString := VertexNumberString + Buffer[j];
- inc(j);
- end;
- inc(j);
- while (j <= Length(Buffer)) and (Buffer[j] <> ')') do
- begin
- DistString := DistString + Buffer[j];
- inc(j);
- end;
- if VertexNumberString <> '' then
- begin
- CurrentVertex.number := strToInt(VertexNumberString);
- CurrentVertex.dist := strToInt(DistString);
- setlength(VertexArray, length(VertexArray) + 1);
- VertexArray[t] := CurrentVertex;
- inc(t);
- end;
- VertexNumberString := '';
- DistString := '';
- i := j;
- end;
- inc(i);
- end;
- end;
- procedure receiveListArray(var ListArray: TListArray; IncidentListStringGrid: TStringGrid);
- var
- i, j: integer;
- VertexArray: TVertexArray;
- Buffer: string;
- CurrentList: TIncidentList;
- begin
- setlength(ListArray, (IncidentListStringGrid.RowCount - 1));
- for i := 1 to (IncidentListStringGrid.RowCount - 1) do
- begin
- Buffer := IncidentListStringGrid.Cells[1, i];
- receiveArrayOfVertices(VertexArray, Buffer);
- ListArray[i - 1] := TIncidentList.Create;
- for j := 0 to high(VertexArray) do
- begin
- AddtoList(ListArray, VertexArray[j] , i - 1);
- end;
- setlength(VertexArray, 0);
- end;
- end;
- procedure receiveAdjacencyMatrix(var ListArray: TListArray; var AdjacencyMatrix: TMatrix);
- var
- i, j: integer;
- begin
- setlength(AdjacencyMatrix, length(ListArray), length(ListArray));
- for i := 0 to high(ListArray) do
- for j := 0 to (ListArray[i].Count - 1) do
- AdjacencyMatrix[i][ListArray[i][j].number - 1] := ListArray[i][j].dist;
- end;
- procedure receiveDistMatrix(Size: integer; var DistMatrix: TMatrix);
- var
- i, j: integer;
- begin
- setlength(DistMatrix, Size, Size);
- for i := 0 to (Size - 1) do
- for j := 0 to (Size - 1) do
- DistMatrix[i][j] := INT_MAX;
- end;
- procedure receivePrecMatrix(Size: integer; var PrecMatrix: TMatrix);
- var
- i, j: integer;
- begin
- setlength(PrecMatrix, Size, Size);
- for i := 0 to (Size - 1) do
- for j := 0 to (Size - 1) do
- PrecMatrix[i][j] := INT_MAX;
- end;
- procedure receiveMatrices(var AdjacencyMatrix: TMatrix; var DistMatrix:
- TMatrix; var PrecMatrix: TMatrix);
- var
- i, j, t, NewDist: integer;
- begin
- for i := 0 to high(AdjacencyMatrix) do
- begin
- DistMatrix[i][i] := 0;
- for j := 0 to high(AdjacencyMatrix) do
- if (AdjacencyMatrix[i][j] <> 0) then
- begin
- DistMatrix[i][j] := AdjacencyMatrix[i][j];
- PrecMatrix[i][j] := i;
- end;
- end;
- for t := 0 to high(AdjacencyMatrix) do
- begin
- for i := 0 to high(AdjacencyMatrix) do
- begin
- for j := 0 to high(AdjacencyMatrix) do
- begin
- if ((DistMatrix[i][t] < INT_MAX) and (DistMatrix[t][j] < INT_MAX)) then
- begin
- NewDist := DistMatrix[i][t] + DistMatrix[t][j];
- if (NewDist < DistMatrix[i][j]) then
- begin
- DistMatrix[i][j] := NewDist;
- PrecMatrix[i][j] := PrecMatrix[t][j];
- end;
- end;
- end;
- end;
- end;
- end;
- procedure ConvertGraphInString(var GraphText: string; var AdjacencyMatrix: TMatrix; var DistMatrix:
- TMatrix; var PrecMatrix: TMatrix; VertexNumber: integer);
- var
- i, j: integer;
- begin
- GraphText := 'digraph G {' + ' graph [dpi = 100]; node [shape=circle]' +
- ' {node [style=filled]' + intToStr(VertexNumber + 1) + '}';
- for i := 0 to high(AdjacencyMatrix) do
- for j := 0 to high(AdjacencyMatrix) do
- if (AdjacencyMatrix[i][j] <> 0) then
- begin
- GraphText := GraphText + ' ' + intToStr(i + 1) + ' -> ' +
- intToStr(j + 1) + ' [label="' + intToStr(AdjacencyMatrix[i][j]) + '"';
- if (i = PrecMatrix[VertexNumber][j]) then
- GraphText := GraphText + ',color=red';
- GraphText := GraphText + '];';
- end;
- GraphText := GraphText + '}';
- end;
- procedure SaveGraph(const GraphText: String);
- var
- GraphFile: TextFile;
- begin
- AssignFile(GraphFile, GRAPH_FILE);
- Rewrite(GraphFile);
- Write(GraphFile, GraphText);
- CloseFile(GraphFile);
- end;
- end.
- unit GraphVisionUnit;
- interface
- uses
- Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
- Vcl.Controls, Vcl.Forms, Vcl.Dialogs, SimpleFormUnit, Vcl.Menus, Vcl.ExtCtrls, GraphUnit, Vcl.Imaging.PNGImage;
- type
- TGraphForm = class(TSimpleForm)
- GraphPicture: TImage;
- procedure FormShow(Sender: TObject);
- procedure SetInstructions(); override;
- end;
- var
- GraphForm: TGraphForm;
- implementation
- {$R *.dfm}
- procedure TGraphForm.SetInstructions;
- Const
- NEW_LINE = #13#10;
- Begin
- Instructions := 'This is the graph image.'+NEW_LINE
- +'Red lines show the shortest path between current vertex and other.'
- End;
- procedure TGraphForm.FormShow(Sender: TObject);
- begin
- inherited;
- GraphPicture.Picture.LoadFromFile(GRAPH_PICTURE_FILE);
- Self.ClientHeight := GraphPicture.Picture.Height;
- Self.ClientWidth := GraphPicture.Picture.Width;
- end;
- end.
- unit InputUnit;
- interface
- uses
- Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
- Vcl.Controls, Vcl.Forms, Vcl.Dialogs, SimpleFormUnit, Vcl.Menus, Vcl.Grids,
- Vcl.StdCtrls, Vcl.Samples.Spin, Vcl.Buttons, GraphUnit, GraphVisionUnit, System.UITypes, ShellApi;
- type
- TInputForm = class(TSimpleForm)
- ShowButton: TBitBtn;
- VertexNumberSpinEdit: TSpinEdit;
- IncidentListStringGrid: TStringGrid;
- OpenDialog: TOpenDialog;
- SaveDialog: TSaveDialog;
- FileMenu: TMenuItem;
- SaveFile: TMenuItem;
- OpenFile: TMenuItem;
- NumberLabel: TLabel;
- VertexLabel: TLabel;
- VertexSpinEdit: TSpinEdit;
- procedure SaveFileClick(Sender: TObject);
- procedure OpenFileClick(Sender: TObject);
- procedure ShowButtonClick(Sender: TObject);
- procedure VertexNumberSpinEditChange(Sender: TObject);
- procedure FormCreate(Sender: TObject);
- procedure CreateGraphPicture();
- procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
- procedure SetInstructions(); override;
- procedure saveInFile(const Name: string; IncidentListStringGrid: TStringGrid);
- function isFileCorrect(const Name: string): boolean;
- end;
- var
- InputForm: TInputForm;
- IsProcessed: Boolean = False;
- implementation
- {$R *.dfm}
- function TrySetOutputFile(const Name: String): Boolean;
- var
- OutputFile: TextFile;
- begin
- Result := True;
- AssignFile(OutputFile, Name);
- try
- Rewrite(OutputFile);
- except
- Result := False;
- end;
- close(OutputFile);
- end;
- function TrySetInputFile(const Name: String): Boolean;
- var
- InputFile: TextFile;
- begin
- Result := True;
- AssignFile(InputFile, Name);
- Try
- Reset(InputFile);
- Except
- Result := False;
- End;
- closeFile(InputFile);
- end;
- function isDataCorrect(var Grid: TStringGrid): boolean;
- var
- i, j: integer;
- begin
- for i := 1 to (Grid.RowCount - 1) do
- begin
- if not IsValidStr((Grid.RowCount - 1), Grid.Cells[1, i], i) then
- begin
- MessageDlg('Wrong input.', mtError, [mbOk], 0);
- Grid.Cells[1, i] := '';
- Result := false;
- end;
- end;
- end;
- procedure OpenFromFile(const Name: string; var Grid: TStringGrid; var VertexNumberEdit: TSpinEdit);
- const
- FIRST_COL = 0;
- SECOND_COL = 1;
- var
- i, Width, CurrentVertex: Integer;
- Buffer: String;
- InputFile: TextFile;
- begin
- AssignFile(InputFile, Name);
- Reset(InputFile);
- Readln(InputFile, Width);
- VertexNumberEdit.Text := IntToStr(Width);
- i := 1;
- while not EOF(InputFile) do
- begin
- Read(InputFile, CurrentVertex);
- Readln(InputFile, Buffer);
- Grid.Cells[FIRST_COL, i] := intToStr(i);
- Grid.Cells[SECOND_COL, i] := Buffer;
- inc(i);
- end;
- closeFile(InputFile);
- end;
- procedure SetGridSize(const Width, Height: Integer; var Grid: TStringGrid);
- Var
- i: Integer;
- begin
- Grid.ColCount := Width + 1;
- Grid.RowCount := Height + 1;
- for i := 1 to Height do
- Begin
- Grid.Cells[i, 0] := IntToStr(I);
- Grid.Cells[0, i] := IntToStr(I);
- End;
- Grid.Width := (Width + 1) * Grid.DefaultColWidth + 15;
- Grid.Height := (Height + 1) * Grid.DefaultRowHeight + 15;
- end;
- procedure TInputForm.SetInstructions;
- Const
- NEW_LINE = #13#10;
- Begin
- inherited;
- Instructions := Instructions + 'This program implements Floud algorithm.'
- + NEW_LINE + 'This program receives incident list and'+ NEW_LINE
- +'outputs the imagw with path.'+NEW_LINE
- +'1. Fullfill grid.'+NEW_LINE+'2. ENTER - to process image.'
- +NEW_LINE+'3. Show result - see the image.';
- End;
- procedure TInputForm.ShowButtonClick(Sender: TObject);
- begin
- if IsProcessed then
- Begin
- if not Assigned(GraphForm) then
- GraphForm := TGraphForm.Create(Self);
- GraphForm.Show;
- IsProcessed := False;
- End
- Else
- MessageDlg('Your data was not processed. Press enter, please', mtError, [mbOk], 0);
- end;
- procedure TInputForm.VertexNumberSpinEditChange(Sender: TObject);
- Const
- WINDOW_DEFAULT_HEIGHT = 200;
- begin
- SetGridSize(1, StrToint(VertexNumberSpinEdit.Text), IncidentListStringGrid);
- VertexSpinEdit.maxValue := VertexNumberSpinEdit.value;
- VertexSpinEdit.minValue := 1;
- if IncidentListStringGrid.height > ClientHeight-WINDOW_DEFAULT_HEIGHT then
- ClientHeight := IncidentListStringGrid.height + WINDOW_DEFAULT_HEIGHT;
- end;
- procedure TInputForm.FormCreate(Sender: TObject);
- begin
- inherited;
- IncidentListStringGrid.Cells[0,0] := 'V';
- IncidentListStringGrid.Cells[1,0] := '1';
- IncidentListStringGrid.Cells[0,1] := '1';
- IncidentListStringGrid.ColWidths[0] := Round(IncidentListStringGrid.Width * 0.1);
- IncidentListStringGrid.ColWidths[1] := Round(IncidentListStringGrid.Width * 0.9);;
- end;
- procedure TInputForm.FormKeyDown(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- var
- AdjacencyMatrix, DistMatrix, PrecMatrix: TMatrix;
- MainVertexNumber: integer;
- Size: integer;
- GraphText: string;
- Const
- ENTER = 13;
- INFO = 'Your information is processed, thanks.';
- EXCEPTION = 'Input incident list.';
- begin
- inherited;
- if (Key = ENTER) and (isDataCorrect(IncidentListStringGrid)) then
- Begin
- receiveListArray(ListArray, IncidentListStringGrid);
- receiveAdjacencyMatrix(ListArray, AdjacencyMatrix);
- Size := length(AdjacencyMatrix);
- receiveDistMatrix(Size, DistMatrix);
- receivePrecMatrix(Size, PrecMatrix);
- receiveMatrices(AdjacencyMatrix, DistMatrix, PrecMatrix);
- MainVertexNumber := VertexSpinEdit.value - 1;
- ConvertGraphInString(GraphText, AdjacencyMatrix, DistMatrix, PrecMatrix, MainVertexNumber);
- SaveGraph(GraphText);
- CreateGraphPicture();
- IsProcessed := True;
- MessageDlg(INFO, mtInformation, [mbOk], 0)
- end;
- end;
- function TInputForm.isFileCorrect(const Name: string): boolean;
- var
- CurrentVertex, NumberOfVertice, i: integer;
- Buffer: string;
- IsCorrect: boolean;
- InputFile: TextFile;
- begin
- AssignFile(InputFile, Name);
- Reset(InputFile);
- IsCorrect := true;
- i := 0;
- try
- Read(InputFile, NumberOfVertice);
- except
- IsCorrect := false;
- end;
- while (not EOF(InputFile)) and IsCorrect do
- begin
- Read(InputFile, CurrentVertex);
- Readln(InputFile, Buffer);
- IsCorrect := isValidStr(NumberOfVertice, Buffer, (i + 1));
- inc(i);
- end;
- if (i <> NumberOfVertice) then
- IsCorrect := false;
- closeFile(InputFile);
- Result := IsCorrect;
- end;
- procedure TInputForm.OpenFileClick(Sender: TObject);
- var
- InputFile: textFile;
- begin
- if OpenDialog.Execute then
- begin
- if FileExists(OpenDialog.FileName) then
- Begin
- if TrySetInputFile(OpenDialog.FileName) then
- begin
- if (IsFileCorrect(OpenDialog.FileName)) then
- begin
- OpenFromFile(OpenDialog.FileName, Self.IncidentListStringGrid, VertexNumberSpinEdit);
- end
- else
- MessageDlg('Wrong data in file.', mtError, [mbOk], 0);
- end
- else
- MessageDlg('This file can not be openned.', mtError, [mbOk], 0);
- end;
- end;
- end;
- procedure TInputForm.saveInFile(const Name: string; IncidentListStringGrid: TStringGrid);
- Var
- i, j: Integer;
- OutputFile: TextFile;
- Begin
- AssignFile(OutputFile, Name);
- Rewrite(OutputFile);
- Writeln(OutputFile, IncidentListStringGrid.RowCount-1);
- for i := 1 to IncidentListStringGrid.RowCount-1 do
- Begin
- for j := 0 to IncidentListStringGrid.ColCount-1 do
- Begin
- Write(OutputFile, IncidentListStringGrid.Cells[j, i]);
- Write(OutputFile, ' ');
- End;
- Writeln(OutputFile);
- End;
- closeFile(OutputFile);
- End;
- procedure TInputForm.SaveFileClick(Sender: TObject);
- Var
- OutputFile: TextFile;
- begin
- if SaveDialog.Execute then
- Begin
- If FileExists(SaveDialog.FileName) then
- Begin
- if TrySetOutputFile(SaveDialog.FileName) then
- Begin
- SaveInFile(SaveDialog.FileName, Self.IncidentListStringGrid);
- MessageDlg('Graph is saved.', mtInformation, [mbOk], 0);
- End
- Else
- MessageDlg('Data is not saved', mtError, [mbOk], 0);
- End;
- End;
- end;
- procedure TInputForm.CreateGraphPicture();
- Begin
- ShellExecute(Handle, nil, 'cmd.exe', PChar(CREATE_GRAPH_PICTURE_COMMAND), nil, SW_HIDE)
- End;
- end.
- Unit SimpleFormUnit;
- interface
- uses
- Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
- Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, System.UITypes;
- type
- TSimpleForm = class(TForm)
- Menu: TMainMenu;
- Instruction: TMenuItem;
- Developer: TMenuItem;
- procedure InstructionClick(Sender: TObject);
- procedure DeveloperClick(Sender: TObject);
- Procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
- procedure SetInstructions(); virtual;
- procedure FormCreate(Sender: TObject);
- procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); virtual;
- Procedure FormCloseQueryNope(Sender: TObject; var CanClose: Boolean);
- private
- { Private declarations }
- protected
- Instructions: String;
- public
- { Public declarations }
- end;
- var
- SimpleForm: TSimpleForm;
- implementation
- {$R *.dfm}
- procedure TSimpleForm.DeveloperClick(Sender: TObject);
- begin
- ShowMessage('Ravodin Alexander 151002');
- end;
- procedure TSimpleForm.InstructionClick(Sender: TObject);
- begin
- ShowMessage(Instructions);
- end;
- Procedure TSimpleForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
- begin
- CanClose := False;
- if MessageDlg('Are you sure if you want to exit?',mtConfirmation, mbOKCancel, 0) = mrOk then
- begin
- CanClose := True;
- end;
- end;
- Procedure TSimpleForm.FormCloseQueryNope(Sender: TObject; var CanClose: Boolean);
- Begin
- CanClose := True;
- End;
- procedure TSimpleForm.SetInstructions();
- begin
- Instructions := 'This is main window' + #13#10 + #13#10 +
- 'Here you should input incident lists and choose main vertex' +
- 'F1 - see instruction.' + #13#10 + 'F2 - show developer.' +
- #13#10 + 'ESC - close window.';
- end;
- procedure TSimpleForm.FormCreate(Sender: TObject);
- begin
- SetInstructions;
- end;
- procedure TSimpleForm.FormKeyDown(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- begin
- if (Key = VK_ESCAPE) then
- Self.Close;
- end;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement