Модели систем. Графы

Исследование эффективности алгоритма поиска в графе в ширину. Матрицы инциденций для графов. Анализ алгоритма поиска в графе. Основные входные и выходные данные, процедуры, их обозначение в листинге программы. Текст программы на языке TURBO PASCAL.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 26.04.2015
Размер файла 183,6 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

ГОСУДАРСТВЕННОЕ АВТОНОМНОЕ ПРОФЕССИОНАЛЬНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ САРАТОВСКОЙ ОБЛАСТИ

«САРАТОВСКИЙ ТЕХНИКУМ СТРОИТЕЛЬНЫХ ТЕХНОЛОГИЙ И СФЕРЫ ОБСЛУЖИВАНИЯ»

Специальность: 230115 - «Программирование в компьютерных системах»

КУРСОВАЯ РАБОТА

ПМ 03: Участие в интеграции программных модулей

Тема: Модели систем. Графы

Саратов, 2014 г.

Содержание

Введение

1. Основная часть

2. Анализ алгоритма

3. Спецификация задачи

3.1 Входные и выходные данные

3.2 Используемые процедуры

4. Программа на языке Turbo Pascal

4.1 Листинг программы

4.2 Контрольный пример для тестирования №1

4.3 Контрольный пример для тестирования №2

4.4 Руководство пользователя

5. Результаты тестирования

Заключение

Список используемой литературы

Приложение А

Введение

Термин «граф» впервые появился в работах венгерского математика Д.Кенига в 1936 году, хотя ряд задач по теории графов решался еще Л.Эйлером в XVIII веке.

Графы встречаются в сотнях разных задач, и алгоритмы обработки графов очень важны.

Существует множество разработанных алгоритмов для решения различных задач из самых разных областей человеческой деятельности. Формулировка задачи описывает, каким требованиям должно удовлетворять решение задачи, а алгоритм, решающий эту задачу, находит объект, этим требованиям удовлетворяющий.

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

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

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

Если заданная информационная вершина найдена, то происходит вывод об успешном окончании поиска, вывод времени поиска и времени поиска ключа. графа матрица программа pascal

В данной работе: 7 рисунков, 1 программа, 1 приложение, 35 листов.

Ключевые слова: граф, алгоритм, поиск, ширина, программа, аргумент, элемент, массив, очередь, память, время, сравнение.

Цель работы: Исследовать эффективность алгоритма поиска в графе в ширину.

Результат работы программы: количество сравнений элемента с ключом поиска и время, за которое был найден элемент по данному алгоритму поиска.

Область применение данного алгоритма может быть разнообразна, например, при построении карт местности: вершины графа - города, связи - дороги.

1. Основная часть

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

Будем рассматривать как ориентированные, так и неориентированные графы. Граф будем всегда обозначать G = (V,E), где V обозначает множество вершин, а Е -- множество ребер, причем Е V X V для ориентированного графа и Е{{х,у}: х,у V ? ху} для неориентированного графа. Будем также использовать обозначения |V| = n и |Е| = m.

В теории графов классическим способом представления графа служит матрица инциденций. Это матрица А с n строками, соответствующими вершинам, и m столбцами, соответствующими ребрам. Для ориентированного графа столбец, соответствующий дуге <x, y> E, содержит --1 в строке, соответствующей вершине х, 1 в строке, соответствующей вершине у, и нули во всех остальных строках (петлю, т. е. дугу вида <x, x>, удобно представлять иным значением в строке х, например, 2).

В случае неориентированного графа столбец, соответствующий ребру {х,у}, содержит 1 в строках, соответствующих х и у, и нули в остальных строках. Это проиллюстрировано на рисунке 1. С алгоритмической точки зрения матрица инциденций является, вероятно, самым худшим способом представления графа, который только можно себе представить. Во-первых, он требует nm ячеек памяти, причем большинство этих ячеек вообще занято нулями. Неудобен также доступ к информации. Ответ на элементарные вопросы типа «существует ли дуга <x,y>?», «к каким вершинам ведут ребра из х?» требует в худшем случае перебора всех столбцов матрицы, а, следовательно, m шагов.

Рисунок 1. а) Ориентированный граф и его матрица инциденций; б) Неориентированный граф и его матрица инциденций.

Лучшим способом представления графа является матрица смежности, определяемая как матрица В = [b*j] размера nхm, где bij = 1, если существует ребро, идущее из вершины х в вершину у, и bij = 0 в противном случае. Здесь мы подразумеваем, что ребро {х, у} неориентированного графа идет как от х к у, так и от у к х, так что матрица смежности такого графа всегда является симметричной. Это проиллюстрировано на рисунке 2.

Основным преимуществом матрицы смежности является тот факт, что за один шаг можно получить ответ на вопрос «существует ли ребро из х в y?». Недостатком же является тот факт, что независимо от числа ребер объем занятой памяти составляет n2. На практике это неудобство можно иногда уменьшить, храня целую строку (столбец) матрицы в одном машинном слове -- это возможно для малых n.

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

Пусть Р -- некоторое свойство графа P(G) = 0 или P(G)=1 в зависимости от того, обладает или не обладает G нашим свойством. Предположим, что свойство Р удовлетворяет следующим трем условиям:

(а) P(G)=P(G'), если графы G и G' изоморфны;

(б) P(G) = 0 для произвольного пустого графа <V,> и P(G)=1 для произвольного полного графа <V, P2(V)> с достаточно большим числом вершин;

Рисунок 2. Матрицы инциденций для графов на рисунке 1.

(в) добавление ребра не нарушает свойства Р, т. е. P(G)<P(G') для произвольных графов G=(F,E) и G'=(V, E'), таких что Е = Е'.

Примером такого свойства Р является существование цикла (в графе, имеющем, по крайней мере три вершины).

Теорема. Если Р -- свойство графа, отвечающее условиям (а), (б), (в), то каждый алгоритм, проверяющий свойство Р (т. е. вычисляющий значение P(G) для данного графа G) на основе матрицы смежности, выполняет в худшем случае Щ(n2) шагов, где n -- число вершин графа.

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

(г) P(G) = P(G') для произвольных ориентированных графов G = < V, E>, G' = < V, Е> U <v, v>>, v C V.

Более экономным в отношении памяти (особенно в случае, неплотных графов, когда m гораздо меньше n2) является метод представления графа с помощью списка пар, соответствующих его ребрам. Пара <x, у> соответствует дуге <х, у>, если граф ориентированный, и ребру {х, y} - в случае неориентированного графа.

Рисунок 3. Списки ребер соответствующие графам на рисунке 1.

Очевидно, что объем памяти в этом случае составляет 2n. Неудобством является большое число шагов -- порядка n в худшем случае, -- необходимое для получения множества вершин, к которым ведут ребра из данной вершины.

Ситуацию можно значительно улучшить, упорядочив множество пар лексикографически и применяя двоичный поиск, но лучшим решением во многих случаях оказывается структура данных, которую мы будем называть списками инцидентности. Она содержит для каждой вершины v C V список вершин и, таких что v -> u (или v -- и в случае неориентированного графа). Точнее, каждый элемент такого списка является записью u, содержащей вершину u. строка и указатель u. след на следующую запись в списке (u. след = nil для последней записи в списке). Начало каждого списка хранится в таблице НАЧАЛО; точнее, НАЧАЛО[v] является указателем на начало списка, содержащего вершины из множества {u: v+u} ({u: v - u} для неориентированного графа). Весь такой список обычно неформально будем обозначать 3AПИСЬ[v], а цикл, выполняющий определенную операцию для каждого элемента и из этого списка в произвольной, но четко установленной последовательности, соответствующей очередности элементов в списке, будем записывать «for u C ЗАПИСЬ [v] do ...».

Отметим, что для неориентированных графов каждое ребро {u, v} представлено дважды: через вершину v в списке ЗАПИСЬ[u] и через вершину u в списке ЗАПИСЬ[v]. Во многих алгоритмах структура графа динамически модифицируется добавлением и удалением ребер. В таких случаях полагаем, что в наших списках инцидентности элемент списка ЗАПИСЬ [u], содержащий вершину u, снабжен указателем на элемент списка 3AПИCЬ[v], содержащий вершину u, и что каждый элемент списка содержит указатель не только к следующему элементу, но и к предыдущему. Тогда удаляя некоторый элемент из списка, можем легко за число шагов, ограниченное константой, удалить другой элемент, представляющий то же самое ребро, не просматривая список, содержащий этот элемент.

Аналогичным способом определяем для каждой вершины и неориентированного графа список ПРЕДШ[v], содержащий вершины из множества (u: u -> v).

Число ячеек памяти, необходимое для представления графа с помощью списков инцидентности, будет, очевидно, иметь порядок m + n. На рисунке 4 представлены списки инцидентности, соответствующие графам на рисунке 1.

Рисунок 4. Списки инцидентности ЗАПИСЬ[v], v =V, соответствующие графам на рисунке 1.

2. Анализ алгоритма

Рассмотрим метод поиска в графе, называемый поиском в ширину (англ.: breadth first search). Прежде чем описать его, отметим, что при поиске в глубину, чем позднее будет посещена вершина, тем раньше она будет использована -- точнее, так будет при допущении, что вторая вершина посещается перед использованием первой. Это прямое следствие того факта, что просмотренные, но еще не использованные вершины скапливаются в стеке. Поиск в ширину, грубо говоря, основывается на замене стека очередью. После такой модификации, чем раньше посещается вершина (помещается в очередь), тем раньше она используется (удаляется из очереди). Использование вершины происходит с помощью просмотра сразу всех еще не просмотренных соседей этой вершины. Вся процедура поиска представлена ниже (данная процедура используется также и для просмотра графа, и в псевдокоде, описанном ниже, отсутствуют операторы, которые не используются для поиска).

1 procedure WS (v);

(*поиск в ширину в графе с началом в вершине v;

переменные НОВЫЙ, ЗАПИСЬ -- глобальные *)

2 begin

3 ОЧЕРЕДЬ := ?; ОЧЕРЕДЬ <= v; НОВЫЙ [v] := ложь

4 while ОЧЕРЕДЬ ? ? do

5 begin р<= ОЧЕРЕДЬ; посетить р;

6 for u ? ЗАПИСЬ [р] do

7 if НОВЫЙ [u] then

8 begin ОЧЕРЕДЬ <= u; НОВЫЙ [u]:=ложь

9 end

10 end

11 end

Примечание: в 7-й строке псевдокода кроме условия НОВЫЙ[u] должно также выполниться условие наличия связи (ребра) между v-й и u-й вершинами. Для установки наличия ребра сначала в списке v-й вершины ищется информационное значение u-й вершины. Если оно найдено, то ребро установлено, если нет, то информационное значение v-й вершины ищется в списке u-й вершины, т.е. наоборот. В результате добавления двух лишних циклов поиска общий алгоритм поиска несколько теряет компактность, но на быстродействии в целом это не сказывается.

1 procedure Write_S;

2 begin

3 for v ? V do НОВЫЙ[u]:= истина; (* инициализация *)

4 for v ? V do

5 if HOBЫЙ[v] then WG(v)

6 end

Способом, аналогичным тому, какой был применен для поиска в глубину, можно легко показать, что вызов процедуры WS(v) приводит к посещению всех вершин связной компоненты графа, содержащей вершину v, причем каждая вершина просматривается в точности один раз. Вычислительная сложность поиска в ширину также имеет порядок О(m + n), так как каждая вершина помещается в очередь и удаляется из очереди в точности один раз, а число итераций цикла 6, очевидно, будет иметь порядок числа ребер графа.

В очереди помещены сначала вершины, находящиеся на расстоянии 0 от v (т. е. сама вершина v), затем поочередно все новые вершины, достижимые из v, т. е. вершины, находящиеся на расстоянии 1 от v, и т. д. Под расстоянием здесь мы понимаем длину кратчайшего пути. Предположим теперь, что уже рассмотрели все вершины, находящиеся на расстоянии, не превосходящем r, от v, что очередь содержит все вершины, находящиеся от v на расстоянии r, и только эти вершины. Использовав каждую вершину р, находящуюся в очереди, наша процедура просматривает некоторые новые вершины, и каждая такая новая вершина u находится, очевидно, на расстоянии г + 1 от v. После использования всех вершин из очереди, находящихся на расстоянии r от v, она (очередь), очевидно, содержит множество вершин, находящихся на расстоянии r + 1 от v, и легко заметить, что условие индукции выполняется и для расстояния r + 1.

На рисунке 5 представлен граф, вершины которого занумерованы согласно очередности, в которой они посещаются в процессе поиска в глубину.

Как и в случае поиска в глубину, процедуру WS можно использовать без всяких модификаций и тогда, когда списки инцидентности ЗАПИСЬ[v], v = V, определяют некоторый ориентированный граф. Очевидно, что тогда посещаются только те вершины, до которых существует путь от вершины, с которой мы начинаем поиск.

Размещено на http://www.allbest.ru/

Рисунок 5. Нумерация вершин графа (в скобках), соответствующая очередности, в которой они просматриваются в процессе поиска в ширину.

3. Спецификация задачи

3.1 Входные и выходные данные

ver - массив вершин графа, заполняемый случайным образом целыми числами в диапазоне от 0 до 1000;

nv - массив флагов проверки вершин;

ocher - массив для организации очереди, заполняемой значениями рассматриваемых информационных вершин графа;

raz - переменная целочисленного типа, определяющая в программе размер создаваемого графа;

schet - счетчик количества сравнений в процедуре поиска;

key - вводимый с клавиатуры ключ поиска;

mgsi - переменная логического типа, разрешающая вывод списка инцидентности графа;

prosm - переменная логического типа, превращающая процедуру поиска WS в процедуру просмотра графа;

find - переменная логического типа, определяемая при нахождении искомой информационной вершины;

craz, menu, mg, sormen - переменные символьного типа для работы с меню программы.

3.2 Используемые процедуры

Make_Graph - процедура создания графа в динамической памяти;

WS - процедура просмотра графа с v-той вершины методом поиска в ширину;

Write_S - процедура инициализации признаков просмотра вершин и управляющая процедурой WS;

Sort - процедура сортировки вершин графа по неубыванию.

4. Текст программы на языке TURBO PASCAL

4.1 Листинг программы

{$S+} {$R+} {$I+} {$M 65520,0,655360}

program graph;

uses crt,newtimer;

const

maxraz=400;

type index=^list;

list= record

inf: word;

next: index;

end;

connection=array[1..maxraz] of index;

var

el,em,size: pointer;

lst,m: connection;

ver: array[1..maxraz] of word; {массив вершин}

Nw: array[1..maxraz] of boolean;

ocher: array[1..maxraz+1] of integer;

raz: integer;

exch,fil,i,j,l,schet,v,u,p: word;

key,kols,t,tm: longint;

mgsi,mem,sor,prosm,find: boolean;

craz,menu,mg,sormen:char;

{------------------------------------------------------

***Процедура создания графа в динамической памяти***}

procedure Make_Graph(mgsi: boolean);

label Er;

var

n: index;

i,j: word;

kolvo: longint;

spro: boolean;

begin

randomize;

for i:=1 to raz do begin

ver[i]:=random(1000);

end;

kolvo:=0;

for i:=1 to raz do begin

lst[i]:=nil;

for j:=1 to raz do begin

spro:=true;

if j=raz then goto Er;

if j=i then inc(j);

n:=nil;

n:=lst[j];

if lst[j]<>nil then

repeat

if n^.inf=ver[i] then spro:=false;

n:=n^.next;

until (n=nil) or (not(spro));

if (round(random)=1) and spro then

begin

new(m[i]);

inc(kolvo);

m[i]^.inf:=ver[j];

m[i]^.next:=lst[i];

lst[i]:=m[i];

end;

Er:

end;

end;

writeln;

if mgsi then {ВЫВОД СВЯЗЕЙ ВЕРШИН}

for i:=1 to raz do {}

begin {}

write(ver[i],'-'); {}

m[i]:=lst[i]; {}

if m[i]<>nil then {}

repeat {}

write(m[i]^.inf,'='); {}

m[i]:=m[i]^.next; {}

until m[i]=nil; {}

writeln('_'); writeln; {}

end; {}

writeln('КОЛ-ВО РЕБЕР СОЗДАННОГО ГРАФА: ',kolvo);

end;

{------------------------------------------------------

***Процедура просмотра графа с v-той вершины методом поиска в ширину***}

Procedure WS(v:word; var find: boolean;

var schet: word);

var {v - пор. номер вершины графа}

ik,oo,o9,o3,op: integer;

rebro: boolean;

begin {оо - размер очереди в данном цикле}

ocher[1]:=v; oo:=1; {вставка текущего индекса вершины в начало очереди}

Nw[v]:=False; {флаг на вершину текущего индекса}

while oo>0 do begin {пока есть очередь...}

p:=ocher[1];{удаление 1-го элемента из очереди и присваивание его p}

for op:=1 to oo-1 do ocher[op]:=ocher[op+1]; ocher[oo]:=0;

dec(oo);

inc(schet); {счетчик сравнений}

if not(prosm) and (ver[p]=key) then {if ver[p]=key...}

begin

find:=true;

exit; {поиск окончен} end;

{вывод (просмотр) информации вершины}

if prosm then begin

if wherex>=79 then writeln;

write(ver[p],' ');

end;

o9:=oo;

for u:=1 to o9 do {u изменяется в диапазоне размера очереди}

begin

rebro:=false;{связи между ver[v] и ver[u] нет}

{указатель на начало списка связей v-й вершины}

m[v]:=lst[v];

while m[v]<>nil do

begin {поиск значения ver[u] в списке связей v-й вершины}

if m[v]^.inf=ver[u] then begin

{ребро есть} rebro:=true;

break;

end;

m[v]:=m[v]^.next; {ребра пока нет...}

end;

{если связь не установлена, поищем связь с ver[v] в списке u-й вершины, т.е. наоборот...}

if not(rebro) then

begin

m[u]:=lst[u];{указатель на начало списка связей u-й вершины}

while m[u]<>nil do

begin if m[u]^.inf=ver[v] then begin

rebro:=true;

break;

end;

m[u]:=m[u]^.next;

end;

end;

{если связь все таки есть и u-я вершина еще не рассмотрена...}

if rebro and Nw[u] then

begin

inc(oo); {вставка u в начало очереди}

for op:=oo downto 2 do ocher[op]:=ocher[op-1];

ocher[1]:=u;

Nw[u]:=False;{флаг на вершину с индексом u}

end;

end;

end;

end;

{------------------------------------------------------

***Процедура просмотра графа***}

Procedure Write_S(key: longint; prosm: boolean;

var find: boolean; var schet: word);

begin

{инициализация признаков просмотра вершин}

for i:=1 to raz do Nw[i]:=true;

for i:=1 to raz do

{если из raz вершин i-ая не использована, то смотреть граф с i-ой вершины}

if Nw[i] and not(find) then WS(i,find,schet);

end;

{------------------------------------------------------

***Процедура сортировки вершин по неубыванию***}

procedure Sort;

begin

for l:=1 to raz-1 do

for j:=1 to raz-l do

if ver[j]>ver[j+1] then

begin

exch:=ver[j];

el:=lst[j];

em:=m[j];

ver[j]:=ver[j+1];

lst[j]:=lst[j+1];

m[j]:=m[j+1];

ver[j+1]:=exch;

lst[j+1]:=el;

m[j+1]:=em;

end;

end;

{=====================================================}

begin

while menu<>'4' do

begin

textmode(1);

textbackground(blue);

clrscr;

textcolor(red);

gotoxy(16,3); writeln('Г Р А Ф Ы');

textcolor(white);gotoxy(5,5);

writeln('* Исследование поиска в ширину *');

textcolor(black); gotoxy(7,22);

writeln('Created by Andrew Spikhailo');

gotoxy(15,24); write('ARMAVIR 2001');

textcolor(white);

gotoxy(7,10); write('------------MENU-----------¬');

gotoxy(7,11); write('¦');textcolor(green);

write('1 Создание графа '); textcolor(white);write('¦');

gotoxy(7,12); write('¦');textcolor(green);

write('2 Просмотр графа '); textcolor(white);write('¦');

gotoxy(7,13); write('¦');textcolor(green);

write('3 Поиск элемента графа '); textcolor(white);write('¦');

gotoxy(7,14); write('¦');textcolor(green);

write('4 Выход '); textcolor(white);write('¦');

gotoxy(7,15); write('¦');textcolor(white+128);

write('Выберите номер пункта меню'); textcolor(white);write('¦');

gotoxy(7,16); write('L==========================-');

menu:=readkey;

case menu of

'1': begin

{освобождение памяти, если она была занята}

textmode(2);

textbackground(blue);

clrscr; textcolor(lightgreen);

if mem then release(size);

repeat

clrscr;

write('Число вершин графа: ');

writeln('(1) - десять');

gotoxy(21,wherey);

writeln('(2) - сто');

gotoxy(21,wherey);

writeln('(3) - четыреста');

gotoxy(21,wherey);

write('(4) - другое...');

raz:=0;

repeat

craz:=readkey;

case craz of

'1': raz:=10;

'2': raz:=100;

'3': raz:=400;

'4': begin

write(' ___');

gotoxy(wherex-3,wherey);

read(raz);

if (raz<=0) or (raz>400) then begin

raz:=0;

gotoxy(38,wherey-1);

write('ERROR...');

delay(1000);

end;

end;

end;

until (craz='1') or (craz='2') or (craz='3') or (craz='4');

clrscr;

until raz>0;

writeln;

write('вывод списка инцидентности графа: ');

writeln('0 - запретить');

gotoxy(35,wherey);

write('1 - разрешить');

mg:=readkey;

if mg='1' then mgsi:=true

else mgsi:=false;

clrscr;

mark(size);

Make_Graph(mgsi);

mem:=true;{теперь память можно освобождать}

sor:=false; {вершины не отсортированы}

readkey;

end;

'2': begin {Просмотр графа }

textmode(2);

textbackground(blue);

clrscr; textcolor(lightgreen);

gotoxy(32,3); Writeln('Просмотр графа:');

key:=-1;

find:=false;

prosm:=true; schet:=0;

Write_S(key,prosm,find,schet); writeln;

readkey;

end;

'3': begin {Поиск элемента графа}

clrscr; textcolor(lightgreen);

if not(sor) then begin

writeln('Отсортировать вершины по неубыванию?');

writeln(' 1-ДА');

writeln(' 2-НЕТ');

sormen:=readkey;

if sormen='1' then begin

Sort;

sor:=true;

end;

end;

prosm:=false;

write('Что будем искать : ');

readln(key); writeln;

start(t);

kols:=0;

for fil:=1 to 10000 do

begin

schet:=0;

find:=false;

Write_S(key,prosm,find,schet); {поиск в ширину}

kols:=kols+schet;

end;

stop(t);

if not(find) then write('К сожалению такой вершины нет...')

else begin

writeln('Вершина графа ',ver[p],' найдена!');

writeln('Количество сравнений: ',kols/10000:5:1);

report('Время поиска вершины',t);

end;

readkey;

end;

end;

end;

end.

4.2 Контрольный пример для тестирования №1

Количество вершин графа - 5, ребра между ними формируются случайным образом.

Список инцидентности созданного графа:

74 497-174-§

174 §

55 497-§

497 §

661 497-§

КОЛ-ВО РЕБЕР СОЗДАННОГО ГРАФА: 4

Содержание информационных вершин: 74 174 55 497 661

Примечание: символ «§» соответствует концу списка (nil).

Полученный граф изображен на рисунке 6

Рисунок 6 - Результат теста

4.3 Контрольный пример для тестирования №2

Количество вершин графа - 7, ребра между ними формируются случайным образом.

Список инцидентности созданного графа:

704 66-373-434-§

434 373-§

766 706-373-434-§

373 66-§

66 §

706 66-704-§

454 706-66-373-§

КОЛ-ВО РЕБЕР СОЗДАННОГО ГРАФА: 13

Содержание информационных вершин: 704 434 766 373 66 706 454

Примечание: символ «§» соответствует концу списка (nil).

Полученный граф изображен на рисунке 7

Рисунок 7- Результат теста 2.

4.4 Руководство пользователя

При запуске программы на экране появляется основное меню программы, которое состоит из четырех пунктов:

1. Создание графа

2. Просмотр графа

3. Поиск элемента графа

4. Выход.

Выбор интересующего пункта осуществляется с помощью клавиш «1», «2», «3» и «4».

а) «Создание графа»

Выбрав пункт «Создание графа», на экране появится меню выбора количества вершин графа: 10, 100, 400 и другое.

Нажав клавишу с порядковым номером пункта меню, Вы выберете необходимое количество вершин. Далее, нажав клавишу 1, Вы разрешите программе вывести на экран список инцидентности графа, а нажав 0 - запретите.

б) «Просмотр графа»

При выборе пункта «Просмотр графа», на экране появится список информационных вершин созданного графа.

в) «Поиск элемента графа»

При выборе пункта «Поиск элемента графа» на экране сначала появляется запрос на сортировку информационных вершин. Затем Вам предстоит задать элемент поиска в графе, после чего при удачном поиске на экран будет выведено время поиска и среднее количество сравнений. Время поиска вычисляется с помощью процедур Start,Stop и Report, описанных в модуле Newtimer. Листинг модуля Newtimer описан в Приложении А.

г) «Выход»

При выборе пункта «Выход» программа прекращает свою работу.

5. Результаты тестирования

Исследуем результаты работы программы, для чего сначала измерим время поиска для трех графов из 100, 200 и 400 элементов, отсортированных в порядке возрастания и не отсортированных и сравним полученные результаты.

Количество информационных вершин - 10, вершины не отсортированы, их содержание:

97 920 635 286 590 938 981 716 427 474

Что будем искать: 427

Вершина графа 427 найдена!

Количество сравнений: 9.0

Момент запуска: 23:53:46.50

Момент остановки: 23:53:46.66

Время поиска вершины: 0.00001 cek.

Количество информационных вершин - 10, вершины отсортированы, их содержание:

32 192 234 243 297 324 775 804 982 986

Что будем искать: 192

Вершина графа 192 найдена!

Количество сравнений: 2.0

Момент запуска: 23:55:28.33

Момент остановки: 23:55:28.44

Время поиска вершины: 0.00001 cek.

Количество информационных вершин - 100, вершины не отсортированы, их содержание:

575 128 905 777 923 75 716 446 477 627 70 591 250 555 111 208 315 417 309 723 963 250 561 966 790 982 965 446 228 1 344 446 237 552 912 756 142 875 665 83 863 265 369 427 0 476 253 987 537 135 768 374 117 86 12 204 149 849 694 332 219 600 738 310 532 358 882 844 394 285 899 302 940 293 276 569 607 350 478 806 95 190 153 891 774 322 876 605 798 525 310 851 399 246 876 464 91 567 308 386

Что будем искать: 293

Вершина графа 293 найдена!

Количество сравнений: 74.0

Момент запуска: 23:58:09.98

Момент остановки: 23:58:11.08

Время поиска вершины: 0.00010 cek.

Количество информационных вершин - 100, вершины отсортированы, их содержание:

0 1 12 70 75 83 86 91 95 111 117 128 135 142 149 153 190 204 208 219 228 237 246 250 250 253 265 276 285 293 302 308 309 310 310 315 322 332 344 350 358 369 374 386 394 399 417 427 446 446 446 464 476 477 478 525 532 537 552 555 561 567 569 575 591 600 605 607 627 665 694 716 723 738 756 768 774 777 790 798 806 844 849 851 863 875 876 876 882 891 899 905 912 923 940 963 965 966 982 987

Что будем искать: 293

Вершина графа 293 найдена!

Количество сравнений: 30.0

Момент запуска: 23:59:08.14

Момент остановки: 23:59:08.80

Время поиска вершины: 0.00006 cek.

Количество информационных вершин - 400, вершины не отсортированы, их содержание:

963 663 915 353 650 103 540 531 548 338 960 515 143 963 765 42 822 188 102 85 361 193 137 582 756 241 325 234 400 482 104 416 826 611 874 500 505 805 365 134 436 606 755 278 513 684 151 42 895 633 291 621 873 249 566 877 965 925 747 359 220 126 991 823 970 79 18 524 513 127 551 851 462 403 375 88 739 754 645 357 457 82 274 23 171 523 537 131 227 148 231 657 201 88 12 620 660 273 759 359 725 191 88 517 178 361 361 527 92 412 803 656 220 967 597 889 625 740 50 219 289 519 202 120 687 957 483 263 554 353 273 769 330 825 486 546 26 566 520 501 487 96 201 682 288 677 570 647 745 329 619 594 787 100 348 70 661 523 736 286 699 434 505 345 659 558 767 930 339 559 923 246 477 449 428 262 152 551 269 552 182 421 277 286 252 408 624 157 746 782 119 302 534 581 163 506 184 622 470 239 341 330 908 326 255 318 89 294 696 884 536 687 729 849 570 903 100 412 251 359 207 930 994 3 888 816 722 499 517 955 649 619 145 328 80 633 657 752 805 761 195 920 978 963 318 152 560 634 643 533 715 982 950 369 742 156 980 111 421 401 411 194 876 797 756 449 306 387 158 3 213 719 314 861 968 122 21 570 826 242 79 648 768 660 520 702 755 610 420 391 267 114 759 683 235 77 71 46 722 136 875 526 966 306 108 858 644 729 54 46 460 71 499 85 428 356 103 737 445 289 210 538 31 371 595 466 328 342 874 924 727 757 563 981 730 734 23 18 911 181 769 228 73 43 886 626 977 359 527 483 236 196 741 382 250 731 95 291 273 51 843 342 988 453 621 228 190 296 897 399 438 703 663 466 789 656 110 504 964 289 260 154 570 413 796 709

226 583 573 611 701 244 544 10 436 759 86 333 44 364

Что будем искать: 228

Вершина графа 228 найдена!

Количество сравнений: 342.0

Момент запуска: 00:03:13.99

Момент остановки: 00:03:18.83

Время поиска вершины: 0.00048 cek.

Количество информационных вершин - 400, вершины отсортированы, их содержание:

3 3 10 12 18 18 21 23 23 26 31 42 42 43 44 46 46 50 51 54 70 71 71 73 77 79 79

80 82 85 85 86 88 88 88 89 92 95 96 100 100 102 103 103 104 108 110 111 114 119 120 122 126 127 131 134 136 137 143 145 148 151 152 152 154 156 157 158 163 171 178 181 182 184 188 190 191 193 194 195 196 201 201 202 207 210 213 219 220 220 226 227 228 229 231 234 235 236 239 241 242 244 246 249 250 251 252 255 260 262 263 267 269 273 273 273 274 277 278 286 286 288 289 289 289 291 291 294 296 302 306 306 314 318 318 325 326 328 328 329 330 330 333 338 339 341 342 342 345 348 353 353 356 357 359 359 359 359 361 361 361 364 365 369 371 375 382 387 391 399 400 401 403 408 411 412 412 413 416 420 421 421 428 428 434 436 436 438 445 449 449 453 457 460 462 466 466 470 477 482 483 483 486 487 499 499 500 501 504 505 505 506 513 513 515 517 517 519 520 520 523 523 524 526 527 527 531 533 534 536 537 538 540 544 546 548 551 551 552 554 558 559 560 563 566 566 570 570 570 570 573 581 582 583 594 595 597 606 610 611 611 619 619 620 621 621 622 624 625 626 633 633 634 643 644 645 647 648 649 650 656 656 657 657 659 660 660 661 663 663 677 682 683 684 687 687 696 699 701 702 703 709 715 719 722 722 725 727 729 729 730 731 734 736 737 739 740 741 742 745 746 747 752 754 755 755 756 756 757 759 759 759 761 765 767 768 769 769 782 787 789 796 797 803 805 805 816 822 823 825 826 826 843 849 851 858 861 873 874 874 875 876 877 884 886 888 889 895 897 903 908 911 915 920 923 924 925 930 930 950 955 957 960 963 963 963 964 965 966 967 968 970 977 978 980 981 982 988 991 994

Что будем искать: 228

Вершина графа 228 найдена!

Количество сравнений: 93.0

Момент запуска: 00:04:21.33

Момент остановки: 00:04:23.58

Время поиска вершины: 0.00022 cek.

Как показал эксперимент, сортировка информационных вершин графа влияет на время поиска элемента методом просмотра в ширину в графе. Уменьшается количество сравнений, что также повышает быстродействие алгоритма. Однако это существенно повышает эффективность алгоритма только при намного большем количестве вершин, чем в произведенных опытах.

Время поиска даже при максимально возможном количестве вершин (400) настолько мало, что засечь его не представляется возможным. Поэтому процесс поиска повторяется 10000 раз. Точное время вычисляется в подключенном модуле Newtimer по формуле:

T=Q/n , где

Q- общее время поиска;

n - количество циклов поиска (10000).

Полученное время практически не заметно, так как исследовались графы небольшой размерности, но если графы будут размерности более чем 1 миллиард вершин, то время будет ощутимо. И можно получить выгоду из алгоритма поиска в ширину, если использовать его сразу для максимального количества элементов, а не несколько раз, но используя немного элементов.

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

Заключение

Современное состояние и тенденции развития вычислительной техники как основного инструмента информатики таковы, что наряду с увеличением функциональности вычислительная техника приобретает свойства, позволяющие работать на ней пользователю, не разбирающемуся в программировании. В этот период появился более качественный интерфейс программ. Появились структуры графических данных и более крупные, интегральные информационные единицы - объекты. Следствием стало бурное развитие объектно-ориентированных систем программирования, таких как Visual C++, Visual BASIC и других, в основе которых лежит обработка объектных структур данных. Также появились новые языки программирования ADA, OCCAM.([3]) И если раньше большой популярностью пользовались простые линейные алгоритмы, то в настоящее время алгоритмы таких типов как деревья, графы, списки, очереди - получают все большее распространение.

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

Таким образом, развитие информационных технологий, их проникновение во все области жизнедеятельности человека требуют компьютерного отображения информации в виде соответствующих структур данных. И графы, являясь одной из частей этих структур данных, играют важную роль в современном программировании, графы встречаются в сотнях разных задач.

Список литературы

1. Вирт Н. Алгоритмы и структуры данных.- М.: Мир, 1989.

2. Кнут Д. Искусство программирования для ЭВМ. - В 7 т. - М.: Мир, 1876.

3. Лойко В.И. Структуры и алгоритмы данных ЭВМ: Курс лекций для спец. 220400 - Краснодар: КубГТУ, 1998.

4. Марченко А.И., «Программирование в среде «Turbo Pascal 7.0», «Век+», Киев 1999 г.

Приложение А

Листинг модуля Newtimer

unit newtimer;

interface

procedure start(var x: longint); {определяет время начала работы}

procedure stop(var x: longint); {определяет время окончания работы}

procedure format(hour, min, sec, hund: word);

procedure Report(Msg:string; x:longint);

implementation

uses dos;

var

hour_start, min_start, sec_start, hund_start,

hour_stop, min_stop, sec_stop, hund_stop,

hour, min, sec, hund: word;

systimer : longint absolute $0040 : $006c;

procedure start;

begin

gettime(hour_start, min_start, sec_start, hund_start);

x:=systimer;

while x=systimer do; {ожиание момента изменения таймера}

x:=systimer;

end;

procedure stop;

begin

gettime(hour_stop, min_stop, sec_stop, hund_stop);

x:=systimer-x;

end;

procedure format;

procedure print(w: word);

begin

if w<10 then write('0');

write(w);

end;

begin

print(hour); write(':');

print(min); write(':');

print(sec); write('.');

print(hund);

writeln;

end;

procedure Report;

{Вывод на печать измеренного интервала в секундах и

сообщения через переменную Msg}

begin

write('Момент запуска: ');

format(hour_start, min_start, sec_start, hund_start);

write('Момент остановки: ');

format(hour_stop, min_stop, sec_stop, hund_stop);

writeln(msg,' : ',x/182000:5:5,' cek.'); end; end.

Поиск в глубину

Идея поиска в глубину формулируется следующим образом: начиная с некоторой вершины (например, первой) идем «вглубь» пока это возможно. Далее выбирается вершина u, смежная с v. Процесс повторяется с вершиной u. Если на очередном шаге оказалось что нет непросмотренных вершин связанных с текущей, то выполняется возврат к предыдущей вершине и ищется новая вершина, связанная с ней. Если такой вершины не найдено, то выполняется еще один шаг возврата к предыдущей вершине, и так до тех пор, пока вычислительный процесс не вернется к вершине, с которой начат просмотр.

Для графа приведенного на рис. 8, очередность просмотра вершин при поиске в глубину указана в круглых скобках рядом с вершинами. Просмотр начат с первой вершины и приведена только часть ребер графа, по которым выполнялся следующий шаг поиска.

Рисунок 8. Очередность просмотра вершин при поиске в глубину.

При реализации поиска используется второй способ представления графа-перечень списков смежных вершин. Описание элементов списка очевидно. Для хранения значений указателей на первые элементы списков для каждой вершины графа используется массив А. номера вершин записываются в массив Rez в той очередности, в которой они просматриваются в процессе поискав глубину (рис. 8 числа в круглых скобках). Для фиксации признака, просмотрена вершина графа или нет , требуется массив Nnew с элементами логического типа.

Program Graph_Deths;

Const MaxN=10;

Type pt=^elem;

Elem=Record

data:integer;

next:pt

End;

MyArray=Array [1...MaxN] Of pt;

MyNew=Array [1...MaxN] Of Boolean;

MyRez=Array [1...MaxN] Of Integer;

Var A:MyArray;

{*Массив указателей на первые элементы списков.*}

Nnew:MyNew;

{*Массив признаков просмотренных вершин графа.*}

Rez:MyRez;

{*Очередность просмотра вершин графа*}

N, cnt:Integer;

{ *Количество вершин в гарфе. Счетчик числа записей в массив Rez.*}

Procedure Insert_List_End (Var t:pt;x:Integer);

{* Вставка элемента в конец списка. Процедура рассмотрена на предыдущих занятиях.*}

Procedure Init; { *Ввод и инициализация данных. Структура входного файла: в первой строке количество вершин графа (N); затем N строк, по одной на каждую из вершин графа. Первое число в строке-количество ребер выходящих из вершины, а затем номера вершин, с которыми связана текущая вершина. Справа по тексту приведен пример входного файладля графа, рассмотренного ранее.*}

Var i,j,w,q:Integer;

Begin

Cnt:=0;

Assign (Input.'Input.txt'); Reset (Input);

Readln (N); {*количество вершин графа*}

For i:=1 To N Do

Begin

A[i]:=Nil; Nnew [i]:=True; Rez [i]:=0

End;

For i:=1 To N Do

Begin

Read (q);

{* Степень вершины графа-число ребер, связанных с данной вершиной.*}

For j:=1 To q Do

Begin

Read (w);

Insert_List_End (A[i],w)

End;

End;

Close (Input);

End;

Procedure Inc_Rez (v:Integer);

Begin

Inc (cnt); Rez [cnt]:=v;

End;

Procedure Search_Depths (v:Integer);

{* Рекурсивный вариант процедуры поиска в глубину.*}

Var t:pt;

Begin

Nnew [v]=False;

{* Помечаем вершину как просмотренную.*}

While t<>Nil Do

Begin

If Nnew [t^.data] Then

Begin

{* если вершина не просмотрена, то записываем ее номер в результирующий массив и идем `вглубь', т.е. к этой вершине.* }

Inc_Rez (t^.data);

Search_Depths (t^.data);

End;

t:=t^.next;

{* Переход к следующему элементу списка.*}

End;

End;

Procedure Print; {* Вывод результата.* }

Var i:Integer;

Begin

Assign (Output, `Output.txt'); ReWritw (Output);

For i:=1 To N Do Write (Rez[i], ` `);

Writeln;

Close (Output);

End;

Begin {* Один из вариантов основной программы.*}

Init;

Inc_Rez (1);

Search_Depths (1);

Print;

End.

Рассмотрена рекурсивная реализация поиска в глубину. Уход от рекурсии требует введения стека для запоминания просмотренных вершин. Последняя запомненная вершина должна первой выбираться на последующую обработку.

DRAM (Dynamic random access memory, Динамическая память с произвольным доступом) -- тип энергозависимой полупроводниковой памяти с произвольным доступом; DRAM широко используемая в качестве оперативной памяти современных компьютеров, а также в качестве постоянного хранилища информации в системах, требовательных к задержкам.

Язык программирования Оккам (англ. Occam) -- это процедурный язык параллельного программирования высокого уровня, разработанный в начале 80-х годов группой учёных из Оксфорда под руководством Дэвида Мэя (англ. David May) по заданию английской компании INMOS Ltd. в рамках работ по созданию транспьютеров. Назван в честь английского философа XIV века Уильма Оккамского, а его сентенция, известная как бритва Оккама, является девизом проекта.

Размещено на Allbest.ru

...

Подобные документы

  • Разработка алгоритма реализации на ЭВМ процесса поиска кратчайшего пути в графе методом Дейкстры. Программная реализация алгоритма поиска кратчайшего пути между двумя любыми вершинами графа. Проверка работоспособности программы на тестовых примерах.

    реферат [929,8 K], добавлен 23.09.2013

  • Разработка программы, находящей эйлеров путь в графе с количеством вершин n от 2 до 20. Входные и выходные данные. Алгоритм поиска эйлерова пути с возвратом массива, содержащего результат. Описание модулей. Проектирование тестов методами черного ящика.

    курсовая работа [89,9 K], добавлен 25.02.2012

  • Графы: определения, примеры, способы изображения. Смежные вершины и рёбра. Путь в ориентированном и взвешенном графе. Матрица смежности и иерархический список. Алгоритм Дейкстры - алгоритм поиска кратчайших путей в графе. Работа в программе "ProGraph".

    презентация [383,8 K], добавлен 27.03.2011

  • Программа на языке Turbo Pascal для шифрования данных с помощью шифра Тритемиуса. Входные, выходные данные. Схема алгоритма и текст программы. Порядок ввода исходных данных и описание получаемых результатов. Тестовых задания и анализ их функционирования.

    курсовая работа [4,0 M], добавлен 06.01.2011

  • Разработка программного продукта для поиска максимально удалённых вершин в графе. Характеристика ориентированного, смешанного и изоморфного графов. Обзор способов представления графа в информатике. Алгоритм поиска пути. Графический интерфейс программы.

    курсовая работа [384,0 K], добавлен 10.01.2015

  • Понятие алгоритма как набора инструкций, описывающего порядок действий. Поиск в ширину - метод обхода графа и поиска пути в нем. Пример работы алгоритма поиска в ширину, его неформальное и формальное описание. Реализация с помощью структуры "очередь".

    курсовая работа [684,8 K], добавлен 05.04.2015

  • Решения задачи графическим и программным способами. Описание алгоритма решения графическим способом, укрупненная схема алгоритма. Ввод элементов двумерного массива, вывод преобразованного массива, разработка программы на языке pascal, листинг программы.

    курсовая работа [115,5 K], добавлен 22.05.2010

  • Особенности и преимущества языка C#. Алгоритмы поиска маршрутов в графе. Разработка вычислительной системы транспортной логистики на языке C#. Выбор среды разработки, визуализация транспортной сети. Задание условий поиска и пример работы алгоритма.

    дипломная работа [457,1 K], добавлен 24.06.2015

  • Описание алгоритма решения задачи по вычислению суммы элементов строк матрицы с использованием графического способа. Детализация укрупненной схемы алгоритма и разработка программы для решения задачи в среде Turbo Pascal. Листинг и тестирование программы.

    курсовая работа [446,0 K], добавлен 19.06.2014

  • Составление программы на алгоритмическом языке Turbo Pascal. Разработка блок-схемы алгоритма её решения. Составление исходной Pascal-программы и реализация вычислений по составленной программе. Применение методов Рунге-Кутта и Рунге-Кутта-Мерсона.

    курсовая работа [385,0 K], добавлен 17.09.2009

  • Этапы процедуры принятия решений. Разработка математического алгоритма. Блок-схема алгоритма работы программы. Разработка программы на языке программирования С++ в среде разработки MFC. Текст программы определения технического состояния станка с ЧПУ.

    курсовая работа [823,0 K], добавлен 18.12.2011

  • Описание методов вычисления определителя матрицы. Математическое решение задачи с применением метода исключения Гаусса с выбором главного элемента. Схема алгоритма программы, описание переменных и структур данных, текст программы на языке Pascal.

    курсовая работа [438,8 K], добавлен 16.02.2011

  • Программирование и структура программы на языке Turbo Pascal и MS Visual C++6.0. Вычисление площади круга. Реализация программы в системе Turbo Pascal и MS VISUAL C++6.0 для Windows. Структура окна ТРW. Сохранение текста программы в файле на диске.

    лабораторная работа [3,7 M], добавлен 22.03.2012

  • Теория графов и её применения. Разработка программного продукта для решения задач нахождения минимального пути. Анализ надежности и качества ПП "метода Дейкстры". Математическая модель задачи. Алгоритмы Дейкстры на языке программирования Turbo Pascal.

    курсовая работа [1,6 M], добавлен 26.03.2013

  • Особенности поиска среднеарифметического значения элементов массива. Общая характеристика проблем разработки в среде Turbo Pascal программы упорядочивания массива по возрастанию. Рассмотрение основных этапов разработки программы на языке PASCAL.

    курсовая работа [896,7 K], добавлен 18.05.2014

  • Разработка и тестирование программы на языке Pascal для поиска, вывода на экран и сохранения в файл списка книг с фамилиями авторов в алфавитном порядке, изданных после 2012 года. Разработка алгоритма и его описание. Инструкции по эксплуатации приложения.

    курсовая работа [903,0 K], добавлен 13.06.2013

  • Оценка погрешности и точности в математике. Составление программы и алгоритма для численного дифференцирования с заданной допустимой погрешностью на алгоритмическом языке Turbo Pascal 7.0. Составление алгоритма и программы аппроксимации функции.

    курсовая работа [810,6 K], добавлен 24.03.2012

  • Разработка эскизного и технического проектов программы "Helpopr" (ввод, хранение и вывод данных на дисплей по запросу пользователя). Язык программирования Turbo Pascal. Описание алгоритма программы. Требования к компьютеру и программному обеспечению.

    курсовая работа [198,1 K], добавлен 03.02.2010

  • Анализ эффективности методов сортировки данных в языке Turbo Pascal. Разработка эскизного и технического проекта программы. Сортировка без и с использованием дополнительной памяти, за исключением небольшого стека (массива). Сортировка связанных списков.

    курсовая работа [359,0 K], добавлен 23.05.2012

  • Составление программы вычисления матрицы и программы вычисления интеграла с погрешностью, не превышающей заданную величину. Схема алгоритма и её описание. Инструкция по использованию разработанной программы и проверка правильности е функционирования.

    курсовая работа [54,8 K], добавлен 27.10.2010

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.