Министерство Российской Федерации по связи и информатизации Сибирский Государственный Университет Телекоммуникаций и Информатики




Скачать 194.87 Kb.
НазваниеМинистерство Российской Федерации по связи и информатизации Сибирский Государственный Университет Телекоммуникаций и Информатики
Дата публикации24.06.2013
Размер194.87 Kb.
ТипЛабораторная работа
shkolnie.ru > Информатика > Лабораторная работа
Министерство Российской Федерации по связи и информатизации
Сибирский Государственный Университет Телекоммуникаций и Информатики

Межрегиональный центр переподготовки специалистов

Лабораторная работа № 5

По дисциплине: Дискретная математика


Выполнил:

Группа:

Проверил:

2011

Тема: Поиск компонент связности графа

Задание:

Граф задан его матрицей смежности. Требуется определить количество компонент связности этого графа (по материалам главы 3, п. 3.2.3 и 3.4). При этом должны быть конкретно перечислены вершины, входящие в каждую компоненту связности.

Выбор алгоритма поиска компонент связности – произвольный. Например, приветствуется использование одного из видов обхода (поиск в глубину или поиск в ширину по материалам п. 3.4.3).

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

^ Вход программы: число вершин графа и матрица смежности.

Выход: разбиение множества вершин на подмножества, соответствующие компонентам связности.

Решение:

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

Создадим главное меню программы в следующем виде:

1 Ввод матрицы смежности графа

2 Генерация матрицы смежности графа

3 Просмотр матрицы смежности графа

4 Поиск компонент связности графа

ESC - Выход

Все вспомогательные типы, процедуры и функции будут вынесены в отдельный модуль SKUtil.pas

Для обхода графа будем использовать алгоритм обхода в ширину. Для этого нам потребуется организовать очередь по принципу First In – First Out (FIFO). При этом, элемент помещённый в неё первым, будет извлечён также первым.

{Структура для хранения списка пройденных вершин}

PTops = ^TTops;

TTops = record

Co : Integer;

NextItem: PTops;

end;

{Очередь}

PQueue = ^TQueue;

TQueue = object(TObject)

Head: PTops; {Указатель на начало очереди}

Tail: PTops; {Указатель на конец очереди}

constructor Init; {Конструктор}

destructor Done; virtual; {Деструктор}

procedure Clear; {Очистка очереди}

procedure PutItem(Data: Integer); {Добавление элемента в очередь}

function GetItem: Integer; {Извлечение элемента из очереди}

end;

В качестве примера рассмотрим следующий неориентированный граф:



Матрица смежности для этого графа выглядит следующим образом:




А1

А2

А3

А4

А5

А6

А7

А1

0

0

1

0

0

0

0

А2

0

0

0

0

1

0

0

А3

1

0

0

1

0

0

0

А4

0

0

1

0

0

0

1

А5

0

1

0

0

0

1

0

А6

0

0

0

0

1

0

0

А7

0

0

0

1

0

0

0

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

Это очень любезно с Вашей стороны, но:

  1. Если Вы предполагаете работать с неорграфом, следует уведомлять об этом пользователя сразу. Иначе «очищение» матрицы после ее ввода выглядит по меньшей мере странным.

  2. В этом случае матрица должна СРАЗУ вводиться как симметричная! Или треугольной формы, или как угодно. Но то, как реализовано – это издевательство.

  3. Сделайте указанные изменения.

  4. То, что было написано Вам в замечаниях по второй работе, действительно и здесь. Лучше напишите свою программу!

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

program laba5;

uses Crt, SKUtil, Objects;

var

TopsCol: Integer; {Число вершин графа}

PMatr: MatrPtr; {Матрица смежности графа}

Queue: PQueue; {Очередь для обхода}

PList: PTops; {Список для хранения пройденных вершин}

{Функция вывода главного меню программы}

function CreateMenu: Char;

begin

clrscr;

Writeln('***** Поиск компонент связности неориентированного графа *****');

WriteLn('1 Ввод матрицы смежности графа');

WriteLn('2 Генерация матрицы смежности графа');

WriteLn('3 Просмотр матрицы смежности графа');

WriteLn('4 Поиск компонент связности графа');

Writeln('ESC - Выход');

CreateMenu := ReadKey;

end ;

{Процедура ожидания нажатие клавиши ESC либо ENTER}

procedure StopKey;

begin

WriteLn('Для продолжения нажмте клавишу ESC или ENTER...');

WriteLn;

while not (ReadKey in [#27, #13]) do;

end;

{Функция определения симметричности матрицы.}

function Is_Simmetr(TmpMatr: MatrPtr): Boolean;

var

i, j: Integer;

begin

Is_Simmetr := True;

With TmpMatr^ do begin

for i := 1 to RowValue do

for j := 1 to Colvalue do

if GetElement(TmpMatr, i, j) <> GetElement(TmpMatr, j, i) then begin

Is_Simmetr := False;

Break;

end;

end;

end;

procedure PrintMatr;

var

i, j: Integer;

s: string;

begin

if PMatr = nil then Exit;

with PMatr^ do begin

Write(' ');

for i := 1 to TopsCol do begin

Str(i, s);

Write('A' + s);

Write(' ');

end;

WriteLn;

for i := 0 to RowValue - 1 do begin

for j := 0 to ColValue do begin

Str(i + 1, s);

if (j = 0) and (i < TopsCol) then begin

Write('A' + s);

Write(' ');

end;

if (j > 0) then begin

Write(' ');

Write(GetElement(PMatr, i + 1, j));

end;

end;

WriteLn;

end;

end;

end;

procedure CreateMatrix;

var

i, j, k: Integer;

s1, s2: string;

begin

clrscr;

ClearMemMatrix(PMatr);

Write('Введите количество вершин графа: ');

Read(TopsCol);

WriteLn;

PMatr := CreateMatr(TopsCol, TopsCol);

with PMatr^ do begin

PrintMatr;

WriteLn;

for i := 1 to RowValue do begin

for j := 1 to ColValue do begin

Str(i, s1);

Str(j, s2);

repeat

Write('Введите элемент A(' + s1 + ',' + s2 + ') (Количество рёбер): ');

Read(k);

if (k < 0) then begin

WriteLn;

WriteLn;

WriteLn('Некорректный ввод! В матрице смежности должны быть элементов больее 0');

WriteLn;

WriteLn;

end;

Until (k >= 0);

SetElement(PMatr, i, j, k);

end;

end;

WriteLn;

WriteLn('Матрица смежности:');

PrintMatr;

WriteLn;

WriteLn;

if not is_simmetr(PMatr) then begin

ClearMemMatrix(PMatr); TopsCol := 0;

WriteLn('Матрица смежности неориентированного графа должна быть симметричной!');

WriteLn('Матрица смежности очищена.Необходимо повторить ввод матрицы.');

WriteLn;

WriteLn;

end ;

end;

StopKey;

end;

procedure GenerateMatr;

var

i, j: Integer;

begin

clrscr;

ClearMemMatrix(PMatr);

TopsCol := 7;

PMatr := CreateMatr(TopsCol, TopsCol);

with PMatr^ do begin

for i := 1 to RowValue do begin

for j := 1 to ColValue do begin

if ((i = 1) and (j = 3)) or

((i = 2) and (j = 5)) or

((i = 3) and (j = 1)) or

((i = 3) and (j = 4)) or

((i = 4) and (j = 3)) or

((i = 4) and (j = 7)) or

((i = 5) and (j = 2)) or

((i = 5) and (j = 6)) or

((i = 7) and (j = 4))

then

SetElement(PMatr, i, j, 1);

end;

end;

end;

WriteLn;

WriteLn('Матрица смежности');

PrintMatr;

StopKey;

end;

procedure ViewMatr;

begin

clrscr;

WriteLn('***** Матрица смежности графа *****');

WriteLn;

PrintMatr;

StopKey;

end;

procedure ClearList;

var

ps, ps1: PTops;

begin

ps := PList;

while ps <> nil do begin

ps1 := ps;

ps := ps1^.NextItem;

Dispose(ps1);

end;

PList := nil;

end;

procedure PutList(var TmpList: PTops; Co: Integer);

var

ps, ps1: PTops;

begin

ps := TmpList;

{Устанавливаем указатель в конец списка}

if ps <> nil then begin

while ps^.NextItem <> nil do

ps := ps^.NextItem;

end;

{Выделение память под элемент}

New(ps1);

ps1^.Co := Co;

ps1^.NextItem := nil;

if ps <> nil then

ps^.NextItem := ps1

else

TmpList := ps1;

end;

{Функция проверки наличия вершины в списке}

function RecExists(Co: Integer): Boolean;

var

Pt: PTops;

begin

RecExists := False;

Pt := PList;

while (pt <> nil) do begin

if (pt^.Co = Co) then begin

RecExists := True;

Break;

end;

pt := pt^.nextItem;

end;

end;

{Функция вывода компоненты связности на экран}

function GetTopsLink(TmpList: PTops): string;

var

s, s1: string;

pt: PTops;

begin

s1 := '';

pt := TmpList;

while pt <> nil do begin

if s1 <> '' then s1 := s1 + ' - ';

Str(pt^.Co, s);

s1 := s1 + 'A' + s;

pt := pt^.NextItem;

end;

GetTopsLink := s1;

end;

procedure isFindLink(StartNode: Integer);

var

i, j, x, k: Integer;

ps: PTops; {Список вершин в компоненте связности}

begin

Queue^.Clear; {Очищаем очередь}

i := StartNode; {Вершина, с которой начинаем обход}

Queue^.PutItem(i); {Заносим вершину в очередь}

PutList(PList, i); {Помечаем вершину}

ps := nil;

PutList(ps, i); {Заносим стартовую вершину в начало списка}

repeat

x := Queue^.GetItem;

with PMatr^ do begin

for j := 1 to ColValue do begin

k := GetElement(PMatr, x, j); {Проверим связь вершин по матрице смежности}

if (k > 0) then begin

if not RecExists(j) then begin

{Вершины с номерами X и J связаны, и вершина J еще не в очереди}

Queue^.PutItem(j); {Заносим вершину в очередь}

PutList(PList, j); {Помечаем вершину, как пройденную}

PutList(ps, j); {Заносим следующую вершину в список текущей компоненты связности}

end;

end;

end;

end;

until Queue^.Head = nil; {Выполняем обход, пока очередь не станет пустой}

{Вывод компоненты связности на экран}

WriteLn(GetTopsLink(ps));

end;

procedure SearchAllLinks;

var

i: Integer;

s, sl: string;

begin

clrscr;

WriteLn('***** Поиск компонент связности графа *****');

if TopsCol = 0 then begin

WriteLn('Не задан граф! Для поиска компонент связности необходимо задайть граф !');

StopKey;

Exit;

end;

ClearList; {Очиска списка}

WriteLn;

WriteLn('** Матрица смежности **');

PrintMatr;

WriteLn;

WriteLn('** Компоненты связности **');

WriteLn;

{Производим перебор по всем вершинам, и пытаемся от каждой найти маршруты}

for i := 1 to TopsCol do begin

if not RecExists(i) then

isFindLink(i);

end;

StopKey;

end;

var

ch: Char;

begin

PMatr := nil;

PList := nil;

Queue := nil ;

TopsCol := 0;

Queue := New(PQueue, Init);

repeat

ch := createMenu;

case ch of

'1': CreateMatrix;

'2': GenerateMatr;

'3': ViewMatr;

'4': SearchAllLinks;

end;

until ch = #27;

if PMatr <> nil then ClearMemMatrix(PMatr);

if PList <> nil then ClearList;

if Queue <> nil then Dispose(Queue);

end.

^ Код модуля SKUtil.pas на языка Pascal:

unit SKUtil;

interface

uses Objects;

type

{Структура для хранения списка пройденных вершин}

PTops = ^TTops;

TTops = record

Co : Integer;

NextItem: PTops;

end;

{Очередь}

PQueue = ^TQueue;

TQueue = object(TObject)

Head: PTops; {Указатель на начало очереди}

Tail: PTops; {Указатель на конец очереди}

constructor Init; {Конструктор}

destructor Done; virtual; {Деструктор}

procedure Clear; {Очистка очереди}

procedure PutItem(Data: Integer); {Добавление элемента в очередь}

function GetItem: Integer; {Извлечение элемента из очереди}

end;

MatrRec = record

RowValue : byte;

ColValue : byte;

PDim : pointer;

end;

MatrPtr = ^MatrRec;

{ Создание прямоугольной матрицы }

function CreateMatr(RValue,CValue : byte) : MatrPtr;

{ Заполнение матрицы указанным числом }

function FillMatr(Mp: MatrPtr; El : Integer) : boolean;

{ Отображение матрицы на консоль }

function PrintMatr(Mp : MatrPtr; Im: byte) : boolean;

{ Освобождение памяти выделенное под матрицу, в случае успеха возвращает True }

function ClearMemMatrix(var Mp : MatrPtr) : boolean;

{ Присвоение значения определённого элемента матрицы }

procedure SetElement(Mp : MatrPtr;RValue,CValue : byte; Me : Integer);

{ Возвращает значение заданного элемента матрицы }

function GetElement(Mp : MatrPtr;RValue,CValue : byte) : Integer;

{ Умножает соответствующие элементы матриц одинакового размера без сложения элементов}

function MultMatrixNotAdd(Mp1,Mp2 : MatrPtr) : MatrPtr;

{ Умножение матрицы на матрицу алгебраически }

function MultipleMatr(Mp1,Mp2 : MatrPtr) : MatrPtr;

{ Транспонирует матрицу }

function TranspMatr(Mp : MatrPtr) : MatrPtr;

{ Умножает элементы матриц одинакового размера алгебраически с логическим сложением}

function MultMatrixLogical(Mp1,Mp2 : MatrPtr) : MatrPtr;

implementation

constructor TQueue.Init;

begin

Head := nil;

Tail := nil;

end;

destructor TQueue.Done;

begin

Clear;

end;

procedure TQueue.Clear;

var

p, p1: PTops;

begin

p := Head;

while (p <> nil) do begin

p1 := p;

p := p1^.nextItem;

Dispose(p1); {Освобождаем память, занимаемую эелементом очереди}

end;

end;

{Процедура добавления эелемента в очередь}

procedure TQueue.PutItem(Data: Integer);

var

p: PTops;

begin

New(P);

P^.Co := Data;

P^.NextItem := nil;

if Head <> nil then

Tail^.NextItem := P

else

Head := P;

Tail := P;

end;

{Извлечение элемента из очереди}

function TQueue.GetItem: Integer;

var

p: PTops;

begin

GetItem := 0; {Значение, если очередь пуста}

p := Head;

if p <> nil then begin

Head := p^.NextItem;

GetItem := p^.Co;

Dispose(p);

end;

end;

{ Создание прямоугольной матрицы }

function CreateMatr(RValue,CValue : byte) : MatrPtr;

var

TmpPtr : MatrPtr;

begin

TmpPtr:= nil;

GetMem(TmpPtr,SizeOf(MatrRec));

if TmpPtr = nil then begin

CreateMatr:= nil;

Exit;

end;

with TmpPtr^ do begin

RowValue:= RValue;

ColValue:= CValue;

PDim:= nil;

GetMem(PDim,RValue*CValue*SizeOf(Integer));

if PDim = nil then begin

FreeMem(TmpPtr,SizeOf(MatrRec));

CreateMatr:= nil;

Exit;

end;

end;

FillMatr(TmpPtr,0);

CreateMatr:= TmpPtr;

end;

{ Освобождение памяти выделенное под матрицу, в случае успеха возвращает True }

function ClearMemMatrix(var Mp : MatrPtr) : boolean;

begin

if Mp = nil then ClearMemMatrix:= False

else with Mp^ do begin

if PDim <> nil then

FreeMem(PDim,RowValue*ColValue*SizeOf(Integer));

FreeMem(Mp,SizeOf(MatrRec));

Mp:= nil;

ClearMemMatrix:= True;

end;

end;

{ Отображение матрицы на консоль }

function PrintMatr(Mp : MatrPtr; Im: byte) : boolean;

var

i,j : byte;

begin

if Mp = nil then PrintMatr:= False

else with Mp^ do begin

for i:= 1 to RowValue do begin

for j:= 1 to ColValue do

write(GetElement(Mp,i,j) : Im);

writeln;

end;

PrintMatr:= True;

end;

end;

{ Заполнение матрицы указанным числом }

function FillMatr(Mp: MatrPtr; El : Integer) : boolean;

var

i,j : byte;

begin

if Mp = nil then FillMatr:= False

else with Mp^ do begin

for i:= 1 to RowValue do

for j:= 1 to ColValue do

SetElement(Mp,i,j,El);

FillMatr:= True;

end;

end;

{ Присвоение значения определённого элемента матрицы }

procedure SetElement(Mp : MatrPtr;RValue,CValue : byte; Me : Integer);

var

TmpPtr : ^Integer;

begin

if Mp <> nil then

if (RValue <> 0) or (CValue <> 0) then with Mp^ do begin

pointer(TmpPtr):= pointer(PDim);

Inc(TmpPtr,RowValue*(CValue-1)+RValue-1);

TmpPtr^:= Me;

end;

end;

{ Возвращает значение заданного элемента матрицы }

function GetElement(Mp : MatrPtr;RValue,CValue : byte) : Integer;

var

TmpPtr : ^Integer;

begin

if Mp <> nil then begin

if (RValue <> 0) and (CValue <> 0) then with Mp^ do begin

pointer(TmpPtr):= pointer(PDim);

Inc(TmpPtr,RowValue*(CValue-1)+RValue-1);

GetElement:= TmpPtr^;

end else GetElement:= 0;

end else GetElement:= 0;

end;

{ Транспонирует матрицу }

function TranspMatr(Mp : MatrPtr) : MatrPtr;

var

i,j : byte;

TmpPtr : MatrPtr;

begin

if (Mp <> nil) or (Mp^.PDim <> nil) then

with Mp^ do begin

TmpPtr:= CreateMatr(ColValue,RowValue);

for i:= 1 to RowValue do

for j:= 1 to ColValue do

SetElement(TmpPtr,j,i,GetElement(Mp,i,j));

TranspMatr:= TmpPtr;

end else TranspMatr:= nil;

end;

{ умножает соответствующие элементы матриц одинакового размера без сложения элементов}

function MultMatrixNotAdd(Mp1,Mp2 : MatrPtr) : MatrPtr;

var

TmpPtr : MatrPtr;

i,j,k : byte;

begin

if (Mp1 <> nil) and (Mp2 <> nil) then begin

TmpPtr:= CreateMatr(Mp1^.RowValue,Mp1^.ColValue);

if TmpPtr = nil then begin

MultMatrixNotAdd:= nil;

Exit;

end;

for i:= 1 to TmpPtr^.RowValue do

for j:= 1 to TmpPtr^.ColValue do

SetElement(TmpPtr,i,j,

GetElement(Mp1,i,j)*GetElement(Mp2,i,j));

MultMatrixNotAdd:= TmpPtr;

end else MultMatrixNotAdd :=nil;

end;

{ умножает матрицу на матрицу алгебраически }

function MultipleMatr(Mp1,Mp2 : MatrPtr) : MatrPtr;

var

i,j,k : byte;

TmpPtr : MatrPtr;

begin

if (Mp1 <> nil) and (Mp2 <> nil) then begin

TmpPtr:= CreateMatr(Mp1^.RowValue,Mp2^.ColValue);

if TmpPtr = nil then begin

MultipleMatr:= nil;

Exit;

end;

for i:= 1 to TmpPtr^.RowValue do

for j:= 1 to TmpPtr^.ColValue do

for k:= 1 to Mp1^.ColValue do

SetElement(TmpPtr,i,j,GetElement(TmpPtr,i,j)+

GetElement(Mp1,i,k)*GetElement(Mp2,k,j));

MultipleMatr:= TmpPtr;

end else MultipleMatr:= nil;

end;

function LogicSumm(I1, I2: Integer): Integer;

begin

if (I1 = 0) and (I2 = 0) then

LogicSumm := 0

else

LogicSumm := 1;

end;

{ Умножает элементы матриц одинакового размера алгебраически с логическим сложением}

function MultMatrixLogical(Mp1,Mp2 : MatrPtr) : MatrPtr;

var

i,j,k : byte;

TmpPtr : MatrPtr;

begin

if (Mp1 <> nil) and (Mp2 <> nil) then begin

TmpPtr:= CreateMatr(Mp1^.RowValue,Mp1^.ColValue);

if TmpPtr = nil then begin

MultMatrixLogical:= nil;

Exit;

end;

for i:= 1 to TmpPtr^.RowValue do

for j:= 1 to TmpPtr^.ColValue do

for k:= 1 to Mp1^.ColValue do

SetElement(TmpPtr,i,j, LogicSumm(GetElement(TmpPtr,i,j),

GetElement(Mp1,i,k)*GetElement(Mp2,k,j)));

MultMatrixLogical:= TmpPtr;

end else MultMatrixLogical:= nil;

end;

end.

^ Результат работы программы

Главное меню программы



Генерация матрицы смежности:



Просмотр матрицы смежности графа



Поиск компонент связности:



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

Похожие:

Министерство Российской Федерации по связи и информатизации Сибирский Государственный Университет Телекоммуникаций и Информатики iconМинистерство Российской Федерации по связи и информатизации Сибирский...
Программа должна определять свойства заданного отношения: рефлексивность, симметричность, антисимметричность, транзитивность (по...
Министерство Российской Федерации по связи и информатизации Сибирский Государственный Университет Телекоммуникаций и Информатики iconМинистерство Российской Федерации по связи и информатизации Санкт-Петербургский...
Конструкторские расчеты, связанные с обеспечением прочности и жесткости радиоэлектронных средств и определение собственных резонансных...
Министерство Российской Федерации по связи и информатизации Сибирский Государственный Университет Телекоммуникаций и Информатики iconМинистерство российской федерации по связи и информатизации стандарт отрасли
Стандарт соответствует стандартам Российской Федерации в отрасли связи и смежных областях науки и техники, учитывает рекомендации...
Министерство Российской Федерации по связи и информатизации Сибирский Государственный Университет Телекоммуникаций и Информатики iconМинистерство российской федерации по связи и информатизации стандарт отрасли
Стандарт соответствует стандартам Российской Федерации в области электросвязи и смежных областях науки и техники
Министерство Российской Федерации по связи и информатизации Сибирский Государственный Университет Телекоммуникаций и Информатики iconНовосибирский государственный университет
Министерство образования и науки Российской Федерации новосибирский государственный университет экономики и управления «нинх»
Министерство Российской Федерации по связи и информатизации Сибирский Государственный Университет Телекоммуникаций и Информатики iconНовосибирский государственный университет
Министерство образования и науки Российской Федерации новосибирский государственный университет экономики и управления «нинх»
Министерство Российской Федерации по связи и информатизации Сибирский Государственный Университет Телекоммуникаций и Информатики iconМинистерство образования и науки российской федерации министерство...
В соответствии с Правилами приема в Российский государственный социальный университет в 2012 году
Министерство Российской Федерации по связи и информатизации Сибирский Государственный Университет Телекоммуникаций и Информатики iconМинистерство образования и науки российской федерации министерство...
В соответствии с Правилами приема в Российский государственный социальный университет в 2012 году
Министерство Российской Федерации по связи и информатизации Сибирский Государственный Университет Телекоммуникаций и Информатики iconМинистерство образования и науки российской федерации министерство...
В соответствии с Правилами приёма в Российский государственный социальный университет в 2012 году
Министерство Российской Федерации по связи и информатизации Сибирский Государственный Университет Телекоммуникаций и Информатики iconМинистерство образования и науки российской федерации министерство...
В соответствии с Правилами приема в Российский государственный социальный университет в 2012 году
Вы можете разместить ссылку на наш сайт:
Школьные материалы


При копировании материала укажите ссылку © 2014
shkolnie.ru
Главная страница