4837

Создание рекурсии в программировании на языке Pascal

Лекция

Информатика, кибернетика и программирование

Рекурсия Цель: Научить студентов создавать рекурсию. Задачи: Воспитательная: работа над собой. Учебная: создание приложений. Развивающая: развитие внимательности. План занятия. Организационный момент. Изучение нового материала. Кон...

Русский

2012-11-27

288.5 KB

6 чел.

Рекурсия

Цель:

Научить студентов создавать рекурсию.

Задачи:

Воспитательная: работа над собой.

Учебная: создание приложений.

Развивающая: развитие внимательности.

План занятия.

  1.  Организационный момент.
  2.  Изучение нового материала.
  3.  Контрольные вопросы.
  4.  Резюме.
  5.  Домашнее задание.

Изучение нового материала.

   Рекурсивным называется объект, частично состоящий или определяемый с помощью самого себя. Факториал — это классический пример рекурсивного объекта. Факториал числа n — это произведение целых чисел от 1 до n. Обозначается факториал числа n так: n!.

Согласно определению

n! = 1 х 2 х 3 х ... х (n - 1) х n. Приведенное выражение можно переписать так:

n! = nх ((n - 1) х (n - 2) х ...х 3 х 2 х 1) = n х (n - 1)!

То есть, факториал числа п равен произведению числа n на факториал числа (n - 1). В свою очередь, факториал числа («-!) — это произведение числа (n - 1) на факториал числа (n - 2) и т. д.

Таким образом, если вычисление факториала n реализовать как функцию, то в теле этой функции будет инструкция вызова функции вычисления факториала числа (n - 1), т. е. функция будет вызывать сама себя. Такой способ вызова называется рекурсией, а функция, которая обращается сама к себе, называется рекурсивной функцией. В листинге 1 приведена рекурсивная функция вычисления факториала.

Листинг 1. Рекурсивная функция вычисления факториала

function factorial(n: integer): integer;

begin

if n <> 1

then factorials n * factorial(n-1)

// функция вызывает сама себя

else factorial := 1; // рекурсивный процесс закончен

end;

Обратите внимание, что функция вызывает сама себя только в том случае, если значение полученного параметра k не равно единице. Если значение параметра равно единице, то функция сама себя не вызывает, а возвращает значение, и рекурсивный процесс завершается. На рис.  приведен вид диалогового окна программы, которая для вычисления факториала числа использует рекурсивную функцию factorial. Текст программы приведен в листинге2.

Листинг 2. Использование рекурсивной функции

unit factor ;

interface

uses

Windows, Messages, SysUtils, Classes,

Graphics, Controls, Forms, Dialogs, StdCtrls;

type

TForm1 = class(TForm)

Label1: TLabel;

Edit1: TEdit;

Button1: TButton;

Label2: TLabel;

procedure ButtonlClick(Sender: TObject) ;

private

{ Private declarations } public

{ Public declarations } end;

var

Form1: TForm1;

implementation

{$R *.DFM}

// рекурсивная функция

function factorial(n: integer): integer;

begin

if n > 1

then factorial := n * factorial(n-1) // функция вызывает сама себя

else factorial:= 1; // факториал 1 равен 1

end;

procedure TForml.ButtonlClick(Sender: TObject);

var

k:integer; // число, факториал которого надо вычислить

f:integer; // значение факториала числа k

begin

k := StrToInt(Edit1.Text);

f := factorial(k);

label2.caption:='Факториал числа '+Edit1.Text

+ ' равен '+IntToStr(f);

end;

end.

   На рис. приведены два диалоговых окна. Результат вычисления факториала, представленный на рис., соответствует ожидаемому.

   

   Результат, представленный на рис.  не соответствует ожидаемому. Факториал числа 44 равен нулю! Произошло это потому, что факториал числа 44 настолько велик, что превысил максимальное значение для переменной типа integer, и, как говорят программисты, произошло переполнение с потерей значения. Delphi может включить в исполняемую программу инструкции контроля диапазона значений переменных. Чтобы инструкции контроля были добавлены в программу, нужно во вкладке Compiler диалогового окна Project Options установить флажок Overflow checking (Контроль переполнения), который находится в группе Runtime errors (Ошибки времени выполнения).

Примеры программ

Поиск файлов

   В качестве примера использования рекурсии рассмотрим задачу поиска файлов. Пусть нужно получить список всех файлов, например, с расширением bmp, которые находятся в указанном пользователем каталоге и во всех подкаталогах этого каталога. Словесно алгоритм обработки каталога может быть представлен так:

1. Вывести список всех файлов удовлетворяющих критерию запроса.

2. Если в каталоге есть подкаталоги, то обработать каждый из этих каталогов.

   Приведенный алгоритм (его блок-схема представлена на рис.) является рекурсивным: для того чтобы обработать подкаталог, процедура обработки текущего каталога должна вызвать сама себя.

   Вид диалогового окна программы приведен на рис., текст — в листинге. Поле Файл (Edit1) используется для ввода имени искомого файла или маски (для поиска файлов одного типа). Имя каталога, в котором нужно выполнить поиск, можно ввести непосредственно в поле Папка или выбрать из стандартного диалогового окна Обзор папок, которое появляется в результате щелчка на кнопке Папка. Окно Обзор папок выводит на экран стандартная функция Seiectoirectory. Следует обратить внимание, что имя каталога, который используется в диалоговом окне Обзор папок в качестве корневого, должно передаваться функции SeiectDirectory как Строка WhideChar. Для Преобразования обычной строки в строку WideChar использована функция StringToWhideChar.

   

   Основную работу выполняет рекурсивная функция Find. У функции Find один-единственный параметр — структура searchRec, которая используется функциями FindFirst и FindNext для поиска соответственнопервого и следующего файла, удовлетворяющего критерию поиска. Следует обратить внимание на то, как осуществляется перебор каталогов в текущем каталоге. Если текущий каталог не корневой, то помимо обычных, то есть имеющих имя, в каталоге есть еще два каталога: .. и ., которые обозначают каталог предыдущего уровня. Эти два каталога не обрабатываются, так как при входе в эти каталоги фактически выполняется выход (переход) в родительский каталог. Если этого не учесть, то программа зациклится.

Листинг. Программа поиск файлов

// поиск файла в указанном каталоге и его подкаталогах

// используется рекурсивная процедура Find

unit FindFile_;

interface

uses

Windows, Messages, SysUtils, Variants,

Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, FileCtr;

type

TForm1 = class(TForm)

Editl: TEdit; // что искать

Edit2: TEdit; // где искать

Memo1: TMemo; // результат поиска

Button1: TButton; // кнопка Поиск

Button2: TButton; // кнопка Папка

Label1: TLabel;

Label2: TLabel;

Label3: TLabel;

Label4: TLabel;

procedure Button1Click(Sender: TObject);

procedure Button2Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.dfm}

var

FileName: string; // имя или маска искомого файла

cDir: string;

n: integer; // кол-во файлов, удовлетворяющих запросу

// поиск файла в текущем каталоге

procedure Find;

var

SearchRec: TSearchRec; // информация о файле или каталоге

begin

GetDir(0,cDir); // получить имя текущего каталога

if cDir [length (cDir) ] <> 'V then cDir := cDir+'\';

if FindFirst(FileName, faArchive,SearchRec) = 0

then repeat

if (SearchRec.Attr and faAnyFile) = SearchRec.Attr

then begin

Form1.Memo1.Lines.Add(cDir + SearchRec.Name);

n := n + 1; end; until FindNext(SearchRec) <> 0;

// обработка подкаталогов текущего каталога 

if FindFirst('*', faDirectory, SearchRec) = 0 then repeat

if (SearchRec.Attr and faDirectory) = SearchRec.Attr then begin

// каталоги .. и . тоже каталоги,

// но в них входить не надо .'.'.'

if SearchRec.Name[1] <> '.' then begin

ChDir(SearchRec.Name);// войти в каталог

Find; // выполнить поиск в подкаталоге

ChDir('..');// выйти из каталога

end;

end;

until FindNext(SearchRec) <> 0;

end;

/ возвращает каталог, выбранный пользователем

function GetPath(mes: string):string;

var

Root: string; // корневой каталог

pwRoot : PWideChar; Dir: string;

begin

Root := '';

GetMem(pwRoot, (Length(Root)+1) * 2);

pwRoot := StringToWideChar(Root, pwRoot, MAX_PATH*2);

if SelectDirectory(mes, pwRoot, Dir) then

if length(Dir) =2 // пользователь выбрал корневой каталог

then GetPath := Dir+'\' else GetPath := Dir else

GetPath := '';

end;

щелчок на кнопке Поиск

procedure TForml.ButtonlClick(Sender: TObject);

begin

Memo1.Clear; // очистить поле Memol

Label4.Caption := '';

FileName := Edit1.Text; // что искать.

cDir := Edit2.Text; // где искать

n:=0; // кол-во найденных файлов

ChDir(cDir); // войти в каталог начала поиска

Find; // начать поиск

if n = 0 then

ShowMessage('Файлов, удовлетворяющих критерию поиска нет.')

else Label4.Caption := 'Найдено файлов:' + IntToStr(n);

end;

// щелчок на кнопке Папка

procedure TForml.Button2Click (Sender: TObject);

var

Path: string; begin

Path := GetPath('Выберите папку');

if Path <> ''

then Edit2.Text := Path;

end;

end.

Кривая Гильберта

   Следующая программа вычерчивает в диалоговом окне кривую Гильберта. На рис.  приведены кривые Гильберта первого, второго и третьего порядков. Если присмотреться, то видно, что кривая второго порядка получается путем соединения прямыми линиями четырех кривых первого порядка. Аналогичным образом получается кривая третьего порядка, но при этом в качестве "кирпичиков" используются кривые второго порядка. Таким образом, чтобы нарисовать кривую третьего порядка, надо нарисовать четыре кривых второго порядка. В свою очередь, чтобы нарисовать кривую второго порядка, надо нарисовать четыре кривых первого порядка. Таким образом, алгоритм вычерчивания кривой Гильберта является рекурсивным. Диалоговое окно программы Кривая Гильберта, в котором находится кривая пятого порядка, приведено на рис., текст программы — в листинге4.

   

Листинг 4. Кривая Гильберта

unit gilbert_;

interface

uses

Windows, Messages, SysUtils,

Variants, Classes, Graphics,

Controls, Forms, Dialogs, StdCtrls, ComCtrls;

type

TForml = class(TForm)

procedure FormPaint(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation {$R *.dfm}

var

p: integer =5; // порядок кривой 

u: integer =7; // длина штриха

{ Кривую Гильберта можно получить путем

соединения элементов а,b,с и d.

Каждый элемент строит

соответствующая процедура. }

procedure a(i:integer; canvas: TCanvas); forward;

procedure b(i:integer; canvas: TCanvas); forward;

procedure с(i:integer; canvas: TCanvas); forward;

procedure d(i:integer; canvas: TCanvas); forward;

// Элементы кривой

procedure a(i: integer; canvas: TCanvas);

begin

if i > 0 then begin

d(i-l, canvas);

canvas.LineTo(canvas.PenPos.X+u,canvas.PenPos.Y);

a(i-l, canvas);

canvas.LineTo(canvas.PenPos.X,canvas.PenPos.Y+u);

a(i-l, canvas);

canvas.LineTo(canvas.PenPos.X-u,canvas.PenPos.Y);

с (i-1, canvas);

end; 

end;

procedure b(i: integer; canvas: TCanvas);

begin

if i > 0 then begin

c(i-l, canvas);

canvas.LineTo(canvas.PenPos.X-u,canvas.PenPos.Y);

b(i-1, canvas);

canvas.LineTo(canvas.PenPos.X,canvas.PenPos.Y-u);

b(i-l, canvas);

canvas.LineTo(canvas.PenPos.X+u, canvas.PenPos.Y);

d(i-l, canvas);

end;

end;

procedure c(i: integer; canvas: TCanvas);

begin

if i > 0 then begin

b(i-1, canvas);

canvas.LineTo(canvas.PenPos.X,canvas.PenPos.Y-u);

с (i-1, canvas);

canvas.LineTo(canvas.PenPos.X-u,canvas.PenPos.Y);

c(i-1, canvas);

canvas.LineTo(canvas.PenPos.X,canvas.PenPos.Y+u);

a(i-1, canvas);

end; 

end;

procedure d(i: integer; canvas: TCanvas);

begin

if i > 0 then begin

a(i-1, canvas);

canvas.LineTo(canvas.PenPos.X,canvas.PenPos.Y+u);

d(i-1, canvas);

canvas.LineTo(canvas.PenPos.X+u,canvas.PenPos. Y) ;

d(i-1, canvas);

canvas.LineTo(canvas.PenPos.X,canvas.PenPos.Y-u);

b(i-1, canvas);

end; 

end;

procedure TForml.FormPaint(Sender: TObject);

begin

Form1.Canvas.MoveTo(u, u) ;

a(5,Form1.Canvas); // вычертить кривую Гильберта

end;

end.

Следует обратить внимание на следующую особенность реализации программы. Процедура, которая вычерчивает элемент а, помимо самой себя (для вычерчивания элемента а кривой более низкого порядка) вызывает процедуры d и ь, описание (текст) которых в тексте программы находится после процедуры а. Чтобы компилятор не вывел сообщение об ошибке, в текст программы помещено объявление процедуры с ключевым словом forward, означающим, что это только объявление, а описание (реализация) находится дальше. Таким образом, уже в процессе компиляции процедуры а, компилятор "знает", что имена ь и d означают процедуры.

Поиск пути

   Механизм рекурсии весьма эффективен при программировании задач поиска. В качестве еще одного примера рассмотрим задачу поиска пути между двумя городами. Если несколько городов соединены дорогами, то очевидно, что попасть из одного города в другой можно различными маршрутами. Задача состоит в нахождении всех возможных маршрутов.

Карта дорог между городами может быть изображена в виде графа — набора вершин, означающих города, и ребер, обозначающих дороги.

   Процесс поиска может быть представлен как последовательность шагов. На каждом шаге с использованием некоторого критерия выбирается точка, в которую можно попасть из текущей. Если очередная выбранная точка совпала с заданной конечной точкой, то маршрут найден. Если не совпала, то делаем из этой точки еще шаг. Так как текущая точка может быть соединена с несколькими другими, то нужен какой-то формальный критерий выбора. В простейшем случае можно выбрать точку с наименьшим номером. Пусть, например, надо найти все возможные пути из точки 1 в точку 5. Согласно принятому правилу, сначала выбираем точку 2. На следующем шаге выясняем, что точка 2 тупиковая, поэтому возвращаемся в точку 1 и делаем шаг в точку 3. Из точки 3 — в точку 4, из 4 — в 6 и из точки 6 — в точку 5. Один маршрут найден. После этого возвращаемся в точку 6 и проверяем, возможен ли шаг в точку, отличную от 5. Так как это возможно, то делаем шаг в точку 7, и затем — в 5. Найден еще один путь. Таким образом, процесс поиска состоит из шагов вперед и возвратов назад. Поиск завершается, если из узла начала движения уже некуда идти. Алгоритм поиска имеет рекурсивный характер: чтобы сделать шаг, мы выбираем точку и опять делаем шаг, и так продолжаем до тех пор, пока не достигнем цели. Таким образом, задача поиска маршрута может рассматриваться как задача выбора очередной точки (города) и поиска оставшейся части маршрута, т. е. имеет место рекурсия. Граф можно представить двумерным массивом, который назовем тар (карта). Значение элемента массива map[i, j] — это расстояние между городами i и j, если города соединены дорогой, или ноль, если города не соединены прямой дорогой. Для приведенного графа массив тар можно изобразить в виде таблицы, представленной на рис.

   Содержимое ячейки таблицы на пересечении строки i и столбца j соответcтвует значению map [ i, j ]. Помимо массива тар нам потребуются массив road (дорога) и массив incl(от include — включать). В road мы будем записывать номера пройденных городов. В момент достижения конечной точки он будет содержать номера всех пройденных точек, т. е. описание маршрута. В inci [i] будем записывать true, если точка с номером i включена в маршрут. Делается это для того, чтобы не включать в маршрут уже пройденную точку (не ходить по кругу). Так как мы используем рекурсивную процедуру, то надо обратить особое внимание на условие завершения рекурсивного процесса. Процедура должна прекратить вызывать сама себя, если текущая точка совпала с заданной конечной точкой. На рис. приведена блок-схема алгоритма процедуры выбора очередной точки формируемого маршрута, а диалоговое окно — на рис. Для ввода массива, представляющего описание карты, используется компонент stringGridl (значения его свойств приведены в таблице), для вывода результата (найденного маршрута) — поле метки Label 1. Начальная и конечная точки маршрута задаются вводом значений в поля редактирования Edit1 и Edit2. Процедура поиска запускается щелчком кнопки Поиск (Buttonl). Поля меток Label2, Label3 и Label4 используются для вывода поясняющего текста.

Таблица. Значения свойств компонента stringGrid1

Свойство

Значение

Name

StringGrid1

ColCount

11

RowCount

11

FixedCols

1

FixedRows

1

Options . goEditing

TRUE

DefaultColWidth

16

DefaultRowHeight

14

Текст программы приведен в листинге 5.

Листинг5. Поиск маршрута

unit road_;

interface

uses

Windows, Messages, SysUtils, Classes,

Graphics, Controls, Forms,

Dialogs, StdCtrls, Grids;

type

TForml = class(TForm)

StringGridl: TStringGrid;

Edit1: TEdit;

Edit2: TEdit;

Label1: TLabel;

Label2: TLabel;

Label3: TLabel;

Button1: TButton;

Label4: TLabel;

procedure FormActivate(Sender: TObject);

procedure ButtonlClickfSender: TObject);

private

{ Private declarations } public

{ Public declarations } end;

var

Form1: TForm1;

implementation

{$R *.DFM}

procedure TForml.FormActivate(Sender: TObject);

var

i:integer; begin

// нумерация строк

for i:=1 to 10 do

StringGridl.Cells[0,i]:=IntToStr(i); // нумерация колонок

for i:=l to 10 do

StringGridl.Cells[1,0]:=IntToStr(i);

// описание предопределенной карты StringGridl.Cells[1,2]:='1' StringGridl.Cells[2,l]:='1'

StringGridl.Cells[1,3]:='1'

StringGridl.Cells[3,1]:='1'

StringGridl.Cells[1,4]:='1'

StringGridl.Cells[4,1]:='1'

StringGridl.Cells[3,7]:='1'

StringGridl.Cells[7,3]:='1'

StringGridl.Cells[4,6]:='1'

StringGridl.Cells[6,4]:='1'

StringGridl.Cells[5,6]:='1'

StringGridl.Cells[6,5]:='1'

StringGridl.Cells[5,7]:='1'

StringGridl.Cells[7,5]:='1'

StringGridl.Cells[6,7]:='1'

StringGridl.Cells[7,6]:='1'

end;

procedure TForml.ButtonlClick(Sender: TObject);

const

N=10;// кол-во вершин графа var

map:array[1..N,1..N]of integer; // Карта.map[i,j]ne 0,

// если точки i и j соединены

road:array[1..N]of integer;

// Дорога - номера точек карты 

incl:array[1..N]of boolean; // incl[1]равен TRUE, если точка

// с номером i включена в road

start,finish:integer; // Начальная и конечная точки

found:boolean; i,j:integer;

procedure step(s,f,p:integer);

var

с:integer;// Номер точки, в которую делаем очередной шаг

i:integer;

begin

if s=f then begin

// Точки s и f совпали !

found:=TRUE;

Labell.caption:=Labell.caption+#13+'Путь:';

for i:=l to p-1 do

Labell.caption:=Labell.caption+' '

+IntToStr(road[i]); end

else begin

// выбираем очередную точку for c:=l to N do

begin // проверяем все вершины

if(map[s,c]<> 0)and(NOT incite1)

// точка соединена с текущей и не включена в маршрут

then begin

road[p]:=c;// добавим вершину в путь

incl[c]:=TRUE;// пометим вершину как включенную

step(c,f,p+l); incite]:=FALSE; road[p]:=0;

end;

end;

end;

end;// конец процедуры step

begin

Label1.caption: =' ' ;

// инициализация массивов

for i:=l to N do road[i]:=0;

for i:=l to N do incl[i]:=FALSE;

// ввод описания карты из SrtingGrid.Cells

for i:=l to N do

for j:=1 to N do

if StringGrid1.Cells[i,j] <> ''

then map[i,j]:=StrToInt(StringGridl.Cells[i, j] ;

else map[i,j]:=0;

start:=StrToInt(Editl.text);

finish:=StrToInt(Edit2.text);

road[l]:=start;// внесем точку в маршрут

incl[start]:=TRUE;// пометим ее как включенную

step(start,finish,2);//ищем вторую точку маршрута

// проверим, найден ли хотя бы один путь

if not found

then Labell.caption:='Указанные точки не соединены!';

end;

end.

При запуске программы в момент активизации формы приложения происходит событие onActivate, процедура обработки которого заполняет массив StringGridl.cells значениями, представляющими описание карты. Этаже процедура нумерует строки и столбцы таблицы, заполняя зафиксированные ячейки первого столбца и первой строки StringGridl.

Поиск маршрута инициирует процедура TFormi.Buttoniciick, которая запускается щелчком на кнопке Поиск. Данная процедура для поиска точки, соединенной с исходной точкой, вызывает процедуру step, которая после выбора первой точки, соединенной с начальной, и включения ее в маршрут вызывает сама себя. При этом в качестве начальной точки задается уже не исходная, а текущая, только что включенная в маршрут.

Поиск кратчайшего пути

  Обычно задача поиска пути на графе формулируется следующим образом: найти наилучший маршрут. Под наилучшим маршрутом, как правило, понимают кратчайший. Найти кратчайший маршрут можно выбором из всех найденных. Однако совсем не обязательно искать все маршруты. Можно поступить иначе: во время выбора очередной точки проверить, не превысит ли длина формируемого маршрута длину уже найденного пути, если эта точка будет включена в маршрут; если превысит, то эту точку следует пропустить и выбрать другую. Таким образом, после того как будет найден первый маршрут, программа будет вести поиск только по тем ветвям графа, которые могут улучшить найденное решение, отсекая пути, делающие формируемый маршрут длиннее уже найденного. В листинге приведена процедура, которая использует процедуру step, выполняющую выбор очередной точки маршрута таким образом, что обеспечивается поиск пути минимальной длины.

Листинг . Поиск кратчайшего пути

procedure TForm1.Button1Click(Sender: TObject);

const

N=10;{ кол-во вершин графа} var

map:array[1..N,1..N]of integer;

// Карта.map[i,j] не 0,если

// точки i и j соединены

road:array[1..N]of integer;

// Дороганомера точек карты 

incl:array[1..N]of boolean; // incl[1]равен TRUE,если точка

// с номером i включена в road

start, finish:integer;

// Начальная и конечная точки

found:boolean; len:integer; // длина найденного (минимального)

// маршрута } c_len:integer; // длина текущего (формируемого)

// маршрута i,j:integer;

// выбор очередной точки

procedure step(s,f,p:integer);

var

с:integer; { Номер точки, в которую делаем очередной шаг }

i:integer; begin

if s=f then begin

len:=c_len;{ сохраним длину найденного маршрута }

{ вывод найденного маршрута }

for i:=1 to p-1 do

Label1.caption:=Label1.caption+' '+IntToStr(road[i]);

Label1.caption:=Label1.caption

+', длина:'+IntToStr(len)+#13;

end

else

{ выбираем очередную точку }

for c:=l to N do { проверяем все вершины }

if(map[s,c]<> 0)and(NOT incite])

and((len=0)or(c_len+map[s,c]< len)) then begin

// точка соединена с текущей, но не включена в

// маршрут

roadtp]:=c;{ добавим вершину в путь }

incl[c]:=TRUE;{ пометим вершину как включенную }

c_len:=c_len+map[s,с];

step(c,f,p+l);

incite]:=FALSE; roadtp]:=0;

c_len:=c_len-map[s,с];

end;

end;

{ конец процедуры step }

begin

Labell.caption:='';

{ инициализация массивов }

for i: =1 to N do road [ i ] : =0;

for i:=l to N do incl[i]:=FALSE;

{ ввод описания карты из SrtingGrid.Cells}

for i:=l to N do

for j:=1 to N do

if StringGridl.Cells[i, j] <> "

then mapti,j]:=StrToInt(StringGridl.Cells[i,j])

else mapti,j]:=0;

len:=0; // длина найденного (минимального) маршрута с

len:=0,- // длина текущего (формируемого) маршрута

start:=StrToInt(Edit1.text);

finish:=StrToInt(Edit2.text);

road[1]:=start;{ внесем точку в маршрут }

incl[start]:=TRUE;{ пометим ее как включенную }

step(start,finish,2);{ищем вторую точку маршрута }

// проверим, найден ли хотя бы один путь

if not found

then Label1.caption:='Указанные точки не соединены!';

end;

PAGE  186


 

А также другие работы, которые могут Вас заинтересовать

43941. Безопасность в чрезвычайных ситуациях. Методические указания 273 KB
  Руководствуется допустимыми дозами облучения установленными для различных категорий населения НРБУ99 оказавшегося в зоне радиоактивного загрязнения при аварии на АЭС. При написании расчетной части студент использует исходные данные полученные у преподавателя цикла ГО и по методическим указаниям к расчетнографической работе Выявление и оценка радиационной обстановки на объекте при загрязнении радиоактивными веществами после аварии на АЭС выполняет ее. Определяет допустимое время начала работы рабочих и служащих...
43942. Обгрунтування застосування пристроїв для збирання, завантаження та транспортування рулонів трести льону-довгунця та конопель в Інстітуті луб'яних культур 27.69 MB
  Обгрунтування застосування пристроїв для збирання завантаження та транспортування рулонів трести льонудовгунця та конопель в Інстітуті луб'яних культур. Зміни у затратах на завантаження та перевезення рулонів впливають на затрати у механізованих роботах та суттєво впливають на собівартість кінцевого продукту. Кількість рулонів на довжині стрічки наприклад довжиною 500 м може бути різною рис. Також на кількість рулонів на довжині стрічки впливають конструктивні особливості прес підбирачів діаметр пресувальної камери та ширина захвату.
43943. Программа MS Publisher как инструмент создания электронного пособия 573.5 KB
  Для этого щелкнуть левой кнопкой мыши внутри текстовой рамки. Текстовый файл Чтобы создать текстовую рамку надо щелкнуть на кнопке на панели инструментов Объекты MS Publisher щелкнуть в публикации протащить указатель мыши при нажатой левой кнопке чтобы нарисовать рамку нужного размера и отпустить кнопку мыши. Чтобы избавиться от фона надо щелкнуть на кнопке Цвет заливки на панели инструментов Форматирование и выбрать значение Нет заливки. Чтобы сгруппировать рамки необходимо их выделить а затем щелкнуть на кнопке Сгруппировать...
43944. Вплив мотивації на вибір професії у підлітковому віці 361 KB
  При задоволенні потреби закінчується потребовий цикл. Задоволення потреби – це оволодіння предметом потреби та його використання. Виконавча діяльність організму, орієнтована у напрямку його потребових зв’язків з оточуючим середовищем, розуміється як діяльність
43945. Организация движения пассажирских поездов дальнего, местного и пригородного сообщения 3.21 MB
  Технология обработки составов пригородных поездов. Основными направлениями развития пассажирских перевозок обеспечивающими их эффективность и качество в ближайшей перспективе являются оптимальное планирование эксплуатационной работы по пассажирским перевозкам четкое выполнение графика движения поездов совершенствование форм и методов продажи билетов повышение уровня пассажирского сервиса и развития материальнотехнической базы пассажирского хозяйства. Наиболее полно...
43946. Разработка и обоснование мероприятия по повышению эффективности деятельности ООО «Феникс-Т» 839.5 KB
  Для предприятия одним из направлений повышения эффективности его деятельности могут рассматриваться инвестиции в расширение деятельности. Обоснование целесообразности инвестиций осуществляется на основе разработки бизнес-проекта инвестиционного проекта и расчета показателей эффективности инвестиций. Цель выпускной квалификационной работы разработать и обосновать мероприятия по повышению эффективности деятельности ООО Феникс Т. Для достижения поставленной цели необходимо решить следующие задачи: рассмотреть теоретические основы повышения...
43947. Практическое выполнение следующих видов макияжа и грима - подиумный, свадебный, портретный и ретро-макияж в стилистике 20-х годов 1.21 MB
  Практическое выполнение следующих видов макияжа и грима подиумный свадебный портретный и ретромакияж в стилистике 20х годов. Для достижения этой цели были поставлены следующие задачи: Собрать и проанализировать теоретический и иллюстративный материал касающийся выполнения подиумного макияжа свадебного макияжа портретного грима и ретромакияжа. Выделить характерные...
43948. Метафора в англоязычном тексте политической рекламы 324 KB
  Роль метафоры в рамках англоязычного рекламного текста Определение роль и место рекламы в современном социуме Рекламный текст как объект функционально-лингвистического исследования Проблема функционально-стилевой дифференциации языка Определение стилевого статуса языка рекламы Метафора в английском рекламном тексте Концепции метафоры общелингвистического характера Метафора в рекламном тексте Метафора в рамках текстов политической рекламы