Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Диплом Voldem@r / Оно / ПЗ_release.doc
Скачиваний:
49
Добавлен:
16.04.2013
Размер:
1.6 Mб
Скачать

1.2.2. Структура входных и выходных данных

На рис. 1.6 показаны потоки входных и выходных данных комплекса. Ниже будет подробно рассмотрена их структура, а пока я опишу процесс циркуляции данных.

При запуске комплекса он считывает настройки из файла settings.opt (такие как: положение формы, параметры ГА, имя временной директории, имя файла с последней редактировавшейся моделью) из папки, откуда было запущено приложение. Размер этого файла фиксирован и составляет 640 байтов. Если файла settings.opt нет в текущей папке, либо его размер неверный, то загружаются настройки по умолчанию, которые «зашиты» в коде программы. При завершении работы комплекса все настройки записываются обратно в файл settings.opt. Этот процесс является обязательным при каждом запуске комплекса и выходе из него. Все последующие являются опциональными и могут отсутствовать.

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

Рис 1.6 Потоки данных

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

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

Структура файла описания модели

Файл с сохранённой моделью является двоичным файлом, в который помещаются структуры по определённому правилу. Рассмотрим подробнее правила формирования данного файла.

#define MASK 0xF3

struct SFileHeader

{

int magic; // = 0x4F6A - число для элементарной проверки того, // что файл содержит информацию о модели

unsigned char productName[27]; // = "ГЕНератор" - дополнительная проверка

unsigned int version; // LO(version) = 0, HI(version) = 1 - версия // программы, сохранившей файл (для возможности // дальнейшего расширения)

int systemsCount; // = 1 - для возможности расширения

int subsystemsCount; // число подсистем

int componentsCount; // число компонентов

int systemInfoOffset; // смещение от начала файла в байтах, с которого // располагаются данные о системе

int subSystemsInfoOffset; // смещение от начала файла в байтах, с которого // располагаются данные о подсистемах

int componentsInfoOffset; // смещение от начала файла в байтах, с которого // располагаются данные о компонентах

unsigned char reserved[256]; // зарезервировано для дальнейшего использования

};

#define MAX_LEN 1023

struct SSubSystemInfo

{

POINT position; // положение на экране

unsigned char hintString[MAX_LEN + 1]; // комментарий

unsigned char nameString[MAX_LEN + 1]; // имя

unsigned char funcString[MAX_LEN + 1]; // функция приспособленности

int childrenCount; // число подсистем и компонентов

unsigned char** names; // массив из char[MAX_LEN + 1] - // содержит имена всех элементов // нижнего уровня

};

struct SComponentInfo

{

POINT position; // положение на экране

unsigned char hintString[MAX_LEN + 1]; // комментарий

unsigned char nameString[MAX_LEN + 1]; // имя

int type; // тип переменной - диапазон или список // значений

double left, right; // левая и правая граница диапазона. Если // тип переменной список, то left = // 2.718281828, right = 3.14159265 - для // проверки :-)

char name[MAX_LEN + 1]; // имя элемента модели верхнего уровня

int listValuesCount; // число значений в списке. Эта и // последующие переменные // игнорируются, если тип переменной - // диапазон (в этом случае равна // 299792458 - для проверки :-) )

unsigned char** values; // массив строк, содержащих значения // переменной

unsigned char** descriptions; // массив строк с описанием

};

В самое начало файла записывается структура SFileHeader. Эта структура является заголовком. Первоначальная проверка осуществляется по полям magic, version и productName. На первом этапе файл признаётся годным, если значения в этих полях соответствуют значениям, указанным в комментариях. Следующие 3 поля – systemsCount, subSystemsCount и componentsCoutn – хранят в себе число систем (в текущей версии программы всегда 1исло систем ()t етра -- 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), число подсистем и число компонентов модели соответственно. Затем 3 поля – systemInfoOffset, subSystemInfoOffset, componentInfoOffset – представляют собой смещение (в байтах) от начала файла до начала данных о системе, подсистемах или компонентах. Эти сведения позволяют также проверять корректность файла (по его размеру), а также позволяют осуществить ускоренную загрузку за счёт распараллеливания процессов (один процесс на один вид элементов). И, наконец, резерв в 256 байтов. Такая техника является достаточно распространённой и позволяет в дальнейшем расширять функциональные возможности программы [3].

Дальше структуры записываются в файл в следующем порядке: одна структура SSubSystemInfo для описания параметров корня дерева системы, subSystemsCount структур SSubSystemInfo для описания параметров всех подсистем и componentsCount структур SComponentInfo для описания всех компонентов модели. Рассмотрим подробнее структуру SSubSystemInfo, а затем структуру SComponentInfo.

Структура SSubSystemInfo содержит строковые поля hintString, nameString, funcString. Чтобы не хранить данные о модели в файле в открытом виде, используется простейший способ шифрования – функция XOR. К каждому байту любой строки применяется функция XOR с константой MASK. Характерной особенностью функции XOR является то, что A xor B xor B = A. Т.е. действие функции XOR легко обратить, что позволяет минимизировать затраты процессорного времени и обеспечить некоторую защиту. Этот же способ скрытия информации используется и для структур SComponentInfo. Поле position хранит экранные координаты графического символа, соответствующего подсистеме или компоненте. Поле childrenCount содержит число подсистем и компонентов, непосредственно связанных с данной подсистемой. Следующее поле – names – является двумерным динамическим массивом, или набором строк размером MAX_LEN + 1. Объём памяти, необходимый для его хранения, составляет childrenCount * (MAX_LEN + 1).

Структура SComponentInfo «богаче» по количеству полей. Эта структура описывает ключевую информацию о компонентах модели – возможные значения критериев. Первые два поля аналогичны таким же полям структуры SSubSystemInfo. Они так же кодируются при записи в файл и декодируются при чтении из него. В программе каждый компонент может быть либо списком дискретных наборов значений, либо диапазоном. В зависимости от этого они по-разному обрабатывается. Информация о типе компонента записывается в поле type. Если значение этого поля равно VRANGE (т.е. диапазон значений), то полезная информация заключена в полях left и right (границы диапазона), поле listValuesCount содержит информацию для дополнительной проверки, а поля values и descriptions игнорируются. В противном случае поля left и right используются для дополнительной проверки, поле listValuesCount содержит число дискретных значений, которые может принимать компонент. Поля values и descriptions являются массивами строк, содержащими конкретные значения и их описания. Для значений используются строки, потому что каждое значение может быть формулой. Так как все вычисления по формулам в программе основаны на обработке строк формул, которые вводит пользователь (т.е. понятной человеку символьной информации), то было решено записывать в файл именно строки, а не промежуточное внутреннее представление формулы. Это позволяет ускорить процесс загрузки, так как отпадает необходимость преобразовывать бинарную информацию в строку, содержащую формулу (а это было бы необходимо, ведь пользователь должен видеть понятную ему запись, т.е. строку).

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

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

  1. Первая строка файла: Время поиска: начало – [дата_и_время], конец – [дата_и_время], затрачено  целое_число минут. дата_и_время – строка вида дд.мм.гггг чч:мм:сс целое_число – десятичное целое число

  2. Вторая строка: Найденное наилучшее значение целевой функции = дробное_число дробное_число – значение целевой функции в виде обыкновенной дроби

  3. Затем идут N строк (N – число критериев оптимизации) следующего вида: Описание_критерия ($имя_переменной) дробное_число Описание_критерия – символьная строка, которую задаёт пользователь для критерия при создании модели $имя_переменной – имя, заданное критерию при создании модели. Это имя является обязательным, в отличие от Описание_критерия, и по нему можно однозначно идентифицировать критерий

  4. Следующие строки – параметры ГА: Вероятность мутации = дробное_число Вероятность кроссовера = дробное_число Число точек кроссовера = целое_число Критерий останова: отношение значений функции приспособленности для лучших особей в двух соседних популяциях = дробное_число или число поколений составит целое_число Направление оптимизации: направление здесь направление может принимать одно из двух значений – «минимум» или «максимум»

  5. И, наконец, некоторая дополнительная информация: Поиск решения завершён. Причина: причина_остановки Число поколений составило целое_число здесь причина_остановки – символьная строка, которая может принимать следующие значения: «Найдено решение», «Достигнут предел в количестве поколений», «Прервано пользователем».

Основываясь на этих данных, в случае, когда поиск решения завершён по причине достижения предельного количества поколений (т.е. получено лучшее к этому моменту решение, но не оптимальное), пользователь может изменить некоторые параметры ГА и повторить попытку. Файл с результатами работы комплекса имеет такое же имя, как и файл с сохранённой моделью, для которой проводилась оптимизация, но с расширением .txt

Структура файла с настройками комплекса

Файл настройки комплекса является бинарным файлом, что несколько затрудняет изменение его пользователем (простейшая защита). Данный файл содержит в себе копию структуры Settings, описание которой приведено ниже:

struct SGAPreferences // параметры модуля ГА

{

double mutationP; // вероятность мутации

double crossoverP; // вероятность кроссовера

int numOfCrossoverPts; // число точек кроссовера

double bestFitFuncDiv; // отношение значений функции приспособленности // для лучших особей в двух соседних популяциях

int generationLimit; // максимальное число поколений

TOptDir optimizationDirection; // направление оптимизации (DIR_MIN или // DIR_MAX)

TCrossoverType crossoverType; // способ отбора родительских групп // (TYPE_GAREM, TYPE_BEST_WITH_WORST)

};

struct SFormPosition // параметры любой формы

{

POINT place; // положение верхнего левого угла формы в экранных координатах

POINT size; // размер в пикселях по горизонтали и вертикали

BOOL isOpen; // флаг, открыта ли форма, или нет

};

struct SOtherSettings // остальные настройки

{

char lastProject[MAX_PATH + 1]; // имя файла (вместе с путём) к последнему // проекту

char tempDir[MAX_PATH + 1]; // временный каталог

COLORREF editorBkGrnd; // цвет фона редактора модели

COLORREF reporterBkGrnd; // цвет фона отчёта

};

struct SSettings // все настройки вместе (для сохранения в файл)

{

SGAPreferences GASettings; // настройки ГА

SFormPosition mainForm; // основная форма

SFormPosition editorForm; // редактор

SFormPosition reporterForm; // форма отчёта

SOtherSettings other; // остальные настройки

} Settings;

Размер данной структуры составляет 640 байтов. Следовательно, размер файла с настройками тоже будет равен 640 байтам.

Соседние файлы в папке Оно