
- •Министерство образования и науки Российской Федерации Московский государственный институт электронной техники (технический университет) Факультет мп и тк
- •«Программный комплекс многокритериальной оптимизации систем на основе мультихромосомных моделей и генетических алгоритмов»
- •Содержание
- •Перечень сокращений
- •Введение
- •1. Специальный раздел
- •1.1. Исследовательская часть
- •1.1.1. Обзор существующих программ для оптимизации
- •1.1.3. Информационные потребности пользователя
- •1.2. Конструкторская часть
- •1.2.1. Требования, предъявляемые к системе
- •1.2.2. Структура входных и выходных данных
- •1.2.3. Конфигурация технических средств
- •1.2.4. Модули комплекса
- •1.2.5. Общий алгоритм работы программы
- •1.2.6. Иерархия классов
- •1.2.7. Переменные в выражениях и их использование в программе
- •1.2.8. Основные алгоритмы и особенности программной реализации
- •1.2.9. Проверка отказоустойчивости программы
- •1.2.10. Проверка работы комплекса на контрольных примерах
- •1.3. Выводы
- •2. Технологический раздел
- •2.1. Использование стандартных библиотек
- •2.1.1. Библиотека stl
- •2.1.2. Библиотека mfc
- •2.1.3. Применение библиотек stl и mfc в программе
- •2.1.4. Средство ClassWizard
- •2.2.2. Встроенные средства языка для отладки программ
- •2.2.3. Отладка программного кода, содержащего stl и mfc
- •2.4. Приёмы объектно-ориентированного проектирования
- •2.4.1. Применение паттернов проектирования в программе
- •2.5. Выводы
- •3. Организационно-экономический раздел
- •3.1. Метод анализа иерархий
- •3.2. Метод парных сравнений.
- •3.2.1. Определение собственных векторов
- •3.3. Применение метода для выбора среды программировани
- •3.3.1. Характеристики сред программирования
- •3.3.2. Таблица сравнений важности критериев
- •3.3.3. Таблицы попарного сравнения сред разработки по каждому критерию
- •3.4. Результаты применения метода
- •3.5. Выводы
- •4. Производственная и экологическая безопасность
- •4.1. Опасные и вредные факторы, воздействующие на программиста
- •4.1.1. Микроклимат рабочей зоны программиста
- •4.1.2. Воздействие шума на программиста. Защита от шума
- •4.1.3. Уровень напряжённости электромагнитного поля
- •4.1.4. Электробезопасность. Статическое электричество
- •4.1.5. Освещенность рабочего места
- •4.2. Заключение
- •Заключение
- •Список литературы
- •Исходный текст программы
- •Результаты испытаний
- •Руководство оператора
- •Аннотация
- •2. Условия выполнения программы
- •2.1. Климатические условия эксплуатации
- •2.2. Состав аппаратных и программных средств
- •3. Требования к персоналу (пользователю)
- •4.2.2. Выполнение функции сохранения модели в файл
- •4.2.3. Выполнение функции ввода информации о системе
- •4.2.4. Выполнение функции задания различных параметров системы
- •4.2.5. Правила записи выражений
- •4.2.6. Выполнение функции задания параметров генетических алгоритмов
- •4.2.7. Выполнение функции поиска решения
- •5.3. Ошибки при проверке модели
- •5.4. Ошибки во время поиска решения
Список литературы
Гагарина Л. Г., Зубов Н. Н., Стрижков А. В., Федотова Е. Л. Методические указания для подготовки дипломного проекта по специальности 220400 / Под ред. д.т.н. Нестерова. А. Э. –М.:МИЭТ, 2005. – 65 с.
Буч Г. Объектно-ориентированный анализ и проектирование с примерами приложений на С++, 2-е изд. / Пер. с англ.– М.: «Издательство Бином», СПб: «Невский диалект», 1998. – 560 с., ил.
Ахо А., Хопкрофт Д., Ульман Д. Структуры данных и алгоритмы. / Пер. с англ. – М.: Издательский дом «Вильямс», 2003. – 384 с.: ил.
Страуструп Б. Язык программирования СИ++ – М.: «Издательство Бином», СПб: «Невский диалект», 1999. – 991 с.
Паппас К. Х., Мюррей У. Х. Отладка в С++ – М.: «Издательство Бином», McGraw-Hill Companies, 2001. – 512 с.
Согомонян А. Статья STL - Standard Template Library – http://infocity.com.ua/
Nicolai M. Josuttis C++ Standard Library, The: A Tutorial and Reference – Addison Wesley, 1999 – 832 p.
Статья Уроки программирования на Visual C++ с помощью MFC – http://click.ipc.ru/~vc/html/Lessons
Гамма Э., Хелм Р. Джонсон Р., Влиссидес Дж. Приёмы объектно-ориентированного проектирования. Паттерны проектирования – Спб: Питер, 2004. – 366 с.: ил.
Валиков А. Технология XSLT – СПб: БХВ-Петербург, 2002. – 544 с.: ил.
Ахо А., Сети Р., Ульман Д. Компиляторы: принципы, технологии и инструменты.: Пер. с англ. – М.: Издательский дом «Вильямс», 2003. – 768 с.: ил.
Брилюк Д. Статья Обучение, самоорганизация и эволюция как методы в искусственном интеллекте – http://msk.nestor.minsk.by/kg/2000/kg0011/kg04712.html
Батищев Д. И., Исаев С. А. Оптимизация многоэкстремальных функций с помощью генетических алгоритмов – http://bspu.secna.ru/Docs/~saisa/ga/summer97.html
Составитель Burger Y. Эволюционные вычисления – http://tz.ints.ru/?prog_ev
Конева К.К., Терехова Л.М. Появление эволюционных алгоритмов – Московский институт электроники и математики – http://nit.miem.edu.ru/cgi-bin/article?id=49
Статья Генетические алгоритмы: стратегии отбора – http://qai.narod.ru/GA/strategies.html
Саати Т. Принятие решений. Метод анализа иерархий. М.: Радио и связь, 1993.
Хостинг обзор Статья Метод анализа иерархий – http://www.hostobzor.ru/manual/mai.php
Статья Технологии принятия решений: метод анализа иерархий – http://www.citforum.ru/consulting/BI/resolution/
Каракеян В.И. Безопасность жизнедеятельности – М. – 1999.
СанПиН 2.2.2.542-96. Гигиенические требования к видеодисплейным терминалам, персональным электронно-вычислительным машинам и организации работы.
ПРИЛОЖЕНИЕ 1
Исходный текст программы
Программная реализация комплекса состоит из 71 файла и в общей сумме составляет около 6 тысяч строк кода. Ниже приведена лишь часть исходных текстов программы.
Заголовочные файлы
//header4.h
#pragma once
#include <afx.h>
#include <vector>
#include <list>
using namespace std;
typedef struct tagSValueListEntry{
CString sDescription;
CString sExpression;
} SValueListEntry;
typedef vector<SValueListEntry> TValuesList;
//--------------------------------- состояния мыши ---------------------------------------------
enum EMOUSESTATE { MS_NONTOOL, MS_LINK,MS_COMPONENT, MS_SUBSYSTEM, MS_SYSTEM};
//--------------------------------- тип активного объекта ---------------------------------------------
enum EACTIVE{ME_NOTHING,ME_COMPONENT,ME_SUBSYSTEM,ME_SYSTEM};
//------------------------------синглтоны---------------------------------------------------------
#include <map>
typedef map<CString,CString> VARVALUES;
#include "concretelexer.h"
extern CConcreteLexer GLOBLexer;
#include "syntax.h"
extern CSyntax GLOBSyntax;
#include "params.h"
extern CParams GLOBParamStorage;
#include "target.h"
extern CTarget GLOBTarget;
extern VARVALUES GLOBVarValues;
//component.h
#pragma once
#include "modelelement.h"
#include "componentdialog.h"
#define I_AM_COMPONENT 35
enum{VLIST = 0xf03,VRANGE};
class CComponent:public CModelElement {// элемент модели "Компонента, критерий"
public:
CComponent() : CModelElement(), _type(VRANGE), _left(0.0), _right(0.0), _vl(9) {
_objType = I_AM_COMPONENT;
}
~CComponent();
// границы диапазона значений
void getBounds(double & left,double & right) const{
left = _left; right = _right;
}
void setBounds(double left,double right){
_left = left; _right = right;
}
TValuesList* getValues(); // получить список дискретов
int getType() const{ return _type; } // получить тип (диапазон или набор дискретов)
void setType(int type){ _type = (type == VLIST) ? VLIST : VRANGE; }
void addValue(SValueListEntry vle){ _vl.push_back(vle); }
void EraseValues(){ _vl.erase(_vl.begin(), _vl.end()); }
public:
virtual void FillDialog();
private:
int _type;
double _left, _right;
TValuesList _vl;
};
//population.h
#pragma once
#include "personset.h"
#include "modelstorage.h"
#include <vector>
class CPopulation {// текущая популяция особей
public:
typedef std::vector<CPersonSet*> TPersons;
CPopulation(CModelStorage* _model);
~CPopulation(){ Destroy(); }
void Create(); // инициализировать все указатели и т.д.
void Destroy(); // удалить созданные объекты
void GenerateStartPopulation();
void Generate(int); // следующее поколение для i-ой подсистемы
CPersonSet* getPersones(int index) const{ return _generations[index]; }
void getValues(double& last,double& prelast) const{
last = _lastValue; prelast = _preLastValue;
};
void nextGeneration();
void ModifyVarValues(CPersonSet* P,int j,int i);
protected:
void Crossover(double[],double[],int);
void Mutation(double[],CHromoPrototype*);
void ProductGroup(int /*# хромосомы*/,int[] /*out - ## особей-родителей*/);
double ObtainResult();
private:
TPersons _generations;
double _lastValue, _preLastValue;
bool _hasCreated;
CModelStorage* model;
};
//modelelement.h
#pragma once
#include <afxwin.h>
#define I_AM_COMMON_OBJECT 21
class CmodelElement { // базовый класс для элемента модели
public:
CModelElement() : _editDialog(NULL), _parent(NULL), _hintString(""), _name(""), _objType(I_AM_COMMON_OBJECT) { _place.x = 20; _place.y = 20; }
void setHintString(CString & aStr){ _hintString = aStr; }
CString getHintString() const{ return _hintString; }
void setName(CString & aStr){ _name = aStr; }
CString getName() const{ return _name; }
void setEditDialog(CDialog* aDialog){ _editDialog = aDialog; }
void setParent(CModelElement* aParent){ _parent = aParent; }
CModelElement* getParent() const{ return _parent; }
void Edit();
const POINT & getPos() const{ return _place; }
void setPos(const POINT & pt){ _place = pt; }
public:
virtual void FillDialog() = 0; // заполнение и вывод диалога с параметрами
int type();
protected:
CString _hintString;
CString _name;
CDialog* _editDialog;
CModelElement* _parent;
POINT _place;
int _objType;
};
//modelstorage.h
#pragma once
#include "subsystem.h"
#include "system.h"
#include "component.h"
#include <vector>
class CModelStorage {// текущая модель. Хранит все элементы
public:
typedef std::vector<CSubSystem*> TSubSystems;
typedef std::vector<CComponent*> TComponents;
CSystem system;
CModelStorage(){}
~CModelStorage();
void addSubsystem(CSubSystem* aSubsystem);
CSubSystem* getSubsystem(int n) const;
void delSubsystem(int n);
int subsystemCount() const{ return _subsystems.size(); }
void addComponent(CComponent* aComponent);
CComponent* getComponent(int n) const;
void delComponent(int n);
int componentCount() const{ return _components.size(); }
CModelElement* Find(CString& name);
private:
TSubSystems _subsystems;
TComponents _components;
};
//subsystem.h
#pragma once
#include "modelelement.h"
#include "subsystemdialog.h"
#include <vector>
#define I_AM_SUBSYSTEM 46
class CSubSystem:public CmodelElement { // элемент модели "Подсистема"
public:
CSubSystem() : CModelElement(), _fitnessFunc("") { _objType = I_AM_SUBSYSTEM; }
~CSubSystem();
CModelElement* getChild(int n) const;
void addChild(CModelElement* aChild);
void delChild(int n);
int childrenCount() const{ return _children.size(); }
CString getFitnessFunc() const{ return _fitnessFunc; }
void setFitnessFunc(CString& str){ _fitnessFunc = str; }
public:
virtual void FillDialog();
protected:
CString _fitnessFunc;
std::vector<CModelElement*> _children;
};
Файлы реализации
//ModelWnd.cpp
#include "StdAfx.h"
#include "modelwnd.h"
#include "zeroStage.h"
#include "nameTable.h"
#include "fileStructures.h"
#include "population.h"
#include <math.h>
#define TRANSPARENT_COLOR 0xCCCCCC
#pragma comment(lib, "Msimg32.lib")
#pragma warning( disable : 4305 )
#pragma warning( disable : 4309 )
CModelWnd::CModelWnd(void) : _mouseState(MS_NONTOOL), _lastObject(NULL), _varKeeper(NULL), splash(NULL){
CColorGluedWnd::CColorGluedWnd();
btmActiveComponent = btmNactiveComponent = btmActiveSubsystem = btmNactiveSubsystem = btmActiveSystem = btmNactiveSystem = btmActive = NULL;
dlgEditComponent = new CComponentDialog();
dlgEditSubsystem = new CSubsystemDialog();
dlgEditSystem = new CSystemDialog();
POINT pt ={ 60, 60 };
_model.system.setPos(pt);
_model.system.setEditDialog(dlgEditSystem);
_lastObject = _activeObject = _linkedObject = NULL;
_objectToDelete = _objectToLinkWith = ME_NOTHING;
_mouseState = MS_NONTOOL;
_dotPen.CreatePen(PS_DOT, 1, RGB(255, 255, 255));
_solidPen.CreatePen(PS_SOLID, 2, RGB(255, 255, 255));
_fileName = "untitled";
}
CModelWnd::~CModelWnd(void){
delete dlgEditComponent;
delete dlgEditSubsystem;
delete dlgEditSystem;
}
void CModelWnd::CriteriyBitmap(CBitmap* ActiveComponent,CBitmap* NactiveComponent,CBitmap* ActiveSubsystem,CBitmap* NactiveSubsystem,CBitmap* ActiveSystem,CBitmap* NactiveSystem){
// заполнить графические представления элементов модели
btmActiveComponent = ActiveComponent;
btmNactiveComponent = NactiveComponent;
btmActiveSubsystem = ActiveSubsystem;
btmNactiveSubsystem = NactiveSubsystem;
btmActiveSystem = ActiveSystem;
btmNactiveSystem = NactiveSystem;
}
void CModelWnd::OnShowWindow(BOOL bShow,UINT nStatus){
SetWindowText(_fileName);
}
void CModelWnd::OnPaint(){
DrawModel();
ValidateRect(NULL);
}
void CModelWnd::OnMouseMove(UINT nFlags,CPoint point){
if ( MS_LINK == _mouseState ){ // связывание элементов модели
if ( ME_NOTHING != _objectToLinkWith ){ // рисовать пунктирную линию
DrawModel();
CClientDC ClientDC(this);
ClientDC.SelectObject(&_dotPen);
ClientDC.SetBkMode(TRANSPARENT);
ClientDC.SelectStockObject(NULL_BRUSH);
ClientDC.MoveTo(_linkedObject->getPos());
ClientDC.LineTo(point);
}
}else{
if ( nFlags == MK_LBUTTON ){
if ( _lastObject ){ // перемещается объект
_lastObject->setPos((POINT) point);
DrawModel();
return;
}
// иначе выбрать перемещаемый объект
BITMAP bmpInfo;
btmNactiveSystem->GetBitmap(&bmpInfo);
POINT pt = _model.system.getPos();
if ( point.x > pt.x - (bmpInfo.bmWidth / 2) && point.x <pt.x + bmpInfo.bmWidth / 2 && point.y> pt.y - (bmpInfo.bmHeight / 2) && point.y < pt.y + bmpInfo.bmHeight / 2 ){
_lastObject = &_model.system;
return;
}
btmNactiveSubsystem->GetBitmap(&bmpInfo);
for ( int i = 0; i < _model.subsystemCount(); i++ ){
POINT pt = _model.getSubsystem(i)->getPos();
if ( point.x > pt.x - (bmpInfo.bmWidth / 2) && point.x <pt.x + bmpInfo.bmWidth / 2 && point.y> pt.y - (bmpInfo.bmHeight / 2) && point.y < pt.y + bmpInfo.bmHeight / 2 ){
_lastObject = _model.getSubsystem(i);
return;
}
}
btmNactiveComponent->GetBitmap(&bmpInfo);
for ( i = 0; i < _model.componentCount(); i++ ){
POINT pt = _model.getComponent(i)->getPos();
if ( point.x > pt.x - (bmpInfo.bmWidth / 2) && point.x <pt.x + bmpInfo.bmWidth / 2 && point.y> pt.y - (bmpInfo.bmHeight / 2) && point.y < pt.y + bmpInfo.bmHeight / 2 ){
_lastObject = _model.getComponent(i);
return;
}
}
} else{
// рисовать текущий элемент (ещё не добавленный в модель)
if ( _mouseState == MS_COMPONENT || _mouseState == MS_SUBSYSTEM || _mouseState == MS_SYSTEM ){
CDC dcBitmap, * screenDC = GetDC();
CBitmap* pOldPictureBitmap = NULL, * pDrawBitmap;
BITMAP bmpInfo;
switch ( _mouseState ){
case MS_COMPONENT:
pDrawBitmap = btmNactiveComponent;
break;
case MS_SUBSYSTEM:
pDrawBitmap = btmNactiveSubsystem;
break;
case MS_SYSTEM:
pDrawBitmap = btmNactiveSystem;
break;
}
DrawModel();
dcBitmap.CreateCompatibleDC(screenDC);
pOldPictureBitmap = dcBitmap.SelectObject(pDrawBitmap);
pDrawBitmap->GetBitmap(&bmpInfo);
TransparentBlt(screenDC->GetSafeHdc(), point.x - bmpInfo.bmWidth / 2, point.y - bmpInfo.bmHeight / 2, bmpInfo.bmWidth, bmpInfo.bmHeight, dcBitmap.GetSafeHdc(), 0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, TRANSPARENT_COLOR);
ReleaseDC(screenDC);
if ( pOldPictureBitmap ) dcBitmap.SelectObject(pOldPictureBitmap);
dcBitmap.DeleteDC();
}
}
}
}
void CModelWnd::OnRButtonUp(UINT nFlags,CPoint point) {
// вывести диалог с параметрами элемента
BITMAP bmpInfo;
btmNactiveSystem->GetBitmap(&bmpInfo);
POINT pt = _model.system.getPos();
if ( point.x > pt.x - (bmpInfo.bmWidth / 2) && point.x <pt.x + bmpInfo.bmWidth / 2 && point.y> pt.y - (bmpInfo.bmHeight / 2) && point.y < pt.y + bmpInfo.bmHeight / 2 )
_model.system.FillDialog(); // для системы
btmNactiveSubsystem->GetBitmap(&bmpInfo);
for ( int i = 0; i < _model.subsystemCount(); i++ ){
POINT pt = _model.getSubsystem(i)->getPos();
if ( point.x > pt.x - (bmpInfo.bmWidth / 2) && point.x <pt.x + bmpInfo.bmWidth / 2 && point.y> pt.y - (bmpInfo.bmHeight / 2) && point.y < pt.y + bmpInfo.bmHeight / 2 ){
_model.getSubsystem(i)->FillDialog(); // для подсистемы
return;
}
}
btmNactiveComponent->GetBitmap(&bmpInfo);
for ( i = 0; i < _model.componentCount(); i++ ){
POINT pt = _model.getComponent(i)->getPos();
if ( point.x > pt.x - (bmpInfo.bmWidth / 2) && point.x <pt.x + bmpInfo.bmWidth / 2 && point.y> pt.y - (bmpInfo.bmHeight / 2) && point.y < pt.y + bmpInfo.bmHeight / 2 ){
_model.getComponent(i)->FillDialog(); // для компоненты
return;
}
}
}
void CModelWnd::OnLButtonUp(UINT nFlags,CPoint point){
_lastObject = NULL;
if ( MS_LINK == _mouseState ) return;
// найти и выделить активный элемент
_objectToDelete = Intersect(point, &_activeObject);
if ( _objectToDelete == ME_NOTHING ) btmActive = NULL;
else
switch ( _objectToDelete ){
case ME_COMPONENT: {
btmActive = btmActiveComponent;
break;
}
case ME_SUBSYSTEM: {
btmActive = btmActiveSubsystem;
break;
}
case ME_SYSTEM: {
btmActive = btmActiveSystem;
break;
}
}
DrawModel();
}
DWORD CModelWnd::ThreadFunc(void* args){
CModelWnd* mw = (CModelWnd*) args;
double last, prelast;
CTime start = CTime::GetCurrentTime();
// создать первое поколение особей
CPopulation GApopulation(&(mw->_model));
GApopulation.Create();
GApopulation.GenerateStartPopulation();
double division = 0.0;
DWORD cnt = 0;
bool DO = true;
do{
// основной цикл ГА
GApopulation.nextGeneration();
GApopulation.getValues(last, prelast);
division = fabs(last - prelast);
cnt++;
}
while (cnt <GLOBParamStorage.populationCnt && division> GLOBParamStorage.funcDiv);
mw->splash->EndDialog(IDCANCEL);
CTime end = CTime::GetCurrentTime();
// сохранить отчёт
mw->SaveReport(last, start, end, cnt);
return 1;
}
void CModelWnd::Evolute(){
// проверить корректность модели
if ( !CheckForCorrect() )
MessageBox("Модель некорректна", "Ошибка", MB_ICONSTOP | MB_OK);
else{
// и запустить поиск решения
splash = new CSplash(this);
HANDLE h = CreateThread(NULL, 0, ThreadFunc, (void*)this, 0, NULL);
splash->DoModal();
WaitForSingleObject(h, INFINITE);
delete splash;
splash = NULL;
MessageBox("Поиск решения завершён", "Конец", MB_ICONINFORMATION | MB_OK);
}
DrawModel();
}
void CModelWnd::SaveModel(){
CFileDialog fileDlg(false, "gml", _fileName, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Файлы с описанием моделей|*.mdl|Все файлы|*.*||", this);
if ( fileDlg.DoModal() == IDOK ){
_fileName = fileDlg.GetFileName();
_filePath = fileDlg.GetPathName();
_filePath.Replace(_fileName, "");
if ( fileDlg.GetFileExt() != "" )
_fileName.Delete(_fileName.GetLength() - fileDlg.GetFileExt().GetLength() - 1, fileDlg.GetFileExt().GetLength() + 1);
SetWindowText(_fileName);
CFile fileToSave(fileDlg.GetPathName(), CFile::modeCreate | CFile::modeWrite);
// формирование заголовка файла
SFileHeader fh;
fh.magic = 0x4F6A;
strncpy((char *) fh.productName, "ГЕНератор", 10);
XORString((char *) fh.productName, MASK, 10);
fh.version = 1 << 8;
fh.systemsCount = 1;
fh.subsystemsCount = _model.subsystemCount();
fh.componentsCount = _model.componentCount();
fh.systemInfoOffset = sizeof(SFileHeader);
fh.subSystemsInfoOffset = 0;
fh.componentsInfoOffset = 0;//fh.subSystemsInfoOffset + fh.subsystemsCount * sizeof(SComponentInfo);
ZeroMemory(&fh.reserved, 256);
fileToSave.Write(&fh, sizeof(SFileHeader));
// записать сведение о системе
SSubSystemInfo sys;
strncpy((char *) sys.hintString, XORString((char *) _model.system.getHintString().operator LPCTSTR(), MASK, MAX_LEN + 1), MAX_LEN);
strncpy((char *) sys.funcString, XORString((char *) _model.system.getFitnessFunc().operator LPCTSTR(), MASK, MAX_LEN + 1), MAX_LEN);
sys.parentName[0] = MASK;
sys.position = _model.system.getPos();
sys.childrenCount = _model.system.childrenCount();
fileToSave.Write(&sys, sizeof(SSubSystemInfo) - sizeof(unsigned char * *));
char names[MAX_LEN + 1];
for ( int i = 0; i < sys.childrenCount; i++ ){
strncpy((char *) names, XORString((char *) _model.system.getChild(i)-> getName().operator LPCTSTR(), MASK, MAX_LEN + 1), MAX_LEN);
fileToSave.Write(names, MAX_LEN + 1);
}
fh.subSystemsInfoOffset = fh.systemInfoOffset + sizeof(SSubSystemInfo) - sizeof(unsigned char * *) + (MAX_LEN + 1) * sys.childrenCount;
// записать сведения о всех подсистемах
SSubSystemInfo subSys;
fh.componentsInfoOffset = fh.subSystemsInfoOffset;
for ( i = 0; i < fh.subsystemsCount; i++ ){
strncpy((char *) subSys.hintString, XORString((char *) _model.getSubsystem(i)-> getHintString().operator LPCTSTR(), MASK, MAX_LEN + 1), MAX_LEN);
strncpy((char *) subSys.nameString, XORString((char *) _model.getSubsystem(i)-> getName().operator LPCTSTR(), MASK, MAX_LEN + 1), MAX_LEN);
strncpy((char *) subSys.funcString, XORString((char *) _model.getSubsystem(i)-> getFitnessFunc().operator LPCTSTR(), MASK, MAX_LEN + 1), MAX_LEN);
if ( _model.getSubsystem(i)->getParent() == NULL )
subSys.parentName[0] = MASK;
else
strncpy((char *) subSys.parentName, XORString((char *) _model.getSubsystem(i)-> getParent()->getName().operator LPCTSTR(), MASK, MAX_LEN + 1), MAX_LEN);
subSys.position = _model.getSubsystem(i)->getPos();
subSys.childrenCount = _model.getSubsystem(i)->childrenCount();
fileToSave.Write(&subSys, sizeof(SSubSystemInfo) - sizeof(unsigned char * *));
for ( int j = 0; j < subSys.childrenCount; j++ ){
strncpy((char *) names, XORString((char *) _model.getSubsystem(i)->getChild(j)-> getName().operator LPCTSTR(), MASK, MAX_LEN + 1), MAX_LEN);
fileToSave.Write(names, MAX_LEN + 1);
}
fh.componentsInfoOffset += sizeof(SSubSystemInfo) - sizeof(unsigned char * *) + (MAX_LEN + 1) * subSys.childrenCount;
}
// записать сведения о всех компонентах
SComponentInfo comp;
for ( i = 0; i < fh.componentsCount; i++ ){
strncpy((char *) comp.hintString, XORString((char *) _model.getComponent(i)-> getHintString().operator LPCTSTR(), MASK, MAX_LEN + 1), MAX_LEN);
strncpy((char *) comp.nameString, XORString((char *) _model.getComponent(i)-> getName().operator LPCTSTR(), MASK, MAX_LEN + 1), MAX_LEN);
comp.position = _model.getComponent(i)->getPos();
comp.type = _model.getComponent(i)->getType();
if ( comp.type == VRANGE ) _model.getComponent(i)->getBounds(comp.left, comp.right);
else {
comp.left = 2.718281828;
comp.right = 3.14159265;
}
if ( _model.getComponent(i)->getParent() == NULL ) comp.parentName[0] = MASK;
else strncpy((char *) comp.parentName, XORString((char *) _model.getComponent(i)-> getParent()->getName().operator LPCTSTR(), MASK, MAX_LEN + 1), MAX_LEN);
if ( comp.type == VRANGE ) comp.listValuesCount = 299792458;
else comp.listValuesCount = ((_model.getComponent(i)->getValues() == NULL) ? 0 : _model.getComponent(i)->getValues()->size());
fileToSave.Write(&comp, sizeof(SComponentInfo) - 2 * sizeof(unsigned char * *));
if ( comp.type == VLIST ){
for ( int j = 0; j < comp.listValuesCount; j++ ){
strncpy((char *) names, XORString((char *) (*(_model.getComponent(i)-> getValues()))[j].sExpression.operator LPCTSTR(), MASK, MAX_LEN + 1), MAX_LEN);
fileToSave.Write(names, MAX_LEN + 1);
}
for ( j = 0; j < comp.listValuesCount; j++ ){
strncpy((char *) names, XORString((char *) (*(_model.getComponent(i)-> getValues()))[j].sDescription.operator LPCTSTR(), MASK, MAX_LEN + 1), MAX_LEN);
fileToSave.Write(names, MAX_LEN + 1);
}
}
}
fileToSave.SeekToBegin();
fileToSave.Write(&fh, sizeof(SFileHeader)); // сохранить в файл
}
}
//syntax.cpp
#include "stdafx.h"
#include "syntax.h"
int CSyntax::syntax(const CString & sExpression){
if ( !sExpression.GetLength() ) return ERR_BLANK;
CString sTmp = sExpression;
sTmp.Replace(" ", "");
sTmp.Replace("(+", "(");
sTmp.Replace("(-", "(0-");
if ( sTmp[0] == '+' ) sTmp.Delete(0);
if ( sTmp[0] == '-' ) sTmp.Insert(0, "0");
//"системные" переменные
int iFCount = -1; //число вложенных ф-ий - 1
#define MAX_F_COUNT 11
int iFArgCount[MAX_F_COUNT]; //число аргументов у функции
int iFBrCount[MAX_F_COUNT]; //число открывающих скобок внутри ф-ии
//(если есть вложенная ф-ия, переходим к ней)
int iExprBrCount = 0;
int t;
int iLastToken = RET_COMPONENT_NAME - 1;
CString lexemma;
int p1 = 0;
while ( p1 >= 0 ){
t = GLOBLexer.lex(sTmp, lexemma, p1);
if ( p1 == -1 ) break;
if ( t < RET_COMPONENT_NAME ) return t;
// есть очередная лексемма
switch ( t ){
// реализуем конечный автомат для проверки выражения по таблице переходов
case RET_COMPONENT_NAME: case RET_SUBSYSTEM_NAME:
case RET_DIGIT: case RET_FUNCTION_NAME: {
if ( iLastToken == RET_COMPONENT_NAME - 1 ){
iLastToken = t;
break;
}
if ( t == RET_FUNCTION_NAME ){
if ( ++iFCount == MAX_F_COUNT ) return ERR_FUNC_COUNT;
iFArgCount[iFCount] = 1; // функция может принимать только один параметр
}
if ( (iLastToken != RET_OPERATION) && (iLastToken != RET_OPEN_BR) && (iLastToken != RET_SEPARATOR) )
return ERR_SEQ;
iLastToken = t;
break;
}
case RET_OPERATION: {
if ( iLastToken == RET_COMPONENT_NAME - 1 ){
iLastToken = t;
break;
}
if ( (iLastToken != RET_COMPONENT_NAME) && (iLastToken != RET_SUBSYSTEM_NAME) && (iLastToken != RET_DIGIT) && (iLastToken != RET_CLOSE_BR) )
return ERR_SEQ;
iLastToken = t;
break;
}
case RET_OPEN_BR: {
if ( iLastToken == RET_COMPONENT_NAME - 1 ){
iLastToken = t;
iExprBrCount++;
break;
}
if ( (iLastToken != RET_OPERATION) && (iLastToken != RET_FUNCTION_NAME) && (iLastToken != RET_SEPARATOR) && (iLastToken != RET_OPEN_BR) )
return ERR_SEQ;
if ( iFCount > -1 ) iFBrCount[iFCount]++;
else iExprBrCount++;
iLastToken = t;
break;
}
case RET_CLOSE_BR: {
if ( iLastToken == RET_COMPONENT_NAME - 1 ){
iLastToken = t;
iExprBrCount--;
break;
}
if ( (iLastToken != RET_COMPONENT_NAME) && (iLastToken != RET_SUBSYSTEM_NAME) && (iLastToken != RET_DIGIT) && (iLastToken != RET_CLOSE_BR) ) return ERR_SEQ;
if ( iFCount > -1 ){
iFBrCount[iFCount]--;
if ( !iFBrCount[iFCount] ){
if ( iFArgCount[iFCount] > 1 ) return ERR_PARAM_COUNT;
iFCount--;
}
}
else iExprBrCount--;
iLastToken = t;
break;
}
case RET_SEPARATOR: {
if ( iLastToken == RET_COMPONENT_NAME - 1 ){
iLastToken = t;
break;
}
if ( (iLastToken != RET_COMPONENT_NAME) && (iLastToken != RET_SUBSYSTEM_NAME) && (iLastToken != RET_DIGIT) && (iLastToken != RET_CLOSE_BR) ) return ERR_SEQ;
if ( iFCount == -1 ) return ERR_SEP_MISPLASED;
iFArgCount[iFCount]--;
iLastToken = t;
break;
}
default: return ERR_UNKNOWN_TOKEN;
}
}
if ( iLastToken == RET_SEPARATOR || iLastToken == RET_OPEN_BR || iLastToken == RET_OPERATION ) return ERR_SEQ;
return ERR_OK;
}
CSyntax GLOBSyntax; // синглтон
//population.cpp
#include "stdafx.h"
#include "population.h"
#include <time.h>
#include <math.h>
#include <stdlib.h>
#include <search.h>
VARVALUES GLOBVarValues;
struct SIndexInfo{
double val;
int index;
};
int compare(const void* arg1,const void* arg2){ // функция для быстрой сортировки
if ( ((SIndexInfo *) arg1)->val > ((SIndexInfo *) arg2)->val ) return -1;
if ( ((SIndexInfo *) arg1)->val < ((SIndexInfo *) arg2)->val ) return 1;
return 0;
}
CPopulation::CPopulation(CModelStorage* _model) : _lastValue(0.0), _preLastValue(0.0), _hasCreated(false), model(_model){
srand(time(NULL));
GLOBTarget.AttachToModel(_model);
}
void CPopulation::ModifyVarValues(CPersonSet* P,int j,int i){
// поставить в соответствие имени переменной строку, содержащую её значение
if ( P->locuses[j]->getType() == VRANGE ){
char str[37];
sprintf(str, "%g", P->getAccess()[j][i]);
GLOBVarValues[P->locuses[j]->getName()] = str;
} else
GLOBVarValues[P->locuses[j]->getName()] = ((*(P->locuses[j]->getValues()))[int(P-> getAccess()[j][i])]).sExpression; }
void CPopulation::Crossover(double first[],double second[],int size){
double v = double(rand()) / double(RAND_MAX);
if ( v > GLOBParamStorage.crossoverP ) return;
// определить число точек кроссовера в соответствии с настройками
int realNumOfPoints = GLOBParamStorage.numOfCrossoverPts;
while ( realNumOfPoints >= size ) realNumOfPoints--;
int left = 0, right = size - realNumOfPoints + 1;
for ( int i = 0; i <= realNumOfPoints; i++ ){ // разбить хромосому на участки
double delta = 1.0 / (right - left);
int x = int (double(rand()) / double(RAND_MAX) / delta);
if ( i % 2 ){
// и поменять их местами
for ( int j = left; j < left + x; j++ ){
double t = first[j];
first[j] = second[j];
second[j] = t;
}
}
left += (x + 1);
right ++;
}
}
#define DELTA 9.76
void CPopulation::Mutation(double gen[],CHromoPrototype* hp){
if ( (double(rand()) / double(RAND_MAX)) > GLOBParamStorage.mutationP ) return;
int locusNum = hp->locuses.size() * rand() / (RAND_MAX + 1); // номер мутируемого гена
if ( hp->locuses[locusNum]->getType() == VRANGE ){
double left, right;
hp->locuses[locusNum]->getBounds(left, right);
double delta = __min(gen[locusNum] - left, right - gen[locusNum]) / DELTA;
double add = 2 * delta * double(rand()) / (RAND_MAX + 1);
gen[locusNum] = gen[locusNum] - delta + add; // мутация
}else{
int cnt = hp->locuses[locusNum]->getValues()->size();
gen[locusNum] = int(double(rand()) / (RAND_MAX + 1) * cnt); // мутация
}
}
void CPopulation::GenerateStartPopulation(){
if ( !_hasCreated ) return;
// создать начальную популяцию из случайных значений
for ( int i = 0; i < _generations.size(); i++ )
for ( int j = 0; j < _generations[i]->locuses.size(); j++ )
for ( int k = 0; k < _generations[i]->getPersonesCount(); k++ ){
if ( _generations[i]->locuses[j]->getType() == VRANGE ){
double left, right;
_generations[i]->locuses[j]->getBounds(left, right);
double** dbg1 = _generations[i]->getAccess();
dbg1[j][k] = left + (right - left) * double(rand()) / RAND_MAX;
}
else (_generations[i]->getAccess())[j][k] = int(double(rand()) * _generations[i]-> locuses[j]->getValues()->size() / (RAND_MAX + 1));
}
}
void CPopulation::Generate(int index){
if ( !_hasCreated || index >= _generations.size() || index < 0 ) return;
int* genIndex = new int[(_generations[index]->getPersonesCount() + 1) / 2];
ProductGroup(index, genIndex);
double* pers1 = new double [_generations[index]->locuses.size()];
double* pers2 = new double [_generations[index]->locuses.size()];
double** tempPop;
tempPop = new double * [_generations[index]->getPersonesCount()];
for ( int k = 0; k < _generations[index]->getPersonesCount(); k++ )
tempPop[k] = new double [_generations[index]->locuses.size()];
if ( GLOBParamStorage.crossoverType == CParams::TYPE_BEST_WITH_WORST ){
int fromTop = 1, fromBottom = 0;
while ( 2 * fromTop * fromBottom < _generations[index]->getPersonesCount() ){
if ( fromBottom < fromTop ) fromBottom++;
else fromTop++;
}
// скрестить особи и сохранить потомков
int osobCnt = 0;
for ( int i = (_generations[index]->getPersonesCount() + 1) / 2 - fromBottom; i < (_generations[index]->getPersonesCount() + 1) / 2; i++ ){
if ( osobCnt >= _generations[index]->getPersonesCount() ) break;
for ( int j = 0; j < fromTop; j++ ){
if ( osobCnt >= _generations[index]->getPersonesCount() ) break;
for ( int k = 0; k < _generations[index]->locuses.size(); k++ ){
pers1[k] = (_generations[index]->getAccess())[k][genIndex[j]];
pers2[k] = (_generations[index]->getAccess())[k][genIndex[i]];
}
Crossover(pers1, pers2, _generations[index]->locuses.size());
for ( k = 0; k < _generations[index]->locuses.size(); k++ ){
tempPop[osobCnt][k] = pers1[k];
tempPop[osobCnt + 1][k] = pers2[k];
};
osobCnt += 2;
if ( osobCnt >= _generations[index]->getPersonesCount() )
break;
}
}
}else{
for ( int k = 0; k < _generations[index]->locuses.size(); k++ )
tempPop[0][k] = (_generations[index]->getAccess())[k][genIndex[0]];
int osobCnt = (_generations[index]->getPersonesCount() + 1) / 2;
for ( int i = 1; i < osobCnt; i++ ){
for ( int k = 0; k < _generations[index]->locuses.size(); k++ ){
pers1[k] = (_generations[index]->getAccess())[k][genIndex[0]];
pers2[k] = (_generations[index]->getAccess())[k][genIndex[i]];
}
Crossover(pers1, pers2, _generations[index]->locuses.size());
bool first = rand() <= RAND_MAX / 2;
for ( k = 0; k < _generations[index]->locuses.size(); k++ )
tempPop[i][k] = first ? pers1[k] : pers2[k];
}
}
for ( int i = 0; i < _generations[index]->getPersonesCount(); i++ )
Mutation(tempPop[i], _generations[index]);
for ( i = 0; i < _generations[index]->getPersonesCount(); i++ )
for ( int j = 0; j < _generations[index]->locuses.size(); j++ )
(_generations[index]->getAccess())[j][i] = tempPop[i][j];
ProductGroup(index, genIndex);
CPersonSet* tmpP = getPersones(index);
int ln = tmpP->locuses.size();
for ( int j = 0; j < ln; j++ ) ModifyVarValues(tmpP, j, genIndex[0]);
for ( k = 0; k < _generations[index]->getPersonesCount(); k++ ) delete[] tempPop[k];
delete tempPop;
delete[] pers2;
delete[] pers1;
delete[] genIndex;
}
void CPopulation::nextGeneration(){
// слежующее поколение для всех хромосом
for ( int i = 0; i < _generations.size(); i++ ) Generate(i);
_preLastValue = _lastValue;
_lastValue = ObtainResult();
}
double CPopulation::ObtainResult(){
return GLOBTarget.Calculate(); // значение функции приспособленности системы
}
void CPopulation::Create() {// создание из модели системы мультихромосомной модели
if ( _hasCreated ) return;
for ( int i = 0; i < model->subsystemCount(); i++ ){
CPersonSet* tmpPS = new CPersonSet(model->getSubsystem(i), GLOBParamStorage.generationSize);
for ( int j = 0; j < model->getSubsystem(i)->childrenCount(); j++ ){
if ( model->getSubsystem(i)->getChild(j)->getName()[0] == '$' )
tmpPS->locuses.push_back((CComponent *) model->getSubsystem(i)->getChild(j));
}
if ( tmpPS->locuses.size() != 0 ){
tmpPS->Init();
_generations.push_back(tmpPS);
} else delete tmpPS;
}
CPersonSet* tmpPS = new CPersonSet(&(model->system), GLOBParamStorage.generationSize);
for ( int j = 0; j < model->system.childrenCount(); j++ ){
if ( model->system.getChild(j)->getName()[0] == '$' )
tmpPS->locuses.push_back((CComponent *) model->system.getChild(j));
}
if ( tmpPS->locuses.size() != 0 ){
tmpPS->Init();
_generations.push_back(tmpPS);
} else delete tmpPS;
_hasCreated = true;
}
void CPopulation::Destroy(){
if ( !_hasCreated ) return;
int sz = _generations.size();
for ( int i = 0; i < sz; i++ )
delete _generations[i];
_hasCreated = false;
}
//variableskeeper.cpp
#include "stdafx.h"
#include "variablesKeeper.h"
#include <math.h>
int CVariablesKeeper::isCorrect() {// проверка отсутствия циклов в зависимостях переменных
const int size = getCount();
if ( size <= 1 ) return ERR_ALLOK;
const int sign = 0x029A;
int* mtr = new int[size* size];
// подготовка матрицы --------------------------┐
for ( int i = 0; i < size; i++ ){
int ptr = 0;
int index = 0;
for ( ; ; ){
CString tS("");
tS = NextVarName(i, ptr, index);
if ( tS.GetLength() ){
int t;
if ( (t = VariableIndex(tS)) < 0 ){
delete[] mtr;
return ERR_NONEXIST;
}
mtr[i * size + t] = sign;
} else break;
}
}
// подготовка матрицы ---------------------------|
// проверка на зависимость переменной от самой себя
for ( i = 0; i < size; i++ )
if ( mtr[i * size + i] == sign ){
delete[] mtr;
return ERR_ISCYCLES;
}
char* indexes = new char[size];
for ( i = 0; i < size - 1; i++ ){
memset(indexes, '0', size);
indexes[i] = '1';
for ( int j = 0; j < int(pow(2, size - i - 1)) - 1; j++ ){
int curInd = size - 1;
while ( curInd != i ){
if ( indexes[curInd] == '0' ){
indexes[curInd]++;
break;
}
--indexes[curInd--];
}
// в этом месте есть сформированный для очередного прохода
// массив индексов
int submtrSize = 0; // размер очередной подматрицы
for ( int k = 0; k < size; k++ )
if ( indexes[k] == '1' ) submtrSize++;
// к-во '+' в строках и столбцах очередной подматрицы --------┐
int* row = new int[submtrSize];
int* column = new int[submtrSize];
memset(row, 0, sizeof(int) * submtrSize);
memset(column, 0, sizeof(int) * submtrSize);
int rowIndex = 0;
for ( int l = 0; l < size; l++ ){
if ( indexes[l] == '0' ) continue;
int columnIndex = 0;
for ( int m = 0; m < size; m++ ){
if ( indexes[m] == '1' ){
if ( mtr[l * size + m] == sign ){
row[rowIndex]++;
column[columnIndex]++;
}
columnIndex++;
}
}
rowIndex++;
}
// к-во '+' в строках и столбцах очередной подматрицы --------|
bool exist = true;
for ( int n = 0; n < submtrSize; n++ ){
if ( row[n] != 1 || column[n] != 1 ){
exist = false;
break;
}
}
delete[] column;
delete[] row;
if ( exist ){
delete[] mtr;
delete[] indexes;
return ERR_ISCYCLES;
}
}
}
delete[] mtr;
delete[] indexes;
return ERR_ALLOK;
}
bool CVariablesKeeper::checkExpression(int var_ind){
if ( var_ind < 0 || var_ind >= _vl.size() || _vl[var_ind]->getType() == VRANGE ) return true;
int sz = (_vl[var_ind]->getValues() == NULL) ? 0 : _vl[var_ind]->getValues()->size();
for ( int i = 0; i < sz; i++ ){
if ( ERR_OK != GLOBSyntax.syntax((*_vl[var_ind]->getValues())[i].sExpression) )
return false;
}
return true;
}
ПРИЛОЖЕНИЕ 2