Проектирование программной коллекции "Простой, статический граф"

Разработка и реализация универсальной программной коллекции для абстрактного типа данных (АТД) "Простой статический граф" с графическим интерфейсом. Особенности использование ее для решения задач для неориентированных, ориентированных и взвешенных графов.

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

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

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

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

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

1. Вводная часть

граф программный статический

1.1 Цель работы

Проектирование и реализация универсальной программной коллекции для АТД «Простой, статический граф» и использование коллекции для решения задач для неориентированных, ориентированных и взвешенных графов.

1.2 Постановка задания

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

Разработать АТД «Простой граф».

Интерфейс АТД «Простой, статический граф» включает операции:

Конструктор ( ) по умолчанию: создает пустой L - граф с нулевым числом вершин и ребер,

Конструктор(V, D, F) создает граф с V вершинами, без ребер, типа D(ориентированный / неориентированный), формы представления F(L- граф/M-граф),

Конструктор(V, E, D, F) создает граф с V вершинами, с E случайными ребрами, типа

D(ориентированный / неориентированный), формы представления F (L- граф/M-граф),

Конструктор (G) - конструктор копирования создает объект - копию графа G,

Деструктор ( ) уничтожает внутренние структуры графа,

V( )- возвращает число вершин в графе,

E( )- возвращает число ребер в графе,

Directed( ) - возвращает тип графа (ориентированный / неориентированный)

Dense( ) - возвращает форму представления графа (L- граф / M- граф),

K( ) - возвращает коэффициент насыщенности графа,

ToListGraph()преобразует граф к L- графу,

ToMatrixGraph()преобразует граф к M- графу,

InsertV(v)добавляет к графу вершину c заданным номером v,

DeleteV (v) -удаляет из графа вершину c заданным номером v,

InsertE(v1, v2) - добавляет ребро (v1, v2) к графу, соединяющую вершины, заданные номерами v1 и v2,

DeleteE (v1, v2)удаляет ребра (v1, v2), соединяющего вершины, заданные номерами v1 и v2,

Is_Edge(v1, v2)возвращает признак существования в графе ребра соединяющего вершины, заданные номерами v1 и v2,

GetEdgeWeight(v1,v2)возвращает вес ребра (v1, v2), соединяющего вершины, заданные номерами v1 и v2,

SetEdgeWeight (v1,v2, w)задает вес ребра (v1, v2), соединяющего вершины, заданные номерами v1 и v2, равным w.

GetEdgeData(v1,v2)возвращает данные ребра (v1, v2), соединяющего вершины, заданные номерами v1 и v2,

SetEdgeData (v1,v2, w)задает данные ребра (v1, v2), соединяющего вершины, заданные номерами v1 и v2, равным w.

Разработать ассоциированные с графом типы:

«Дескриптор ребра графа»

Дескриптор ребра содержит поля:

v1 - номер вершины, из которой исходит ребро,

v2 - номер вершины, в которую входит ребро,

w - вес ребра,

data - данные, связанные с ребром,

АТД «Итератор вершин графа»

Интерфейс АТД «Итератор вершин графа» включает операции:

Конструктор ( ) - создает итератор вершин графа,

beg( ) - возвращает итератор, установленный на первую вершину графа,

end( ) - возвращает итератор, соответствующий окончанию переходов итератора,

operator ++ - переход к следующей вершине графа,

operator * - возвращает номер вершины графа, на которую указывает итератор.

АТД «Итератор ребер графа»

Интерфейс АТД «Итератор ребер графа» включает операции:

Конструктор ( ) - создает итератор ребер графа,

beg( ) - возвращает итератор, установленный на первое ребро графа,

end( ) - возвращает итератор, соответствующий окончанию переходов итератора,

operator ++ - переход к следующему ребру графа,

operator * - возвращает дескриптор ребра графа, на которое указывает итератор.

АТД «Итератор исходящих ребер вершины»

Интерфейс АТД «Итератор исходящих ребер вершины» включает операции:

Конструктор (v) - создает итератор исходящих ребер графа для вершины, заданной номером v,

beg( ) - возвращает итератор, установленный на первое исходящее ребро вершины,

end( ) - возвращает итератор, соответствующий окончанию переходов итератора,

operator ++ - переход к следующему исходящему ребру,

operator * - возвращает дескриптор исходящего ребра вершины, на которое указывает итератор.

АТД «Итератор входящих ребер вершины»

Интерфейс АТД «Итератор входящих ребер вершины» включает операции:

Конструктор (v) - создает итератор входящих ребер графа для вершины, заданной номером v,

beg( ) - возвращает итератор, установленный на первое входящее ребро вершины,

end( ) - возвращает итератор, соответствующий окончанию переходов итератора,

operator ++ - переход к следующему входящему ребру,

operator * - возвращает дескриптор входящего ребра вершины, на которое указывает итератор.

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

2.1 Диаграмма взаимосвязи объектов

UML-диаграмма взаимодействия классов.

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

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

Рисунок 1. диаграмма для класса «Простой граф».

Рисунок 2. UML-диаграмма для классов итераторов.

2.2 АТД «Простой граф»

2.2.1 Формат АТД

АТД “Простой, статический граф”:

Простой статический граф с заданным типом для хранения данных в рёбрах - D, а также типом хранения веса ребра - W. Граф может быть ориентированным или неориентированным, для каждого ребра предусмотрен его вес и данные для хранения. В графе запрещены петли и параллельные рёбра из одной вершины.

Класс абстрактный, создание объекта этого класса не предусмотрено.

ДАННЫЕ:

Параметры:

verticesCount - переменна хранящая количество вершин

edgesCount - переменная хранящая количество ребер

directed - переменная хранящая тип графа ориентированный/неориентированный

ОПЕРАЦИИ:

Конструктор

Вход:нет

Предусловия: нет

Процесс: создание объекта простого графа, граф не ориентированный

Выход: нет

Постусловия: создан пустой неориентированный граф

Конструктор

Вход:cVertex - число вершин, сDirected - признак ориентированности графа

Предусловия: нет

Процесс: создание объекта графа заданной ориентированности и вставка заданного числа вершин

Выход: нет

Постусловия: создан граф заданной ориентированности, с количеством вершин cVertex

Конструктор

Вход:cVertex - число вершин, cEdge-число рёбер, сDirected - признак ориентированности графа

Предусловия: нет

Процесс: создание объекта графа заданной ориентированности и вставка заданного числа вершин и рёбер

Выход: нет

Постусловия: создан граф заданной ориентированности, с количеством вершин cVertex и количеством ребер cEdge.

Конструктор копирования

Вход: объект типа “Простой, статический граф” graph

Предусловия: нет

Процесс: создание нового графа и копирование в него всех свойств graph, а также вершин и рёбер

Выход: нет

Постусловие: создание графа с такой же структурой и элементами, что у graph

Опрос числа вершин в графе

Вход: нет

Предусловия: нет

Процесс: чтение количества вершин

Выход: количество вершин в графе

Постусловия: нет

Опрос числа рёбер в графе

Вход: нет

Предусловия: нет

Процесс: чтение количества рёбер

Выход: количество рёбер в графе

Постусловия: нет

Опрос типа ориентированности графа

Вход: нет

Предусловия: нет

Процесс: чтение типа графа

Выход: тип графа (ориентированный/неориентированный)

Постусловия: нет

Опрос формы представления графа

Вход: нет

Предусловия: нет

Процесс: чтение значения формы представления графа

Выход: форма представления графа (L-граф/M-граф)

Постусловия: нет

Коэффициент насыщенности графа

Вход: нет

Предусловия: нет

Процесс: расчёт коэффициента насыщенности графа

Для ориентированного: Е/(V*(V-1))

Для неориентированного: 2*Е/(V*(V-1)), где E-количество ребер, V-количество врешин

Выход: значение коэффициента насыщенности графа

Постусловия: нет

Преобразования графа к L-графу

Вход: нет

Предусловия: нет

Процесс: преобразование текущего представления графа к L-графу

Выход: нет

Постусловия: граф преобразован к L-графу

Преобразования графа к M-графу

Вход: нет

Предусловия: нет

Процесс: преобразование текущего представления графа к М-графу

Выход: нет

Постусловия: граф преобразован к М-графу

Добавление ребра

Вход: номер исходящей вершины vertex1 и входящий vertex2

Предусловия:

· vertex1 не равно vertex2

· вершины vertex1 и vertex2 существуют

· ребро vertex1- vertex2 не существует

Процесс: вставка ребра соединяющего вершины vertex1и vertex2

Выход: false при не выполнении предусловия, true при выполнении.

Постусловия: ребро вставлено при выполнении предусловия.

Удаление ребра

Вход: номер исходящей вершины vertex1 и входящий vertex2

Предусловия:

· vertex1 не равно vertex2

· вершины vertex1 и vertex2 существуют

· ребро vertex1- vertex2 существует

Процесс: удаление ребра соединяющего вершины vertex1и vertex2

Выход: false при не выполнении предусловия, true при выполнении.

Постусловия: ребро удалено при выполнении предусловия.

Добавление вершины

Вход: номер вершины vertexNumber

Предусловия: вершина vertexNumber не существует

Процесс: вставка вершины vertexNumber

Выход: false при не выполнении предусловия, true при выполнении.

Постусловия: вершина вставлена при выполнении предусловия.

Удаление вершины

Вход: номер вершины vertexNumber

Предусловия: вершина vertexNumber существует

Процесс: удаление вершины vertexNumber и всех связанных с ней ребер

Выход: false при не выполнении предусловия, true при выполнении.

Постусловия: вершина удалена при выполнении предусловия.+

Признак существования ребра

Вход: номер исходящей вершины vertex1 и входящий vertex2

Предусловия: вершины vertex1 и vertex2 существуют

Процесс: проверки есть ли ребро соединяющие вершины vertex1- vertex2

Выход: true - если ребро есть, иначе false

Постусловия: нет

Опрос веса ребра

Вход: номер исходящей вершины vertex1 и входящий vertex2

Предусловия:

· вершины vertex1 и vertex2 существуют

· ребро vertex1- vertex2 существует

Процесс: получение веса ребра vertex1- vertex2

Выход: вес ребра шаблонного типа W

Постусловия: генерация исключения при невыполнении предусловия

Задание веса ребра

Вход: номер исходящей вершины vertex1 и входящий vertex2, вес weight

Предусловия:

· вершины vertex1 и vertex2 существуют

· ребро vertex1- vertex2 существует

Процесс: задание веса ребра vertex1- vertex2

Выход: true при выполнении предусловия, иначе false

Постусловия: задан вес ребра шаблонного типа W

Опрос данных ребра

Вход: номер исходящей вершины vertex1 и входящий vertex2

Предусловия:

· вершины vertex1 и vertex2 существуют

· ребро vertex1- vertex2 существует

Процесс: получение данных ребра vertex1- vertex2

Выход: данные ребра шаблонного типа D

Постусловия: генерация исключения при невыполнении предусловия

Задание данных ребра

Вход: номер исходящей вершины vertex1 и входящий vertex2, данные data

Предусловия:

· вершины vertex1 и vertex2 существуют

· ребро vertex1- vertex2 существует

Процесс: задание данных ребра vertex1- vertex2

Выход: true при выполнении предусловия, иначе false

Постусловия: заданы данные ребра шаблонного типа D

КОНЕЦ АТД

2.2.2 Клиентское определение класса

public abstract class Graph<W, D>

{

// конструктор без параметров

public Graph();

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

public Graph(int cVertex, bool cDirected);

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

public Graph(int cVertex, int cEdge, bool cDirected);

//опрос типа ориентированности

public bool isDirected();

//опрос формы представления графа

abstract public bool getType();

//опрос коэффициента насыщенности

public double denseCoef();

//конвертирование в L-граф

abstract public Graph<W, D> toListGraph();

//конвертирование к М-граф

abstract public Graph<W, D> toMatrixGraph();

//вставка вершины

abstract public bool addVertex(int vertexNumber);

//удаление вершины

abstract public bool removeVertex(int vertexNumber);

//вставка ребра

abstract public bool addEdge(int vertex1, int vertex2);

//удаление ребра

abstract public bool removeEdge(int vertex1, int vertex2);

//проверка наличия ребра

abstract public bool hasEdge(int vertex1, int vertex2);

//получение веса ребра

abstract public W getEdgeWeight(int vertex1, int vertex2);

//установка веса ребра

abstract public bool setEdgeWeight(int vertex1, int vertex2, W weight);

//получение данных ребра

abstract public D getEdgeData(int vertex1, int vertex2);

//установка данных ребра

abstract public bool setEdgeData(int vertex1, int vertex2, D data);

}

2.3 АТД «L-граф»

2.3.1 Формат АТДАТД “L - граф”:

Класс наследник класса «Простой, статический граф». Наследует все операции родительского класса. Представляет граф в виде списка смежности его вершин.

ДАННЫЕ:

Параметры:

adjacencyList - список смежности

ОПЕРАЦИИ:

Конструктор

Вход:нет

Предусловия: нет

Процесс: создание объекта L- графа, граф неориентированный

Выход: нет

Постусловия: создан пустой неориентированный L- граф

Конструктор

Вход:cVertex - число вершин, сDirected - признак ориентированности графа

Предусловия: нет

Процесс: создание объекта L-графа заданной ориентированности и вставка заданного числа вершин

Выход: нет

Постусловия: создан L-граф заданной ориентированности, с количеством вершин cVertex

Конструктор

Вход:cVertex - число вершин, cEdge-число рёбер, сDirected - признак ориентированности графа

Предусловия: нет

Процесс: создание объекта L-графа заданной ориентированности и вставка заданного числа вершин и рёбер

Выход: нет

Постусловия: создан L-граф заданной ориентированности, с количеством вершин cVertex и количеством ребер cEdge.

Конструктор копирования

Вход: объект типа L-граф graph

Предусловия: нет

Процесс: создание нового L-графа и копирование в него всех свойств graph, а также вершин и рёбер

Выход: нет

Постусловие: создание L-графа с такой же структурой и элементами, что у graph

КОНЕЦ АТД

2.3.2 Клиентское определение класса

class LGraph<W, D> : Graph<W, D>, ICloneable

{

// конструктор без параметров

public LGraph() : base();

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

public LGraph(int cVertex, bool cDirected) : base(cVertex, cDirected);

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

public LGraph(int cVertex, int cEdge, bool cDirected) : base(cVertex, cDirected);

//опрос типа ориентированности

public bool hasDirected();

//опрос формы представления графа

public override bool getType()

//вставка вершины

public override bool addVertex(int vertexNumber)

//удаление вершины

public override bool removeVertex(int vertexNumber)

//вставка ребра

public override bool addEdge(int vertex1, int vertex2)

//удаление ребра

public override bool addEdge(int vertex1, int vertex2)

//проверка наличия ребра

public override bool hasEdge(int vertex1, int vertex2)

//получение веса ребра

public override W getEdgeWeight(int vertex1, int vertex2)

//установка веса ребра

public override bool setEdgeWeight(int vertex1, int vertex2, W weight)

//получение данных ребра

public override D getEdgeData(int vertex1, int vertex2)

//установка данных ребра

public override bool setEdgeData(int vertex1, int vertex2, D data)

//конвертирование в L-граф

public override Graph<W, D> toListGraph()

//конвертирование в М-граф

public override Graph<W, D> toMatrixGraph()

}

2.4 АТД «M-граф»

2.4.1 Формат АТД

АТД “M- граф”:

Класс наследник класса «Простой, статический граф». Наследует все операции родительского класса. Представляет граф в виде матрицы смежности.

ДАННЫЕ:

Параметры:

adjacencyMatrix - матрица смежности

ОПЕРАЦИИ:

Конструктор

Вход:cVertex - число вершин, сDirected - признак ориентированности графа

Предусловия: нет

Процесс: создание объекта М-графа заданной ориентированности и вставка заданного числа вершин

Выход: нет

Постусловия: создан М-граф заданной ориентированности, с количеством вершин cVertex

Конструктор

Вход:cVertex - число вершин, cEdge-число рёбер, сDirected - признак ориентированности графа

Предусловия: нет

Процесс: создание объекта М-графа заданной ориентированности и вставка заданного числа вершин и рёбер

Выход: нет

Постусловия: создан М-граф заданной ориентированности, с количеством вершин cVertex и количеством ребер cEdge.

Конструктор копирования

Вход: объект типа М-граф graph

Предусловия: нет

Процесс: создание нового М-графа и копирование в него всех свойств graph, а также вершин и рёбер

Выход: нет

Постусловие: создание М-графа с такой же структурой и элементами, что у graph

КОНЕЦ АТД

2.4.2 Клиентское определение класса

class MGraph<W, D> :Graph<W, D>, ICloneable

{

// конструктор без параметров

public МGraph() : base();

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

public МGraph(int cVertex, bool cDirected) : base(cVertex, cDirected);

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

public МGraph(int cVertex, int cEdge, bool cDirected) : base(cVertex, cDirected);

//опрос типа ориентированности

public bool isDirected();

//опрос формы представления графа

public override bool getType()

//вставка вершины

public override bool addVertex(int vertexNumber)

//удаление вершины

public override bool removeVertex(int vertexNumber)

//вставка ребра

public override bool addEdge(int vertex1, int vertex2)

//удаление ребра

public override bool removeEdge(int vertex1, int vertex2)

//проверка наличия ребра

public override bool hasEdge(int vertex1, int vertex2)

//получение веса ребра

public override W getEdgeWeight(int vertex1, int vertex2)

//установка веса ребра

public override bool setEdgeWeight(int vertex1, int vertex2, W weight)

//получение данных ребра

public override D getEdgeData(int vertex1, int vertex2)

//установка данных ребра

public override bool setEdgeData(int vertex1, int vertex2, D data)

//конвертирование в L-граф

public override Graph<W, D> toListGraph()

//конвертирование в М-граф

public override Graph<W, D> toMatrixGraph()

}

2.5 АТД «Дескриптор ребра»

2.5.1 Формат АТД

АТД “Дескриптор ребра”:

Дескриптор ребра служит для описания ребер графа. Он хранит в себе номера вершин ребра, а также данные и вес.

ДАННЫЕ:

Параметры:

Vertex1 - Номер вершины из которой выходит ребро

Vertex2 - Номер вершины в которую входит ребро

Data - Данные связанные с ребром

Weight - Вес ребра

ОПЕРАЦИИ:

Конструктор

Вход:номер исходящей вершины vertex1 и входящий vertex2

Предусловия: нет

Процесс: создание ребра из исходящей вершины во входящую

Выход: нет

Постусловия: создано ребро из исходящей вершины во входящую

Конструктор

Вход:номер исходящей вершины vertex1 и входящий vertex2, вес weight

Предусловия: нет

Процесс: создание ребра из исходящей вершины во входящую, весом weight

Выход: нет

Постусловия: создано ребро из исходящей вершины во входящую, весом weight

Конструктор

Вход:номер исходящей вершины vertex1 и входящий vertex2, вес weight, данные data

Предусловия: нет

Процесс: создание ребра из исходящей вершины во входящую, весом weight, с данными data

Выход: нет

Постусловия: создано ребро из исходящей вершины во входящую, весом weight, с данными data

КОНЕЦ АТД

2.5.2 Клиентское определение класса

public class Edge<W, D> : ICloneable

{

//конструктор без параметров

public Edge(int v1, int v2)

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

public Edge(int v1, int v2, W w)

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

public Edge(int v1, int v2, W w, D d)

}

2.6 Итератор вершин

2.6.1 Описание формата

АТД “Итератор вершин”:

Итератор служит для последовательного доступа к вершинам графа.

ДАННЫЕ:

Параметры:

currentPosition - текущая вершина в графе

graph - граф

ОПЕРАЦИИ:

Конструктор

Вход:нет

Предусловия: нет

Процесс: создание объекта итератора вершин

Выход: нет

Постусловия: создан объект итератор вершин графа

Установка итератора на первую вершину

Вход:нет

Предусловия: нет

Процесс: установка итератор на первую вершину

Выход: нет

Постусловия: итератор установлен на первую вершину

Установка итератора на последнюю вершину

Вход:нет

Предусловия: нет

Процесс: установка итератор на последнюю вершину

Выход: нет

Постусловия: итератор установлен на последнюю вершину

Установка итератора на следующую вершину

Вход:нет

Предусловия: нет

Процесс: установка итератор на следующую вершину

Выход: нет

Постусловия: итератор установлен на следующую вершину

Получение номера вершины (проверка состояния)

Вход:нет

Предусловия: нет

Процесс: получение номера вершины

Выход: номер вершины графа, на которую указывает итератора или null, если итератор вышел за пределы графа

Постусловия: нет

КОНЕЦ АТД

2.6.2 Клиентское определение класса

public class VertexIterator<W, D> : Iterator<W, D>

{

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

public VertexIterator(Graph<W, D> graphC)

: base(graphC)

//установка на начало

public override void benig()

//установка в конец

public override void end()

//переход к следующей

public override void next()

public override Edge<W, D> state()

}

2.7 Итератор ребер

2.7.1 Описание формата

АТД “Итератор рёбер”:

Итератор служит для последовательного доступа к ребрам графа.

ДАННЫЕ:

Параметры:

currentPosition - текущее ребро в графе

graph - граф

ОПЕРАЦИИ:

Конструктор

Вход:нет

Предусловия: нет

Процесс: создание объекта итератора рёбер

Выход: нет

Постусловия: создан объект итератор рёбер графа

Установка итератора на первое ребро

Вход:нет

Предусловия: нет

Процесс: установка итератор на первое ребро графа

Выход: нет

Постусловия: итератор установлен на первое ребро графа

Установка итератора на послднее ребро

Вход:нет

Предусловия: нет

Процесс: установка итератор на послднее ребро графа

Выход: нет

Постусловия: итератор установлен на послднее ребро графа

Установка итератора на следующее ребро

Вход:нет

Предусловия: нет

Процесс: установка итератор на следующее ребро графа

Выход: нет

Постусловия: итератор установлен на следующее ребро графа

Получение дескриптора текущего ребра (проверка состояния)

Вход:нет

Предусловия: нет

Процесс: получение дескриптора ребра

Выход: дескриптор ребра, на которое указывает итератор, или null если итератор вышел за пределы графа

Постусловия: нет

КОНЕЦ АТД

2.7.2 Клиентское определение класса

public class EdgeIterator<W, D> : Iterator<W, D>

{

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

public EdgeIterator(Graph<W, D> graphC)

: base(graphC)

//установка на начало

public override void benig()

//установка в конец

public override void end()

//переход к следующей

public override void next()

public override Edge<W, D> state()

}

2.8 Итератор исходящих ребер

2.8.1 Описание формата

АТД “Итератор исходящих рёбер”:

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

ДАННЫЕ:

Параметры:

vertexNumber - номер вершины

ОПЕРАЦИИ:

Конструктор

Вход:номер вершины vertexNumb

Предусловия: нет

Процесс: создание объекта итератора исходящих рёбер из заданной вершины

Выход: нет

Постусловия: создан объект итератор исходящих рёбер вершины

Установка итератора на первое исходящее ребро

Вход:нет

Предусловия: нет

Процесс: установка итератор на первое исходящее ребро вершины

Выход: нет

Постусловия: итератор установлен на первое ребро вершины

Установка итератора на послднее исходящее ребро вершины

Вход:нет

Предусловия: нет

Процесс: установка итератор на послднее исходящее ребро вершины

Выход: нет

Постусловия: итератор установлен на послднее исходящее ребро вершины

Установка итератора на следующее ребро

Вход:нет

Предусловия: нет

Процесс: установка итератор на следующее исходящее ребро вершины

Выход: нет

Постусловия: итератор установлен на следующее исходящее ребро вершины

Получение дескриптора текущего ребра (проверка состояния)

Вход:нет

Предусловия: нет

Процесс: получение дескриптора ребра

Выход: дескриптор исходящего ребра, вершины vertexNumber, на которое указывает итератор

Постусловия: нет

КОНЕЦ АТД

2.8.2 Клиентское определение класса

public class OutgoingEdgesIterator<W, D> : Iterator<W, D>

{

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

public OutgoingEdgesIterator (Graph<W, D> graphC)

: base(graphC)

//установка на начало

public override void benig()

//установка в конец

public override void end()

//переход к следующей

public override void next()

public override Edge<W, D> state()

}

2.9 Итератор входящих ребер

2.9.1 Описание формата

АТД “Итератор входящих рёбер”:

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

ДАННЫЕ:

Параметры:

vertexNumber - номер вершины

ОПЕРАЦИИ:

Конструктор

Вход:номер вершины vertexNumb

Предусловия: нет

Процесс: создание объекта итератора входящих рёбер из заданной вершины

Выход: нет

Постусловия: создан объект итератор входящих рёбер вершины

Установка итератора на первое входящее ребро

Вход:нет

Предусловия: нет

Процесс: установка итератор на первое входящее ребро вершины

Выход: нет

Постусловия: итератор установлен на первое входящее ребро вершины

Установка итератора на последнее входящее ребро

Вход:нет

Предусловия: нет

Процесс: установка итератор на последнее входящее ребро вершины

Выход: нет

Постусловия: итератор установлен на последнее входящее ребро вершины

Установка итератора на следующее ребро

Вход:нет

Предусловия: нет

Процесс: установка итератор на следующее входящее ребро вершины

Выход: нет

Постусловия: итератор установлен на следующее входящее ребро вершины

Получение дескриптора текущего ребра (проверка состояния)

Вход:нет

Предусловия: нет

Процесс: получение дескриптора ребра

Выход: дескриптор входящего ребра, вершины vertexNumber, на которое указывает итератор

Постусловия: нет

КОНЕЦ АТД

2.9.2 Клиентское определение класса

public class IncomingEdgesIterator<W, D> : Iterator<W, D>

{

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

public IncomingEdgesIterator (Graph<W, D> graphC)

: base(graphC)

//установка на начало

public override void benig()

//установка в конец

public override void end()

//переход на следующую

public override void next()

public override Edge<W, D> state()

}

Заключение

граф программный статический

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

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

1. Р. Сэджвик, «Фундаментальные алгоритмы на C++. Часть 5. Алгоритмы на графах», 2002 г. - 496 с.

Приложение

Исходные коды

Edge.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace RGR

{

public class Edge<W, D> : ICloneable

{

private int vertex1;

private int vertex2;

private W weight;

private D data;

public Edge()

{

vertex1 = -1;

vertex2 = -1;

}

public Edge(int v1, int v2)

{

vertex1 = v1;

vertex2 = v2;

}

public Edge(int v1, int v2, W w)

{

vertex1 = v1;

vertex2 = v2;

weight = w;

}

public Edge(int v1, int v2, W w, D d)

{

vertex1 = v1;

vertex2 = v2;

weight = w;

data = d;

}

public Object Clone()

{

return new Edge<W, D>(Vertex1, Vertex2, Weight, Data);

}

public int Vertex1

{

set

{

vertex1 = value;

}

get

{

return vertex1;

}

}

public int Vertex2

{

set

{

vertex2 = value;

}

get

{

return vertex2;

}

}

public W Weight

{

set

{

weight =value;

}

get

{

return weight;

}

}

public D Data

{

set

{

data = value;

}

get

{

return data;

}

}

}

}

Graph.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace RGR

{

public abstract class Graph<W, D>

{

public static int MAXVERTICESCOUNT = 10;

private int verticesCount;

private int edgesCount;

private bool directed;

public SortedDictionary<int, int> dictionary;

public Graph()

{

verticesCount = 0;

edgesCount = 0;

directed = false;

}

public Graph(int cVertex, bool cDirected)

{

verticesCount = cVertex;

edgesCount = 0;

directed = cDirected;

}

public Graph(int cVertex, int cEdge, bool cDirected)

{

verticesCount = cVertex;

edgesCount = cEdge;

directed = cDirected;

}

public int getVerticesCount()

{

return verticesCount;

}

public void increaseVerticesCount()

{

verticesCount++;

}

public void decreaseVerticesCount()

{

verticesCount--;

}

public int getEdgesCount()

{

return edgesCount;

}

public void increaseEdgesCount()

{

edgesCount++;

}

public void decreaseEdgesCount()

{

edgesCount--;

}

public void decreaseEdgesCount(int decrease)

{

edgesCount -= decrease;

}

public bool isDirected()

{

return directed;

}

abstract public bool getType();

public double denseCoef()

{

if (directed) return (double)edgesCount / ((double)verticesCount * ((double)verticesCount - 1.0));

return 2.0 * (double)edgesCount / ((double)verticesCount * ((double)verticesCount - 1.0));

}

abstract public Graph<W, D> toListGraph();

abstract public Graph<W, D> toMatrixGraph();

abstract public bool addVertex(int vertexNumber);

abstract public bool removeVertex(int vertexNumber);

abstract public bool addEdge(int vertex1, int vertex2);

abstract public bool addEdge(Edge<W, D> edge);

abstract public bool removeEdge(int vertex1, int vertex2);

abstract public bool hasEdge(int vertex1, int vertex2);

abstract public W getEdgeWeight(int vertex1, int vertex2);

abstract public bool setEdgeWeight(int vertex1, int vertex2, W weight);

abstract public D getEdgeData(int vertex1, int vertex2);

abstract public bool setEdgeData(int vertex1, int vertex2, D data);

abstract public List<int> getNeighbors(int vertexNumber);

//---PARENT ITERATORS--------------------------------

public abstract class Iterator<W, D>

{

public Graph<W, D> graph;

public Edge<W, D> currentPosition;

public Iterator(Graph<W, D> graphC)

{

graph = graphC;

begin();

}

public abstract void begin();

public abstract void end();

public abstract void next();

public abstract Edge<W, D> state();

}

}

}

LGraph.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace RGR

{

class LGraph<W, D> : Graph<W, D>, ICloneable

{

private List<List<Edge<W, D>>> adjacencyList;

public LGraph()

: base()

{

adjacencyList = new List<List<Edge<W, D>>>();

dictionary = new SortedDictionary<int, int>();

}

public LGraph(int cVertex, bool cDirected)

: base(cVertex, cDirected)

{

dictionary = new SortedDictionary<int, int>();

adjacencyList = new List<List<Edge<W, D>>>(cVertex);

for (int i = 0; i < cVertex; i++)

{

adjacencyList.Add(new List<Edge<W, D>>());

dictionary.Add(i, i);

}

}

public LGraph(int cVertex, int cEdge, bool cDirected)

: base(cVertex, cDirected)

{

adjacencyList = new List<List<Edge<W, D>>>(cVertex);

dictionary = new SortedDictionary<int, int>();

for (int i = 0; i < cVertex; i++)

{

adjacencyList.Add(new List<Edge<W, D>>());

dictionary.Add(i, i);

}

Random rand = new Random();

for (int i = 0; i < cEdge; )

{

int vertex1 = rand.Next(cVertex);

int vertex2 = rand.Next(cVertex);

bool edgeInserted = addEdge(vertex1, vertex2);

if (edgeInserted) i++;

}

}

public LGraph(int cVertex, int cEdge, List<List<Edge<W, D>>> list, bool cDirected)

: base(cVertex, cEdge, cDirected)

{

adjacencyList = list;

}

public override bool getType()

{

return true;

}

public override bool addVertex(int vertexNumber)

{

if (vertexNumber < 0) return false;

dictionary.Add(vertexNumber, adjacencyList.Count);

adjacencyList.Add(new List<Edge<W, D>>());

increaseVerticesCount();

return true;

}

public override bool removeVertex(int vertexNumber)

{

if (vertexNumber < 0) return false;

else

{

int deleteIndex = dictionary[vertexNumber];

decreaseEdgesCount(adjacencyList[deleteIndex].Count);

adjacencyList.RemoveAt(deleteIndex);

decreaseVerticesCount();

foreach (List<Edge<W, D>> list in adjacencyList)

{

for (int i = 0; i < list.Count; )

{

if (list[i].Vertex2 == deleteIndex)

{

list.RemoveAt(i);

decreaseEdgesCount();

}

else

{

if (list[i].Vertex1 > deleteIndex) list[i].Vertex1--;

if (list[i].Vertex2 > deleteIndex) list[i].Vertex2--;

i++;

}

}

}

dictionary.Remove(vertexNumber);

for (int key = 0; key <= MAXVERTICESCOUNT; key++)

{

int value;

if (dictionary.TryGetValue(key, out value))

{

if (value > vertexNumber)

{

dictionary.Remove(key);

dictionary.Add(key, value - 1);

}

}

}

return true;

}

}

public override bool addEdge(int vertex1, int vertex2)

{

if (vertex1 == vertex2 || !dictionary.ContainsKey(vertex1) || !dictionary.ContainsKey(vertex2)) return false;

if (hasEdge(vertex1, vertex2)) return false;

int source = dictionary[vertex1];

int destanation = dictionary[vertex2];

Edge<W, D> newEdge = new Edge<W, D>(source, destanation);

bool inserted = false;

if (source < 0 || destanation < 0 || source == destanation) return false;

if (adjacencyList[source].Count == 0)

{

adjacencyList[source].Add(newEdge);

increaseEdgesCount();

inserted = true;

}

else

{

foreach (Edge<W, D> edge in adjacencyList[source])

{

if (edge.Vertex1 == source && edge.Vertex2 == destanation)

return false;

}

adjacencyList[source].Add(newEdge);

increaseEdgesCount();

inserted = true;

}

if (inserted && !isDirected())

{

Edge<W, D> reverseEdge = new Edge<W, D>(destanation, source);

adjacencyList[destanation].Add(reverseEdge);

}

return inserted;

}

public override bool addEdge(Edge<W, D> edge)

{

if (edge == null) return false;

adjacencyList[edge.Vertex1].Add(edge);

increaseEdgesCount();

if (!isDirected())

{

Edge<W, D> reverseEdge = new Edge<W, D>(edge.Vertex2, edge.Vertex1, edge.Weight, edge.Data);

adjacencyList[edge.Vertex2].Add(reverseEdge);

}

return true;

}

public override bool removeEdge(int vertex1, int vertex2)

{

if (vertex1 == vertex2 || !dictionary.ContainsKey(vertex1) || !dictionary.ContainsKey(vertex2)) return false;

if (!hasEdge(vertex1, vertex2)) return false;

int source = dictionary[vertex1];

int destanation = dictionary[vertex2];

if (source > getVerticesCount() - 1 || destanation > getVerticesCount() - 1 || source < 0 || destanation < 0) return false;

for (int i = 0; i < adjacencyList[source].Count; i++)

if (adjacencyList[source][i].Vertex2 == destanation)

{

adjacencyList[source].RemoveAt(i);

decreaseEdgesCount();

if (!isDirected())

{

for (int j = 0; j < adjacencyList[destanation].Count; j++)

{

if (adjacencyList[destanation][j].Vertex2 == source)

adjacencyList[destanation].RemoveAt(j);

}

}

return true;

}

return false;

}

public override bool hasEdge(int vertex1, int vertex2)

{

int source;

int destanation;

if (dictionary.TryGetValue(vertex1, out source) && dictionary.TryGetValue(vertex2, out destanation))

{

if (source > getVerticesCount() - 1 || destanation > getVerticesCount() - 1 || source < 0 || destanation < 0 || source == destanation) return false;

for (int i = 0; i < adjacencyList[source].Count; i++)

if (adjacencyList[source][i].Vertex2 == destanation) return true;

}

return false;

}

public override W getEdgeWeight(int vertex1, int vertex2)

{

if (vertex1 == vertex2 || !dictionary.ContainsKey(vertex1) || !dictionary.ContainsKey(vertex2)) throw new ArgumentException();

if (!hasEdge(vertex1, vertex2)) throw new ArgumentException();

int source = dictionary[vertex1];

int destanation = dictionary[vertex2];

if (source > getVerticesCount() - 1 || destanation > getVerticesCount() - 1 || source < 0 || destanation < 0) throw new ArgumentOutOfRangeException("this edge does not exist");

for (int i = 0; i < adjacencyList[source].Count; i++)

if (adjacencyList[source][i].Vertex2 == destanation) return adjacencyList[source][i].Weight;

throw new ArgumentOutOfRangeException("Ребро не существует");

}

public override bool setEdgeWeight(int vertex1, int vertex2, W weight)

{

if (vertex1 == vertex2 || !dictionary.ContainsKey(vertex1) || !dictionary.ContainsKey(vertex2)) return false;

if (!hasEdge(vertex1, vertex2)) return false;

int source = dictionary[vertex1];

int destanation = dictionary[vertex2];

if (source > getVerticesCount() - 1 || destanation > getVerticesCount() - 1 || source < 0 || destanation < 0) return false;

for (int i = 0; i < adjacencyList[source].Count; i++)

if (adjacencyList[source][i].Vertex2 == destanation)

{

adjacencyList[source][i].Weight = weight;

return true;

}

return false;

}

public override D getEdgeData(int vertex1, int vertex2)

{

if (vertex1 == vertex2 || !dictionary.ContainsKey(vertex1) || !dictionary.ContainsKey(vertex2)) throw new ArgumentException();

if (!hasEdge(vertex1, vertex2)) throw new ArgumentException();

int source = dictionary[vertex1];

int destanation = dictionary[vertex2];

if (source > getVerticesCount() - 1 || destanation > getVerticesCount() - 1 || source < 0 || destanation < 0) throw new ArgumentOutOfRangeException("this edge does not exist");

for (int i = 0; i < adjacencyList[source].Count; i++)

if (adjacencyList[source][i].Vertex2 == destanation) return adjacencyList[source][i].Data;

throw new ArgumentOutOfRangeException("Ребро не существует");

}

public override bool setEdgeData(int vertex1, int vertex2, D data)

{

if (vertex1 == vertex2 || !dictionary.ContainsKey(vertex1) || !dictionary.ContainsKey(vertex2)) return false;

if (!hasEdge(vertex1, vertex2)) return false;

int source = dictionary[vertex1];

int destanation = dictionary[vertex2];

if (source > getVerticesCount() - 1 || destanation > getVerticesCount() - 1 || source < 0 || destanation < 0) return false;

for (int i = 0; i < adjacencyList[source].Count; i++)

if (adjacencyList[source][i].Vertex2 == destanation)

{

adjacencyList[source][i].Data = data;

return true;

}

return false;

}

public Object Clone()

{

return new LGraph<W, D>(getVerticesCount(), getEdgesCount(), adjacencyList, isDirected());

}

public override Graph<W, D> toListGraph()

{

return this;

}

public override Graph<W, D> toMatrixGraph()

{

MGraph<W, D> mGraph = new MGraph<W, D>(getVerticesCount(), isDirected());

foreach (List<Edge<W, D>> listOfEdges in adjacencyList)

foreach (Edge<W, D> edge in listOfEdges)

{

mGraph.addEdge(edge);

}

mGraph.dictionary = dictionary;

return mGraph;

}

public override List<int> getNeighbors(int vertexNumber)

{

int currentVertexNeighbor = 0;

List<int> result = new List<int>();

int min = 100;

if (adjacencyList[vertexNumber].Count != 0)

{

foreach (Edge<W, D> edge in adjacencyList[vertexNumber])

{

if (edge.Vertex2 < min && edge.Vertex2 >= currentVertexNeighbor)

{

min = edge.Vertex2;

}

}

result.Add(min);

currentVertexNeighbor = min;

}

while (true)

{

int old = currentVertexNeighbor;

min = 100;

foreach (Edge<W, D> edge in adjacencyList[vertexNumber])

{

if (edge.Vertex2 < min && edge.Vertex2 > old)

{

min = edge.Vertex2;

}

}

if (min == 100)

{

currentVertexNeighbor = 0;

return result;

}

currentVertexNeighbor = min;

result.Add(currentVertexNeighbor);

}

}

public class VertexIterator<W, D> : Iterator<W, D>

{

public VertexIterator(Graph<W, D> graphC)

: base(graphC)

{

}

public override void begin()

{

if (graph.getVerticesCount() == 0)

{

currentPosition = null;

return;

}

int min = 100;

foreach (KeyValuePair<int, int> entry in graph.dictionary)

{

if (entry.Key < min) min = entry.Key;

}

currentPosition = new Edge<W, D>(min, 100);

}

public override void end()

{

if (graph.getVerticesCount() == 0)

{

currentPosition = null;

return;

}

int max = 0;

foreach (KeyValuePair<int, int> entry in graph.dictionary)

{

if (entry.Key > max) max = entry.Key;

}

currentPosition = new Edge<W, D>(max, 100);

}

public override void next()

{

if (currentPosition == null)

{

return;

}

int min = 100;

int old = currentPosition.Vertex1;

foreach (KeyValuePair<int, int> entry in graph.dictionary)

{

if (entry.Key < min && entry.Key > old) min = entry.Key;

}

if (min != 100)

{

currentPosition = new Edge<W, D>(min, 100);

}

else

{

currentPosition = null;

}

}

public override Edge<W, D> state()

{

return currentPosition;

}

}

public class EdgeIterator<W, D> : Iterator<W, D>

{

int lastI = 0;

int lastJ = 0;

int edgesCount = 0;

public EdgeIterator(Graph<W, D> graphC)

: base(graphC)

{

}

public override void begin()

{

if (graph.getVerticesCount() == 0)

{

currentPosition = null;

return;

}

if (graph.isDirected())

{

int i = 0;

int j = 0;

bool isExist = false;

while (!isExist)

{

if (i == ((LGraph<W, D>)graph).adjacencyList.Count)

{

currentPosition = null;

return;

}

if (((LGraph<W, D>)graph).adjacencyList[i].Count == 0) i++;

else

{

isExist = true;

}

}

int source = ((LGraph<W, D>)graph).adjacencyList[i][j].Vertex1;

int destanation = ((LGraph<W, D>)graph).adjacencyList[i][j].Vertex2;

int sourceVertex = 0;

int destanationVertex = 0;

foreach (KeyValuePair<int, int> entry in graph.dictionary)

{

if (entry.Value == source) sourceVertex = entry.Key;

if (entry.Value == destanation) destanationVertex = entry.Key;

}

currentPosition = new Edge<W, D>(sourceVertex, destanationVertex, graph.getEdgeWeight(sourceVertex, destanationVertex), graph.getEdgeData(sourceVertex, destanationVertex));

lastI = i;

lastJ = j;

edgesCount = 1;

}

else

{

for (int i = 0; i <= MAXVERTICESCOUNT; i++)

{

for (int j = 0; j <= MAXVERTICESCOUNT; j++)

{

if (!graph.dictionary.ContainsKey(i) || !graph.dictionary.ContainsKey(j)) continue;

if (graph.hasEdge(graph.dictionary[i], graph.dictionary[j]))

{

int sourceVertex = 0;

int destanationVertex = 0;

foreach (KeyValuePair<int, int> entry in graph.dictionary)

{

if (entry.Value == i) sourceVertex = entry.Key;

if (entry.Value == j) destanationVertex = entry.Key;

}

currentPosition = new Edge<W, D>(sourceVertex, destanationVertex, graph.getEdgeWeight(sourceVertex, destanationVertex), graph.getEdgeData(sourceVertex, destanationVertex));

lastI = i;

lastJ = j;

edgesCount = 1;

return;

}

}

lastJ = i;

}

}

}

public override void end()

{

if (graph.getVerticesCount() == 0)

{

currentPosition = null;

return;

}

if (graph.isDirected())

{

int i = ((LGraph<W, D>)graph).adjacencyList.Count - 1;

bool isExist = false;

while (!isExist)

{

if (i == -1)

{

currentPosition = null;

return;

}

if (((LGraph<W, D>)graph).adjacencyList[i].Count == 0) i--;

else

{

isExist = true;

}

}

int j = ((LGraph<W, D>)graph).adjacencyList[i].Count - 1;

int source = ((LGraph<W, D>)graph).adjacencyList[i][j].Vertex1;

int destanation = ((LGraph<W, D>)graph).adjacencyList[i][j].Vertex2;

int sourceVertex = i;

int destanationVertex = j;

foreach (KeyValuePair<int, int> entry in graph.dictionary)

{

if (entry.Value == source) sourceVertex = entry.Key;

if (entry.Value == destanation) destanationVertex = entry.Key;

}

currentPosition = new Edge<W, D>(sourceVertex, destanationVertex, graph.getEdgeWeight(sourceVertex, destanationVertex), graph.getEdgeData(sourceVertex, destanationVertex));

edgesCount = graph.getEdgesCount();

}

else

{

for (int i = MAXVERTICESCOUNT; i >= 0; i--)

for (int j = MAXVERTICESCOUNT; j >= i; j--)

{

if (i == j || !graph.dictionary.ContainsKey(i) || !graph.dictionary.ContainsKey(j)) continue;

if (graph.hasEdge(i, j))

{

int sourceVertex = 0;

int destanationVertex = 0;

foreach (KeyValuePair<int, int> entry in graph.dictionary)

{

if (entry.Value == i) sourceVertex = entry.Key;

if (entry.Value == j) destanationVertex = entry.Key;

}

currentPosition = new Edge<W, D>(sourceVertex, destanationVertex, graph.getEdgeWeight(sourceVertex, destanationVertex), graph.getEdgeData(sourceVertex, destanationVertex));

lastI = i;

lastJ = j;

edgesCount = graph.getEdgesCount();

return;

}

}

}

}

public override void next()

{

if (currentPosition == null)

{

return;

}

if (edgesCount == graph.getEdgesCount())

{

currentPosition = null;

return;

}

if (graph.isDirected())

{

int i = lastI;

int j = lastJ + 1;

if (j == ((LGraph<W, D>)graph).adjacencyList[i].Count)

{

j = 0;

i++;

}

bool isExist = false;

while (!isExist)

{

if (i == ((LGraph<W, D>)graph).adjacencyList.Count)

{

currentPosition = null;

return;

}

if (((LGraph<W, D>)graph).adjacencyList[i].Count == 0) i++;

else

{

isExist = true;

}

}

if (i == ((LGraph<W, D>)graph).adjacencyList.Count)

{

currentPosition = null;

return;

}

int source = ((LGraph<W, D>)graph).adjacencyList[i][j].Vertex1;

int destanation = ((LGraph<W, D>)graph).adjacencyList[i][j].Vertex2;

int sourceVertex = 0;

int destanationVertex = 0;

foreach (KeyValuePair<int, int> entry in graph.dictionary)

{

if (entry.Value == source) sourceVertex = entry.Key;

if (entry.Value == destanation) destanationVertex = entry.Key;

}

currentPosition = new Edge<W, D>(sourceVertex, destanationVertex, graph.getEdgeWeight(sourceVertex, destanationVertex), graph.getEdgeData(sourceVertex, destanationVertex));

edgesCount++;

lastI = i;

lastJ = j;

return;

}

else

{

for (int i = lastI; i <= MAXVERTICESCOUNT; i++)

{

for (int j = lastJ + 1; j <= MAXVERTICESCOUNT; j++)

{

if (i == j || !graph.dictionary.ContainsKey(i) || !graph.dictionary.ContainsKey(j)) continue;

if (graph.hasEdge(i, j))

{

int sourceVertex = i;

int destanationVertex = j;

currentPosition = new Edge<W, D>(sourceVertex, destanationVertex, graph.getEdgeWeight(sourceVertex, destanationVertex), graph.getEdgeData(sourceVertex, destanationVertex));

lastI = i;

lastJ = j;

edgesCount++;

return;

}

}

lastJ = i;

}

}

}

public override Edge<W, D> state()

{

return currentPosition;

}

}

public class IncomingEdgesIterator<W, D> : Iterator<W, D>

{

int lastI = 0;

int vertexNumb = -2;

public IncomingEdgesIterator(Graph<W, D> graphC, int vertexNumbC)

: base(graphC)

{

vertexNumb = graph.dictionary[vertexNumbC];

begin();

}

public override void begin()

{

if (vertexNumb == -2) return;

if (graph.getVerticesCount() == 0)

{

currentPosition = null;

return;

}

for (int i = 0; i < graph.getVerticesCount(); i++)

{

int source = 0;

int destanation = 0;

foreach (KeyValuePair<int, int> entry in graph.dictionary)

{

if (entry.Value == i) source = entry.Key;

if (entry.Value == vertexNumb) destanation = entry.Key;

}

if (graph.hasEdge(source, destanation))

{

currentPosition = new Edge<W, D>(source, destanation, graph.getEdgeWeight(source, destanation), graph.getEdgeData(source, destanation));

lastI = i;

return;

}

if (i == graph.getVerticesCount() - 1)

{

currentPosition = null;

}

}

}

public override void end()

{

if (graph.getVerticesCount() == 0)

{

currentPosition = null;

return;

}

for (int i = graph.getVerticesCount() - 1; i >= 0; i--)

{

int source = 0;

int destanation = 0;

foreach (KeyValuePair<int, int> entry in graph.dictionary)

{

if (entry.Value == i) source = entry.Key;

if (entry.Value == vertexNumb) destanation = entry.Key;

}

if (graph.hasEdge(source, destanation))

{

currentPosition = new Edge<W, D>(source, destanation, graph.getEdgeWeight(source, destanation), graph.getEdgeData(source, destanation));

lastI = i;

return;

}

if (i == 0)

{

currentPosition = null;

}

}

}

public override void next()

{

if (currentPosition == null)

{

return;

}

int i;

for (i = lastI + 1; i < graph.getVerticesCount(); i++)

{

int source = 0;

int destanation = 0;

foreach (KeyValuePair<int, int> entry in graph.dictionary)

{

if (entry.Value == i) source = entry.Key;

if (entry.Value == vertexNumb) destanation = entry.Key;

}

if (graph.hasEdge(source, destanation))

{

currentPosition = new Edge<W, D>(source, destanation, graph.getEdgeWeight(source, destanation), graph.getEdgeData(source, destanation));

lastI = i;

return;

}

}

if (i == graph.getVerticesCount())

{

currentPosition = null;

}

}

public override Edge<W, D> state()

{

return currentPosition;

}

}

public class OutGoingEdgesIterator<W, D> : Iterator<W, D>

{

int lastI = 0;

int vertexNumb = -2;

public OutGoingEdgesIterator(Graph<W, D> graphC, int vertexNumbC)

: base(graphC)

{

vertexNumb = graph.dictionary[vertexNumbC];

begin();

}

public override void begin()

{

if (vertexNumb == -2) return;

if (graph.getVerticesCount() == 0)

{

currentPosition = null;

return;

}

if (((LGraph<W, D>)graph).adjacencyList[vertexNumb].Count == 0)

{

currentPosition = null;

return;

}

int i = 0;

int source = ((LGraph<W, D>)graph).adjacencyList[vertexNumb][i].Vertex1;

int destanation = ((LGraph<W, D>)graph).adjacencyList[vertexNumb][i].Vertex2;

bool sourceOK = false;

bool destanationOK = false;

foreach (KeyValuePair<int, int> entry in graph.dictionary)

{

if (entry.Value == source && !sourceOK)

{

source = entry.Key;

sourceOK = true;

}

if (entry.Value == destanation && !destanationOK)

{

destanation = entry.Key;

destanationOK = true;

}

}

currentPosition = new Edge<W, D>(source, destanation, graph.getEdgeWeight(source, destanation), graph.getEdgeData(source, destanation));

lastI = i;

}

public override void end()

{

if (graph.getVerticesCount() == 0)

{

currentPosition = null;

return;

}

if (((LGraph<W, D>)graph).adjacencyList[vertexNumb].Count == 0)

{

currentPosition = null;

return;

}

int i = ((LGraph<W, D>)graph).adjacencyList[vertexNumb].Count - 1;

int source = ((LGraph<W, D>)graph).adjacencyList[vertexNumb][i].Vertex1;

int destanation = ((LGraph<W, D>)graph).adjacencyList[vertexNumb][i].Vertex2;

bool sourceOK = false;

bool destanationOK = false;

foreach (KeyValuePair<int, int> entry in graph.dictionary)

{

if (entry.Value == source && !sourceOK)

{

source = entry.Key;

sourceOK = true;

}

if (entry.Value == destanation && !destanationOK)

{

destanation = entry.Key;

destanationOK = true;

}

}

currentPosition = new Edge<W, D>(source, destanation, graph.getEdgeWeight(source, destanation), graph.getEdgeData(source, destanation));

lastI = i;

}

public override void next()

{

if (currentPosition == null)

{

return;

}

int i = lastI + 1;

if (i == ((LGraph<W, D>)graph).adjacencyList[vertexNumb].Count)

{

currentPosition = null;

return;

}

int source = ((LGraph<W, D>)graph).adjacencyList[vertexNumb][i].Vertex1;

int destanation = ((LGraph<W, D>)graph).adjacencyList[vertexNumb][i].Vertex2;

bool sourceOK = false;

bool destanationOK = false;

foreach (KeyValuePair<int, int> entry in graph.dictionary)

{

if (entry.Value == source && !sourceOK)

{

source = entry.Key;

sourceOK = true;

}

if (entry.Value == destanation && !destanationOK)

{

destanation = entry.Key;

destanationOK = true;

}

}

currentPosition = new Edge<W, D>(source, destanation, graph.getEdgeWeight(source, destanation), graph.getEdgeData(source, destanation));

lastI = i;

}

public override Edge<W, D> state()

{

return currentPosition;

}

}

}

}

MGraph.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace RGR

{

class MGraph<W, D> : Graph<W, D>, ICloneable

{

Edge<W, D>[,] adjacencyMatrix;

public MGraph(int cVertex, bool cDirected)

: base(cVertex, cDirected)

{

adjacencyMatrix = new Edge<W, D>[cVertex * 2, cVertex * 2];

dictionary = new SortedDictionary<int, int>();

for (int i = 0; i < cVertex; i++)

{

dictionary.Add(i, i);


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

  • Использование теории графов для решения задач. Информационные структуры входных и выходных данных. Иерархическая схема программы. Руководство оператора: назначение и условия выполнения программы. Граф-схема FormCreate, Found, RassUpdate и Search.

    курсовая работа [2,5 M], добавлен 07.08.2013

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

    реферат [411,5 K], добавлен 25.01.2010

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

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

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

    курсовая работа [162,2 K], добавлен 04.02.2011

  • Интерфейсы, используемые коллекциями. Применение перечислителя типа IDictionaryEnumerator. Специальные и наблюдаемые коллекции. Итераторы и оператор yield. Основные обобщенные коллекции. Реализация интерфейсов IComparer, IEnumerable и IEnumerator.

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

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

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

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

    курсовая работа [493,3 K], добавлен 27.12.2008

  • Граф - совокупность точек и линий, в которой каждая линия соединяет две точки. Представление графов в ЭВМ. Составление алгоритм Краскала с использованием графов с оперделением оптимального пути прокладки телефонного кабеля в каждый из 8 городов.

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

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

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

  • Алгоритм декомпозиции графов и расчеты динамики логических сетей. Преобразование пространства булевых векторов. Описание блоков программной реализации и их взаимодействие. Разработка программы "слияния" статистик на основе алгоритма объединения.

    дипломная работа [111,8 K], добавлен 07.03.2012

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