Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Дискретная математика / Практика / Лабароторный практикум.doc
Скачиваний:
101
Добавлен:
03.05.2015
Размер:
1.07 Mб
Скачать

Технология выполнения работы.

Рассмотрим возможные подходы к построению программы и используемым типам данных.

1. Множество X, на котором задано бинарное отношение, можно определить статическим одномерным массивом, количество элементов множества – символьной константой. Например,

const int n=5; int X []={1, 2, 3, 4, 5};

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

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

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

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

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

Тип элементов вектора задаётся при описании переменной этого типа. Например, исходное множество X вариантов задания описывается как

vector <int> X ;

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

typedef vector <int> i_set;

typedef vector <vector <int>> matrix;

Так как размер матрицы бинарного отношения n определён после ввода множества, на котором задано отношение, то можно выделить для неё память и инициализировать элементы матрицы

с помощью инструкций

matrix R(n);

for (i=0; i<n; i++) R[i].resize(n);

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

В основной программе строится и печатается матрица бинарного отношения (печать матрицы можно оформить в виде функции). Передача матрицы функции в качестве параметра в этом случае осуществляется через ссылку (matrix&).

Затем для каждого элемента множества X проверяется условие п. а), если условие выполнено, то вызывается функция построения соответствующего среза этого элемента. Верхние или нижние срезы элементов следует сохранить в соответствующей матрице срезов. Если для представления матрицы используется тип matrix, то для объявления переменной воспользуемся конструктором с инициализацией (например, matrix Gs(n);), который выделит память под n пустых векторов. Заполнение соответствующего вектора будет выполняться при построении среза заданного элемента, причем количество элементов в векторе равно числу элементов в соответствующем срезе.

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

void v_srez (int k, int n, int* X, matrix& R, matrix& G);

В теле функции необходимо проверить k-ую строку (для нижних срезов) или k-ый столбец (для верхних срезов) матрицы бинарного отношения. Если элемент матрицы равен 1, то в матрицу срезов необходимо записать соответствующий элемент множества X в конец вектора с помощью функции.push_back(el). Количество записанных в вектор элементов можно получить с помощью функции .size(). На печать выводятся только построенные срезы, печать можно выполнять параллельно с заполнением матрицы срезов.

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

bool refleks(matrix& R,int n);

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