else
crds[0]='\0';
CFont *font = new CFont();
font->CreateFont(14, 10, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Courier");
dc->SelectObject(font);
dc->TextOut(50,10,"Точка x:"+coords+" Степеньпринадлежности:"+crds);
}
CDialog::OnMouseMove(nFlags, point);
}
Результат выполнения программы изображен на рисунке 4.1. В данном случае построена сигмоидальная функция принадлежности.
Рисунок 4.1 – Результат выполнения программы – сигмоидальная функция принадлежности
ВЫВОДЫ
Результатом работы является исполняемое Win32-приложение, позволяющее строить следующие функции принадлежности:
- треугольную;
- трапециидальную;
- гауссовскую;
- расширенную гауссовскую;
- сигмоидальную.
Так же программа позволяет определять значение степени принадлежности заданной точки x.
В ходе разработки приложения были изучены структура и возможности набора классов MFC, принципы проектирования визуального интерфейса пользователя в операционной среде MSWindows с использованием среды разработки MSVisualStudio. Было замечено, что классы MFC существенно ускоряют процесс создания приложений для операционной системы MicrosoftWindows.
Так же были изучены основы теории нечетких множеств, в частности функции принадлежности.
ПЕРЕЧЕНЬ ССЫЛОК
1. Microsoft Developer Network Library ‑ April 2003
2. Васильев В.И., Ильясов Б.Г. Интеллектуальные системы управления с использованием нечеткой логики: Учеб. пособие / Уфимск. гос. авиац. техн. ун-т. -Уфа, 1995. -80 c
3. Грегори К. Использование VisualC++ 6. Специальное издание.: Пер. с англ. – М.: СПб.; К.: Издательский дом «Вильямс», 2003. – 849 с.
4. Заде Л. Понятие лингвистической переменной и его применение к принятию приближенных решений. – М.: Мир, 1976.
5. Нечеткая логика ‑ математические основы ‑ BaseGroupLabs
http://www.basegroup.ru/fuzzylogic/math_print.htm
6. Страуструп Бьярн Язык программирования C++ Второе издание. – К.: ДиаСофт, 1993. – 480 с.
ПРИЛОЖЕНИЕ
ПриложениеА
Листингпрограммы
// Fuzzy_.h: interface for the CFuzzy_ class.
class CFuzzy_
{
public:
void fisError(char *msg);
CFuzzy_();
virtual ~CFuzzy_();
double CFuzzy_::fisTriangleMf(double x, double *params);
double fisTrapezoidMf(double x, double *params);
double fisGaussianMf(double x, double *params);
double fisGaussian2Mf(double x, double *params);
double fisSigmoidMf(double x, double *params);
};
// Fuzzy_.cpp: implementation of the CFuzzy_ class.
#include "stdafx.h"
#include "fuzzy.h"
#include "Fuzzy_.h"
#include <math.h>
#ifndef ABS
# define ABS(x) ( (x) > (0) ? (x): (-(x)) )
#endif
#ifndef MAX
# define MAX(x,y) ( (x) > (y) ? (x) : (y) )
#endif
#ifndef MIN
# define MIN(x,y) ( (x) < (y) ? (x) : (y) )
#endif
CFuzzy_::CFuzzy_()
{
}
CFuzzy_::~CFuzzy_()
{
}
/* Triangular membership function */
double CFuzzy_::fisTriangleMf(double x, double *params)
{
double a = params[0], b = params[1], c = params[2];
if (a>b)
{fisError("Illegal parameters in fisTriangleMf() --> a > b");return -1;}
if (b>c)
{fisError("Illegal parameters in fisTriangleMf() --> b > c");return -1;}
if (a == b && b == c)
return(x == a);
if (a == b)
return((c-x)/(c-b)*(b<=x)*(x<=c));
if (b == c)
return((x-a)/(b-a)*(a<=x)*(x<=b));
return(MAX(MIN((x-a)/(b-a), (c-x)/(c-b)), 0));
}
/* Trapezpoidal membership function */
double CFuzzy_::fisTrapezoidMf(double x, double *params)
{
double a = params[0], b = params[1], c = params[2], d = params[3];
double y1 = 0, y2 = 0;
if (a>b) {
fisError("Illegal parameters in fisTrapezoidMf() --> a > b");
}
if (b>c)
{
fisError("Illegal parameters in fisTrapezoidMf() --> b > c");
}
if (c>d) {
fisError("Illegal parameters in fisTrapezoidMf() --> c > d");
}
if (b <= x)
y1 = 1;
else if (x < a)
y1 = 0;
else if (a != b)
y1 = (x-a)/(b-a);
if (x <= c)
y2 = 1;
else if (d < x)
y2 = 0;
else if (c != d)
y2 = (d-x)/(d-c);
return(MIN(y1, y2));
}
/* Gaussian membership function */
double CFuzzy_::fisGaussianMf(double x, double *params)
{
double sigma = params[0], c = params[1];
double tmp;
if (sigma==0)
fisError("Illegal parameters in fisGaussianMF() --> sigma = 0");
tmp = (x-c)/sigma;
return(exp(-tmp*tmp/2));
}
/* Extended Gaussian membership function */
double CFuzzy_::fisGaussian2Mf(double x, double *params)
{
double sigma1 = params[0], c1 = params[1];
double sigma2 = params[2], c2 = params[3];
double tmp1, tmp2;
if ((sigma1 == 0) || (sigma2 == 0))
fisError("Illegal parameters in fisGaussian2MF() --> sigma1 or sigma2 is zero");
tmp1 = x >= c1? 1:exp(-pow((x-c1)/sigma1, 2.0)/2);
tmp2 = x <= c2? 1:exp(-pow((x-c2)/sigma2, 2.0)/2);
return(tmp1*tmp2);
}
/* Sigmoidal membership function */
double CFuzzy_::fisSigmoidMf(double x, double *params)
{
double a = params[0], c = params[1];
return(1/(1+exp(-a*(x-c))));
}
void CFuzzy_::fisError(char *msg)
{
MessageBox(NULL,msg,"Error",MB_OK|MB_ICONSTOP);
}
// fuzzy.h : main header file for the FUZZY application CFuzzyApp
#include "resource.h"
class CFuzzyApp : public CWinApp
{
public:
CFuzzyApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CFuzzyApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CFuzzyApp)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
// fuzzy.cpp : Defines the class behaviors for the application. CFuzzyApp
#include "stdafx.h"
#include "fuzzy.h"
#include "fuzzyDlg.h"
BEGIN_MESSAGE_MAP(CFuzzyApp, CWinApp)
//{{AFX_MSG_MAP(CFuzzyApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
CFuzzyApp::CFuzzyApp()
{
}
CFuzzyApp theApp;
// CFuzzyApp initialization
BOOL CFuzzyApp::InitInstance()
{
AfxEnableControlContainer();
#ifdef _AFXDLL
Enable3dControls();
#else
Enable3dControlsStatic();
#endif
CFuzzyDlg dlg;
m_pMainWnd = &dlg;
dlg.DoModal();
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
// fuzzyDlg.h : header file
// CFuzzyDlg dialog
class CFuzzyDlg : public CDialog
{
// Construction
public:
void PlotTrapezoid();
void PlotTriangle();
void PlotGaussian();
void PlotSigmoid();
void PlotGaussian2();
void Axis();
CButton *R_Tri, *R_Tra, *R_Ga, *R_Ga2, *R_Sig;
CFuzzyDlg(CWnd* pParent = NULL);// standard constructor
// Dialog Data
//{{AFX_DATA(CFuzzyDlg)
enum { IDD = IDD_FUZZY_DIALOG };
CEditpar_d;
CEditpar_c;
CEditpar_b;
CEditpar_a;
CStaticm_grapho;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CFuzzyDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX);// DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CFuzzyDlg)
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnButton1();
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnRadio1();
afx_msg void OnRadio2();
afx_msg void OnRadio3();
afx_msg void OnRadio4();
afx_msg void OnRadio5();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
// fuzzyDlg.cpp : implementation file
//
#include "stdafx.h"
#include "fuzzy.h"
#include "fuzzyDlg.h"
#include "fuzzy_.h"
#ifndef ABS
# define ABS(x) ( (x) > (0) ? (x): (-(x)) )
#endif
#ifndef MAX
# define MAX(x,y) ( (x) > (y) ? (x) : (y) )
#endif
#ifndef MIN
# define MIN(x,y) ( (x) < (y) ? (x) : (y) )
#endif
CFuzzy_ fuzzy;
double *param, x, y=0, kX=1000, _par=0;
int WIDTH, HEIGHT;
byte function=0;
const byte TRIANGLE = 1;
const byte TRAPEZOID = 2;
const byte GAUSSIAN = 3;
const byte GAUSSIAN2 = 4;
const byte SIGMOID = 5;
/////////////////////////////////////////////////////////////////////////////
// CFuzzyDlg dialog
CFuzzyDlg::CFuzzyDlg(CWnd* pParent /*=NULL*/)
: CDialog(CFuzzyDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CFuzzyDlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CFuzzyDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CFuzzyDlg)
DDX_Control(pDX, IDC_EDITD, par_d);
DDX_Control(pDX, IDC_EDITC, par_c);
DDX_Control(pDX, IDC_EDITB, par_b);
DDX_Control(pDX, IDC_EDITA, par_a);
DDX_Control(pDX, IDC_GRAPHO, m_grapho);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CFuzzyDlg, CDialog)
//{{AFX_MSG_MAP(CFuzzyDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_WM_MOUSEMOVE()
ON_BN_CLICKED(IDC_RADIO1, OnRadio1)
ON_BN_CLICKED(IDC_RADIO2, OnRadio2)
ON_BN_CLICKED(IDC_RADIO3, OnRadio3)
ON_BN_CLICKED(IDC_RADIO4, OnRadio4)
ON_BN_CLICKED(IDC_RADIO5, OnRadio5)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFuzzyDlg message handlers
BOOL CFuzzyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
SetIcon(m_hIcon, TRUE);// Set big icon
SetIcon(m_hIcon, FALSE);
par_a.SetWindowText("1");
par_b.SetWindowText("3");
par_c.SetWindowText("5");
par_d.SetWindowText("9");
R_Tri=(CButton*)GetDlgItem(IDC_RADIO1);
R_Tra=(CButton*)GetDlgItem(IDC_RADIO2);
R_Ga=(CButton*)GetDlgItem(IDC_RADIO3);
R_Ga2=(CButton*)GetDlgItem(IDC_RADIO4);
R_Sig=(CButton*)GetDlgItem(IDC_RADIO5);
param = new double[3];
WIDTH = 600;
HEIGHT = 400;
// Set small icon
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CFuzzyDlg::OnPaint()
{
CDialog::OnPaint();
Axis();
if (function==GAUSSIAN)
PlotGaussian();
else
if (function==TRIANGLE)
PlotTriangle();
else
if (function==TRAPEZOID)
PlotTrapezoid();
else
if (function==GAUSSIAN2)
PlotGaussian2();
else
if (function==SIGMOID)
PlotSigmoid();
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CFuzzyDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CFuzzyDlg::OnButton1()
{
Axis();
if (R_Tri->GetState()==1)
{
PlotTriangle();
} else
if (R_Tra->GetState()==1)
{
PlotTrapezoid();
} else
if (R_Ga->GetState()==1)
{
PlotGaussian();
}
else
if (R_Ga2->GetState()==1)
{
PlotGaussian2();
} else
if (R_Sig->GetState()==1)
{
PlotSigmoid();
}
else AfxMessageBox("Выберите тип функции!!", MB_ICONWARNING|MB_OK, 0);
}
void CFuzzyDlg::OnMouseMove(UINT nFlags, CPoint point)
{
if (point.x>10 && point.x<WIDTH && point.y>10 && point.y<HEIGHT)
{
CDC *dc = m_grapho.GetDC();
CPen SolidPen;
SolidPen.CreatePen(PS_SOLID,1,RGB(255,255,255));
CBrush brush;
brush.CreateSolidBrush(RGB(255,255,255));
dc->SelectObject(brush);
dc->SelectObject(SolidPen);
dc->Rectangle(350,10,580,30);
double _tmp;
char crds[15];
CString coords;
_tmp=(point.x-36)*1000/kX+_par;
itoa((int)(_tmp),crds,10);
coords=crds;
itoa(ABS((int)(_tmp*100)%100),crds,10);
(ABS((int)(_tmp*100)%100)<10)?coords+=".0":coords+=".";
coords+=crds;
if (function==GAUSSIAN)
gcvt(fuzzy.fisGaussianMf(_tmp,param),2,crds);
else
if (function==TRIANGLE)
gcvt(fuzzy.fisTriangleMf(_tmp,param),2,crds);
else
if (function==TRAPEZOID)
gcvt(fuzzy.fisTrapezoidMf(_tmp,param),2,crds);
else
if (function==GAUSSIAN2)
gcvt(fuzzy.fisGaussian2Mf(_tmp,param),2,crds);
else
if (function==SIGMOID)
gcvt(fuzzy.fisSigmoidMf(_tmp,param),2,crds);
else
crds[0]='\0';
CFont *font = new CFont();
font->CreateFont(14, 10, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Courier");
dc->SelectObject(font);
dc->TextOut(50,10,"Точка x:"+coords+" Степень принадлежности:"+crds);
}
CDialog::OnMouseMove(nFlags, point);
}
void CFuzzyDlg::OnRadio1()
{
par_d.EnableWindow(false);
}
void CFuzzyDlg::OnRadio2()
{
par_c.EnableWindow(true);
par_d.EnableWindow(true);
}
void CFuzzyDlg::OnRadio3()
{
par_c.EnableWindow(false);
par_d.EnableWindow(false);
}
void CFuzzyDlg::OnRadio4()
{
par_c.EnableWindow(true);
par_d.EnableWindow(true);
}
void CFuzzyDlg::OnRadio5()
{
par_c.EnableWindow(false);
par_d.EnableWindow(false);
}
void CFuzzyDlg::Axis()
{
CDC *_dc = m_grapho.GetDC();
CPen DotPen;
DotPen.CreatePen(PS_DOT,1,RGB(0,0,0));
CPen SolidPen;
SolidPen.CreatePen(PS_SOLID,1,RGB(0,0,0));
CBrush brush;
brush.CreateSolidBrush(RGB(255,255,255));
_dc->SelectObject(brush);
_dc->Rectangle(0,0,WIDTH, HEIGHT);
_dc->SelectObject(SolidPen);
_dc->MoveTo(25,10);
_dc->LineTo(25, HEIGHT-40);
_dc->MoveTo(20,HEIGHT-40);
_dc->LineTo(WIDTH-20, HEIGHT-40);
_dc->SelectObject(DotPen);;
CFont *font = new CFont();
font->CreateFont(12, 7, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,