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


 

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

41610. Первинні засоби пожежогасіння. Вибір типу та визначення необхідної кількості первинних засобів пожежогасіння 309.89 KB
  Головним критерієм вибору виду вогнегасників є величина можливого осередку пожежі. Визначаємо рекомендовані типи вогнегасників. Користуючись рекомендаціями таблиці Д5 щодо порошкових вогнегасників визначаємо що для захисту промислових обєктів рекомендованими є такі типи переносних порошкових вогнегасників: ВП5 ВП6 ВП9 ВП12 записуємо в табл. Визначаємо кількість вогнегасників.
41611. Диференціальні рівняння в частинних похідних 44.88 KB
  resizeN1; forint i = 0; i N1; i u[0][i] = conditionih; forint j = 1; j NT; j { file T: htj endl; forint i = 1; i N; i f[i] = u[j1][i1] 2u[j1][i] u[j1][i1] 2hh u[j1][i]1 ht Q 2; l[2] = c; b[2] = f[1] c; u[j][0] = 0; u[j][N] = 0; forint i = 2; i N; i { l[i1] = c l[i]; b[i1] = f[i] b[i] c l[i]; } forint i = N1; i 0; i u[j][i] = l[i1]u[j][i1] b[i1]; int emx = 0; for int i = 0; i N; i { file x: ih ...
41612. Створення нової бази даних в середовищі MySQL 138.93 KB
  Створити нову базу даних та заповнити її даними. Короткі теоретичні відомості: Основи роботи з phpMydmin При установці Denwer також встановлюється на комп'ютер phpMydmin за допомогою якого можна керувати базою даних MySQL через вебінтерфейс. У цьому полі латинськими буквами записується назва бази даних наприклад exmple і натискається створити.
41613. Приближенное вычисление интеграла методом Симпсона и методом Гаусса 92.3 KB
  Требуется вычислить интеграл: Требуется использовать: метод Симпсона метод Гаусса Теория: 1 Метод Симпсона Для приближённого вычисления интеграла чаще всего подынтегральную функцию заменяют близкой ей вспомогательной функцией интеграла от которой вычисляется аналитически. В частности если при вычислении подынтегральную функцию заменить интерполяционным многочленом второй степени построенным по значениям функции в трёх...
41614. Состояние дерматовенерологических больных в Винницкой области 354.5 KB
  Проблема совершенствования лекарственного обеспечения населения регионов Украины остается актуальной. Особое значение в её решении имеет региональный подход к изучению фармацевтического рынка, его насыщенности и рациональному использованию лекарственных средств. С этой целью широко используются метод фармакоэкономического анализа
41615. Решение уравнения f(x)=0 методами простых итераций и Ньютона 134.65 KB
  Если же то вычисления заканчивают и за приближённое значение корня принимают величину . Абсциссы вершин этой ломанной представляют собой последовательные приближения корня . Из рисунков видно что если на отрезке то последовательные приближения колеблются около корня если же производная положительна то последовательные приближения сходятся к корню монотонно. Если через точку с координатами провести касательную то абсцисса точки пересечения этой касательной с осью и есть очередное приближение корня уравнения .
41616. Інтенсифікація сільськогосподарського виробництва в землеробстві і удосконалення с структури посівних площ в господарстві \"Студенний Яр\" у селі Купа Новоушицького району Хмельницької області 541.5 KB
  Загальні відомості про господарство на період написання курсової роботи. Агрокліматичні умови зони розташування господарства. Агрохімічна характеристика ґрунтів та рекомендації до їх раціонального використання. Експлікація і трансформація земельних угідь господарства. Існуюча система сівозмін у господарстві. Обґрунтування та проектування нової системи сівозмін для господарства
41617. Приближённое решение задачи Коши методами Эйлера и Рунге-Кутта 97.24 KB
  Решить на отрезке с шагом задачу Коши для системы второго порядка = Требуется использовать: метод Эйлера метод Рунге-Кутта Теория: 1 Метод Эйлера Пусть требуется найти приближённое решение дифференциального уравнения удовлетворяющее начальному условию. Чаще всего 1 Этот метод относится к группе одношаговых методов в которых для расчёта точки...
41618. Автоматизация кодирования графа переходов 145 KB
  В результате выполнения данной лабораторной работы я приобрёл навыки по автоматизации соседнего кодирования графа переходов автомата Мили. Соседнее кодирование реализовано по алгоритму, описаному выше...