Advertisement
Guest User

Untitled

a guest
May 16th, 2019
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 13.39 KB | None | 0 0
  1. unit View;
  2.  
  3. interface
  4.  
  5. uses
  6.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  7.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.StdCtrls, System.Actions,
  8.   Vcl.ActnList, Model, Vcl.Menus, Vcl.ExtCtrls, Math;
  9.  
  10. type
  11.   TMainForm = class(TForm)
  12.     gbList: TGroupBox;
  13.     btnFindFlow: TButton;
  14.     sgAdjacencyList: TStringGrid;
  15.     ActionList: TActionList;
  16.     edListSize: TEdit;
  17.     MainMenu: TMainMenu;
  18.     Open: TMenuItem;
  19.     N1: TMenuItem;
  20.     Exit: TMenuItem;
  21.     Exit1: TMenuItem;
  22.     Help: TMenuItem;
  23.     actionSaveToFile: TAction;
  24.     OpenDialog: TOpenDialog;
  25.     PopupMenu: TPopupMenu;
  26.     Areyouserious1: TMenuItem;
  27.     lbAmountNodes: TLabel;
  28.     actionHelpClick: TAction;
  29.     actionClickTransformFromList: TAction;
  30.     lbInformation: TLabel;
  31.     lbMaxFlow: TLabel;
  32.     imgDrawPlace: TImage;
  33.     sgEdgesCost: TStringGrid;
  34.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  35.     procedure edListSizeKeyPress(Sender: TObject; var Key: Char);
  36.     procedure edListSizeChange(Sender: TObject);
  37.     procedure sgAdjacencyListKeyPress(Sender: TObject; var Key: Char);
  38.     procedure FormCreate(Sender: TObject);
  39.     procedure sgAdjacencyListKeyDown(Sender: TObject; var Key: Word;
  40.       Shift: TShiftState);
  41.     procedure actionSaveToFileExecute(Sender: TObject);
  42.     procedure Exit1Click(Sender: TObject);
  43.     procedure actionHelpClickExecute(Sender: TObject);
  44.     procedure actionClickTransformFromListExecute(Sender: TObject);
  45.     procedure actionClickTranformExecute(Sender: TObject);
  46.   private
  47.    const
  48.      NodeRadius = 20;
  49.      EdgesLen = 100;
  50.      PenWidth = 2;
  51.      PenArrowWidth = 7;
  52.      CentrePoint: TPoint = (X: 200; Y: 200);
  53.  
  54.     procedure ClearDrawPlace;
  55.     procedure RedrawFixedColInAdjancyList(const sg: TStringGrid);
  56.     procedure DrawCircle(const Value, Radius: Integer; const Pos: TPoint);
  57.     procedure DrawLine(const FPoint, SPoint: TPoint);
  58.     procedure DrawArrow(FPoint, SPoint: TPoint; const Color: TColor);
  59.     procedure DrawGraph(const StartAdjacentMatrix, FinalAdjacentMatrix :TMatrix);
  60.  
  61.     function IsCorrectKey(const Key: char; const Text: string): Boolean;
  62.     function  CountSecontPointPosByAngle(const Angle, Linelen: integer;
  63.          const FPoint: TPoint): TPoint;
  64.  
  65.     procedure Clear(const sg: TStrinGgrid);
  66.     procedure ClearFlowlabel;
  67.     //Надо изменить
  68.     procedure WriteInformationToFile(var f: TextFile;
  69.        const sgAdjacencyList, sgAdjacencyMatrix: TStringGrid);
  70.   public
  71.     procedure ShowErrorMsg(const Msg, MsgHead: string);
  72.   end;
  73.  
  74.  
  75. const
  76.    msgFileError = 'Critical error writing to file';
  77.    headFileError = 'Error';
  78.  
  79. var
  80.   MainForm: TMainForm;
  81.  
  82. implementation
  83.  
  84.  
  85.  
  86. {$R *.dfm}
  87.  
  88.  
  89. procedure TMainForm.ShowErrorMsg(const Msg, MsgHead: string);
  90. begin
  91.    MessageBox(Handle, PChar(Msg), PChar(MsgHead), MB_ICONERROR)
  92. end;
  93.  
  94.  
  95. procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
  96. const
  97.    Question = 'Are you sure?';
  98. begin
  99.    if MessageBox(Handle, PChar(Question), PChar(Question), MB_ICONINFORMATION + MB_YESNO) = mrno then
  100.       Action := caNone;
  101. end;
  102.  
  103. procedure TMainForm.FormCreate(Sender: TObject);
  104. begin
  105.    RedrawFixedColInAdjancyList(sgAdjacencyList);
  106.    RedrawFixedColInAdjancyList(sgEdgesCost);
  107. end;
  108.  
  109.  
  110. procedure TMainForm.edListSizeChange(Sender: TObject);
  111. const
  112.    FixedCol = 1;
  113. var
  114.    RowCount: integer;
  115. begin
  116.    ClearFlowlabel;
  117.    if (Sender as TEdit).Text <> '' then
  118.    begin
  119.       RowCount := StrToInt((Sender as TEdit).Text);
  120.  
  121.       sgAdjacencyList.RowCount := RowCount;
  122.       sgAdjacencyList.ColCount := RowCount + FixedCol;
  123.  
  124.       sgEdgesCost.RowCount := RowCount;
  125.       sgEdgesCost.ColCount := RowCount + FixedCol;
  126.  
  127.    end;
  128.    ClearDrawPlace;
  129.    Clear(sgAdjacencyList);
  130.    Clear(sgEdgesCost);
  131.  
  132.    RedrawFixedColInAdjancyList(sgAdjacencyList);
  133.    RedrawFixedColInAdjancyList(sgEdgesCost);
  134. end;
  135.  
  136. procedure TMainForm.RedrawFixedColInAdjancyList(const sg: TStringGrid);
  137. var
  138.    i: integer;
  139. begin
  140.    if sg.FixedCols <> 0 then
  141.       for i := 0 to (sg.RowCount - 1) do
  142.          sg.Cells[0, i] := IntToStr(i+1) + '    -> ';
  143. end;
  144.  
  145.  
  146. procedure TMainForm.sgAdjacencyListKeyDown(Sender: TObject; var Key: Word;
  147.   Shift: TShiftState);
  148. begin
  149.    if Key = VK_INSERT then
  150.       Key := 0;
  151. end;
  152.  
  153.  
  154. procedure TMainForm.ClearFlowlabel;
  155. begin
  156.    lbMaxFlow.Caption := '';
  157. end;
  158.  
  159. procedure TMainForm.sgAdjacencyListKeyPress(Sender: TObject; var Key: Char);
  160. const
  161.    BackSpace = #8;
  162. var
  163.    CurCellText, PreviousCellText: string;
  164.    CurI, CurJ, j: integer;
  165. begin
  166.    ClearDrawPlace;
  167.    ClearFlowLabel;
  168.  
  169.    CurI := (Sender as TStringGrid).Row;
  170.    CurJ := (Sender as TStringGrid).Col;
  171.  
  172.    CurCellText := (Sender as TStringGrid).Cells[CurJ, CurI];
  173.    PreviousCellText := (Sender as TStringGrid).Cells[CurJ - 1, CurI];
  174.  
  175.    if (not IsCorrectKey(Key, CurCellText) or (PreviousCellText = '')) then
  176.       Key := #0;
  177.  
  178.    if Key = BackSpace then
  179.       for j := CurJ to (Sender as TStringGrid).ColCount - 1 do
  180.          (Sender as TStringGrid).Cells[j, CurI] := '';
  181. end;
  182.  
  183. procedure TMainForm.ClearDrawPlace;
  184. const
  185.    StandartColor = clWhite;
  186. var
  187.    OldColor: TColor;
  188. begin
  189.    OldColor := imgDrawPlace.Canvas.Brush.Color;
  190.    imgDrawPlace.Canvas.Brush.Color := StandartColor;
  191.  
  192.    imgDrawPlace.Canvas.FillRect(Rect(0, 0, imgDrawPlace.Width, imgDrawPlace.Height));
  193.  
  194.    imgDrawPlace.Canvas.Brush.Color := OldColor;
  195. end;
  196.  
  197.  
  198. function IsCorrectKeyInedListSize(const Key: char; const Text: string): Boolean;
  199. const
  200.    BackSpace = #8;
  201.    ValidSize = ['2'..'6', #8];
  202. begin
  203.    if (Length(Text) <> 0) and (Key <> BackSpace) then
  204.       Result := False
  205.    else
  206.       Result := Key in ValidSize;
  207. end;
  208.  
  209.  
  210. procedure TMainForm.edListSizeKeyPress(Sender: TObject; var Key: Char);
  211. begin
  212.    if (not IsCorrectKeyInedListSize(Key, (Sender as TEdit).Text)) then
  213.       Key := #0;
  214. end;
  215.  
  216. procedure TMainForm.Exit1Click(Sender: TObject);
  217. begin
  218.    Close;
  219. end;
  220.  
  221. procedure TMainForm.actionClickTransformFromListExecute(Sender: TObject);
  222. var
  223.    ListArr: TListArr;
  224.    StartAdjacencyMatrix, FinalAdjacencyMatrix: TMatrix;
  225.    FlowSize: Integer;
  226. begin
  227.    ListArr := InitList(sgAdjacencyList);
  228.    if Length(ListArr) <> 0 then
  229.    begin
  230.       StartAdjacencyMatrix := CreateAdjacencyMatrixFromList(ListArr);
  231. //      FinalAdjacencyMatrix := FindFinalAnjacentMatrix(StartAdjacencyMatrix, FlowSize);
  232.       lbMaxFlow.Caption := IntToStr(FlowSize);
  233.  
  234.       DrawGraph(StartAdjacencyMatrix, FinalAdjacencyMatrix);
  235.    end;
  236. end;
  237.  
  238. procedure TMainForm.actionClickTranformExecute(Sender: TObject);
  239. const
  240.    msgIncorrectList = 'Incorrect list, please, read help and try again.';
  241. var
  242.    StartAdjacencyMatrix, FinalAdjacencyMatrix: TMatrix;
  243.    FlowSize: Integer;
  244.    i: Integer;
  245.    j: Integer;
  246.    IsCorrectLists: Boolean;
  247. begin
  248.    IsCorrectLists := True;
  249.    TransformToMatrix(StartAdjacencyMatrix, sgAdjacencyList);
  250.    TransformToMatrix(FinalAdjacencyMatrix, sgEdgesCost);
  251.    if IsCorrectList(StartAdjacencyMatrix) then
  252.    begin
  253.       for i := 0 to High(StartAdjacencyMatrix) do
  254.       begin
  255.          for j := 0 to High(StartAdjacencyMatrix) do
  256.             if StartAdjacencyMatrix[i, j] <> 0 then
  257.                if FinalAdjacencyMatrix[i, j] = 0 then
  258.                begin
  259.                   IsCorrectLists := False;
  260.                   ShowMessage(msgIncorrectList);
  261.                   Break;
  262.                end;
  263.          if not IsCorrectLists then
  264.             Break;
  265.       end;
  266.  
  267.       if IsCorrectLists then
  268.       begin
  269.          StartAdjacencyMatrix := CreateAdjacencyMatrix(StartAdjacencyMatrix, FinalAdjacencyMatrix);
  270.  
  271.          FinalAdjacencyMatrix := FindFinalAnjacentMatrix(StartAdjacencyMatrix, FlowSize);
  272.           lbMaxFlow.Caption := IntToStr(FlowSize);
  273.  
  274.          DrawGraph(StartAdjacencyMatrix, FinalAdjacencyMatrix);
  275.       end;
  276.    end
  277.    else
  278.       ShowMessage(msgIncorrectList);
  279. end;
  280.  
  281. procedure TMainForm.actionHelpClickExecute(Sender: TObject);
  282. const
  283.    msgAboutProgram1 = 'This program tranform adjancy lists in the adjacency matrix.';
  284.    msgAboutProgram2 = 'For translation is necessary to fill lists in the increasing order, ';
  285.    msgAboutProgram3 = 'the biggest number you may use it is amount nodes in the your graph.';
  286.    msgHead = 'Help';
  287. begin
  288.    MessageBox(Handle, PChar(msgAboutProgram1 + #13 + msgAboutProgram2 + #13 + msgAboutProgram3),
  289.               PChar(msgHead), MB_ICONINFORMATION);
  290. end;
  291.  
  292. procedure TMainForm.actionSaveToFileExecute(Sender: TObject);
  293. var
  294.    FileName: string;
  295.    f: TextFile;
  296. begin
  297.    if OpenDialog.Execute then
  298.    begin
  299.       FileName := OpenDialog.FileName;
  300.       if FileExists(FileName) then
  301.       begin
  302.          try
  303.             AssignFile(f, FileName);
  304.             Rewrite(f);
  305.          except
  306.             MessageBox(Handle, PChar(msgFileError), PChar(headFileError), MB_ICONERROR);
  307.          end;
  308.       end;
  309.       CloseFile(f);
  310.    end;
  311. end;
  312.  
  313. procedure TMainForm.WriteInformationToFile(var f: TextFile;
  314.    const sgAdjacencyList, sgAdjacencyMatrix: TStringGrid);
  315.  
  316. const
  317.    msgList = 'List: ';
  318.    msgMatrix = 'Matrix: ';
  319. var
  320.    i,j: integer;
  321. begin
  322.    Writeln(f, msgList);
  323.    for i := 0 to (sgAdjacencyList.RowCount - 1) do
  324.    begin
  325.       Write(f, IntToStr(i) + ': ');
  326.       for j := 1 to (sgAdjacencyList.ColCount - 1) do
  327.          if sgAdjacencyList.Cells[j, i] <> '' then
  328.             Write(f, sgAdjacencyList.Cells[j, i] + ' -> ');
  329.       Writeln(f);
  330.    end;
  331.  
  332.    Writeln(f);
  333.    Writeln(f, msgMatrix);
  334.    for i := 1 to (sgAdjacencyMatrix.RowCount - 1) do
  335.    begin
  336.       for j := 1 to (sgAdjacencyMatrix.ColCount - 1) do
  337.          Write(f, sgAdjacencyMatrix.Cells[j, i] + ' ');
  338.       Writeln(f);
  339.    end;
  340. end;
  341.  
  342. procedure TMainForm.Clear(const sg: TStrinGgrid);
  343. var
  344.   i, j: Integer;
  345. begin
  346.    for i := (0 + sg.FixedRows) to sg.RowCount do
  347.       for j := (0 + sg.FixedCols) to sg.ColCount do
  348.          sg.Cells[j, i] := '';
  349. end;
  350.  
  351. function TMainForm.IsCorrectKey(const Key: char; const Text: string): Boolean;
  352. const
  353.    BackSpace = #8;
  354.    ValidSize = ['1'..'9', #8];
  355. begin
  356.    if (Length(Text) > 2) and (Key <> BackSpace) then
  357.       Result := False
  358.    else
  359.       Result := Key in ValidSize;
  360. end;
  361.  
  362.  
  363. procedure TMainForm.DrawCircle(const Value, Radius: Integer; const Pos: TPoint);
  364. const
  365.    Offset = 5;
  366.    TextSize = 13;
  367. var
  368.    XTextOffset, YTextOffset: integer;
  369. begin
  370.    XTextOffset := (Radius div Offset);
  371.    YTextOffset := (Radius div Offset) + Offset;
  372.  
  373.    imgDrawPlace.Canvas.Pen.Width := PenWidth;
  374.    imgDrawPlace.Canvas.Ellipse((Pos.X - Radius), (Pos.Y - Radius),
  375.                                (Pos.X + Radius), (Pos.Y + Radius));
  376.    imgDrawPlace.Canvas.Font.Size := TextSize;
  377.    imgDrawPlace.Canvas.TextOut(Pos.X - XTextOffset, Pos.Y - YTextOffset, IntToStr(Value));
  378. end;
  379.  
  380. procedure TMainForm.DrawLine(const FPoint, SPoint: TPoint);
  381. begin
  382.    imgDrawPlace.Canvas.MoveTo(FPoint.X, FPoint.Y);
  383.    imgDrawPlace.Canvas.LineTo(SPoint.X, SPoint.Y);
  384. end;
  385.  
  386. procedure TMainForm.DrawArrow(FPoint, SPoint: TPoint; const Color: TColor);
  387. const
  388.    ArrowLenCoefficient = 4;
  389. var
  390.    OldPenColor: TColor;
  391.    OldPenWidth: Integer;
  392.    XOffset, YOffset: Integer;
  393. begin
  394.    OldPenColor := imgDrawPlace.Canvas.Pen.Color;
  395.    imgDrawPlace.Canvas.Pen.Color := Color;
  396.  
  397.    DrawLine(FPoint, SPoint);
  398.  
  399.    OldPenWidth := imgDrawPlace.Canvas.Pen.Width;
  400.    imgDrawPlace.Canvas.Pen.Width :=  PenArrowWidth;
  401.  
  402.    XOffset := Abs(FPoint.X - SPoint.X) div ArrowLenCoefficient;
  403.    YOffset := Abs(FPoint.Y - SPoint.Y) div ArrowLenCoefficient;
  404.  
  405.    if Max(FPoint.X, SPoint.X) = SPoint.X then
  406.       FPoint.X := SPoint.X - XOffset
  407.    else
  408.       FPoint.X := SPoint.X + XOffset;
  409.  
  410.    if Max(FPoint.Y, SPoint.Y) = SPoint.Y then
  411.       FPoint.Y := SPoint.Y - YOffset
  412.    else
  413.       FPoint.Y := SPoint.Y + YOffset;
  414.  
  415.    DrawLine(FPoint, SPoint);
  416.  
  417.    imgDrawPlace.Canvas.Pen.Width := OldPenWidth;
  418.    imgDrawPlace.Canvas.Pen.Color := OldPenColor;
  419. end;
  420.  
  421. procedure TMainForm.DrawGraph(const StartAdjacentMatrix, FinalAdjacentMatrix: TMatrix);
  422. const
  423.    StandartColor = clBlack;
  424.    HilighedColor = clMoneyGreen;
  425. var
  426.    CurAngle, AngleOffset, i, j, StartAdjacentMatrixLen: Integer;
  427.    NodesPositions: array of TPoint;
  428. begin
  429.    StartAdjacentMatrixLen := Length(StartAdjacentMatrix);
  430.  
  431.    AngleOffset := (360 div StartAdjacentMatrixLen);
  432.    SetLength(NodesPositions, StartAdjacentMatrixLen);
  433.    CurAngle := 0;
  434.  
  435.    for i := 0 to High(StartAdjacentMatrix) do
  436.    begin
  437.       NodesPositions[i] := CountSecontPointPosByAngle(CurAngle, EdgesLen, CentrePoint);
  438.       Inc(CurAngle, AngleOffset);
  439.    end;
  440.  
  441.    //Draw arrows by standart color
  442.    for i := 0 to High(StartAdjacentMatrix) do
  443.       for j := 0 to High(StartAdjacentMatrix) do
  444.          if StartAdjacentMatrix[i, j] <> 0 then
  445.                DrawArrow(NodesPositions[i], NodesPositions[j], StandartColor);
  446.  
  447.    //Draw useful arrow special color (above)
  448.    for i := 0 to High(StartAdjacentMatrix) do
  449.       for j := i to High(StartAdjacentMatrix) do
  450.          if StartAdjacentMatrix[i, j] <> FinalAdjacentMatrix[i, j] then
  451.                DrawArrow(NodesPositions[i], NodesPositions[j], HilighedColor);
  452.  
  453.    for i := 0 to High(NodesPositions) do
  454.       DrawCircle(i + 1, NodeRadius, NodesPositions[i]);
  455. end;
  456.  
  457.  
  458.  
  459. function TMainForm.CountSecontPointPosByAngle(const Angle, Linelen: integer;
  460.    const FPoint: TPoint): TPoint;
  461. begin
  462.    Result.X := FPoint.X + Round(Linelen * Cos(Angle * Pi / 180));
  463.    Result.Y := FPoint.Y - Round(Linelen * Sin(Angle * Pi / 180));
  464. end;
  465.  
  466. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement