МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ

advertisement
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ
Федеральное государственное бюджетное образовательное учреждение высшего
профессионального образования
«КУБАНСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ»
(ФГБОУ ВПО «КубГУ»)
Кафедра вычислительных технологий
ОЦЕНКА ВЕРОЯТНОСТИ ПОЯВЛЕНИЯ РЕДКИХ ГРАФОВ
Д.О.Валуйский
Краснодар 2014
СОДЕРЖАНИЕ
ВВЕДЕНИЕ .............................................................................................................. 3
1 Постановка задачи................................................................................................ 4
1.1 Вводная информация. ................................................................................. 4
1.2 Об ad hoc сетях. ........................................................................................... 5
1.3 Анализ поставленной задачи. .................................................................... 6
1.4 Многопоточность и распараллеливание средствами языка C#.............. 8
2 Выполнение поставленной задачи. .................................................................. 10
2.1 Предварительный этап работы программы. ........................................... 10
2.2 Реализация компонент программы. ........................................................ 11
2.3 Анализ результатов работы программы. ................................................ 12
ЗАКЛЮЧЕНИЕ ..................................................................................................... 16
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ ........................................... 17
ПРИЛОЖЕНИЕ А.Код вспомогательных функций .......................................... 18
2
ВВЕДЕНИЕ
При исследовании геометрических графов, моделирующих ad hoc сети,
выяснилось, что некоторые графы встречаются очень редко, а другие графы –
довольно часто.
Например, при генерации одного млн. случайных геометрических
графов с 6 вершинами и сопоставлении их со 156 возможными
обыкновенными графами получается, что в среднем каждый граф мог бы
встречаться 1000000 / 156 = 6410 раз.
Но частота появления многих графов зависит от радиуса зоны
покрытия вершины графа (узла в ad hoc сети). Так, например, полный граф
K6 при радиусе зоны покрытия большем 0,4 встречается более 5 тысяч раз.
При уменьшении радиуса частота его появления сводится к единичным
случаям.
Так же есть графы, которые встречаются намного чаще, чем
среднестатистические, и реже, чем среднестатистические. Интерес для нас
представляют редкие графы, то есть графы, которые при любом заданном
радиусе покрытия встречаются очень редко. Примером редкого графа
является несвязный граф, состоящий из двух компонент: граф-звезда с одной
центральной вершиной и пятью периферийными и одна изолированная
вершина.
Задачей моей курсовой является оценка вероятностей для таких графов.
Сложность данной работы – в оптимизации времени работы вычислительной
машины. Если за один миллион статистических экспериментов редкий граф
встретился всего один раз, то это еще не означает, что вероятность его
появления 10-6. Для получения надежной оценки необходимо, чтобы граф
встретился желательно несколько тысяч раз. Это приводит нас к увеличению
статистических экспериментов до нескольких миллиардов раз.
В данной работе я попробовал решить проблему вычислительной
сложности и свести время работы программы к разумным границам.
3
1 Постановка задачи.
1.1 Вводная информация.
Теория графов представляет собой раздел математики, имеющий
широкие практические приложения. Многие проблемы, возникающие в таких
весьма различных областях знания, как психология, химия, электротехника,
планирования перевозок и образование, могут быть сформулированы как
задачи теории графов.
Геометрическим графом G называют пару множеств (V,E), где V –
множество точек пространств, а E –множество простых кривых (возможно,
направленных), удовлетворяющих следующим условиям:
а) Каждая замкнутая кривая множества E содержит только одну точку
множества V;
б) Каждая незамкнутая кривая множества E содержит ровно две точки
множества V;
в) Кривые множества U не имеют общих точек, за исключением точек
из множества V.
Элементами множества V называют вершинами графа, а само это
множество – носителем графа; элементы множества E называются ребрами
графа, а само E – его сигнатурой.
Таким образом, геометрический граф есть просто геометрическая
конфигурация или структура в пространстве, состоящая из множества точек,
взаимосвязанных множеством простых (не имеющих точек самопересечения)
кривых [1].
Данные графы могут использоваться для моделирования различных
объектов. В нашем случае, описывать строение Ad Hoc сетей.
4
1.2 Об ad hoc сетях.
На данный момент, одной из перспективных современной технологий
передачи данных являются беспроводные сети типа «ad hoc» (беспроводные
самоорганизующиеся сети). Их отличительной особенностью является
способность узлов такой сети соединяться «на лету». Если при этом сеть
является телекоммуникационной, то есть предназначенной для передачи
данных на значительные расстояния, превосходящие радиус действия
используемых приемопередающих устройств, то для передачи данных
необходимо использовать принцип «возьми и передай дальше». Технологии,
используемые при построении беспроводных самоорганизующихся сетей
различны. Это могут быть:
а) Bluetooth (IEEE 802.15.1);
б) WiFi (IEEE 802.11);
в) ZigBee (IEEE 802.15.4);
г) ONE-NET;
д) Wideband Networking Waveform.
Привлекательность технологий ad hoc сетей обусловлена многими
факторами. Во-первых, сети с данной технологией позволяют эффективно
использовать неиспользуемый большую часть времени коммуникационный
ресурс вычислительных систем, оснащенных интерфейсами беспроводной
связи. Кроме того, одноранговый принцип организации динамических сетей
обуславливает их высокую отказоустойчивость за счет исключения проблем
уязвимости центрального звена, характерной для систем с асимметричной
функциональностью. Поскольку в ad hoc сетях каждый узел обязан
выполнять роль маршрутизатора, то отказ любого из них не является
критичным для работоспособности сети в целом.
Минимальное конфигурирование и быстрое развертывание позволяет
использовать данный тип сетей в чрезвычайных ситуациях, таких как
5
природные катастрофы и военные конфликты. Эти преимущества заставляют
разработчиков
активно
развивать
технологию
беспроводных
самоорганизующихся сетей, даже, несмотря на относительно высокую
сложность их реализации [2].
В качестве основного формального представления такой сети, как уже
было сказано выше, используется геометрический граф, где множество
вершин V – это множество узлов сети, а множество E – это множество ребер.
Ребро соединяет два узла сети, если расстояния между ними меньше или
равно радиусу покрытия этих узлов.
Важным обстоятельством беспроводной самоорганизующейся
сети
является то, что узлы могут включаться и выключаться из нее в любой
момент, что предопределяет случайный характер структуры сети. Именно из
данного
фактора
появления
вытекает
различных
необходимость
графов,
что
вычисления
приводит
нас
к
вероятности
применению
статистических методов и теории вероятности, которые позволили бы
выявить и изучить закономерности появления при генерации различных
графов во время моделирования системы.
1.3 Анализ поставленной задачи.
Как было сказано в ведении, задача данной работы состоит в вычислении
вероятности появления редких графов при их случайной генерации. Редкими
графами считаются графы, которые из миллиона случаев появляются всего
десятки раз, а то и не появляются ни разу. Но данные показатели не
позволяют выявить точное значение вероятности для таких графов. Именно
поэтому, количество генераций случайных величин во время экспериментов
должно увеличиться в разы (до 10 миллиардов генераций). При этом
появляется несколько проблем, связанных с решением поставленной задачи.
Одним из вопросов, требующих рассмотрения при создании описанной
выше программы – это проверка сгенерированных графов на изоморфизм
6
редким графам. В теории графов изоморфизмом графов G=(VG,EG) и
H=(VH,EH) называется биекция между множествами вершин графов
f: VG ->VH такая, что любые две вершины u и v графа G смежны тогда и
только тогда, когда вершины f(u) и f(v) смежны в графе H. Иначе говоря,
графы G и H являются изоморфными, если путем перестановки строк и
столбцов матрицы смежности графа G удается получить матрицу смежности
графа H. Однако перебор всех возможных перестановок характеризуется
вычислительной сложностью O(N!) (при условии, что сравнение матриц
смежности производится за время, не зависящее от N, что обычно
несправедливо и дополнительно увеличивает приведенную оценку). Это
существенно ограничивает применение подобного подхода на практике.
Для уменьшения вычислительной сложности проверки изоморфизма
графов, мной были использованы полные инварианты графов.
Инвариант графа – это некоторое числовое значение или упорядоченный
набор значений (хэш-функция), характеризующее структуру графа G=(V,E) и
не зависящее от способа обозначения вершин или графического изображения
графа. Существует большое количество различных инвариантов (диаметр
графа, индекс Винера, обхват графа и т.д.). Полным инвариантом графа
называются инварианты, совпадение которых необходимо для установления
изоморфизма. Такими инвариантами является мини-код и макси-код графа.
Данные коды получается путем выписывание в строку двоичных значений
матрицы смежности с последующим переводом полученного двоичного
числа в десятичную форму. Мини-коду соответствует такой порядок
следования строк и столбцов, при котором полученное значение является
минимально возможным; макси-коду – соответственно максимальный [3].
Для своей работы я использовал инвариант графа мини-код. Так как наш
генерируемый граф является моделью сети связи, то дуги в нем
неориентированные, а, следовательно, можно рассматривать матрицу
смежности только выше главной диагонали, не опасаясь потерять свойство
полноты инварианта.
7
Еще одним вопросом, требующим внимания, была задача уменьшения
вычислительной сложности при генерации случайных графов, а вместе с ней
и времени работы программы. Для решения этой проблемы в данной работе
было решено использовать многопоточность.
1.4 Многопоточность и распараллеливание средствами языка C#.
Для
реализации
поставленной
задачи
мной
был
выбран
язык
программирования С#. Это было сделано по ряду причин. Во-первых, С# это
мощный
язык
ориентированную
разнообразных
программирования,
парадигму.
приложений,
Он
от
поддерживающий
предназначен
простых
для
приложений
объектноразработки
Windows
до
приложений типа «клиент – сервер - база данных», выполняемых в среде
.NET Framework. Во-вторых, данный язык имеет встроенную поддержку
многопоточного
программирования.
Благодаря
этому,
C#
позволяет
полностью избежать возможных «подводных камней», появляющихся во
время разработки многопоточного приложения, или, в худшем случае, свести
их к минимуму [4].
Многопоточность – это свойство приложения выполнять некоторый
определенный процесс параллельно, то есть без предписанного порядка во
времени. Сутью многопоточности является квазимногозадачность на уровне
одного исполняемого процесса, то есть все потоки выполняются в адресном
пространстве процесса. Кроме этого, все потоки процесса имеют не только
общее адресное пространство, но и общие дескрипторы файлов.
Управление многопоточностью осуществляет планировщик потоков. На
однопроцессорных
квантование
компьютерах
планировщик
потоков
использует
времени – быстрое переключение между выполнениями
каждого из активных потоков.
На многопроцессорных компьютерах многопоточность реализована как
смесь квантования и подлинного параллелизма, когда разные потоки
8
выполняют код на разных CPU. Необходимость квантования остается, так
как операционной системе необходимо переключаться между выполнениями
потоков приложений и своих собственных процессов [5].
Недостатком
использования
потоков
является
их
сложность
и
необходимость организации их взаимодействия. Так же, большое количество
потоков (число потоков больше количества ядер компьютера) требует
больших затрат на переключение между ними, тем самым, увеличивая время
работы программы.
Многопоточность в среде .NET Framework реализована следующим
образом: существует два типа потока:
а)
Высокоприоритетный;
б) Низкоприоритетный;
Высокоприоритетный
поток
назначается
потоком
по
умолчанию.
Программа не будет закрыта, пока не выполняться все потоки данного
уровня.
Низкоприоритетный поток так же называется фоновым потоком. Он
может быть прерван по окончании работы потока высокоприоритетного.
В
классы,
C#,
отвечающие
за
поддержку
многопоточного
программирования, определены в пространстве имен System.Threading.
Каждый новый поток инициализируется с помощью конструктора Thread(
function_name), где function_name – это название процедуры, код которой
каждый поток будет выполнять. Для запуска работы потока необходимо
вызвать метод Start(). Если необходимо передать данные в тело процедуры,
выполняемой потоком, необходимо вызвать перегрузку метода Start(object),
где object –передаваемые данные. Выполнение потока можно приостановить
методами Join() (поток будет ожидать выполнение другого потока) и
Sleep(time)
(поток
будет
приостановлен
миллисекунд).
9
на
указанное
количество
2 Выполнение поставленной задачи.
2.1 Предварительный этап работы программы.
Для решения поставленной задачи мной была написана задача,
вычисляющая количество появлений редких графов при заданном количестве
генераций случайных графов.
На первом этапе задаются все входные данные, необходимые для
соблюдения поставленных нами условий:
а) Кнопка «Добавление графов» позволяет нам регулировать, для каких
именно редких графов будет производиться подсчет появлений. На
вход поддаются мини-коды редких графов.
б) Поля
«Максимальная
граница»
и
«Минимальная
граница»
необходимы для задания диапазона, в границах которого будет
меняться радиус покрытия узлами нашей сети. Шаг изменения
радиуса равен 0,05. Это обусловлено условиями задачи (генерация
вершин графа происходит внутри квадрата [0;1][0;1]).
в) Поле «Кол-во потоков» задает количество потоков, которые будут
параллельно выполняться.
г) Поле «Кол-во генераций» задает количество генераций случайных
графов. Данное количество генераций будет выполняться на каждом
шаге изменения радиуса радиосвязи узла.
Дальше происходит запуск генераций графов. Общее число генераций
делится на количество потоков, и каждый поток выполняет свое количество
генераций.
Перед непосредственным запуском генераций графов, каждый из потоков
проделывает подготовительный этап: для каждого добавленного редкого
графа по его мини-коду строится матрица смежности, после чего происходит
перестановка строк и столбцов. Каждая новая полученная
матрица
смежности переводится в десятичное число (используется тот же алгоритм,
что и для получения мини-кода графа). Данные числа заносятся в хэш10
таблицу, общую для всех графов. Таким образом, по завершению
подготовительного этапа, каждый потов имеет свою таблицу, в которой
сопоставлены коды графа и его мини-код.
Сама генерация графов происходит уже внутри цикла, выполняющегося
необходимое
число
раз,
и
представляет
собой
несколько
этапов:
генерируются 6 вершин, вычисляется расстояние между ними, полученное
расстояние сравнивается с текущим радиусом покрытия узла и по значению
данной проверки строится матрица смежности.
Заключительным этапом работы внутри цикла является непосредственно
проверка полученного графа на изоморфизм одному из редких графов,
поданного в качестве входных данных. Для этого строится десятичный код
сгенерированного графа и происходит сравнения данного кода с кодами из
таблицы.
Таким образом, мы видим преимущество идеи такого подхода.
Построение хэш-таблицы для редких графов увеличивает время работы
потока, но это время незначительно, по сравнению с тем, насколько она
упрощает процесс проверки на изоморфизм сгенерированного графа и графа,
поданного
на
вход
программе.
Данный
метод,
в
совокупности
с
использованием многопоточности, обеспечивает максимально возможное
приближение время работы данной программы к приемлемому времени
работы для приложений такого типа.
2.2 Реализация компонент программы.
Для упрощения работы с приложением и улучшения наглядности кода,
мной были написаны следующие процедуры и функции:
Вспомогательные
функции
decimalToBinary(int
decimalNumber)
и
binaryToDecimal(string binaryString) позволяют переводить десятичное число
в двоичное представление и наоборот, соответственно.
11
Функции
getBinaryNumberFromMatrix(int[,]
matrix)
и
getMatrixFromBinaryNumber(string binaryString) позволяет получить двоичное
представление графа по его матрицы смежности и наоборот, соответственно.
Процедура getGeneratedMatrix() отвечает за генерацию случайного графа.
Для получения случайных чисел используется встроенный класс С# Random,
и его метод NextDouble(), который возвращает число из диапазона [0;1], что
отвечает поставленным перед нами условием. Псевдослучайные числа
выбираются с равной вероятностью из конечного набора чисел. Выбранные
числа не являются строго случайными, так как для их выборки используется
четкий математический алгоритм, но они достаточно случайны для
практического применения [6].
Процедура
threadWorker(object
count)
является
наиболее
важным
компонентом программы. Именно эта процедура выполняется разными
потоками. Внутри нее происходит генерация циклов необходимое число раз.
По завершению цикла, идет объединения локальных результатов с
результатами глобальными для всех потоков вместе. Для этого внутри
данной процедуры вызывается метод unionResult(int[] resultMatrix, int
countForThread), которая собственно и осуществляет слияние. Чтобы
избежать конфликтов при использовании этой процедуры несколькими
потоками одновременно (например, возможна потеря данных), внутри нее
используется оператор lock, который блокирует данный метод при
выполнении одним потоком для доступа других потоков. При попытке входа
другого потока в заблокированный код потребуется дождаться снятия
блокировки.
2.3 Анализ результатов работы программы.
Для проверки работоспособности программы было проведено некоторое
количество экспериментов при различных условиях.
12
Целью экспериментов было проверить, как меняется время генераций и
вычислений при увеличении количества потоков.
Было проведено 4 эксперимента, по 100000000 генераций. Для верхней
границы радиуса покрытия каждого узла было задано значение 1, для нижней
границы – значение 0,1. Так как шаг изменения радиуса покрытия равен 0,1,
то общее количества генераций увеличивается до 1 миллиарда.
В качестве редких графов было задано двенадцать мини-кодов (75, 1103,
1118, 1247, 1467, 1531, 3295, 3309, 3448, 3452, 7916, 16350)
Рисунок 1 – Пример программы с заданными условиями до запуска
Такие эксперименты были проведены на двух компьютерах с различными
техническими характеристиками. Для нашего эксперимента значимым
фактором является количество ядер процессора. На
1-ом
компьютере,
используемом в эксперименте, два физических ядра. На 2-ом компьютере –
два
физических
ядра
и
четыре
логических.
экспериментов представлены в таблице 1.
13
Результаты
данных
Таблица 1 – результаты экспериментов для различного количества
потоков
Количество потоков,
задаваемых для
Компьютеры, используемые при проверке
эксперимента
1-ый
2-ый
1
12367,34124 сек.
8658,4392344 сек.
2
7568,45326 сек.
5364,64284 сек.
4
8904,35346 сек.
4508,9498972 сек.
8
9443,525225 сек.
4521,2516008 сек.
Из таблицы 1 видно, что, действительно, количество потоков влияет на
время работы данной программы. При использовании только одного потока,
мы наблюдаем самое долгое выполнение. Для 1-го компьютера наиболее
минимальное время работы достигается при запуске на двух потоках. Это
объясняется, как было сказано выше, количеством ядер. При превышении
количества задаваемых потоков количества ядер, приложению необходимо
чаще переключаться между потоками, теряется преимущества подлинного
параллелизма. Этот фактор способствует увеличению времени работы.
Аналогичную ситуацию мы видим для 2-го экспериментального
компьютера. Минимальное время работы достигается при четырех потоках
(так как 2-ой компьютер имеет четыре логических ядра).
Последний эксперимент включал в себя запуск написанной программы
для того же количества редких графов, с использованием четырех потоков,
при генерации одного миллиарда случайных графов. Результаты появления
редких графов наглядно представлены на рисунке 2.
14
Chart Title
12000
75
10000
1103
1118
1247
8000
1467
1531
6000
3295
3309
4000
3448
3452
2000
7916
16351
0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1
Рисунок 2 – результаты работы программы
Таким образом, мы видим, что некоторые графы появляются только лишь
при определенном радиусе покрытия узла в ad-hoc сети, как и говорилось
ранее. Так же на графике видно, в среднем редкие графы встречаются не
больше десяти тысяч раз. Данного количества уже достаточно, чтобы дать
надежную оценку вероятности появления практического любого из
рассматриваемых графов. Время выполнения программы при этом составило
около 10 часов (36025,7365543 сек.), что можно считать разумным временем
работы компьютера.
15
ЗАКЛЮЧЕНИЕ
В ходе работы выполнения данной курсовой работы мной была изучена
теоретическая часть, посвященная геометрическим графам, инвариантам
графам. Так же были изучены методы работы с потоками в среде .NET
Framework для C#, и была разработана программа с использованием
преимуществ многопоточности. Были проведены исследования о скорости
вычислений при использовании различного числа потоков.
Опираясь на использованные методы оптимизации вычислений, были
подсчитаны количества появлений редких графов при большом числе
генераций случайных графов.
Данные подходы минимизации позволили приблизить время выполнение
данной задачи на компьютере к разумному времени (несколько часов) и дать
более надежную оценку вероятности появления редкого графа.
16
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
1. Лекция 11. Графы. Геометрические графы. [Электронный ресурс],
URL: http://vuz.exponenta.ru/PDF/L11.html, [Дата обращения: 11 мая
2014].
2. Шишаев М.Г., Потаман С.А. Современные технологии сетей типа adhoc и возможные подходы к организации одноранговых
телекоммуникационных сетей на базе мобильных устройств малого
радиуса действия. [Электронный ресурс] , URL
http://cyberleninka.ru/article/n/sovremennye-tehnologii-setey-tipa-ad-hoc-ivozmozhnye-podhody-k-organizatsii-odnorangovyhtelekommunikatsionnyh-setey-na-baze-mobilnyh, [Дата обращения: 11 мая
2014].
3. Зыков А. А. Основы теории графов// М.: Наука, - 1986, - с 384.
4. Многопоточность. Потоки в C#.NET. [Электронный ресурс], URL:
http://www.esate.ru/page/mnogopotochnost-i-potoki-v-c-sharp,
[Дата обращения: 20 мая 2014].
5. Джозеф А. Работа с потоками в C#. Часть 1. [Электронный ресурс],
URL: http://www.rsdn.ru/article/dotnet/CSThreading1.xml, [Дата
обращения: 20 мая 2014].
6. Microsoft Developer Network. [Электронный ресурс], URL:
http://msdn.microsoft.com/ru-ru/library/system.random.aspx, [Дата
обращения: 14 мая 2014].
17
ПРИЛОЖЕНИЕ А
Код вспомогательных функций
//Задаваемый радиус
public double maxRadius;
public double minRadius;
public static int threadsCount;
public static int test = 0;
//Задаваемое кол-во вершин графа
public static int countPoint = 6;
//Список редких графов и количества его появлений
public static List<int[]> listCountRareGraph = new List<int[]>();
//Структура графа
public struct Graph{
public Tuple<double, double>[] point;
}
//Перевод десятичного числа в двоичное
public string decimalToBinary(int decimalNumber){
int residual;
string binaryString = "";
while (decimalNumber > 0){
residual = decimalNumber % 2;
binaryString = residual.ToString() + binaryString;
decimalNumber = decimalNumber / 2;
}
return binaryString;
}
//Перевод двоичного числа в десятичное
public int binaryToDecimal(string binaryString){
double result = 0;
for (int i = 0; i < binaryString.Length; i++)
if (binaryString[binaryString.Length - i - 1] == '1')
result += Math.Pow(2, i);
return Convert.ToInt16(result);
}
//Получение по матрице смежности бинарного кода
public string getBinaryNumberFromMatrix(int[,] matrix){
string result = "";
for (int i = 0; i < countPoint; i++)
for (int j = (i + 1); j < countPoint; j++)
result += matrix[i, j].ToString();
return result;
18
}
//Генерация вершин графа на промежутке [0,1][0,1]
public void pointGeneration(Graph graph){
Random rand = new Random();
for (int i = 0; i < countPoint; i++)
{
double x = rand.NextDouble();
double y = rand.NextDouble();
graph.point[i] = new Tuple<double, double>(x, y);
}
}
//Вычисление расстояния между двумя вершинами
public double distanceCalculating(Tuple<double, double> point1, Tuple<double, double>
point2){
return Math.Sqrt(Math.Pow(point2.Item1 - point1.Item1,2) + Math.Pow(point2.Item2 point1.Item2, 2));
}
//Получение матрицы смежности по двоичному коду графа
public int[,] getMatrixFromBinaryNumber(string binaryString){
int[,] matrix;
matrix = new int[countPoint, countPoint];
while (binaryString.Length < 15)
binaryString = "0" + binaryString;
int k = 0;
for (int i = 0; i < 5; i++)
for (int j = (i + 1); j < 6; j++){
matrix[i, j] = Convert.ToInt16(binaryString[k].ToString());
matrix[j, i] = matrix[i, j];
k++;
}
return matrix;
}
//Получение списка всех матриц смежности для заданного графа
public Hashtable getAdjacencyMatrixNumber(int decimalNumber){
int tempPoint;
//int [,] tempMatrix;
int[,] originalMatrix =
getMatrixFromBinaryNumber(decimalToBinary(decimalNumber));
Hashtable table = new Hashtable();
//tempLine = new int [countPoint];
for (int i = 0; i < countPoint; i++)
{
for (int j = 0; j < countPoint; j++)
{
int [,] tempMatrix = originalMatrix;
for (int k = 0; k < countPoint; k++)
{
19
tempPoint = tempMatrix[i, k];
tempMatrix[i, k] = tempMatrix[j, k];
tempMatrix[j, k] = tempPoint;
}
for (int k = 0; k < countPoint; k++)
{
tempPoint = tempMatrix[k, i];
tempMatrix[k, i] = tempMatrix[k, j];
tempMatrix[k, j] = tempPoint;
}
If(!table.ContainsKey(binaryToDecimal(getBinaryNumberFromMatrix(tempMatrix))))
table.Add(binaryToDecimal(getBinaryNumberFromMatrix(tempMatrix)),
decimalNumber);
}
}
return table;
}
//Добавление графа в список редких графов
public void addRareGraph(int decimalNumber)
{
int[] temp = new int[2];
temp[0] = decimalNumber;
temp[1] = 0;
listCountRareGraph.Add(temp);
}
//Генерация графа
public int[,] getGeneratedMatrix()
{
int[,] matrix;
matrix = new int[countPoint, countPoint];
Graph graph = new Graph();
graph.point = new Tuple<double, double>[countPoint];
pointGeneration(graph);
for (int i = 0; i < countPoint; i++)
for (int j = 0; j < countPoint; j++)
if (i != j)
{
if (distanceCalculating(graph.point[i], graph.point[j]) <= maxRadius)
matrix[i, j] = 1;
else
matrix[i, j] = 0;
}
else
matrix[i, j] = 0;
return matrix;
}
20
//Проверка сгенерированного графа на приналежность к спику редких графов
public int checkForRareGraph(int [,] matrix, Hashtable tableGraph)
{
int miniCode = binaryToDecimal(getBinaryNumberFromMatrix(matrix));
foreach (DictionaryEntry graph in tableGraph)
{
if ((int)graph.Key == miniCode)
return (int)graph.Value;
}
return -1;
}
static int forCheck = 0;
static readonly object locker = new object();
//Объединение результатов
public void unionResult(int[] resultMatrix)
{
lock (locker)
{
for (int i = 0; i < listCountRareGraph.Count; i++)
{
listCountRareGraph[i][1] += resultMatrix[i];
}
}
}
21
Download