В результате выполнения курсовой работы был закреплен и в том числе изучен новый материал, по дисциплине «Структуры и алгоритмы обработки данных», а так же закреплена информация о графах их визуализации определения параметров и т.д. Приобретены более углубленные знания в программировании на языке Object Pascal в среде Delphi.
Итогом данной работы является программа “NeoGraf”, которая позволяет не только вычислить некоторые характеристики графа, но и визуализировать их.
Список используемой литературы
1) Хромоненко А.Д. – Delphi 7 – CПБ: БВХ - Петербург. 2008 – 1207 с.
2) Интернет источник: http://rudocs.exdat.com/docs/index-400475.html алгоритмы нахождения характеристик графа.
3) Интернет источник: http://algolib.narod.ru/Graph/Doublelinks.html Алгоритм определения компонент двусвязности.
4) Интернет источник: http://delphi-prg.ru/category/komponenti-delphi-7 все компоненты Delphi 7.
Приложение 1
МИНОБРНАУКИ РОССИИ
ФГБОУ ВПО «ЧЕРЕПОВЕЦКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ»
Институт информационных технологий
Кафедра МПО ЭВМ
Утверждаю зав. кафедрой ПО ВТ и АС
к.т.н., проф.________ Ершов Е.В.
«____»_____________2012г.
Алгоритмы обработки данных
Техническое задание на курсовую работу
Выполнил: студент гр.1ПО-31
Шаханов Н.И..
Руководитель:
Селивановских В.В.
Череповец, 2012 г
1. Введение
Данное техническое задание распространяется на разработку программы «Neo Graf» для определения точек сочленения и компонент двусвязности графа заданного пользователем.
2. Основание для разработки
Основанием для разработки служит задание на курсовую работу по дисциплине «Структуры и алгоритмы обработки данных».
Задание:
Разработать программу для определения точек сочленения и компонент двусвязности неориентированного графа заданного пользователем.
Возможности:
1) Задание графа вручную матрицей смежности;
2) Наглядная визуализация графа, возможность изменять его внешний вид;
3) Нахождение компонент двусвязности и точек сочленения неориентированного графа.
3. Назначение разработки:
Программа «NeoGraf» позволит пользователю работать с неориентированными графами и так же определять их некоторые свойства.
4. Требования к программе:
a) требования к функциональным характеристикам
Исходные данные:
· Таблица для ввода матрицы смежности, размер которой пользователь задает вручную:
Результаты:
· Отображение графа и вывод его характеристики:
- Изобразить визуально на форме;
- Описать выбранные для него свойства.
Программа должна обеспечивать выполнение следующих функций:
· Ввод графа матрицей смежности, с упрощением ввода и ограничением на количество вершин (не более 255);
· Визуализация неориентированного графа;
· Определение точек сочленения и компонент двусвязности;
b) Требования к надежности
Для контроля ввода данных, т.е. матрицы смежности и ее размера, будет использоваться проверка на соответствие типа данных, т.е. размер таблицы будет ограничен до 255. В таблицу можно вводить только 2 символа: «0» и «1».
c) Требования к составу и параметрам технических средств.
Данная программа будет работать на любом компьютере, под управлением системы Windows.
d) Требования к информационной и программной совместимости.
Программа будет разработана на языке Object Pascal в среде Delphi 7 и должна работать под управлением операционной системы семейства Windows.
5. Требование к программной документации:
Программная документация будет содержать:
· расчетно-пояснительную записку;
· техническое задание (приложение 1);
· блок-схемы алгоритмов (приложение 2);
· текст программы (приложение 3);
· руководство пользователя (приложение 4).
6. Стадии и этапы разработки.
Таблица П1.1
Наименование этапа разработки | Сроки разработки | Результат | Отметка о выполнении |
Постановка задачи и разработка технического задания | 15 – 30 сентября | Техническое задание | |
Разработка алгоритма программы (блок-схемы) | 1 – 10 октября | Обобщенный алгоритм рабочей программы (в текстовом виде) | |
Разработка интерфейса | 10 октября – 10 ноября | Интерфейс программы (в эл. виде) | |
Написание кода программы | 10 ноября – 8 декабря | Не менее 50 % рабочей программы (в эл. виде) | |
Написание расчетно-пояснительной записки | 8 – 15 декабря | Расчетно-пояснительная записка | |
Подготовка к защите | 15 – 20 декабря | - | |
Защита | 20 - 24 декабря | - |
7. Порядок контроля и приемки:
Таблица П1.2
Наименование контрольного этапа | Сроки контроля | Отметка о приеме |
Техническое задание в бумажном виде | До 1 октября | |
Обобщенный алгоритм в бумажном виде | До 10 октября | |
Приблизительный интерфейс в электронном виде | До 10 ноября | |
Не менее 50% реализованной программы в электронном виде | До 17 ноября | |
Тестирование | До 1 декабря | |
Расчетно-пояснительная записка в бумажном виде (без приложений) | До 15 декабря | |
Защита | 20 - 24 декабря |
Приложение 2
Блок-схемы основных процедур
1) Процедура построения вектора - DrawArrow.
|
2) Процедура обхода графа в глибину
Рис. П2.2. Обход в глубину
3) Поиск компонент связности
Рис. П.2.3.Компоненты связности
4) Визуализация графа
Рис. П2.4. Визуализация графа
Рис. П2.5. Визуализация графа
Рис. П2.6. Визуализация графа
5) Нахождение и построение точек сочленения
Рис. П2.7. Точки сочленения графа
Приложение 3
Листинг программы:
unit Graf;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, ExtCtrls, Buttons, StdCtrls, Grids, XPMan;
type
TMainGraf = class(TForm)
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
GroupBox1: TGroupBox;
Edit1: TEdit;
Label4: TLabel;
Button1: TButton;
Button2: TButton;
Label6: TLabel;
TabSheet3: TTabSheet;
RadioGroup1: TRadioGroup;
CheckBox1: TCheckBox;
GroupBox2: TGroupBox;
Label3: TLabel;
Label5: TLabel;
Label13: TLabel;
TabSheet4: TTabSheet;
Image2: TImage;
Panel3: TPanel;
Memo1: TMemo;
XPManifest1: TXPManifest;
XPManifest2: TXPManifest;
XPManifest3: TXPManifest;
XPManifest4: TXPManifest;
SpeedButton1: TSpeedButton;
SpeedButton3: TSpeedButton;
SpeedButton4: TSpeedButton;
SpeedButton2: TSpeedButton;
SpeedButton5: TSpeedButton;
SpeedButton6: TSpeedButton;
SpeedButton8: TSpeedButton;
SpeedButton7: TSpeedButton;
Edit2: TEdit;
StringGrid1: TStringGrid;
Image1: TImage;
StringGrid2: TStringGrid;
Image3: TImage;
Label2: TLabel;
BitBtn1: TBitBtn;
CheckBox2: TCheckBox;
Timer1: TTimer;
RadioGroup2: TRadioGroup;
Panel1: TPanel;
ColorBox2: TColorBox;
ColorBox3: TColorBox;
ColorBox1: TColorBox;
ColorBox7: TColorBox;
ColorBox4: TColorBox;
ColorBox5: TColorBox;
ColorBox6: TColorBox;
Label11: TLabel;
Label12: TLabel;
Label10: TLabel;
Label1: TLabel;
Label7: TLabel;
Label9: TLabel;
Label8: TLabel;
Label14: TLabel;
Label15: TLabel;
Label16: TLabel;
Label17: TLabel;
Label18: TLabel;
Label19: TLabel;
Label20: TLabel;
XPManifest5: TXPManifest;
procedure TabSheet2Resize(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure SpeedButton5Click(Sender: TObject);
procedure SpeedButton5MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure PageControl1Change(Sender: TObject);
procedure SpeedButton7Click(Sender: TObject);
procedure SpeedButton4Click(Sender: TObject);
procedure SpeedButton3Click(Sender: TObject);
procedure SpeedButton6Click(Sender: TObject);
procedure SpeedButton8Click(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
procedure StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure StringGrid1SetEditText(Sender: TObject; ACol, ARow: Integer;
const Value: String);
procedure SpeedButton1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure SpeedButton2MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure SpeedButton3MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure SpeedButton4MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure SpeedButton6MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure SpeedButton7MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure SpeedButton8MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure BitBtn1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure CheckBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure StringGrid1KeyPress(Sender: TObject; var Key: Char);
procedure ColorBox2Change(Sender: TObject);
procedure ColorBox3Change(Sender: TObject);
procedure ColorBox1Change(Sender: TObject);
procedure ColorBox7Change(Sender: TObject);
procedure ColorBox4Change(Sender: TObject);
procedure ColorBox5Change(Sender: TObject);
procedure ColorBox6Change(Sender: TObject);
procedure Edit2KeyPress(Sender: TObject; var Key: Char);
procedure Memo1KeyPress(Sender: TObject; var Key: Char);
private
{ Private declarations }
public
Procedure Depth(v:byte; _Type:byte);
// Procedure Reach();
Procedure Recursiya(ii: integer);
Procedure Visualization(Canvas: TCanvas;_Type: byte);
procedure DrawArrow(Canvas: TCanvas;x0, y0,x1,y1: Integer; __type,penwidth: byte);
function FindKS(_Type: byte): byte;
end;
var
MainGraf: TMainGraf;
i,j: integer;
ShowGraf: boolean; //построен ли граф.
RSel,CSel: integer; //выделенная вершина
CountDel: integer; //делитель
CenterX, CenterY,Radius: integer; //цент окружности и построения
Vershina: byte; //количисетво вершин, не больше 255
masX,MasY: array of integer; //массивы координат вершин
MouseDowning,MouseMoving: boolean; //нажата ли клавиша мыши
UsingPoint: byte; //вершина которую можно переместить
R1: Array [1..255] of array[1..255] of integer; //массив для проверки на связность
mark,Emark: array of byte; //глобалные переменные для обхода в ширину
KountKS: byte; //счётчик количества компонент связности
GroupKS: array of byte; //прохождения вершин для нахождения компонент свяности.
ExceptionV: byte; //вершина проверяемая на точку сочленения.
Mark1:array [byte] of boolean; // в глубину
K: boolean;
S,c: integer;
PS: array of byte; //точки сочленения;
clrOfP: array[0..256] of TColor; //массив цетов для компонентов свяности\двусвязнсти
_TypeOV: byte;
implementation
{$R *.dfm}
//нахождение количества компонент связности:
function TmainGraf.FindKS(_Type: byte): byte;
Begin
//стандартное количество компонент связности
for i:=1 to Vershina do begin Mark1[i]:=false; GroupKS[i-1]:=0; end;
KountKS:=1;
if _type=1 then
begin
Memo1.Clear;
Memo1.text:=('Компоненты связности: (');
For i:=1 to Vershina do begin
if GroupKS[i-1]=0 then
begin
Memo1.Text:=Memo1.Text+' {';
Depth(i,2);
Memo1.Text:=Memo1.Text+' } ';
inc(KountKS);
end;
end;
Memo1.Text:=Memo1.Text+')';
Memo1.Lines.Add('Число компонентов связности: - '+inttostr(KountKS-1));
end;
//количество компонент связности, исключая вершину
if _type=2 then
begin
For i:=1 to Vershina do begin
if i<>ExceptionV then
if GroupKS[i-1]=0 then
begin
Depth(i,1);
inc(KountKS);
end;
end;
FindKS:=KountKS-1;
end;
//количество компонент связности, исключая все точки сочленения
if _type=3 then
begin
For i:=1 to Vershina do begin
if PS[i-1]<>1 then
if GroupKS[i-1]=0 then
begin
Depth(i,3);
inc(KountKS);
end;
end;
FindKS:=KountKS-1;
end;
end;
// Обход в глубину--------------------------------------------------------------
procedure TMainGraf.Depth(v:byte;_Type:byte);
var u,z:byte;
begin
GroupKS[v-1]:=KountKS;
Mark1[v]:=true;
//обход для нахождения точек сочленения
if _type=1 then begin
for u:=1 to Vershina do
if (u<>ExceptionV) then
if (not Mark1[u]) and (StringGrid2.Cells[v,u]='1') then Depth(u,1);
end;
//стандартный обход в глубину
if _type=2 then begin
Memo1.text:=Memo1.text+' '+inttostr(v);
for u:=1 to Vershina do
if not Mark1[u] and (StringGrid1.Cells[v,u]='1') then Depth(u,2);
end;
//обход если не рассматривать точки сочленения
if _type=3 then begin
for u:=1 to Vershina do
if (PS[u-1]<>1) then
if (not Mark1[u]) and (StringGrid1.Cells[v,u]='1') then Depth(u,3);
end;
end;
//Обход в ширину--------------------------------------
Procedure TMainGraf.Recursiya(ii: integer);
var
a,b: integer;
begin
//ОТМЕЧАЕМ ЧТО НА ДАННЫЙ МОМЕНТ ЭТА ВЕРШИНА ПО КОТОРОЙ БУДУТ ОПРЕДЕЛЯТЬСЯ СМЕЖНЫЕ
Emark[ii-1]:=0;
//ЕСЛИ ВСЕ ВЕРШИНЫ ПРОЙДЕНЫ ТО ВЫХОД
if k=false then begin
S:=0;
for b:=0 to Vershina-1 do
begin
S:=S+Mark[b];
end;
if S=Vershina then k:=true;
//ПРОВЕРЯЕМ СМЕЖНЫЕ ВЕРШИНЫ
For a:=1 to Vershina do begin
if a<>ii then begin
if (mark[a-1]=0) then begin
if (MainGraf.StringGrid1.Cells[a,ii]<>'0') then
begin
mark[a-1]:=1;
Memo1.Text:=Memo1.Text+' '+inttostr(a);
end;
end;
end;
end;
//ВЫЗВАЕМ РЕКРСИЮ НА КАЖДУЮ ИЗ НЕ ПРОЙДЕННЫХ!!! СМЕЖНЫХ ВЕРШИН
for c:=1 to Vershina do begin
if c<>ii then begin
if (Emark[c-1]=1) then begin
if (Mark[c-1]=1) then begin
Recursiya(c);
end;
end;
end;
end;
end;
end;
//Проверка графа на связность---------------------
procedure Reach();
{enoiaiua aaiiua - iao?eoa nia?iinoe A, aeiaaeuiay ia?aiaiiay}
var
S,T:set of 1..255;
i,j,l:integer;
begin
FillChar(R1,SizeOf(R1),0);
for i:=1 to Vershina do begin {ainoe?eiinou ec aa?oeiu n iiia?ii i}
T:=[i];
repeat
S:=T;
for l:=1 to Vershina do if l in S then{ii no?ieai iao?eou A, i?eiaaea?auei iii?anoao S}
for j:=1 to Vershina do if strtoint(MainGraf.StringGrid1.cells[l,j])=1 then T:=T+[j];
until S=T;{anee T ia eciaieeinu, oi iaeaaiu ana aa?oeiu a?aoa, ainoe?eiua ec aa?oeiu n iiia?ii i}
for j:=1 to Vershina do if j in T then R1[i,j]:=1;
end;
end;
//ПРОЦЕДУРА ПОСТРОЕНИЯ ЛИНИИ 2 ВАРИАНТОВ НАПРАВЛЕННУЮ(1) ИЛИ НЕТ(2)
//C НАСТРОЙКОЙ ШИРИНЫ ЛИНИИ
procedure TMainGraf.DrawArrow(Canvas: TCanvas;x0, y0,x1,y1: Integer; __type,penwidth: byte);
var
XB, YB, XE, YE, XM, YM,x11,y11: Integer;
Angle_Line, Angle_Arrow: Extended;
Length_Line, Length_Arrow: integer;
begin
Canvas.Pen.Width:=penwidth;
Canvas.MoveTo(x0,y0);
Angle_Arrow:=pi/24;
if (y1=y0) and (x1>x0) then Angle_Line:=0;
if (x1=x0) and (y1<y0) then Angle_Line:=pi/2;
if (y0=y0) and (x0>x1) then Angle_Line:=pi;
if (x1=x0) and (y1>y0) then Angle_Line:=-pi/2;
if (x0<x1) and (y0<>y1) then Angle_Line:=ArcTan((y0-y1)/(x1-x0));
if (x0>x1) and (y0<>y1) then Angle_Line:=ArcTan(((y0-y1)/(x1-x0)))+pi;
if (x0=x1) and (y0=y1) then
begin MainGraf.Image1.Picture.Bitmap.Canvas.MoveTo(x0,y0);
MainGraf.Image1.Picture.Bitmap.Canvas.LineTo(x0+1,y0+1);
exit;
end;
x11:= abs(Round(cos(Angle_Line)*10));
y11:=abs(Round(sin(Angle_Line)*10));
if (x0>x1) and (y0>y1) then
begin x1:=x1+x11; y1:=y1+y11; x0:=x0-x11; y0:=y0-y11; end;
if (x0<=x1) and (y0>y1) then
begin x1:=x1-x11; y1:=y1+y11; x0:=x0+x11; y0:=y0-y11; end;
if (x0>x1) and (y0<=y1) then
begin x1:=x1+x11; y1:=y1-y11; x0:=x0-x11; y0:=y0+y11; end;
if (x0<=x1) and (y0<=y1) then
begin x1:=x1-x11; y1:=y1-y11; x0:=x0+x11; y0:=y0+y11; end;
XM:= Round(X1 - Cos(Angle_Arrow - Angle_Line) * 15);
YM:= Round(Y1 - Sin(Angle_Arrow - Angle_Line) * 15);
XE:= Round(X1 + Sin(Angle_Arrow + Angle_Line - Pi / 2) * 15);
YE:= Round(Y1 + Cos(Angle_Arrow + Angle_Line - Pi / 2) * 15);
if __type=1 then begin
Canvas.MoveTo(x0, y0); Canvas.LineTo(x1, y1);
Canvas.LineTo(XM, YM); Canvas.MoveTo(XE, YE);
Canvas.LineTo(X1, Y1)
end;
if __type=2 then begin
Canvas.MoveTo(x0, y0); Canvas.LineTo(x1, y1);
end;
end;
//-построение графа-----------------------------------
Procedure TMainGraf.Visualization(Canvas: TCanvas;_Type: byte);
var
i,j: integer; //cчетчики
a,b,c: integer; //переменный для дополниельных вычислений
Xx,Yy:integer; //переменные для хранения координаты вершины
cosS,SinS: real; // син и косинус угла наклона
Ugol: real; // угол наклона прямой
alpha: real; // угол наклона стрелки у прямой
Step: integer; //шаг для построения квадрата
s1,s2: string; //строки для записи в лейбл
begin
Canvas.Pen.Color:=clWhite;
Canvas.Brush.Color:=clWhite;
canvas.Rectangle(0,0,MainGraf.Image1.Width, MainGraf.Image1.Height);
//НАЧАЛЬНОЕ ПОСТРОЕНИЕ ПО КРУГУ ВСЕХ ВЕРШИН
//ПОСТРОЕНИЕ ПО ОКРУЖНОСТИ ----------------
if _type=1 then begin
Ugol:=360/vershina;
ugol:=ugol*Pi/180;
alpha:=Pi;
Canvas.Pen.Width:=2;
Canvas.Pen.Color:=MainGraf.ColorBox3.Selected; //!!!
Canvas.Brush.Color:=MainGraf.ColorBox1.Selected;; //!!!
for i:=0 to Vershina-1 do
begin
if (ugol<=Pi/2) and (ugol>=3*Pi/2) then Xx:=Trunc(240+(200*cos(alpha)-0*sin(alpha))) else Xx:=trunc(240-(200*cos(alpha)-0*sin(alpha)));
If (ugol<=Pi) and (ugol>=2*Pi) then Yy:=Trunc(240+(200*sin(alpha)+0*cos(alpha))) else Yy:=Trunc(240-(200*sin(alpha)+0*cos(alpha)));
MasX[i]:=Xx;
MasY[i]:=Yy;
alpha:=alpha-ugol;
end;
end;
//ПОСТРОЕНИЕ ПРИ ПЕРЕМЩЕНИИ ВЕРШИНЫ --------------------------------------------
if _type=2 then begin
Canvas.Pen.Width:=2; Canvas.Pen.Color:=MainGraf.ColorBox3.Selected;; //!!!
Canvas.Brush.Color:=MainGraf.ColorBox1.Selected;; //!!!
MainGraf.Label3.Caption:='';
for i:=0 to Vershina-1 do
begin
if MasX[i]<=20 then MasX[i]:=20;
if MasY[i]<=20 then MasY[i]:=20;
if MasX[i]>=MainGraf.Image1.Width-10 then MasX[i]:=MainGraf.Image1.Width-10;
if MasY[i]>=MainGraf.Image1.Height-10 then MasY[i]:=MainGraf.Image1.Height-10;
Xx:=MasX[i];
Yy:=MasY[i];
alpha:=alpha-ugol;
end;
end;
//ПОСТРОЕНИЕ ПО КВАДРАТУ ---------------------
if _type=3 then begin
if Vershina=3 then begin
MasX[0]:=30;
MasY[0]:=450;
MasX[1]:=450;
MasY[1]:=450;
MasX[2]:=450;
MasY[2]:=30;
exit;
end;
if Vershina=2 then begin
MasX[0]:=30;
MasY[0]:=450;
MasX[1]:=450;
MasY[1]:=30;
exit;
end;
b:=Vershina div 2;
a:=b div 2;
c:=(Vershina-(b+1)) div 2 +(b+1);
//1
Step:=420 div a;
Yy:=450;
Xx:=30;
For i:=1 to a do
begin
MasX[i-1]:=Xx;
MasY[i-1]:=Yy;
Xx:=Xx+Step;
end;
//2
Step:=420 div (b-a);
Xx:=450;
Yy:=450;
For i:=a+1 to b do
begin
MasX[i-1]:=Xx;
MasY[i-1]:=Yy;
Yy:=Yy-Step;
end;
//3
Step:=420 div (c-b);
Yy:=30;
Xx:=450;
For i:=b+1 to c do
begin
MasX[i-1]:=Xx;
MasY[i-1]:=Yy;
Xx:=Xx-Step;
end;
//4
Step:=420 div (Vershina-c);
Xx:=30;
Yy:=30;
For i:=c+1 to Vershina do
begin
MasX[i-1]:=Xx;
MasY[i-1]:=Yy;
Yy:=Yy+Step;
end;
end;
//ПОСТРОЕНИЕ В РАНДОМНОМ СЛУЧАЕ -------
if _type=4 then begin
Randomize;
Canvas.Pen.Width:=2;
Canvas.Pen.Color:=MainGraf.ColorBox3.Selected;
Canvas.Brush.Color:=MainGraf.ColorBox1.Selected;; //!!!
if Vershina<=2 then Vershina:=3;
For i:=0 to Vershina-1 do begin
MasX[i]:=random(MainGraf.Image1.Width);
if MasX[i]<20 then MasX[i]:=20;
if MasX[i]>460 then MasX[i]:=460;
MasY[i]:=random(MainGraf.Image1.Height);
if MasY[i]<20 then MasY[i]:=20;
if MasY[i]>460 then MasY[i]:=460;
end;
end;
//-------------------------------------------------------------
for i:=1 to Vershina do begin
For j:=1 to Vershina do begin
if MainGraf.StringGrid1.cells[i,j]='1' then
begin Canvas.brush.Color:=MainGraf.ColorBox4.Selected; Canvas.pen.Color:=MainGraf.ColorBox4.Selected;
if (i<>UsingPoint+1) and (j<>UsingPoint+1) then
begin
DrawArrow(Canvas,MasX[i-1],MasY[i-1],MasX[j-1],MasY[j-1],2,1);
end;
end;
end;
end;
//выделение дуги
if (MainGraf.StringGrid1.cells[Rsel,CSel]='1') or (MainGraf.StringGrid1.cells[Csel,RSel]='1') then
begin Canvas.pen.Color:=MainGraf.ColorBox5.Selected;
DrawArrow(Canvas,MasX[Rsel-1],MasY[Rsel-1],MasX[CSel-1],MasY[CSel-1],2,2);
end;
//-выделение вершин
if (Mousedowning) and (MouseMoving) then begin
MainGraf.Memo1.Clear;
MainGraf.Memo1.Lines.Add('Выделенная вершина'); MainGraf.Memo1.Lines.Add(inttostr(UsingPoint+1));
MainGraf.Edit2.Text:=inttostr(UsingPoint+1);
MainGraf.Memo1.Lines.Add('Смежные вершины c данной: ');
end;
For j:=1 to Vershina do begin
if MainGraf.StringGrid1.cells[UsingPoint+1,j]='1' then
begin Canvas.brush.Color:=MainGraf.ColorBox4.Selected;; //!!! Canvas.Pen.Color:=MainGraf.ColorBox5.Selected; DrawArrow(Canvas,MasX[UsingPoint],MasY[UsingPoint],MasX[j-1],MasY[j-1],2,2);
if (Mousedowning) and (MouseMoving) then MainGraf.Memo1.Text:=MainGraf.Memo1.Text+' - '+inttostr(j);
end;
end;
//---------ПОСТРОЕНИЕ-ВЕРШИН-------------------
For i:=1 to Vershina do
begin
//Canvas.Font.Style:=[fsbold]; Canvas.Pen.Color:=MainGraf.ColorBox2.Selected; //!!!
Canvas.Pen.Width:=2; Canvas.Brush.Color:=MainGraf.ColorBox1.Selected; //!!!
if (i=UsingPoint+1) or (i=RSel) or (i=CSel) then
begin
Canvas.Ellipse(MasX[i-1]-15,MasY[i-1]-15,MasX[i-1]+15,masY[i-1]+15);
end;
if MainGraf.StringGrid1.Cells[UsingPoint+1,i]='1' then
begin
Canvas.Ellipse(MasX[i-1]-10,MasY[i-1]-10,MasX[i-1]+10,masY[i-1]+10);
end
else
begin
//-----СЕЛЕКТОР ТИПА ВЕРШИНЫ------------------ Canvas.Brush.Color:=MainGraf.ColorBox3.Selected;
if (_TypeOV=1) and(PS[i-1]=1) then Canvas.Brush.Color:=MainGraf.ColorBox7.Selected;
if (_TypeOV=2) then
begin
Canvas.Brush.Color:=ClrOfP[GroupKS[i-1]];
end;
Canvas.Ellipse(MasX[i-1]-10,MasY[i-1]-10,MasX[i-1]+10,masY[i-1]+10);
end;
Canvas.Pen.Width:=1;
Canvas.Font.Height:=6; Canvas.Font.Color:=MainGraf.ColorBox6.Selected; //!!!
if i<10 then Canvas.TextOut(MasX[i-1]-3,masY[i-1]-6,inttostr(i)) else
Canvas.TextOut(MasX[i-1]-6,masY[i-1]-6,inttostr(i));
end;
//----------------------------------------------------------
MainGraf.Label3.caption:='';
For i:=0 to Vershina-1 do begin
if masX[i]<100 then s1:='0'+inttostr(masX[i]) else s1:=inttostr(masX[i]);
if masY[i]<100 then s2:='0'+inttostr(masY[i]) else s2:=inttostr(masY[i]);
if ((i+1) mod CountDel)=0 then MainGraf.Label3.Caption:=MainGraf.Label3.caption+'('+s1+','+s2+')'+#13 else MainGraf.Label3.Caption:=MainGraf.Label3.caption+'('+s1+','+s2+')'+' ';
end;
CSel:=0;
RSel:=0;
end;
//---при изменени размера формы---------------
procedure TMainGraf.TabSheet2Resize(Sender: TObject);
var
a,b: integer;
begin
a:=MainGraf.ClientHeight;
b:=MainGraf.ClientWidth;
end;
//-------------------------------------------------------------
procedure TMainGraf.SpeedButton1Click(Sender: TObject);
var i,j,a: integer;
begin
//АВТОЗАПОЛНЕНИЕ МАТРИЦЫ СМЕЖНОСТИ (ТАБЛИЦЫ)
randomize;
if SpeedButton1.Caption='&Автозаполнение' then begin
For i:=1 to vershina do begin
For j:=1 to vershina do begin
if j>=i then begin
if i=j then StringGrid1.Cells[i,j]:='0'
else
begin
a:=random(2);
if (a=1) and (RadioGroup2.ItemIndex>=1) then a:=random(2);
if (a=1) and (RadioGroup2.ItemIndex>=2) then a:=random(2);
if (a=1) and (RadioGroup2.ItemIndex>=3) then a:=random(2);
if (a=1) and (RadioGroup2.ItemIndex>=4) then a:=random(2);
if (a=1) and (RadioGroup2.ItemIndex>=5) then a:=random(2);
if (a=1) and (RadioGroup2.ItemIndex>=6) then a:=random(2);
StringGrid1.Cells[i,j]:=IntToStr(a); StringGrid1.Cells[j,i]:=StringGrid1.Cells[i,j];
end;
end;
end;
end;
SpeedButton1.Caption:='О&чистить';
end
else
begin
ShowGraf:=false; //---!!!!___POSMOTRET'_______
For i:=1 to vershina do begin
MasX[i-1]:=0;
MasY[i-1]:=0;
GroupKs[i-1]:=0;
For j:=1 to vershina do begin
if i=j then StringGrid1.Cells[i,j]:='0'
else StringGrid1.Cells[i,j]:='';
end;
end;
SpeedButton1.Caption:='&Автозаполнение';
Label3.Caption:='';
{ For i:=0 to Image1.Height do
For j:=0 to Image1.Width do
Image1.Canvas.Pixels[i,j]:=clWhite; }
end;
end;
//-------------------------------------------------------------
procedure TMainGraf.SpeedButton2Click(Sender: TObject);
begin
For i:=1 to Vershina do
For j:=1 to Vershina do
if (StringGrid1.Cells[i,j]<>'1') and (StringGrid1.Cells[i,j]<>'0') then StringGrid1.Cells[i,j]:='0';
ShowGraf:=true;
Csel:=0;
RSel:=0;
_TypeOv:=0;
if RadioGroup1.ItemIndex=0 then if vershina<=60 then Visualization(MainGraf.Image1.Canvas,1) else
begin
For i:=0 to Maingraf.ClientHeight do
For j:=0 to MainGraf.ClientWidth do
MainGraf.Canvas.Pixels[i,j]:=clWhite; Image1.Canvas.TextOut(100,200,'Визуализация графа затруднена');
end;
if RadioGroup1.ItemIndex=1 then if vershina<=80 then Visualization(MainGraf.Image1.Canvas,3)else
begin
For i:=0 to Maingraf.ClientHeight do
For j:=0 to MainGraf.ClientWidth do
MainGraf.Canvas.Pixels[i,j]:=clWhite; Image1.Canvas.TextOut(100,200,'Визуализация графа затруднена');
end;
if RadioGroup1.ItemIndex=2 then if vershina<=255 then Visualization(MainGraf.Image1.Canvas,4)else
begin
For i:=0 to Maingraf.ClientHeight do
For j:=0 to MainGraf.ClientWidth do
MainGraf.Canvas.Pixels[i,j]:=clWhite; Image1.Canvas.TextOut(100,200,'Визуализация графа затруднена');
Image1.Canvas.TextOut(100,300,'Введите меньшее число вершин');
end;
end;
//-------------------------------------------------------------
procedure TMainGraf.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var Xpos, Ypos,i: integer;
begin
Timer1.Enabled:=false;
Timer1.Interval:=1000;
Xpos:=X;
Ypos:=Y;
mouseDowning:=true;
MouseMoving:=true;
UsingPoint:=255;
For i:=0 to VERSHINA-1 do begin
if (Xpos>=masX[i]-10) and (Xpos<=masX[i]+10) then begin
if (Ypos>=masY[i]-10) and (Ypos<=masY[i]+10) then begin
UsingPoint:=i;
end;
end;
end;
//-------------------------------------------------------------
Label5.Caption:=inttostr(UsingPoint+1);
if UsingPoint<=vershina-1 then begin
if CheckBox1.Checked then begin
masX[UsingPoint]:=X;
masY[UsingPoint]:=Y;
end;
Visualization(MainGraf.image1.Canvas,2);
MouseMoving:=false;
end;
end;
//-------------------------------------------------------------